mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-24 02:28:34 +01:00
Add ts/js deprecated support (#97742)
* 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
This commit is contained in:
@@ -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;
|
||||
@@ -75,11 +82,11 @@ 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,
|
||||
@@ -87,6 +94,12 @@ function fromProtocolCallHierarchyItem(item: Proto.CallHierarchyItem): vscode.Ca
|
||||
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 {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
@@ -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) {
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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,
|
||||
@@ -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));
|
||||
@@ -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 {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
Reference in New Issue
Block a user