From 637deab91ac408582dfa62165513fa696812386f Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 30 Jun 2020 13:27:57 -0700 Subject: [PATCH 1/2] Disable signature help on unresolved bare identifiers; add more declaration info on unresolvedproperty access --- src/services/signatureHelp.ts | 18 ++++++++++++++---- .../signatureHelpJSMissingIdentifier.ts | 9 +++++++++ .../signatureHelpJSMissingPropertyAccess.ts | 19 +++++++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 tests/cases/fourslash/signatureHelpJSMissingIdentifier.ts create mode 100644 tests/cases/fourslash/signatureHelpJSMissingPropertyAccess.ts diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 54447417a2a49..3bcac9d0fd5a8 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -116,18 +116,27 @@ namespace ts.SignatureHelp { } } + // @ts-ignore function createJSSignatureHelpItems(argumentInfo: ArgumentListInfo, program: Program, cancellationToken: CancellationToken): SignatureHelpItems | undefined { if (argumentInfo.invocation.kind === InvocationKind.Contextual) return undefined; // See if we can find some symbol with the call expression name that has call signatures. const expression = getExpressionFromInvocation(argumentInfo.invocation); - const name = isIdentifier(expression) ? expression.text : isPropertyAccessExpression(expression) ? expression.name.text : undefined; + const name = isPropertyAccessExpression(expression) ? expression.name.text : undefined; const typeChecker = program.getTypeChecker(); return name === undefined ? undefined : firstDefined(program.getSourceFiles(), sourceFile => firstDefined(sourceFile.getNamedDeclarations().get(name), declaration => { const type = declaration.symbol && typeChecker.getTypeOfSymbolAtLocation(declaration.symbol, declaration); const callSignatures = type && type.getCallSignatures(); if (callSignatures && callSignatures.length) { - return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(callSignatures, callSignatures[0], argumentInfo, sourceFile, typeChecker)); + return typeChecker.runWithCancellationToken( + cancellationToken, + typeChecker => createSignatureHelpItems( + callSignatures, + callSignatures[0], + argumentInfo, + sourceFile, + typeChecker, + /*useFullPrefix*/ true)); } })); } @@ -496,10 +505,11 @@ namespace ts.SignatureHelp { { isTypeParameterList, argumentCount, argumentsSpan: applicableSpan, invocation, argumentIndex }: ArgumentListInfo, sourceFile: SourceFile, typeChecker: TypeChecker, + useFullPrefix?: boolean, ): SignatureHelpItems { const enclosingDeclaration = getEnclosingDeclarationFromInvocation(invocation); - const callTargetSymbol = invocation.kind === InvocationKind.Contextual ? invocation.symbol : typeChecker.getSymbolAtLocation(getExpressionFromInvocation(invocation)); - const callTargetDisplayParts = callTargetSymbol ? symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined) : emptyArray; + const callTargetSymbol = invocation.kind === InvocationKind.Contextual ? invocation.symbol : (typeChecker.getSymbolAtLocation(getExpressionFromInvocation(invocation)) || useFullPrefix && resolvedSignature.declaration?.symbol); + const callTargetDisplayParts = callTargetSymbol ? symbolToDisplayParts(typeChecker, callTargetSymbol, useFullPrefix ? sourceFile : undefined, /*meaning*/ undefined) : emptyArray; const items = map(candidates, candidateSignature => getSignatureHelpItem(candidateSignature, callTargetDisplayParts, isTypeParameterList, typeChecker, enclosingDeclaration, sourceFile)); if (argumentIndex !== 0) { diff --git a/tests/cases/fourslash/signatureHelpJSMissingIdentifier.ts b/tests/cases/fourslash/signatureHelpJSMissingIdentifier.ts new file mode 100644 index 0000000000000..73b22459d6303 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpJSMissingIdentifier.ts @@ -0,0 +1,9 @@ +/// + +// @allowJs: true +// @checkJs: true + +// @Filename: test.js +////log(/**/) + +verify.noSignatureHelp(""); diff --git a/tests/cases/fourslash/signatureHelpJSMissingPropertyAccess.ts b/tests/cases/fourslash/signatureHelpJSMissingPropertyAccess.ts new file mode 100644 index 0000000000000..1c1cf427528b0 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpJSMissingPropertyAccess.ts @@ -0,0 +1,19 @@ +/// + +// @allowJs: true +// @checkJs: true + +// @Filename: test.js +////foo.filter(/**/) + +goTo.marker(""); +verify.signatureHelp({ + text: "ReadonlyArray.filter(predicate: (value: T, index: number, array: readonly T[]) => value is S, thisArg?: any): S[]", + overloadsCount: 2, + docComment: "Returns the elements of an array that meet the condition specified in a callback function.", + parameterDocComment: "A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array.", + tags: [ + { name: "param", text: "predicate A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array." }, + { name: "param", text: "thisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value." } + ] +}); From c5b70d9623934c13067da7016d907a47d108b30a Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 30 Jun 2020 13:57:39 -0700 Subject: [PATCH 2/2] Remove stray ts-ignore --- src/services/signatureHelp.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 3bcac9d0fd5a8..954cd1da9e1bf 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -116,7 +116,6 @@ namespace ts.SignatureHelp { } } - // @ts-ignore function createJSSignatureHelpItems(argumentInfo: ArgumentListInfo, program: Program, cancellationToken: CancellationToken): SignatureHelpItems | undefined { if (argumentInfo.invocation.kind === InvocationKind.Contextual) return undefined; // See if we can find some symbol with the call expression name that has call signatures.