Skip to content

Commit 1182233

Browse files
iisaduangabritto
andauthored
autoimport completions (#1553)
Co-authored-by: Gabriela Araujo Britto <[email protected]>
1 parent 5d1d69a commit 1182233

Some content is hidden

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

54 files changed

+4829
-279
lines changed

internal/ast/ast.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,8 @@ func (n *Node) ModuleSpecifier() *Expression {
994994
return n.AsImportDeclaration().ModuleSpecifier
995995
case KindExportDeclaration:
996996
return n.AsExportDeclaration().ModuleSpecifier
997+
case KindJSDocImportTag:
998+
return n.AsJSDocImportTag().ModuleSpecifier
997999
}
9981000
panic("Unhandled case in Node.ModuleSpecifier: " + n.Kind.String())
9991001
}

internal/ast/utilities.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,6 +1409,16 @@ func GetNameOfDeclaration(declaration *Node) *Node {
14091409
return nil
14101410
}
14111411

1412+
func GetImportClauseOfDeclaration(declaration *Declaration) *ImportClause {
1413+
switch declaration.Kind {
1414+
case KindImportDeclaration:
1415+
return declaration.AsImportDeclaration().ImportClause.AsImportClause()
1416+
case KindJSDocImportTag:
1417+
return declaration.AsJSDocImportTag().ImportClause.AsImportClause()
1418+
}
1419+
return nil
1420+
}
1421+
14121422
func GetNonAssignedNameOfDeclaration(declaration *Node) *Node {
14131423
// !!!
14141424
switch declaration.Kind {
@@ -2723,6 +2733,15 @@ func IsRequireCall(node *Node, requireStringLiteralLikeArgument bool) bool {
27232733
return !requireStringLiteralLikeArgument || IsStringLiteralLike(call.Arguments.Nodes[0])
27242734
}
27252735

2736+
func IsRequireVariableStatement(node *Node) bool {
2737+
if IsVariableStatement(node) {
2738+
if declarations := node.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes; len(declarations) > 0 {
2739+
return core.Every(declarations, IsVariableDeclarationInitializedToRequire)
2740+
}
2741+
}
2742+
return false
2743+
}
2744+
27262745
func GetJSXImplicitImportBase(compilerOptions *core.CompilerOptions, file *SourceFile) string {
27272746
jsxImportSourcePragma := GetPragmaFromSourceFile(file, "jsximportsource")
27282747
jsxRuntimePragma := GetPragmaFromSourceFile(file, "jsxruntime")

internal/checker/exports.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,26 @@ func (c *Checker) GetMergedSymbol(symbol *ast.Symbol) *ast.Symbol {
2626
return c.getMergedSymbol(symbol)
2727
}
2828

29+
func (c *Checker) TryFindAmbientModule(moduleName string) *ast.Symbol {
30+
return c.tryFindAmbientModule(moduleName, true /* withAugmentations */)
31+
}
32+
33+
func (c *Checker) GetImmediateAliasedSymbol(symbol *ast.Symbol) *ast.Symbol {
34+
return c.getImmediateAliasedSymbol(symbol)
35+
}
36+
37+
func (c *Checker) GetTypeOnlyAliasDeclaration(symbol *ast.Symbol) *ast.Node {
38+
return c.getTypeOnlyAliasDeclaration(symbol)
39+
}
40+
41+
func (c *Checker) ResolveExternalModuleName(moduleSpecifier *ast.Node) *ast.Symbol {
42+
return c.resolveExternalModuleName(moduleSpecifier, moduleSpecifier, true /*ignoreErrors*/)
43+
}
44+
45+
func (c *Checker) ResolveExternalModuleSymbol(moduleSymbol *ast.Symbol) *ast.Symbol {
46+
return c.resolveExternalModuleSymbol(moduleSymbol, false /*dontResolveAlias*/)
47+
}
48+
2949
func (c *Checker) GetTypeFromTypeNode(node *ast.Node) *Type {
3050
return c.getTypeFromTypeNode(node)
3151
}
@@ -150,7 +170,3 @@ func (c *Checker) GetIndexSignaturesAtLocation(node *ast.Node) []*ast.Node {
150170
func (c *Checker) GetResolvedSymbol(node *ast.Node) *ast.Symbol {
151171
return c.getResolvedSymbol(node)
152172
}
153-
154-
func (c *Checker) GetImmediateAliasedSymbol(symbol *ast.Symbol) *ast.Symbol {
155-
return c.getImmediateAliasedSymbol(symbol)
156-
}

internal/checker/nodebuilderimpl.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,7 @@ func canHaveModuleSpecifier(node *ast.Node) bool {
10761076
return false
10771077
}
10781078

1079-
func tryGetModuleSpecifierFromDeclaration(node *ast.Node) *ast.Node {
1079+
func TryGetModuleSpecifierFromDeclaration(node *ast.Node) *ast.Node {
10801080
res := tryGetModuleSpecifierFromDeclarationWorker(node)
10811081
if res == nil || !ast.IsStringLiteral(res) {
10821082
return nil
@@ -1162,7 +1162,7 @@ func (b *nodeBuilderImpl) getSpecifierForModuleSymbol(symbol *ast.Symbol, overri
11621162
enclosingDeclaration := b.e.MostOriginal(b.ctx.enclosingDeclaration)
11631163
var originalModuleSpecifier *ast.Node
11641164
if canHaveModuleSpecifier(enclosingDeclaration) {
1165-
originalModuleSpecifier = tryGetModuleSpecifierFromDeclaration(enclosingDeclaration)
1165+
originalModuleSpecifier = TryGetModuleSpecifierFromDeclaration(enclosingDeclaration)
11661166
}
11671167
contextFile := b.ctx.enclosingFile
11681168
resolutionMode := overrideImportMode
@@ -1213,6 +1213,7 @@ func (b *nodeBuilderImpl) getSpecifierForModuleSymbol(symbol *ast.Symbol, overri
12131213
modulespecifiers.ModuleSpecifierOptions{
12141214
OverrideImportMode: overrideImportMode,
12151215
},
1216+
false, /*forAutoImports*/
12161217
)
12171218
specifier := allSpecifiers[0]
12181219
links.specifierCache[cacheKey] = specifier

internal/checker/services.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,35 @@ func (c *Checker) GetExportsOfModule(symbol *ast.Symbol) []*ast.Symbol {
118118
return symbolsToArray(c.getExportsOfModule(symbol))
119119
}
120120

121+
func (c *Checker) ForEachExportAndPropertyOfModule(moduleSymbol *ast.Symbol, cb func(*ast.Symbol, string)) {
122+
for key, exportedSymbol := range c.getExportsOfModule(moduleSymbol) {
123+
if !isReservedMemberName(key) {
124+
cb(exportedSymbol, key)
125+
}
126+
}
127+
128+
exportEquals := c.resolveExternalModuleSymbol(moduleSymbol, false /*dontResolveAlias*/)
129+
if exportEquals == moduleSymbol {
130+
return
131+
}
132+
133+
typeOfSymbol := c.getTypeOfSymbol(exportEquals)
134+
if !c.shouldTreatPropertiesOfExternalModuleAsExports(typeOfSymbol) {
135+
return
136+
}
137+
138+
// forEachPropertyOfType
139+
reducedType := c.getReducedApparentType(typeOfSymbol)
140+
if reducedType.flags&TypeFlagsStructuredType == 0 {
141+
return
142+
}
143+
for name, symbol := range c.resolveStructuredTypeMembers(reducedType).members {
144+
if c.isNamedMember(symbol, name) {
145+
cb(symbol, name)
146+
}
147+
}
148+
}
149+
121150
func (c *Checker) IsValidPropertyAccess(node *ast.Node, propertyName string) bool {
122151
return c.isValidPropertyAccess(node, propertyName)
123152
}
@@ -345,6 +374,13 @@ func runWithoutResolvedSignatureCaching[T any](c *Checker, node *ast.Node, fn fu
345374
return fn()
346375
}
347376

377+
func (c *Checker) SkipAlias(symbol *ast.Symbol) *ast.Symbol {
378+
if symbol.Flags&ast.SymbolFlagsAlias != 0 {
379+
return c.GetAliasedSymbol(symbol)
380+
}
381+
return symbol
382+
}
383+
348384
func (c *Checker) GetRootSymbols(symbol *ast.Symbol) []*ast.Symbol {
349385
roots := c.getImmediateRootSymbols(symbol)
350386
if len(roots) == 0 {

internal/compiler/program.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ func (p *Program) UseCaseSensitiveFileNames() bool {
155155
return p.Host().FS().UseCaseSensitiveFileNames()
156156
}
157157

158+
func (p *Program) UsesUriStyleNodeCoreModules() bool {
159+
return p.usesUriStyleNodeCoreModules.IsTrue()
160+
}
161+
158162
var _ checker.Program = (*Program)(nil)
159163

160164
/** This should have similar behavior to 'processSourceFile' without diagnostics or mutation. */

internal/core/compileroptions.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,17 @@ const (
477477
NewLineKindLF NewLineKind = 2
478478
)
479479

480+
func GetNewLineKind(s string) NewLineKind {
481+
switch s {
482+
case "\r\n":
483+
return NewLineKindCRLF
484+
case "\n":
485+
return NewLineKindLF
486+
default:
487+
return NewLineKindNone
488+
}
489+
}
490+
480491
func (newLine NewLineKind) GetNewLineCharacter() string {
481492
switch newLine {
482493
case NewLineKindCRLF:

internal/core/core.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,17 @@ func Every[T any](slice []T, f func(T) bool) bool {
176176
return true
177177
}
178178

179+
func Or[T any](funcs ...func(T) bool) func(T) bool {
180+
return func(input T) bool {
181+
for _, f := range funcs {
182+
if f(input) {
183+
return true
184+
}
185+
}
186+
return false
187+
}
188+
}
189+
179190
func Find[T any](slice []T, f func(T) bool) T {
180191
for _, value := range slice {
181192
if f(value) {

internal/core/nodemodules.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ var ExclusivelyPrefixedNodeCoreModules = map[string]bool{
7070
"node:test/reporters": true,
7171
}
7272

73-
var nodeCoreModules = sync.OnceValue(func() map[string]bool {
73+
var NodeCoreModules = sync.OnceValue(func() map[string]bool {
7474
nodeCoreModules := make(map[string]bool, len(UnprefixedNodeCoreModules)*2+len(ExclusivelyPrefixedNodeCoreModules))
7575
for unprefixed := range UnprefixedNodeCoreModules {
7676
nodeCoreModules[unprefixed] = true
@@ -81,7 +81,7 @@ var nodeCoreModules = sync.OnceValue(func() map[string]bool {
8181
})
8282

8383
func NonRelativeModuleNameForTypingCache(moduleName string) string {
84-
if nodeCoreModules()[moduleName] {
84+
if NodeCoreModules()[moduleName] {
8585
return "node"
8686
}
8787
return moduleName

internal/core/textchange.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package core
22

3+
import "strings"
4+
35
type TextChange struct {
46
TextRange
57
NewText string
@@ -8,3 +10,21 @@ type TextChange struct {
810
func (t TextChange) ApplyTo(text string) string {
911
return text[:t.Pos()] + t.NewText + text[t.End():]
1012
}
13+
14+
func ApplyBulkEdits(text string, edits []TextChange) string {
15+
b := strings.Builder{}
16+
b.Grow(len(text))
17+
lastEnd := 0
18+
for _, e := range edits {
19+
start := e.TextRange.Pos()
20+
if start != lastEnd {
21+
b.WriteString(text[lastEnd:e.TextRange.Pos()])
22+
}
23+
b.WriteString(e.NewText)
24+
25+
lastEnd = e.TextRange.End()
26+
}
27+
b.WriteString(text[lastEnd:])
28+
29+
return b.String()
30+
}

0 commit comments

Comments
 (0)