Skip to content

Commit f47373a

Browse files
authored
Completions fourslash tests fixes (#1228)
1 parent 3babe5e commit f47373a

File tree

247 files changed

+550
-471
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

247 files changed

+550
-471
lines changed

internal/ast/ast.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,6 +1768,7 @@ type (
17681768
JsxOpeningLikeElement = Node // JsxOpeningElement | JsxSelfClosingElement
17691769
NamedImportsOrExports = Node // NamedImports | NamedExports
17701770
BreakOrContinueStatement = Node // BreakStatement | ContinueStatement
1771+
CallLikeExpression = Node // CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxCallLike | InstanceofExpression
17711772
)
17721773

17731774
// Aliases for node singletons

internal/ast/utilities.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2738,10 +2738,6 @@ func IsRequireCall(node *Node, requireStringLiteralLikeArgument bool) bool {
27382738
return !requireStringLiteralLikeArgument || IsStringLiteralLike(call.Arguments.Nodes[0])
27392739
}
27402740

2741-
func IsUnterminatedLiteral(node *Node) bool {
2742-
return node.LiteralLikeData().TokenFlags&TokenFlagsUnterminated != 0
2743-
}
2744-
27452741
func GetJSXImplicitImportBase(compilerOptions *core.CompilerOptions, file *SourceFile) string {
27462742
jsxImportSourcePragma := GetPragmaFromSourceFile(file, "jsximportsource")
27472743
jsxRuntimePragma := GetPragmaFromSourceFile(file, "jsxruntime")
@@ -3587,8 +3583,9 @@ func compareNodePositions(n1, n2 *Node) int {
35873583
return n1.Pos() - n2.Pos()
35883584
}
35893585

3590-
func IsUnterminatedNode(node *Node) bool {
3591-
return IsLiteralKind(node.Kind) && IsUnterminatedLiteral(node)
3586+
func IsUnterminatedLiteral(node *Node) bool {
3587+
return IsLiteralKind(node.Kind) && node.LiteralLikeData().TokenFlags&TokenFlagsUnterminated != 0 ||
3588+
IsTemplateLiteralKind(node.Kind) && node.TemplateLiteralLikeData().TemplateFlags&TokenFlagsUnterminated != 0
35923589
}
35933590

35943591
// Gets a value indicating whether a class element is either a static or an instance property declaration with an initializer.

internal/checker/exports.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,12 @@ func (c *Checker) GetExpandedParameters(signature *Signature, skipUnionExpanding
133133
func (c *Checker) GetResolvedSignature(node *ast.Node) *Signature {
134134
return c.getResolvedSignature(node, nil, CheckModeNormal)
135135
}
136+
137+
// Return the type of the given property in the given type, or nil if no such property exists
138+
func (c *Checker) GetTypeOfPropertyOfType(t *Type, name string) *Type {
139+
return c.getTypeOfPropertyOfType(t, name)
140+
}
141+
142+
func (c *Checker) GetContextualTypeForArgumentAtIndex(node *ast.Node, argIndex int) *Type {
143+
return c.getContextualTypeForArgumentAtIndex(node, argIndex)
144+
}

internal/checker/services.go

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"slices"
66

77
"github.com/microsoft/typescript-go/internal/ast"
8+
"github.com/microsoft/typescript-go/internal/collections"
89
"github.com/microsoft/typescript-go/internal/core"
910
"github.com/microsoft/typescript-go/internal/printer"
1011
)
@@ -168,7 +169,7 @@ func (c *Checker) GetAllPossiblePropertiesOfTypes(types []*Type) []*ast.Symbol {
168169
return c.getAugmentedPropertiesOfType(unionType)
169170
}
170171

171-
props := createSymbolTable(nil)
172+
props := make(ast.SymbolTable)
172173
for _, memberType := range types {
173174
augmentedProps := c.getAugmentedPropertiesOfType(memberType)
174175
for _, p := range augmentedProps {
@@ -231,6 +232,9 @@ func (c *Checker) getAugmentedPropertiesOfType(t *Type) []*ast.Symbol {
231232
functionType = c.globalNewableFunctionType
232233
}
233234

235+
if propsByName == nil {
236+
propsByName = make(ast.SymbolTable)
237+
}
234238
if functionType != nil {
235239
for _, p := range c.getPropertiesOfType(functionType) {
236240
if _, ok := propsByName[p.Name]; !ok {
@@ -579,3 +583,39 @@ func (c *Checker) getResolvedSignatureWorker(node *ast.Node, checkMode CheckMode
579583
c.apparentArgumentCount = nil
580584
return res, *candidatesOutArray
581585
}
586+
587+
func (c *Checker) GetCandidateSignaturesForStringLiteralCompletions(call *ast.CallLikeExpression, editingArgument *ast.Node) []*Signature {
588+
candidatesSet := collections.Set[*Signature]{}
589+
590+
// first, get candidates when inference is blocked from the source node.
591+
candidates := runWithInferenceBlockedFromSourceNode(c, editingArgument, func() []*Signature {
592+
_, blockedInferenceCandidates := c.getResolvedSignatureWorker(call, CheckModeNormal, 0)
593+
return blockedInferenceCandidates
594+
})
595+
for _, candidate := range candidates {
596+
candidatesSet.Add(candidate)
597+
}
598+
599+
// next, get candidates where the source node is considered for inference.
600+
candidates = runWithoutResolvedSignatureCaching(c, editingArgument, func() []*Signature {
601+
_, inferenceCandidates := c.getResolvedSignatureWorker(call, CheckModeNormal, 0)
602+
return inferenceCandidates
603+
})
604+
605+
for _, candidate := range candidates {
606+
candidatesSet.Add(candidate)
607+
}
608+
609+
return slices.Collect(maps.Keys(candidatesSet.Keys()))
610+
}
611+
612+
func (c *Checker) GetTypeParameterAtPosition(s *Signature, pos int) *Type {
613+
t := c.getTypeAtPosition(s, pos)
614+
if t.IsIndex() && isThisTypeParameter(t.AsIndexType().target) {
615+
constraint := c.getBaseConstraintOfType(t.AsIndexType().target)
616+
if constraint != nil {
617+
return c.getIndexType(constraint)
618+
}
619+
}
620+
return t
621+
}

internal/checker/types.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,10 @@ func (t *Type) IsTypeParameter() bool {
734734
return t.flags&TypeFlagsTypeParameter != 0
735735
}
736736

737+
func (t *Type) IsIndex() bool {
738+
return t.flags&TypeFlagsIndex != 0
739+
}
740+
737741
// TypeData
738742

739743
type TypeData interface {
@@ -1181,6 +1185,14 @@ func (s *Signature) ThisParameter() *ast.Symbol {
11811185
return s.thisParameter
11821186
}
11831187

1188+
func (s *Signature) Parameters() []*ast.Symbol {
1189+
return s.parameters
1190+
}
1191+
1192+
func (s *Signature) HasRestParameter() bool {
1193+
return s.flags&SignatureFlagsHasRestParameter != 0
1194+
}
1195+
11841196
type CompositeSignature struct {
11851197
isUnion bool // True for union, false for intersection
11861198
signatures []*Signature // Individual signatures

internal/fourslash/_scripts/convertFourslash.mts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,9 @@ function parseExpectedCompletionItem(expr: ts.Expression): string | undefined {
337337
return undefined;
338338
}
339339
item += `SortText: ptrTo(string(${result})), `;
340+
if (result === "ls.SortTextOptionalMember") {
341+
isOptional = true;
342+
}
340343
break;
341344
case "insertText":
342345
if (ts.isStringLiteral(init)) {
@@ -534,7 +537,7 @@ interface GoToMarkerCmd {
534537

535538
type Cmd = VerifyCompletionsCmd | GoToMarkerCmd;
536539

537-
function generateVerifyCompletions({ marker, args }: VerifyCompletionsCmd): string {
540+
function generateVerifyCompletions({ marker, args, isNewIdentifierLocation }: VerifyCompletionsCmd): string {
538541
let expectedList = "nil";
539542
if (args) {
540543
const expected = [];
@@ -543,10 +546,11 @@ function generateVerifyCompletions({ marker, args }: VerifyCompletionsCmd): stri
543546
if (args.exact) expected.push(`Exact: ${args.exact},`);
544547
// !!! isIncomplete
545548
// !!! itemDefaults/commitCharacters from `isNewIdentifierLocation`
549+
const commitCharacters = isNewIdentifierLocation ? "[]string{}" : "defaultCommitCharacters";
546550
expectedList = `&fourslash.VerifyCompletionsExpectedList{
547551
IsIncomplete: false,
548552
ItemDefaults: &lsproto.CompletionItemDefaults{
549-
CommitCharacters: &defaultCommitCharacters,
553+
CommitCharacters: &${commitCharacters},
550554
},
551555
Items: &fourslash.VerifyCompletionsExpectedItems{
552556
${expected.join("\n")}

0 commit comments

Comments
 (0)