@@ -1648,14 +1648,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1648
1648
isContextSensitive,
1649
1649
getTypeOfPropertyOfContextualType,
1650
1650
getFullyQualifiedName,
1651
- getResolvedSignature: (node, candidatesOutArray, argumentCount) => getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.Normal),
1652
- getResolvedSignatureForStringLiteralCompletions: (call, editingArgument, candidatesOutArray, checkMode = CheckMode.IsForStringLiteralArgumentCompletions) => {
1653
- if (checkMode & CheckMode.IsForStringLiteralArgumentCompletions) {
1654
- return runWithInferenceBlockedFromSourceNode(editingArgument, () => getResolvedSignatureWorker(call, candidatesOutArray, /*argumentCount*/ undefined, checkMode & ~CheckMode.IsForStringLiteralArgumentCompletions));
1655
- }
1656
- return runWithoutResolvedSignatureCaching(editingArgument, () => getResolvedSignatureWorker(call, candidatesOutArray, /*argumentCount*/ undefined, checkMode & ~CheckMode.IsForStringLiteralArgumentCompletions));
1657
- },
1658
- getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, argumentCount) => runWithoutResolvedSignatureCaching(node, () => getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.IsForSignatureHelp)),
1651
+ getResolvedSignature: (node, candidatesOutArray, argumentCount) =>
1652
+ getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.Normal),
1653
+ getCandidateSignaturesForStringLiteralCompletions,
1654
+ getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, argumentCount) =>
1655
+ runWithoutResolvedSignatureCaching(node, () => getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.IsForSignatureHelp)),
1659
1656
getExpandedParameters,
1660
1657
hasEffectiveRestParameter,
1661
1658
containsArgumentsReference,
@@ -1834,22 +1831,47 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1834
1831
typeHasCallOrConstructSignatures,
1835
1832
};
1836
1833
1837
- function runWithoutResolvedSignatureCaching<T>(node: Node | undefined, fn: () => T): T {
1838
- const cachedSignatures = [];
1839
- while (node) {
1840
- if (isCallLikeExpression(node)) {
1841
- const nodeLinks = getNodeLinks(node);
1842
- const resolvedSignature = nodeLinks.resolvedSignature;
1843
- cachedSignatures.push([nodeLinks, resolvedSignature] as const);
1844
- nodeLinks.resolvedSignature = undefined;
1834
+ function getCandidateSignaturesForStringLiteralCompletions(call: CallLikeExpression, editingArgument: Node, checkMode = CheckMode.IsForStringLiteralArgumentCompletions) {
1835
+ const candidatesSet = new Set<Signature>();
1836
+ const candidates: Signature[] = [];
1837
+
1838
+ if (checkMode & CheckMode.IsForStringLiteralArgumentCompletions) {
1839
+ // first, get candidates when inference is blocked from the source node.
1840
+ runWithInferenceBlockedFromSourceNode(editingArgument, () => getResolvedSignatureWorker(call, candidates, /*argumentCount*/ undefined, checkMode));
1841
+ for (const candidate of candidates) {
1842
+ candidatesSet.add(candidate);
1845
1843
}
1846
- node = node.parent;
1844
+
1845
+ // reset candidates for second pass
1846
+ candidates.length = 0;
1847
1847
}
1848
- const result = fn();
1849
- for (const [nodeLinks, resolvedSignature] of cachedSignatures) {
1850
- nodeLinks.resolvedSignature = resolvedSignature;
1848
+
1849
+ // next, get candidates where the source node is considered for inference.
1850
+ runWithoutResolvedSignatureCaching(editingArgument, () => getResolvedSignatureWorker(call, candidates, /*argumentCount*/ undefined, checkMode & ~CheckMode.IsForStringLiteralArgumentCompletions));
1851
+ for (const candidate of candidates) {
1852
+ candidatesSet.add(candidate);
1851
1853
}
1852
- return result;
1854
+
1855
+ return arrayFrom(candidatesSet);
1856
+ }
1857
+
1858
+ function runWithoutResolvedSignatureCaching<T>(node: Node | undefined, fn: () => T): T {
1859
+ node = findAncestor(node, isCallLikeExpression);
1860
+ if (node) {
1861
+ const cachedSignatures = [];
1862
+ while (node) {
1863
+ const links = getNodeLinks(node);
1864
+ cachedSignatures.push([links, links.resolvedSignature] as const);
1865
+ links.resolvedSignature = undefined;
1866
+ node = findAncestor(node.parent, isCallLikeExpression);
1867
+ }
1868
+ const result = fn();
1869
+ for (const [links, resolvedSignature] of cachedSignatures) {
1870
+ links.resolvedSignature = resolvedSignature;
1871
+ }
1872
+ return result;
1873
+ }
1874
+ return fn();
1853
1875
}
1854
1876
1855
1877
function runWithInferenceBlockedFromSourceNode<T>(node: Node | undefined, fn: () => T): T {
@@ -33103,7 +33125,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
33103
33125
33104
33126
for (let i = 0; i < argCount; i++) {
33105
33127
const arg = args[i];
33106
- if (arg.kind !== SyntaxKind.OmittedExpression) {
33128
+ if (arg.kind !== SyntaxKind.OmittedExpression && !(checkMode & CheckMode.IsForStringLiteralArgumentCompletions && hasSkipDirectInferenceFlag(arg)) ) {
33107
33129
const paramType = getTypeAtPosition(signature, i);
33108
33130
if (couldContainTypeVariables(paramType)) {
33109
33131
const argType = checkExpressionWithContextualType(arg, paramType, context, checkMode);
@@ -33745,6 +33767,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
33745
33767
// decorators are applied to a declaration by the emitter, and not to an expression.
33746
33768
const isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters;
33747
33769
let argCheckMode = !isDecorator && !isSingleNonGenericCandidate && some(args, isContextSensitive) ? CheckMode.SkipContextSensitive : CheckMode.Normal;
33770
+ argCheckMode |= checkMode & CheckMode.IsForStringLiteralArgumentCompletions;
33748
33771
33749
33772
// The following variables are captured and modified by calls to chooseOverload.
33750
33773
// If overload resolution or type argument inference fails, we want to report the
@@ -33984,6 +34007,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
33984
34007
// them now (and keeping do so for any subsequent candidates) and perform a second
33985
34008
// round of type inference and applicability checking for this particular candidate.
33986
34009
argCheckMode = CheckMode.Normal;
34010
+ // argCheckMode = checkMode & CheckMode.IsForStringLiteralArgumentCompletions;
33987
34011
if (inferenceContext) {
33988
34012
const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext);
33989
34013
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext.inferredTypeParameters);
0 commit comments