From dfe23421baefa8a3309b231118f894ebfda79190 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 30 Dec 2020 20:42:38 +0200 Subject: [PATCH] fix(41867): completions - omit the deprecated flag if some declarations are not deprecated (#41941) --- src/services/symbolDisplay.ts | 37 ++++++++++++------- src/services/utilities.ts | 6 ++- ...ag.ts => completionsWithDeprecatedTag1.ts} | 0 .../completionsWithDeprecatedTag2.ts | 15 ++++++++ .../completionsWithDeprecatedTag3.ts | 15 ++++++++ 5 files changed, 58 insertions(+), 15 deletions(-) rename tests/cases/fourslash/{completionsWithDeprecatedTag.ts => completionsWithDeprecatedTag1.ts} (100%) create mode 100644 tests/cases/fourslash/completionsWithDeprecatedTag2.ts create mode 100644 tests/cases/fourslash/completionsWithDeprecatedTag3.ts diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 4acba52253a..b1f74800635 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -100,31 +100,42 @@ namespace ts.SymbolDisplay { return ScriptElementKind.unknown; } + function isDeprecatedDeclaration(decl: Declaration) { + return !!(getCombinedNodeFlagsAlwaysIncludeJSDoc(decl) & ModifierFlags.Deprecated); + } + + function getNormalizedSymbolModifiers(symbol: Symbol) { + if (symbol.declarations && symbol.declarations.length) { + const [declaration, ...declarations] = symbol.declarations; + // omit deprecated flag if some declarations are not deprecated + const excludeFlags = length(declarations) && isDeprecatedDeclaration(declaration) && some(declarations, d => !isDeprecatedDeclaration(d)) + ? ModifierFlags.Deprecated + : ModifierFlags.None; + const modifiers = getNodeModifiers(declaration, excludeFlags); + if (modifiers) { + return modifiers.split(","); + } + } + return []; + } + export function getSymbolModifiers(typeChecker: TypeChecker, symbol: Symbol): string { if (!symbol) { return ScriptElementKindModifier.none; } - const modifiers = new Set(); - if (symbol.declarations && symbol.declarations.length > 0) { - const kindModifiers = getNodeModifiers(symbol.declarations[0]); - if (kindModifiers !== ScriptElementKindModifier.none) { - kindModifiers.split(",").forEach(m => modifiers.add(m)); - } - } + const modifiers = new Set(getNormalizedSymbolModifiers(symbol)); if (symbol.flags & SymbolFlags.Alias) { const resolvedSymbol = typeChecker.getAliasedSymbol(symbol); - if (resolvedSymbol !== symbol && resolvedSymbol.declarations && resolvedSymbol.declarations.length > 0) { - const kindModifiers = getNodeModifiers(resolvedSymbol.declarations[0]); - if (kindModifiers !== ScriptElementKindModifier.none) { - kindModifiers.split(",").forEach(m => modifiers.add(m)); - } + if (resolvedSymbol !== symbol) { + forEach(getNormalizedSymbolModifiers(resolvedSymbol), modifier => { + modifiers.add(modifier); + }); } } if (symbol.flags & SymbolFlags.Optional) { modifiers.add(ScriptElementKindModifier.optionalModifier); } - return modifiers.size > 0 ? arrayFrom(modifiers.values()).join(",") : ScriptElementKindModifier.none; } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 9cf63087ebd..d456c414bc7 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1588,9 +1588,11 @@ namespace ts { return n.kind === SyntaxKind.EndOfFileToken ? !!(n as EndOfFileToken).jsDoc : n.getWidth(sourceFile) !== 0; } - export function getNodeModifiers(node: Node): string { - const flags = isDeclaration(node) ? getCombinedNodeFlagsAlwaysIncludeJSDoc(node) : ModifierFlags.None; + export function getNodeModifiers(node: Node, excludeFlags = ModifierFlags.None): string { const result: string[] = []; + const flags = isDeclaration(node) + ? getCombinedNodeFlagsAlwaysIncludeJSDoc(node) & ~excludeFlags + : ModifierFlags.None; if (flags & ModifierFlags.Private) result.push(ScriptElementKindModifier.privateMemberModifier); if (flags & ModifierFlags.Protected) result.push(ScriptElementKindModifier.protectedMemberModifier); diff --git a/tests/cases/fourslash/completionsWithDeprecatedTag.ts b/tests/cases/fourslash/completionsWithDeprecatedTag1.ts similarity index 100% rename from tests/cases/fourslash/completionsWithDeprecatedTag.ts rename to tests/cases/fourslash/completionsWithDeprecatedTag1.ts diff --git a/tests/cases/fourslash/completionsWithDeprecatedTag2.ts b/tests/cases/fourslash/completionsWithDeprecatedTag2.ts new file mode 100644 index 00000000000..a902c6b30eb --- /dev/null +++ b/tests/cases/fourslash/completionsWithDeprecatedTag2.ts @@ -0,0 +1,15 @@ +/// + +/////** @deprecated foo */ +////declare function foo(); +/////** @deprecated foo */ +////declare function foo(x); +//// +////foo/**/ + +verify.completions({ + marker: "", + includes: [ + { name: "foo", kind: "function", kindModifiers: "deprecated,declare" } + ] +}); diff --git a/tests/cases/fourslash/completionsWithDeprecatedTag3.ts b/tests/cases/fourslash/completionsWithDeprecatedTag3.ts new file mode 100644 index 00000000000..19e9d5c561b --- /dev/null +++ b/tests/cases/fourslash/completionsWithDeprecatedTag3.ts @@ -0,0 +1,15 @@ +/// + +/////** @deprecated foo */ +////declare function foo(); +/////** ok */ +////declare function foo(x); +//// +////foo/**/ + +verify.completions({ + marker: "", + includes: [ + { name: "foo", kind: "function", kindModifiers: "declare" } + ] +});