From f0340005a3d8d7419398b18809e4312e12c0145b Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Sat, 5 Dec 2020 02:37:25 +0200 Subject: [PATCH] fix(41295): handle deprecated callbacks (#41310) --- src/compiler/checker.ts | 23 ++++++++++------- .../fourslash/jsdocDeprecated_suggestion12.ts | 22 ++++++++++++++++ .../fourslash/jsdocDeprecated_suggestion13.ts | 25 +++++++++++++++++++ 3 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 tests/cases/fourslash/jsdocDeprecated_suggestion12.ts create mode 100644 tests/cases/fourslash/jsdocDeprecated_suggestion13.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d4cbf85072a..e470e47b5c3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13844,9 +13844,14 @@ namespace ts { } function isUncalledFunctionReference(node: Node, symbol: Symbol) { - return !(symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) - || !isCallLikeExpression(findAncestor(node, n => !isAccessExpression(n)) || node.parent) - && every(symbol.declarations, d => !isFunctionLike(d) || !!(getCombinedNodeFlags(d) & NodeFlags.Deprecated)); + if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) { + const parent = findAncestor(node.parent, n => !isAccessExpression(n)) || node.parent; + if (isCallLikeExpression(parent)) { + return isCallOrNewExpression(parent) && isIdentifier(node) && hasMatchingArgument(parent, node); + } + return every(symbol.declarations, d => !isFunctionLike(d) || !!(getCombinedNodeFlags(d) & NodeFlags.Deprecated)); + } + return true; } function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags, noUncheckedIndexedAccessCandidate?: boolean, reportDeprecated?: boolean) { @@ -20953,16 +20958,16 @@ namespace ts { return isMatchingReference(source, target) || containsMatchingReference(source, target); } - function hasMatchingArgument(callExpression: CallExpression, reference: Node) { - if (callExpression.arguments) { - for (const argument of callExpression.arguments) { + function hasMatchingArgument(expression: CallExpression | NewExpression, reference: Node) { + if (expression.arguments) { + for (const argument of expression.arguments) { if (isOrContainsMatchingReference(reference, argument)) { return true; } } } - if (callExpression.expression.kind === SyntaxKind.PropertyAccessExpression && - isOrContainsMatchingReference(reference, (callExpression.expression).expression)) { + if (expression.expression.kind === SyntaxKind.PropertyAccessExpression && + isOrContainsMatchingReference(reference, (expression.expression).expression)) { return true; } return false; @@ -22875,7 +22880,7 @@ namespace ts { const localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol); const sourceSymbol = localOrExportSymbol.flags & SymbolFlags.Alias ? resolveAlias(localOrExportSymbol) : localOrExportSymbol; - if (getDeclarationNodeFlagsFromSymbol(sourceSymbol) & NodeFlags.Deprecated && isUncalledFunctionReference(node.parent, sourceSymbol)) { + if (getDeclarationNodeFlagsFromSymbol(sourceSymbol) & NodeFlags.Deprecated && isUncalledFunctionReference(node, sourceSymbol)) { errorOrSuggestion(/* isError */ false, node, Diagnostics._0_is_deprecated, node.escapedText as string); } diff --git a/tests/cases/fourslash/jsdocDeprecated_suggestion12.ts b/tests/cases/fourslash/jsdocDeprecated_suggestion12.ts new file mode 100644 index 00000000000..7c9c76b426e --- /dev/null +++ b/tests/cases/fourslash/jsdocDeprecated_suggestion12.ts @@ -0,0 +1,22 @@ +/// + +// @filename: foo.ts +/////** +//// * @deprecated +//// */ +////function foo() {}; +////function bar(fn: () => void) { +//// fn(); +////} +////bar([|foo|]); + +goTo.file('foo.ts'); +const ranges = test.ranges(); +verify.getSuggestionDiagnostics([ + { + "code": 6385, + "message": "'foo' is deprecated", + "reportsDeprecated": true, + "range": ranges[0] + }, +]); diff --git a/tests/cases/fourslash/jsdocDeprecated_suggestion13.ts b/tests/cases/fourslash/jsdocDeprecated_suggestion13.ts new file mode 100644 index 00000000000..09f2dadb9eb --- /dev/null +++ b/tests/cases/fourslash/jsdocDeprecated_suggestion13.ts @@ -0,0 +1,25 @@ +/// + +// @filename: foo.ts +/////** +//// * @deprecated +//// */ +////function foo() {}; +//// +////class Foo { +//// constructor(fn: () => void) { +//// fn(); +//// } +////} +////new Foo([|foo|]); + +goTo.file('foo.ts'); +const ranges = test.ranges(); +verify.getSuggestionDiagnostics([ + { + "code": 6385, + "message": "'foo' is deprecated", + "reportsDeprecated": true, + "range": ranges[0] + }, +]);