Skip to content

Commit 38047d6

Browse files
committed
auto import host first try
1 parent 97bc51f commit 38047d6

1 file changed

Lines changed: 89 additions & 17 deletions

File tree

internal/lsp/server.go

Lines changed: 89 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/microsoft/typescript-go/internal/ls/lsconv"
2929
"github.com/microsoft/typescript-go/internal/ls/lsutil"
3030
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
31+
"github.com/microsoft/typescript-go/internal/packagejson"
3132
"github.com/microsoft/typescript-go/internal/project"
3233
"github.com/microsoft/typescript-go/internal/project/ata"
3334
"github.com/microsoft/typescript-go/internal/sourcemap"
@@ -146,6 +147,7 @@ type DenoProgramEntry struct {
146147
userPreferences *lsutil.UserPreferences
147148
formatOptions *format.FormatCodeSettings
148149
vfs *DenoVFS
150+
autoImportRegistry *autoimport.Registry
149151
}
150152

151153
type DenoProgramEntries struct {
@@ -159,20 +161,22 @@ type DenoServerData struct {
159161
}
160162

161163
type DenoLanguageServiceHost struct {
162-
vfs *DenoVFS
163-
positionEncoding lsproto.PositionEncodingKind
164-
userPreferences *lsutil.UserPreferences
165-
formatOptions *format.FormatCodeSettings
164+
vfs *DenoVFS
165+
positionEncoding lsproto.PositionEncodingKind
166+
userPreferences *lsutil.UserPreferences
167+
formatOptions *format.FormatCodeSettings
168+
autoImportRegistry *autoimport.Registry
166169
}
167170

168171
var _ ls.Host = (*DenoLanguageServiceHost)(nil)
169172

170-
func NewDenoLanguageServiceHost(vfs *DenoVFS, userPreferences *lsutil.UserPreferences, formatOptions *format.FormatCodeSettings) *DenoLanguageServiceHost {
173+
func NewDenoLanguageServiceHost(vfs *DenoVFS, userPreferences *lsutil.UserPreferences, formatOptions *format.FormatCodeSettings, autoImportRegistry *autoimport.Registry) *DenoLanguageServiceHost {
171174
return &DenoLanguageServiceHost{
172-
vfs: vfs,
173-
positionEncoding: lsproto.PositionEncodingKindUTF16, // default
174-
userPreferences: userPreferences,
175-
formatOptions: formatOptions,
175+
vfs: vfs,
176+
positionEncoding: lsproto.PositionEncodingKindUTF16, // default
177+
userPreferences: userPreferences,
178+
formatOptions: formatOptions,
179+
autoImportRegistry: autoImportRegistry,
176180
}
177181
}
178182

@@ -214,8 +218,7 @@ func (h *DenoLanguageServiceHost) GetECMALineInfo(fileName string) *sourcemap.EC
214218
}
215219

216220
func (h *DenoLanguageServiceHost) AutoImportRegistry() *autoimport.Registry {
217-
// Auto-import not supported for Deno host yet
218-
return nil
221+
return h.autoImportRegistry
219222
}
220223

221224
// DenoVFS implements vfs.FS by reading files from the client via LSP requests
@@ -255,8 +258,8 @@ func (v *DenoVFS) FileExists(path string) bool {
255258

256259
func (v *DenoVFS) GetDocument(path string) *lsproto.DenoDocumentData {
257260
var uri lsproto.DocumentUri
258-
if strings.HasPrefix(path, "asset:///") {
259-
uri = lsproto.DocumentUri(path)
261+
if suffix, found := strings.CutPrefix(path, "asset:///"); found {
262+
uri = lsproto.DocumentUri("deno:/asset/" + suffix)
260263
} else {
261264
uri = lsconv.FileNameToDocumentURI(path)
262265
}
@@ -320,6 +323,47 @@ func (v *DenoVFS) Realpath(path string) string {
320323
return path
321324
}
322325

326+
// denoAutoImportHost is a minimal implementation of autoimport.RegistryCloneHost
327+
// used to initialize the auto-import registry for Deno projects.
328+
type denoAutoImportHost struct {
329+
vfs vfs.FS
330+
cwd string
331+
projectPath tspath.Path
332+
program *compiler.Program
333+
}
334+
335+
var _ autoimport.RegistryCloneHost = (*denoAutoImportHost)(nil)
336+
337+
func (h *denoAutoImportHost) FS() vfs.FS {
338+
return h.vfs
339+
}
340+
341+
func (h *denoAutoImportHost) GetCurrentDirectory() string {
342+
return h.cwd
343+
}
344+
345+
func (h *denoAutoImportHost) GetDefaultProject(path tspath.Path) (tspath.Path, *compiler.Program) {
346+
return h.projectPath, h.program
347+
}
348+
349+
func (h *denoAutoImportHost) GetProgramForProject(projectPath tspath.Path) *compiler.Program {
350+
if projectPath == h.projectPath {
351+
return h.program
352+
}
353+
return nil
354+
}
355+
356+
func (h *denoAutoImportHost) GetPackageJson(fileName string) *packagejson.InfoCacheEntry {
357+
return nil
358+
}
359+
360+
func (h *denoAutoImportHost) GetSourceFile(fileName string, path tspath.Path) *ast.SourceFile {
361+
return h.program.GetSourceFile(fileName)
362+
}
363+
364+
func (h *denoAutoImportHost) Dispose() {
365+
}
366+
323367
type Server struct {
324368
r Reader
325369
w Writer
@@ -1032,7 +1076,7 @@ func (o *DenoCrossProjectOrchestrator) GetLanguageServiceForProjectWithFile(ctx
10321076
return nil
10331077
}
10341078
pe := denoProject.programEntry
1035-
host := NewDenoLanguageServiceHost(pe.vfs, pe.userPreferences, pe.formatOptions)
1079+
host := NewDenoLanguageServiceHost(pe.vfs, pe.userPreferences, pe.formatOptions, pe.autoImportRegistry)
10361080
return ls.NewLanguageService(pe.projectPath, pe.program, host)
10371081
}
10381082

@@ -1264,13 +1308,13 @@ func (s *Server) handleDenoRequest(ctx context.Context, params *lsproto.DenoRequ
12641308
for _, pe := range s.deno.programEntries.byCompilerOptionsKey {
12651309
programs = append(programs, pe.program)
12661310
if firstHost == nil {
1267-
firstHost = NewDenoLanguageServiceHost(pe.vfs, pe.userPreferences, pe.formatOptions)
1311+
firstHost = NewDenoLanguageServiceHost(pe.vfs, pe.userPreferences, pe.formatOptions, pe.autoImportRegistry)
12681312
}
12691313
}
12701314
for _, pe := range s.deno.programEntries.byNotebookUri {
12711315
programs = append(programs, pe.program)
12721316
if firstHost == nil {
1273-
firstHost = NewDenoLanguageServiceHost(pe.vfs, pe.userPreferences, pe.formatOptions)
1317+
firstHost = NewDenoLanguageServiceHost(pe.vfs, pe.userPreferences, pe.formatOptions, pe.autoImportRegistry)
12741318
}
12751319
}
12761320
if firstHost == nil {
@@ -1296,7 +1340,7 @@ func (s *Server) getDenoLanguageService(ctx context.Context, compilerOptionsKey
12961340
return nil, nil, nil, fmt.Errorf("Couldn't find program entry for key: %s", compilerOptionsKey)
12971341
}
12981342

1299-
host := NewDenoLanguageServiceHost(pe.vfs, pe.userPreferences, pe.formatOptions)
1343+
host := NewDenoLanguageServiceHost(pe.vfs, pe.userPreferences, pe.formatOptions, pe.autoImportRegistry)
13001344
orchestrator := &DenoCrossProjectOrchestrator{
13011345
server: s,
13021346
ctx: ctx,
@@ -1334,6 +1378,33 @@ func (s *Server) createDenoProgramEntry(ctx context.Context, compilerOptionsKey
13341378
})
13351379
projectPath := tspath.ToPath(s.cwd, "", denoVFS.UseCaseSensitiveFileNames())
13361380

1381+
toPath := func(fileName string) tspath.Path {
1382+
return tspath.ToPath(fileName, s.cwd, denoVFS.UseCaseSensitiveFileNames())
1383+
}
1384+
autoImportRegistry := autoimport.NewRegistry(toPath)
1385+
1386+
// Initialize the registry with a project bucket by calling Clone with the open files
1387+
autoImportHost := &denoAutoImportHost{
1388+
vfs: wrappedFS,
1389+
cwd: s.cwd,
1390+
projectPath: projectPath,
1391+
program: program,
1392+
}
1393+
openFiles := make(map[tspath.Path]string)
1394+
var firstFilePath tspath.Path
1395+
for _, file := range projectConfig.Files {
1396+
fileName := file.FileName()
1397+
filePath := toPath(fileName)
1398+
openFiles[filePath] = fileName
1399+
if firstFilePath == "" {
1400+
firstFilePath = filePath
1401+
}
1402+
}
1403+
autoImportRegistry, _ = autoImportRegistry.Clone(ctx, autoimport.RegistryChange{
1404+
OpenFiles: openFiles,
1405+
RequestedFile: firstFilePath, // Triggers updateIndexes to build the project bucket
1406+
}, autoImportHost, nil)
1407+
13371408
return &DenoProgramEntry{
13381409
program: program,
13391410
projectPath: projectPath,
@@ -1343,6 +1414,7 @@ func (s *Server) createDenoProgramEntry(ctx context.Context, compilerOptionsKey
13431414
userPreferences: projectConfig.UserPreferences,
13441415
formatOptions: projectConfig.FormatOptions,
13451416
vfs: denoVFS,
1417+
autoImportRegistry: autoImportRegistry,
13461418
}, nil
13471419
}
13481420

0 commit comments

Comments
 (0)