Skip to content

Commit

Permalink
Add ts/js deprecated support (#97742)
Browse files Browse the repository at this point in the history
* Add ts/js deprecated support

* Support callhierarchy

* avoid tags

* fix lint

* fix lint

* Avoid changes

* Avoid assign

* Avoid changes

* Avoid styles

* Add temp deps for build

* update version

* add config item

* fix type

* Use expiremental namepsace

* fix types
  • Loading branch information
Kingwl authored Jun 22, 2020
1 parent 60da9d8 commit 9d6054c
Show file tree
Hide file tree
Showing 16 changed files with 108 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ import { VersionDependentRegistration } from '../utils/dependentRegistration';
import type * as Proto from '../protocol';
import * as path from 'path';
import * as PConst from '../protocol.const';
import { parseKindModifier } from '../utils/modifiers';

namespace Experimental {
export interface CallHierarchyItem extends Proto.CallHierarchyItem {
readonly kindModifiers?: string;
}
}

class TypeScriptCallHierarchySupport implements vscode.CallHierarchyProvider {
public static readonly minVersion = API.v380;
Expand Down Expand Up @@ -75,18 +82,24 @@ function isSourceFileItem(item: Proto.CallHierarchyItem) {
return item.kind === PConst.Kind.script || item.kind === PConst.Kind.module && item.selectionSpan.start.line === 1 && item.selectionSpan.start.offset === 1;
}

function fromProtocolCallHierarchyItem(item: Proto.CallHierarchyItem): vscode.CallHierarchyItem {
function fromProtocolCallHierarchyItem(item: Experimental.CallHierarchyItem): vscode.CallHierarchyItem {
const useFileName = isSourceFileItem(item);
const name = useFileName ? path.basename(item.file) : item.name;
const detail = useFileName ? vscode.workspace.asRelativePath(path.dirname(item.file)) : '';
return new vscode.CallHierarchyItem(
const result = new vscode.CallHierarchyItem(
typeConverters.SymbolKind.fromProtocolScriptElementKind(item.kind),
name,
detail,
vscode.Uri.file(item.file),
typeConverters.Range.fromTextSpan(item.span),
typeConverters.Range.fromTextSpan(item.selectionSpan)
);

const kindModifiers = item.kindModifiers ? parseKindModifier(item.kindModifiers) : undefined;
if (kindModifiers?.has(PConst.KindModifiers.depreacted)) {
result.tags = [vscode.SymbolTag.Deprecated];
}
return result;
}

function fromProtocolCallHierchyIncomingCall(item: Proto.CallHierarchyIncomingCall): vscode.CallHierarchyIncomingCall {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { TelemetryReporter } from '../utils/telemetry';
import * as typeConverters from '../utils/typeConverters';
import TypingsStatus from '../utils/typingsStatus';
import FileConfigurationManager from './fileConfigurationManager';
import { parseKindModifier } from '../utils/modifiers';

const localize = nls.loadMessageBundle();

Expand Down Expand Up @@ -90,8 +91,8 @@ class MyCompletionItem extends vscode.CompletionItem {
}

if (tsEntry.kindModifiers) {
const kindModifiers = tsEntry.kindModifiers.split(/,|\s+/g);
if (kindModifiers.includes(PConst.KindModifiers.optional)) {
const kindModifiers = parseKindModifier(tsEntry.kindModifiers);
if (kindModifiers.has(PConst.KindModifiers.optional)) {
if (!this.insertText) {
this.insertText = this.label;
}
Expand All @@ -101,14 +102,17 @@ class MyCompletionItem extends vscode.CompletionItem {
}
this.label += '?';
}
if (kindModifiers.has(PConst.KindModifiers.depreacted)) {
this.tags = [vscode.CompletionItemTag.Deprecated];
}

if (kindModifiers.includes(PConst.KindModifiers.color)) {
if (kindModifiers.has(PConst.KindModifiers.color)) {
this.kind = vscode.CompletionItemKind.Color;
}

if (tsEntry.kind === PConst.Kind.script) {
for (const extModifier of PConst.KindModifiers.fileExtensionKindModifiers) {
if (kindModifiers.includes(extModifier)) {
if (kindModifiers.has(extModifier)) {
if (tsEntry.name.toLowerCase().endsWith(extModifier)) {
this.detail = tsEntry.name;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class FileDiagnostics {
return this.get(DiagnosticKind.Suggestion).filter(x => {
if (!enableSuggestions) {
// Still show unused
return x.tags && x.tags.includes(vscode.DiagnosticTag.Unnecessary);
return x.tags && (x.tags.includes(vscode.DiagnosticTag.Unnecessary) || x.tags.includes(vscode.DiagnosticTag.Deprecated));
}
return true;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import * as PConst from '../protocol.const';
import { ITypeScriptServiceClient } from '../typescriptService';
import * as typeConverters from '../utils/typeConverters';
import { CachedResponse } from '../tsServer/cachedResponse';
import { parseKindModifier } from '../utils/modifiers';

const getSymbolKind = (kind: string): vscode.SymbolKind => {
switch (kind) {
Expand Down Expand Up @@ -79,6 +80,12 @@ class TypeScriptDocumentSymbolProvider implements vscode.DocumentSymbolProvider
range,
range.contains(selectionRange) ? selectionRange : range);


const kindModifiers = parseKindModifier(item.kindModifiers);
if (kindModifiers.has(PConst.KindModifiers.depreacted)) {
symbolInfo.tags = [vscode.SymbolTag.Deprecated];
}

for (const child of children) {
if (child.spans.some(span => !!range.intersection(typeConverters.Range.fromTextSpan(span)))) {
const includedChild = TypeScriptDocumentSymbolProvider.convertNavTree(resource, symbolInfo.children, child);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import API from '../utils/api';
import * as fileSchemes from '../utils/fileSchemes';
import { doesResourceLookLikeAJavaScriptFile, doesResourceLookLikeATypeScriptFile } from '../utils/languageDescription';
import * as typeConverters from '../utils/typeConverters';
import { parseKindModifier } from '../utils/modifiers';

function getSymbolKind(item: Proto.NavtoItem): vscode.SymbolKind {
switch (item.kind) {
Expand Down Expand Up @@ -90,11 +91,16 @@ class TypeScriptWorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvide

private toSymbolInformation(item: Proto.NavtoItem) {
const label = TypeScriptWorkspaceSymbolProvider.getLabel(item);
return new vscode.SymbolInformation(
const info = new vscode.SymbolInformation(
label,
getSymbolKind(item),
item.containerName || '',
typeConverters.Location.fromTextSpan(this.client.toResource(item.file), item));
const kindModifiers = item.kindModifiers ? parseKindModifier(item.kindModifiers) : undefined;
if (kindModifiers?.has(PConst.KindModifiers.depreacted)) {
info.tags = [vscode.SymbolTag.Deprecated];
}
return info;
}

private static getLabel(item: Proto.NavtoItem) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,16 +122,21 @@ export default class LanguageProvider extends Disposable {
this.client.bufferSyncSupport.requestAllDiagnostics();
}

public diagnosticsReceived(diagnosticsKind: DiagnosticKind, file: vscode.Uri, diagnostics: (vscode.Diagnostic & { reportUnnecessary: any })[]): void {
public diagnosticsReceived(diagnosticsKind: DiagnosticKind, file: vscode.Uri, diagnostics: (vscode.Diagnostic & { reportUnnecessary: any, reportDeprecated: any })[]): void {
const config = vscode.workspace.getConfiguration(this.id, file);
const reportUnnecessary = config.get<boolean>('showUnused', true);
const reportDeprecated = config.get<boolean>('showDeprecated', true);
this.client.diagnosticsManager.updateDiagnostics(file, this._diagnosticLanguage, diagnosticsKind, diagnostics.filter(diag => {
if (!reportUnnecessary) {
diag.tags = undefined;
if (diag.reportUnnecessary && diag.severity === vscode.DiagnosticSeverity.Hint) {
return false;
}
}
if (!reportDeprecated) {
if (diag.reportDeprecated && diag.severity === vscode.DiagnosticSeverity.Hint) {
return false;
}
}
return true;
}));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export class DiagnosticCategory {

export class KindModifiers {
public static readonly optional = 'optional';
public static readonly depreacted = 'deprecated';
public static readonly color = 'color';

public static readonly dtsFile = '.d.ts';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ import * as typeConverters from './utils/typeConverters';
import TypingsStatus, { AtaProgressReporter } from './utils/typingsStatus';
import VersionStatus from './utils/versionStatus';

namespace Experimental {
export interface Diagnostic extends Proto.Diagnostic {
readonly reportsDeprecated?: {}
}
}

// Style check diagnostics that can be reported as warnings
const styleCheckDiagnostics = new Set([
...errorCodes.variableDeclaredButNeverUsed,
Expand Down Expand Up @@ -233,11 +239,11 @@ export default class TypeScriptServiceClientHost extends Disposable {
private createMarkerDatas(
diagnostics: Proto.Diagnostic[],
source: string
): (vscode.Diagnostic & { reportUnnecessary: any })[] {
): (vscode.Diagnostic & { reportUnnecessary: any, reportDeprecated: any })[] {
return diagnostics.map(tsDiag => this.tsDiagnosticToVsDiagnostic(tsDiag, source));
}

private tsDiagnosticToVsDiagnostic(diagnostic: Proto.Diagnostic, source: string): vscode.Diagnostic & { reportUnnecessary: any } {
private tsDiagnosticToVsDiagnostic(diagnostic: Experimental.Diagnostic, source: string): vscode.Diagnostic & { reportUnnecessary: any, reportDeprecated: any } {
const { start, end, text } = diagnostic;
const range = new vscode.Range(typeConverters.Position.fromLocation(start), typeConverters.Position.fromLocation(end));
const converted = new vscode.Diagnostic(range, text, this.getDiagnosticSeverity(diagnostic));
Expand All @@ -255,11 +261,19 @@ export default class TypeScriptServiceClientHost extends Disposable {
return new vscode.DiagnosticRelatedInformation(typeConverters.Location.fromTextSpan(this.client.toResource(span.file), span), info.message);
}));
}
const tags: vscode.DiagnosticTag[] = [];
if (diagnostic.reportsUnnecessary) {
converted.tags = [vscode.DiagnosticTag.Unnecessary];
tags.push(vscode.DiagnosticTag.Unnecessary);
}
(converted as vscode.Diagnostic & { reportUnnecessary: any }).reportUnnecessary = diagnostic.reportsUnnecessary;
return converted as vscode.Diagnostic & { reportUnnecessary: any };
if (diagnostic.reportsDeprecated) {
tags.push(vscode.DiagnosticTag.Deprecated);
}
converted.tags = tags.length ? tags : undefined;

const resultConverted = converted as vscode.Diagnostic & { reportUnnecessary: any, reportDeprecated: any };
resultConverted.reportUnnecessary = diagnostic.reportsUnnecessary;
resultConverted.reportDeprecated = diagnostic.reportsDeprecated;
return resultConverted;
}

private getDiagnosticSeverity(diagnostic: Proto.Diagnostic): vscode.DiagnosticSeverity {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

export function parseKindModifier(kindModifiers: string): Set<string> {
return new Set(kindModifiers.split(/,|\s+/g));
}
9 changes: 9 additions & 0 deletions src/vs/editor/common/config/editorOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,10 @@ export interface IEditorOptions {
* Defaults to false.
*/
definitionLinkOpensInPeek?: boolean;
/**
* Controls strikethrough deprecated variables.
*/
showDeprecated?: boolean;
}

export interface IEditorConstructionOptions extends IEditorOptions {
Expand Down Expand Up @@ -3591,6 +3595,7 @@ export const enum EditorOption {
wordWrapMinified,
wrappingIndent,
wrappingStrategy,
showDeprecated,

// Leave these at the end (because they have dependencies!)
editorClassName,
Expand Down Expand Up @@ -4077,6 +4082,10 @@ export const EditorOptions = {
EditorOption.showUnused, 'showUnused', true,
{ description: nls.localize('showUnused', "Controls fading out of unused code.") }
)),
showDeprecated: register(new EditorBooleanOption(
EditorOption.showDeprecated, 'showDeprecated', true,
{ description: nls.localize('showDeprecated', "Controls strikethrough deprecated variables.") }
)),
snippetSuggestions: register(new EditorStringEnumOption(
EditorOption.snippetSuggestions, 'snippetSuggestions',
'inline' as 'top' | 'bottom' | 'inline' | 'none',
Expand Down
11 changes: 6 additions & 5 deletions src/vs/editor/common/standalone/standaloneEnums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,12 @@ export enum EditorOption {
wordWrapMinified = 109,
wrappingIndent = 110,
wrappingStrategy = 111,
editorClassName = 112,
pixelRatio = 113,
tabFocusMode = 114,
layoutInfo = 115,
wrappingInfo = 116
showDeprecated = 112,
editorClassName = 113,
pixelRatio = 114,
tabFocusMode = 115,
layoutInfo = 116,
wrappingInfo = 117
}

/**
Expand Down
16 changes: 11 additions & 5 deletions src/vs/monaco.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3129,6 +3129,10 @@ declare namespace monaco.editor {
* Defaults to false.
*/
definitionLinkOpensInPeek?: boolean;
/**
* Controls strikethrough deprecated variables.
*/
showDeprecated?: boolean;
}

export interface IEditorConstructionOptions extends IEditorOptions {
Expand Down Expand Up @@ -3945,11 +3949,12 @@ declare namespace monaco.editor {
wordWrapMinified = 109,
wrappingIndent = 110,
wrappingStrategy = 111,
editorClassName = 112,
pixelRatio = 113,
tabFocusMode = 114,
layoutInfo = 115,
wrappingInfo = 116
showDeprecated = 112,
editorClassName = 113,
pixelRatio = 114,
tabFocusMode = 115,
layoutInfo = 116,
wrappingInfo = 117
}
export const EditorOptions: {
acceptSuggestionOnCommitCharacter: IEditorOption<EditorOption.acceptSuggestionOnCommitCharacter, boolean>;
Expand Down Expand Up @@ -4045,6 +4050,7 @@ declare namespace monaco.editor {
selectOnLineNumbers: IEditorOption<EditorOption.selectOnLineNumbers, boolean>;
showFoldingControls: IEditorOption<EditorOption.showFoldingControls, 'always' | 'mouseover'>;
showUnused: IEditorOption<EditorOption.showUnused, boolean>;
showDeprecated: IEditorOption<EditorOption.showDeprecated, boolean>;
snippetSuggestions: IEditorOption<EditorOption.snippetSuggestions, 'none' | 'top' | 'bottom' | 'inline'>;
smoothScrolling: IEditorOption<EditorOption.smoothScrolling, boolean>;
stopRenderingLineAfter: IEditorOption<EditorOption.stopRenderingLineAfter, number>;
Expand Down
3 changes: 2 additions & 1 deletion src/vs/workbench/api/common/extHostLanguageFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class DocumentSymbolAdapter {
const element: modes.DocumentSymbol = {
name: info.name || '!!MISSING: name!!',
kind: typeConvert.SymbolKind.from(info.kind),
tags: info.tags ? info.tags.map(typeConvert.SymbolTag.from) : [],
tags: info.tags?.map(typeConvert.SymbolTag.from) || [],
detail: '',
containerName: info.containerName,
range: typeConvert.Range.from(info.location.range),
Expand Down Expand Up @@ -1287,6 +1287,7 @@ class CallHierarchyAdapter {
uri: item.uri,
range: typeConvert.Range.from(item.range),
selectionRange: typeConvert.Range.from(item.selectionRange),
tags: item.tags?.map(typeConvert.SymbolTag.from)
};
map.set(dto._itemId, item);
return dto;
Expand Down
4 changes: 2 additions & 2 deletions src/vs/workbench/api/common/extHostTypeConverters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ export namespace DocumentSymbol {
range: Range.from(info.range),
selectionRange: Range.from(info.selectionRange),
kind: SymbolKind.from(info.kind),
tags: info.tags ? info.tags.map(SymbolTag.from) : []
tags: info.tags?.map(SymbolTag.from) ?? []
};
if (info.children) {
result.children = info.children.map(from);
Expand Down Expand Up @@ -911,7 +911,7 @@ export namespace CompletionItem {

result.insertText = suggestion.insertText;
result.kind = CompletionItemKind.to(suggestion.kind);
result.tags = suggestion.tags && suggestion.tags.map(CompletionItemTag.to);
result.tags = suggestion.tags?.map(CompletionItemTag.to);
result.detail = suggestion.detail;
result.documentation = htmlContent.isMarkdownString(suggestion.documentation) ? MarkdownString.to(suggestion.documentation) : suggestion.documentation;
result.sortText = suggestion.sortText;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import { IIdentityProvider, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { FuzzyScore, createMatches } from 'vs/base/common/filters';
import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel';
import { SymbolKinds, Location } from 'vs/editor/common/modes';
import { SymbolKinds, Location, SymbolTag } from 'vs/editor/common/modes';
import { compare } from 'vs/base/common/strings';
import { Range } from 'vs/editor/common/core/range';
import { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
Expand Down Expand Up @@ -117,11 +117,12 @@ export class CallRenderer implements ITreeRenderer<Call, FuzzyScore, CallRenderi

renderElement(node: ITreeNode<Call, FuzzyScore>, _index: number, template: CallRenderingTemplate): void {
const { element, filterData } = node;
const deprecated = element.item.tags?.includes(SymbolTag.Deprecated);
template.icon.className = SymbolKinds.toCssClassName(element.item.kind, true);
template.label.setLabel(
element.item.name,
element.item.detail,
{ labelEscapeNewLines: true, matches: createMatches(filterData) }
{ labelEscapeNewLines: true, matches: createMatches(filterData), strikethrough: deprecated }
);
}
disposeTemplate(template: CallRenderingTemplate): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import { IRange } from 'vs/editor/common/core/range';
import { SymbolKind, ProviderResult } from 'vs/editor/common/modes';
import { SymbolKind, ProviderResult, SymbolTag } from 'vs/editor/common/modes';
import { ITextModel } from 'vs/editor/common/model';
import { CancellationToken } from 'vs/base/common/cancellation';
import { LanguageFeatureRegistry } from 'vs/editor/common/modes/languageFeatureRegistry';
Expand Down Expand Up @@ -32,6 +32,7 @@ export interface CallHierarchyItem {
uri: URI;
range: IRange;
selectionRange: IRange;
tags?: SymbolTag[]
}

export interface IncomingCall {
Expand Down

0 comments on commit 9d6054c

Please sign in to comment.