From a3bc393de83fc9aa50d244bcf2b0d5756da831d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 23 Jun 2025 13:22:34 +0200 Subject: [PATCH 1/2] Handle `blockedStringType` --- internal/ast/nodeflags.go | 2 -- internal/checker/checker.go | 4 +++- internal/fourslash/_scripts/failingTests.txt | 4 ---- .../gen/completionsLiteralMatchingGenericSignature_test.go | 2 +- ...omGenericConditionalTypesUsingTemplateLiteralTypes_test.go | 2 +- ...orGenericConditionalTypesUsingTemplateLiteralTypes_test.go | 2 +- .../stringLiteralCompletionsInPositionTypedUsingRest_test.go | 2 +- 7 files changed, 7 insertions(+), 11 deletions(-) diff --git a/internal/ast/nodeflags.go b/internal/ast/nodeflags.go index 5b6441ed58..2feb4f2a52 100644 --- a/internal/ast/nodeflags.go +++ b/internal/ast/nodeflags.go @@ -43,8 +43,6 @@ const ( NodeFlagsJsonFile NodeFlags = 1 << 25 // If node was parsed in a Json NodeFlagsDeprecated NodeFlags = 1 << 26 // If has '@deprecated' JSDoc tag - NodeFlagsSkipDirectInference NodeFlags = 1 << 27 // If the node should skip direct type inference. - NodeFlagsBlockScoped = NodeFlagsLet | NodeFlagsConst | NodeFlagsUsing NodeFlagsConstant = NodeFlagsConst | NodeFlagsUsing NodeFlagsAwaitUsing = NodeFlagsConst | NodeFlagsUsing // Variable declaration (NOTE: on a single node these flags would otherwise be mutually exclusive) diff --git a/internal/checker/checker.go b/internal/checker/checker.go index a20cd5ddd8..4b595b6e2e 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -7352,7 +7352,9 @@ func (c *Checker) checkExpressionWorker(node *ast.Node, checkMode CheckMode) *Ty case ast.KindNullKeyword: return c.nullWideningType case ast.KindStringLiteral, ast.KindNoSubstitutionTemplateLiteral: - // !!! Handle blockedStringType + if c.isSkipDirectInferenceNode(node) { + return c.blockedStringType + } return c.getFreshTypeOfLiteralType(c.getStringLiteralType(node.Text())) case ast.KindNumericLiteral: c.checkGrammarNumericLiteral(node.AsNumericLiteral()) diff --git a/internal/fourslash/_scripts/failingTests.txt b/internal/fourslash/_scripts/failingTests.txt index e8d7eed736..44318e35a7 100644 --- a/internal/fourslash/_scripts/failingTests.txt +++ b/internal/fourslash/_scripts/failingTests.txt @@ -115,7 +115,6 @@ TestCompletionsJsPropertyAssignment TestCompletionsJsxAttribute2 TestCompletionsKeyof TestCompletionsLiteralFromInferenceWithinInferredType3 -TestCompletionsLiteralMatchingGenericSignature TestCompletionsNamespaceName TestCompletionsNewTarget TestCompletionsNonExistentImport @@ -237,11 +236,8 @@ TestPathCompletionsPackageJsonImportsWildcard9 TestPathCompletionsTypesVersionsLocal TestPathCompletionsTypesVersionsWildcard2 TestSatisfiesOperatorCompletion -TestStringCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes TestStringCompletionsImportOrExportSpecifier TestStringCompletionsVsEscaping -TestStringLiteralCompletionsForGenericConditionalTypesUsingTemplateLiteralTypes -TestStringLiteralCompletionsInPositionTypedUsingRest TestStringLiteralTypeCompletionsInTypeArgForNonGeneric1 TestTripleSlashRefPathCompletionAbsolutePaths TestTripleSlashRefPathCompletionContext diff --git a/internal/fourslash/tests/gen/completionsLiteralMatchingGenericSignature_test.go b/internal/fourslash/tests/gen/completionsLiteralMatchingGenericSignature_test.go index 35c3199418..52e1a7f4a0 100644 --- a/internal/fourslash/tests/gen/completionsLiteralMatchingGenericSignature_test.go +++ b/internal/fourslash/tests/gen/completionsLiteralMatchingGenericSignature_test.go @@ -10,7 +10,7 @@ import ( func TestCompletionsLiteralMatchingGenericSignature(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @Filename: /a.tsx declare function bar1

(p: P): void; diff --git a/internal/fourslash/tests/gen/stringCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes_test.go b/internal/fourslash/tests/gen/stringCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes_test.go index 736800e502..9a0a4bf8b1 100644 --- a/internal/fourslash/tests/gen/stringCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes_test.go +++ b/internal/fourslash/tests/gen/stringCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes_test.go @@ -10,7 +10,7 @@ import ( func TestStringCompletionsFromGenericConditionalTypesUsingTemplateLiteralTypes(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `// @strict: true type keyword = "foo" | "bar" | "baz" diff --git a/internal/fourslash/tests/gen/stringLiteralCompletionsForGenericConditionalTypesUsingTemplateLiteralTypes_test.go b/internal/fourslash/tests/gen/stringLiteralCompletionsForGenericConditionalTypesUsingTemplateLiteralTypes_test.go index 928a41ccda..d51a867f4c 100644 --- a/internal/fourslash/tests/gen/stringLiteralCompletionsForGenericConditionalTypesUsingTemplateLiteralTypes_test.go +++ b/internal/fourslash/tests/gen/stringLiteralCompletionsForGenericConditionalTypesUsingTemplateLiteralTypes_test.go @@ -10,7 +10,7 @@ import ( func TestStringLiteralCompletionsForGenericConditionalTypesUsingTemplateLiteralTypes(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = ` type PathOf = K extends ` + "`" + `${infer U}.${infer V}` + "`" + ` diff --git a/internal/fourslash/tests/gen/stringLiteralCompletionsInPositionTypedUsingRest_test.go b/internal/fourslash/tests/gen/stringLiteralCompletionsInPositionTypedUsingRest_test.go index 2b9cb483e5..0a77fc5807 100644 --- a/internal/fourslash/tests/gen/stringLiteralCompletionsInPositionTypedUsingRest_test.go +++ b/internal/fourslash/tests/gen/stringLiteralCompletionsInPositionTypedUsingRest_test.go @@ -10,7 +10,7 @@ import ( func TestStringLiteralCompletionsInPositionTypedUsingRest(t *testing.T) { t.Parallel() - t.Skip() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = `declare function pick(obj: T, ...keys: K[]): Pick; declare function pick2(obj: T, ...keys: K): Pick; From 33d2015a2524d317b7a70ed56819309d5571e412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 23 Jun 2025 18:28:50 +0200 Subject: [PATCH 2/2] stable candidates order --- internal/checker/services.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/internal/checker/services.go b/internal/checker/services.go index 62b842f1be..ad5e39b857 100644 --- a/internal/checker/services.go +++ b/internal/checker/services.go @@ -585,28 +585,27 @@ func (c *Checker) getResolvedSignatureWorker(node *ast.Node, checkMode CheckMode } func (c *Checker) GetCandidateSignaturesForStringLiteralCompletions(call *ast.CallLikeExpression, editingArgument *ast.Node) []*Signature { - candidatesSet := collections.Set[*Signature]{} - // first, get candidates when inference is blocked from the source node. candidates := runWithInferenceBlockedFromSourceNode(c, editingArgument, func() []*Signature { _, blockedInferenceCandidates := c.getResolvedSignatureWorker(call, CheckModeNormal, 0) return blockedInferenceCandidates }) - for _, candidate := range candidates { - candidatesSet.Add(candidate) - } + candidatesSet := collections.NewSetFromItems(candidates...) // next, get candidates where the source node is considered for inference. - candidates = runWithoutResolvedSignatureCaching(c, editingArgument, func() []*Signature { + otherCandidates := runWithoutResolvedSignatureCaching(c, editingArgument, func() []*Signature { _, inferenceCandidates := c.getResolvedSignatureWorker(call, CheckModeNormal, 0) return inferenceCandidates }) - for _, candidate := range candidates { - candidatesSet.Add(candidate) + for _, candidate := range otherCandidates { + if candidatesSet.Has(candidate) { + continue + } + candidates = append(candidates, candidate) } - return slices.Collect(maps.Keys(candidatesSet.Keys())) + return candidates } func (c *Checker) GetTypeParameterAtPosition(s *Signature, pos int) *Type {