@@ -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
151153type DenoProgramEntries struct {
@@ -159,20 +161,22 @@ type DenoServerData struct {
159161}
160162
161163type 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
168171var _ 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
216220func (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
256259func (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+
323367type 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