From 038bfd49066624ed582e3d2dbfd522ccc062311c Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 3 May 2023 15:32:30 -0400 Subject: [PATCH 1/7] Include source node inferences in string literal completions --- src/compiler/checker.ts | 68 +++++++++++++------ src/compiler/types.ts | 2 +- src/services/stringCompletions.ts | 4 +- ...nditionalTypesUsingTemplateLiteralTypes.ts | 15 ++++ 4 files changed, 63 insertions(+), 26 deletions(-) create mode 100644 tests/cases/fourslash/stringLiteralCompletionsForGenericConditionalTypesUsingTemplateLiteralTypes.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8e49e18d4d1a3..17daa4cea9eaf 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1648,14 +1648,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { isContextSensitive, getTypeOfPropertyOfContextualType, getFullyQualifiedName, - getResolvedSignature: (node, candidatesOutArray, argumentCount) => getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.Normal), - getResolvedSignatureForStringLiteralCompletions: (call, editingArgument, candidatesOutArray, checkMode = CheckMode.IsForStringLiteralArgumentCompletions) => { - if (checkMode & CheckMode.IsForStringLiteralArgumentCompletions) { - return runWithInferenceBlockedFromSourceNode(editingArgument, () => getResolvedSignatureWorker(call, candidatesOutArray, /*argumentCount*/ undefined, checkMode & ~CheckMode.IsForStringLiteralArgumentCompletions)); - } - return runWithoutResolvedSignatureCaching(editingArgument, () => getResolvedSignatureWorker(call, candidatesOutArray, /*argumentCount*/ undefined, checkMode & ~CheckMode.IsForStringLiteralArgumentCompletions)); - }, - getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, argumentCount) => runWithoutResolvedSignatureCaching(node, () => getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.IsForSignatureHelp)), + getResolvedSignature: (node, candidatesOutArray, argumentCount) => + getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.Normal), + getCandidateSignaturesForStringLiteralCompletions, + getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, argumentCount) => + runWithoutResolvedSignatureCaching(node, () => getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.IsForSignatureHelp)), getExpandedParameters, hasEffectiveRestParameter, containsArgumentsReference, @@ -1834,22 +1831,47 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { typeHasCallOrConstructSignatures, }; - function runWithoutResolvedSignatureCaching(node: Node | undefined, fn: () => T): T { - const cachedSignatures = []; - while (node) { - if (isCallLikeExpression(node)) { - const nodeLinks = getNodeLinks(node); - const resolvedSignature = nodeLinks.resolvedSignature; - cachedSignatures.push([nodeLinks, resolvedSignature] as const); - nodeLinks.resolvedSignature = undefined; + function getCandidateSignaturesForStringLiteralCompletions(call: CallLikeExpression, editingArgument: Node, checkMode = CheckMode.IsForStringLiteralArgumentCompletions) { + const candidatesSet = new Set(); + const candidates: Signature[] = []; + + if (checkMode & CheckMode.IsForStringLiteralArgumentCompletions) { + // first, get candidates when inference is blocked from the source node. + runWithInferenceBlockedFromSourceNode(editingArgument, () => getResolvedSignatureWorker(call, candidates, /*argumentCount*/ undefined, checkMode)); + for (const candidate of candidates) { + candidatesSet.add(candidate); } - node = node.parent; + + // reset candidates for second pass + candidates.length = 0; } - const result = fn(); - for (const [nodeLinks, resolvedSignature] of cachedSignatures) { - nodeLinks.resolvedSignature = resolvedSignature; + + // next, get candidates where the source node is considered for inference. + runWithoutResolvedSignatureCaching(editingArgument, () => getResolvedSignatureWorker(call, candidates, /*argumentCount*/ undefined, checkMode & ~CheckMode.IsForStringLiteralArgumentCompletions)); + for (const candidate of candidates) { + candidatesSet.add(candidate); } - return result; + + return arrayFrom(candidatesSet); + } + + function runWithoutResolvedSignatureCaching(node: Node | undefined, fn: () => T): T { + node = findAncestor(node, isCallLikeExpression); + if (node) { + const cachedSignatures = []; + while (node) { + const links = getNodeLinks(node); + cachedSignatures.push([links, links.resolvedSignature] as const); + links.resolvedSignature = undefined; + node = findAncestor(node.parent, isCallLikeExpression); + } + const result = fn(); + for (const [links, resolvedSignature] of cachedSignatures) { + links.resolvedSignature = resolvedSignature; + } + return result; + } + return fn(); } function runWithInferenceBlockedFromSourceNode(node: Node | undefined, fn: () => T): T { @@ -33103,7 +33125,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { for (let i = 0; i < argCount; i++) { const arg = args[i]; - if (arg.kind !== SyntaxKind.OmittedExpression) { + if (arg.kind !== SyntaxKind.OmittedExpression && !(checkMode & CheckMode.IsForStringLiteralArgumentCompletions && hasSkipDirectInferenceFlag(arg))) { const paramType = getTypeAtPosition(signature, i); if (couldContainTypeVariables(paramType)) { const argType = checkExpressionWithContextualType(arg, paramType, context, checkMode); @@ -33745,6 +33767,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // decorators are applied to a declaration by the emitter, and not to an expression. const isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters; let argCheckMode = !isDecorator && !isSingleNonGenericCandidate && some(args, isContextSensitive) ? CheckMode.SkipContextSensitive : CheckMode.Normal; + argCheckMode |= checkMode & CheckMode.IsForStringLiteralArgumentCompletions; // The following variables are captured and modified by calls to chooseOverload. // If overload resolution or type argument inference fails, we want to report the @@ -33984,6 +34007,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // them now (and keeping do so for any subsequent candidates) and perform a second // round of type inference and applicability checking for this particular candidate. argCheckMode = CheckMode.Normal; + // argCheckMode = checkMode & CheckMode.IsForStringLiteralArgumentCompletions; if (inferenceContext) { const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext); checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext.inferredTypeParameters); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 14575e7f1733d..00ca1e79ee999 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4992,7 +4992,7 @@ export interface TypeChecker { */ getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature | undefined; /** @internal */ getResolvedSignatureForSignatureHelp(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature | undefined; - /** @internal */ getResolvedSignatureForStringLiteralCompletions(call: CallLikeExpression, editingArgument: Node, candidatesOutArray: Signature[], checkMode?: CheckMode): Signature | undefined; + /** @internal */ getCandidateSignaturesForStringLiteralCompletions(call: CallLikeExpression, editingArgument: Node, checkMode?: CheckMode): Signature[]; /** @internal */ getExpandedParameters(sig: Signature): readonly (readonly Symbol[])[]; /** @internal */ hasEffectiveRestParameter(sig: Signature): boolean; /** @internal */ containsArgumentsReference(declaration: SignatureDeclaration): boolean; diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 76326ad5ed9f9..89486ca2baa7b 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -117,7 +117,6 @@ import { ScriptElementKind, ScriptElementKindModifier, ScriptTarget, - Signature, signatureHasRestParameter, SignatureHelp, singleElementArray, @@ -500,9 +499,8 @@ function getAlreadyUsedTypesInStringLiteralUnion(union: UnionTypeNode, current: function getStringLiteralCompletionsFromSignature(call: CallLikeExpression, arg: StringLiteralLike, argumentInfo: SignatureHelp.ArgumentInfoForCompletions, checker: TypeChecker, checkMode = CheckMode.IsForStringLiteralArgumentCompletions): StringLiteralCompletionsFromTypes | undefined { let isNewIdentifier = false; const uniques = new Map(); - const candidates: Signature[] = []; const editingArgument = isJsxOpeningLikeElement(call) ? Debug.checkDefined(findAncestor(arg.parent, isJsxAttribute)) : arg; - checker.getResolvedSignatureForStringLiteralCompletions(call, editingArgument, candidates, checkMode); + const candidates = checker.getCandidateSignaturesForStringLiteralCompletions(call, editingArgument, checkMode); const types = flatMap(candidates, candidate => { if (!signatureHasRestParameter(candidate) && argumentInfo.argumentCount > candidate.parameters.length) return; let type = candidate.getTypeParameterAtPosition(argumentInfo.argumentIndex); diff --git a/tests/cases/fourslash/stringLiteralCompletionsForGenericConditionalTypesUsingTemplateLiteralTypes.ts b/tests/cases/fourslash/stringLiteralCompletionsForGenericConditionalTypesUsingTemplateLiteralTypes.ts new file mode 100644 index 0000000000000..5c63857b2feaa --- /dev/null +++ b/tests/cases/fourslash/stringLiteralCompletionsForGenericConditionalTypesUsingTemplateLiteralTypes.ts @@ -0,0 +1,15 @@ +/// + +// NOTE: Test pulled from https://github.com/microsoft/TypeScript/pull/52997 + +// @Filename: /a.tsx +//// type PathOf = +//// K extends `${infer U}.${infer V}` +//// ? U extends keyof T ? PathOf : `${P}${keyof T & (string | number)}` +//// : K extends keyof T ? `${P}${K}` : `${P}${keyof T & (string | number)}`; +//// +//// declare function consumer(path: PathOf<{a: string, b: {c: string}}, K>) : number; +//// +//// consumer('b./*ts*/') + +verify.completions({ marker: ["ts"], exact: ["a", "b", "b.c"] }); \ No newline at end of file From c667870c776baef059d6391e7b8386e809e020b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Wed, 31 May 2023 19:53:44 +0200 Subject: [PATCH 2/7] Add extra test cases for string completions (#54133) --- ...nditionalTypesUsingTemplateLiteralTypes.ts | 5 ++- ...nditionalTypesUsingTemplateLiteralTypes.ts | 35 +++++++++++++++++++ ...eralCompletionsInPositionTypedUsingRest.ts | 21 +++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/stringLiteralCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes.ts create mode 100644 tests/cases/fourslash/stringLiteralCompletionsInPositionTypedUsingRest.ts diff --git a/tests/cases/fourslash/stringLiteralCompletionsForGenericConditionalTypesUsingTemplateLiteralTypes.ts b/tests/cases/fourslash/stringLiteralCompletionsForGenericConditionalTypesUsingTemplateLiteralTypes.ts index 5c63857b2feaa..0074976300ce3 100644 --- a/tests/cases/fourslash/stringLiteralCompletionsForGenericConditionalTypesUsingTemplateLiteralTypes.ts +++ b/tests/cases/fourslash/stringLiteralCompletionsForGenericConditionalTypesUsingTemplateLiteralTypes.ts @@ -1,8 +1,7 @@ /// -// NOTE: Test pulled from https://github.com/microsoft/TypeScript/pull/52997 +// repro from https://github.com/microsoft/TypeScript/issues/49680 -// @Filename: /a.tsx //// type PathOf = //// K extends `${infer U}.${infer V}` //// ? U extends keyof T ? PathOf : `${P}${keyof T & (string | number)}` @@ -12,4 +11,4 @@ //// //// consumer('b./*ts*/') -verify.completions({ marker: ["ts"], exact: ["a", "b", "b.c"] }); \ No newline at end of file +verify.completions({ marker: ["ts"], exact: ["a", "b", "b.c"] }); diff --git a/tests/cases/fourslash/stringLiteralCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes.ts b/tests/cases/fourslash/stringLiteralCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes.ts new file mode 100644 index 0000000000000..c222c615a8886 --- /dev/null +++ b/tests/cases/fourslash/stringLiteralCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes.ts @@ -0,0 +1,35 @@ +/// + +// @strict: true + +// repro from https://github.com/microsoft/TypeScript/issues/53997 + +//// type keyword = "foo" | "bar" | "baz" +//// +//// type validateString = s extends keyword +//// ? s +//// : s extends `${infer left extends keyword}|${infer right}` +//// ? right extends keyword +//// ? s +//// : `${left}|${keyword}` +//// : keyword +//// +//// type isUnknown = unknown extends t +//// ? [t] extends [{}] +//// ? false +//// : true +//// : false +//// +//// type validate = def extends string +//// ? validateString +//// : isUnknown extends true +//// ? keyword +//// : { +//// [k in keyof def]: validate +//// } +//// const parse = (def: validate) => def +//// const shallowExpression = parse("foo|/*ts*/") +//// const nestedExpression = parse({ prop: "foo|/*ts2*/" }) + +verify.completions({ marker: ["ts"], exact: ["foo", "bar", "baz", "foo|foo", "foo|bar", "foo|baz"] }); +verify.completions({ marker: ["ts2"], exact: ["foo|foo", "foo|bar", "foo|baz"] }); diff --git a/tests/cases/fourslash/stringLiteralCompletionsInPositionTypedUsingRest.ts b/tests/cases/fourslash/stringLiteralCompletionsInPositionTypedUsingRest.ts new file mode 100644 index 0000000000000..bd4a11eac9e00 --- /dev/null +++ b/tests/cases/fourslash/stringLiteralCompletionsInPositionTypedUsingRest.ts @@ -0,0 +1,21 @@ +/// + +// repro from https://github.com/microsoft/TypeScript/issues/49680#issuecomment-1249191842 + +//// declare function pick(obj: T, ...keys: K[]): Pick; +//// declare function pick2(obj: T, ...keys: K): Pick; +//// +//// const obj = { aaa: 1, bbb: '2', ccc: true }; +//// +//// pick(obj, 'aaa', '/*ts1*/'); +//// pick2(obj, 'aaa', '/*ts2*/'); + +// repro from https://github.com/microsoft/TypeScript/issues/49680#issuecomment-1273677941 + +//// class Q { +//// public select(...args: Keys[]) {} +//// } +//// new Q<{ id: string; name: string }>().select("name", "/*ts3*/"); + +verify.completions({ marker: ["ts1", "ts2"], exact: ["aaa", "bbb", "ccc"] }); +verify.completions({ marker: ["ts3"], exact: ["name", "id"] }); From 3e23961305fbddff4a842a9baf57a4c28a09477c Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 31 Aug 2023 15:48:04 -0400 Subject: [PATCH 3/7] Remove commented line of code --- src/compiler/checker.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 17daa4cea9eaf..a119fb6f8d70b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -34007,7 +34007,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // them now (and keeping do so for any subsequent candidates) and perform a second // round of type inference and applicability checking for this particular candidate. argCheckMode = CheckMode.Normal; - // argCheckMode = checkMode & CheckMode.IsForStringLiteralArgumentCompletions; if (inferenceContext) { const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext); checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext.inferredTypeParameters); From e51def6e81d1b20609112a469cb3d5bcfba5e033 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 31 Aug 2023 16:21:17 -0400 Subject: [PATCH 4/7] Remove extra completions from test --- ...tionsFromGenericConditionalTypesUsingTemplateLiteralTypes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/fourslash/stringLiteralCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes.ts b/tests/cases/fourslash/stringLiteralCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes.ts index c222c615a8886..da203a444d129 100644 --- a/tests/cases/fourslash/stringLiteralCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes.ts +++ b/tests/cases/fourslash/stringLiteralCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes.ts @@ -31,5 +31,5 @@ //// const shallowExpression = parse("foo|/*ts*/") //// const nestedExpression = parse({ prop: "foo|/*ts2*/" }) -verify.completions({ marker: ["ts"], exact: ["foo", "bar", "baz", "foo|foo", "foo|bar", "foo|baz"] }); +verify.completions({ marker: ["ts"], exact: ["foo|foo", "foo|bar", "foo|baz"] }); verify.completions({ marker: ["ts2"], exact: ["foo|foo", "foo|bar", "foo|baz"] }); From 83434def7cbac4534554fa561d8207db8882a32d Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 31 Aug 2023 17:07:49 -0400 Subject: [PATCH 5/7] Remove duplicate test --- ...nditionalTypesUsingTemplateLiteralTypes.ts | 35 ------------------- 1 file changed, 35 deletions(-) delete mode 100644 tests/cases/fourslash/stringLiteralCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes.ts diff --git a/tests/cases/fourslash/stringLiteralCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes.ts b/tests/cases/fourslash/stringLiteralCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes.ts deleted file mode 100644 index da203a444d129..0000000000000 --- a/tests/cases/fourslash/stringLiteralCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes.ts +++ /dev/null @@ -1,35 +0,0 @@ -/// - -// @strict: true - -// repro from https://github.com/microsoft/TypeScript/issues/53997 - -//// type keyword = "foo" | "bar" | "baz" -//// -//// type validateString = s extends keyword -//// ? s -//// : s extends `${infer left extends keyword}|${infer right}` -//// ? right extends keyword -//// ? s -//// : `${left}|${keyword}` -//// : keyword -//// -//// type isUnknown = unknown extends t -//// ? [t] extends [{}] -//// ? false -//// : true -//// : false -//// -//// type validate = def extends string -//// ? validateString -//// : isUnknown extends true -//// ? keyword -//// : { -//// [k in keyof def]: validate -//// } -//// const parse = (def: validate) => def -//// const shallowExpression = parse("foo|/*ts*/") -//// const nestedExpression = parse({ prop: "foo|/*ts2*/" }) - -verify.completions({ marker: ["ts"], exact: ["foo|foo", "foo|bar", "foo|baz"] }); -verify.completions({ marker: ["ts2"], exact: ["foo|foo", "foo|bar", "foo|baz"] }); From 7210673e6f4a0ccb9ad64eb41bec1189f92f3e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Fri, 8 Sep 2023 16:45:44 +0200 Subject: [PATCH 6/7] Remove redundant code related to argument string completions (#55624) --- src/compiler/checker.ts | 20 +++++++++----------- src/compiler/types.ts | 3 +-- src/services/stringCompletions.ts | 7 +++---- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a119fb6f8d70b..785aba5d2576a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1831,23 +1831,21 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { typeHasCallOrConstructSignatures, }; - function getCandidateSignaturesForStringLiteralCompletions(call: CallLikeExpression, editingArgument: Node, checkMode = CheckMode.IsForStringLiteralArgumentCompletions) { + function getCandidateSignaturesForStringLiteralCompletions(call: CallLikeExpression, editingArgument: Node) { const candidatesSet = new Set(); const candidates: Signature[] = []; - if (checkMode & CheckMode.IsForStringLiteralArgumentCompletions) { - // first, get candidates when inference is blocked from the source node. - runWithInferenceBlockedFromSourceNode(editingArgument, () => getResolvedSignatureWorker(call, candidates, /*argumentCount*/ undefined, checkMode)); - for (const candidate of candidates) { - candidatesSet.add(candidate); - } - - // reset candidates for second pass - candidates.length = 0; + // first, get candidates when inference is blocked from the source node. + runWithInferenceBlockedFromSourceNode(editingArgument, () => getResolvedSignatureWorker(call, candidates, /*argumentCount*/ undefined, CheckMode.IsForStringLiteralArgumentCompletions)); + for (const candidate of candidates) { + candidatesSet.add(candidate); } + // reset candidates for second pass + candidates.length = 0; + // next, get candidates where the source node is considered for inference. - runWithoutResolvedSignatureCaching(editingArgument, () => getResolvedSignatureWorker(call, candidates, /*argumentCount*/ undefined, checkMode & ~CheckMode.IsForStringLiteralArgumentCompletions)); + runWithoutResolvedSignatureCaching(editingArgument, () => getResolvedSignatureWorker(call, candidates, /*argumentCount*/ undefined, CheckMode.Normal)); for (const candidate of candidates) { candidatesSet.add(candidate); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 00ca1e79ee999..33fd0ba2a4c28 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1,6 +1,5 @@ import { BaseNodeFactory, - CheckMode, CreateSourceFileOptions, EmitHelperFactory, GetCanonicalFileName, @@ -4992,7 +4991,7 @@ export interface TypeChecker { */ getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature | undefined; /** @internal */ getResolvedSignatureForSignatureHelp(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature | undefined; - /** @internal */ getCandidateSignaturesForStringLiteralCompletions(call: CallLikeExpression, editingArgument: Node, checkMode?: CheckMode): Signature[]; + /** @internal */ getCandidateSignaturesForStringLiteralCompletions(call: CallLikeExpression, editingArgument: Node): Signature[]; /** @internal */ getExpandedParameters(sig: Signature): readonly (readonly Symbol[])[]; /** @internal */ hasEffectiveRestParameter(sig: Signature): boolean; /** @internal */ containsArgumentsReference(declaration: SignatureDeclaration): boolean; diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 89486ca2baa7b..3f8bc5fa0861b 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -7,7 +7,6 @@ import { CaseClause, changeExtension, CharacterCodes, - CheckMode, combinePaths, comparePaths, comparePatternKeys, @@ -406,7 +405,7 @@ function getStringLiteralCompletionEntries(sourceFile: SourceFile, node: StringL // Get string literal completions from specialized signatures of the target // i.e. declare function f(a: 'A'); // f("/*completion position*/") - return argumentInfo && (getStringLiteralCompletionsFromSignature(argumentInfo.invocation, node, argumentInfo, typeChecker) || getStringLiteralCompletionsFromSignature(argumentInfo.invocation, node, argumentInfo, typeChecker, CheckMode.Normal)) || fromContextualType(ContextFlags.None); + return argumentInfo && getStringLiteralCompletionsFromSignature(argumentInfo.invocation, node, argumentInfo, typeChecker) || fromContextualType(ContextFlags.None); } // falls through (is `require("")` or `require(""` or `import("")`) @@ -496,11 +495,11 @@ function getAlreadyUsedTypesInStringLiteralUnion(union: UnionTypeNode, current: return mapDefined(union.types, type => type !== current && isLiteralTypeNode(type) && isStringLiteral(type.literal) ? type.literal.text : undefined); } -function getStringLiteralCompletionsFromSignature(call: CallLikeExpression, arg: StringLiteralLike, argumentInfo: SignatureHelp.ArgumentInfoForCompletions, checker: TypeChecker, checkMode = CheckMode.IsForStringLiteralArgumentCompletions): StringLiteralCompletionsFromTypes | undefined { +function getStringLiteralCompletionsFromSignature(call: CallLikeExpression, arg: StringLiteralLike, argumentInfo: SignatureHelp.ArgumentInfoForCompletions, checker: TypeChecker): StringLiteralCompletionsFromTypes | undefined { let isNewIdentifier = false; const uniques = new Map(); const editingArgument = isJsxOpeningLikeElement(call) ? Debug.checkDefined(findAncestor(arg.parent, isJsxAttribute)) : arg; - const candidates = checker.getCandidateSignaturesForStringLiteralCompletions(call, editingArgument, checkMode); + const candidates = checker.getCandidateSignaturesForStringLiteralCompletions(call, editingArgument); const types = flatMap(candidates, candidate => { if (!signatureHasRestParameter(candidate) && argumentInfo.argumentCount > candidate.parameters.length) return; let type = candidate.getTypeParameterAtPosition(argumentInfo.argumentIndex); From cf58c08ed1fe8f569fcf20d074e60f72eab3015c Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 25 Sep 2023 16:01:18 -0400 Subject: [PATCH 7/7] Fix formatting --- src/compiler/checker.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 785aba5d2576a..84d1974f5e88e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1648,11 +1648,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { isContextSensitive, getTypeOfPropertyOfContextualType, getFullyQualifiedName, - getResolvedSignature: (node, candidatesOutArray, argumentCount) => - getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.Normal), + getResolvedSignature: (node, candidatesOutArray, argumentCount) => getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.Normal), getCandidateSignaturesForStringLiteralCompletions, - getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, argumentCount) => - runWithoutResolvedSignatureCaching(node, () => getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.IsForSignatureHelp)), + getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, argumentCount) => runWithoutResolvedSignatureCaching(node, () => getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.IsForSignatureHelp)), getExpandedParameters, hasEffectiveRestParameter, containsArgumentsReference,