@@ -20,6 +20,8 @@ import (
2020 "github.com/microsoft/typescript-go/internal/collections"
2121 "github.com/microsoft/typescript-go/internal/compiler"
2222 "github.com/microsoft/typescript-go/internal/core"
23+ "github.com/microsoft/typescript-go/internal/diagnostics"
24+ "github.com/microsoft/typescript-go/internal/module"
2325 "github.com/microsoft/typescript-go/internal/format"
2426 "github.com/microsoft/typescript-go/internal/jsonutil"
2527 "github.com/microsoft/typescript-go/internal/locale"
@@ -241,13 +243,6 @@ func NewDenoVFS(server *Server, ctx context.Context, compilerOptionsKey string,
241243 }
242244}
243245
244- func (v * DenoVFS ) baseParams () lsproto.DenoHostBaseParams {
245- return lsproto.DenoHostBaseParams {
246- CompilerOptionsKey : v .compilerOptionsKey ,
247- NotebookUri : v .notebookUri ,
248- }
249- }
250-
251246func (v * DenoVFS ) UseCaseSensitiveFileNames () bool {
252247 return true
253248}
@@ -271,12 +266,13 @@ func (v *DenoVFS) GetDocument(path string) *lsproto.DenoDocumentData {
271266 return data
272267 }
273268 }
274- params := lsproto.DenoHostGetDocumentParams {
275- DenoHostBaseParams : v .baseParams (),
276- Uri : uri ,
269+ params := lsproto.DenoCallbackParams {
270+ GetDocument : & lsproto.DenoGetDocumentParams {
271+ Uri : uri ,
272+ },
277273 }
278274 var response lsproto.DenoDocumentData
279- err := v .server .sendRequestSync (v .ctx , lsproto .MethodDenoHostGetDocument , params , & response )
275+ err := v .server .sendRequestSync (v .ctx , lsproto .MethodDenoCallback , params , & response )
280276 if err != nil || response .Text == nil {
281277 return nil
282278 }
@@ -367,6 +363,94 @@ func (h *denoAutoImportHost) GetSourceFile(fileName string, path tspath.Path) *a
367363func (h * denoAutoImportHost ) Dispose () {
368364}
369365
366+ // denoCompilerHost wraps a CompilerHost to intercept resolver creation for Deno LSP
367+ type denoCompilerHost struct {
368+ inner compiler.CompilerHost
369+ server * Server
370+ }
371+
372+ var _ compiler.CompilerHost = (* denoCompilerHost )(nil )
373+
374+ func (h * denoCompilerHost ) FS () vfs.FS {
375+ return h .inner .FS ()
376+ }
377+
378+ func (h * denoCompilerHost ) DefaultLibraryPath () string {
379+ return h .inner .DefaultLibraryPath ()
380+ }
381+
382+ func (h * denoCompilerHost ) GetCurrentDirectory () string {
383+ return h .inner .GetCurrentDirectory ()
384+ }
385+
386+ func (h * denoCompilerHost ) Trace (msg * diagnostics.Message , args ... any ) {
387+ h .inner .Trace (msg , args ... )
388+ }
389+
390+ func (h * denoCompilerHost ) GetSourceFile (opts ast.SourceFileParseOptions ) * ast.SourceFile {
391+ return h .inner .GetSourceFile (opts )
392+ }
393+
394+ func (h * denoCompilerHost ) GetResolvedProjectReference (fileName string , path tspath.Path ) * tsoptions.ParsedCommandLine {
395+ return h .inner .GetResolvedProjectReference (fileName , path )
396+ }
397+
398+ func (h * denoCompilerHost ) IsNodeSourceFile (path tspath.Path ) bool {
399+ return h .inner .IsNodeSourceFile (path )
400+ }
401+
402+ func (h * denoCompilerHost ) GetDenoForkContextInfo () ast.DenoForkContextInfo {
403+ return h .inner .GetDenoForkContextInfo ()
404+ }
405+
406+ // MakeResolver overrides the inner host's MakeResolver to return a wrapped resolver
407+ func (h * denoCompilerHost ) MakeResolver (host module.ResolutionHost , options * core.CompilerOptions ,
408+ typingsLocation string , projectName string ) module.ResolverInterface {
409+ baseResolver := h .inner .MakeResolver (host , options , typingsLocation , projectName )
410+ return & denoResolverWrapper {inner : baseResolver , server : h .server }
411+ }
412+
413+ // denoResolverWrapper wraps a ResolverInterface to intercept module resolution for Deno LSP
414+ type denoResolverWrapper struct {
415+ inner module.ResolverInterface
416+ server * Server
417+ }
418+
419+ var _ module.ResolverInterface = (* denoResolverWrapper )(nil )
420+
421+ func (r * denoResolverWrapper ) ResolveModuleName (moduleName string , containingFile string ,
422+ importAttributeType * string , resolutionMode core.ResolutionMode ,
423+ redirectedReference module.ResolvedProjectReference ) (* module.ResolvedModule , []module.DiagAndArgs ) {
424+ // Hook point: Call Deno's custom resolution via LSP or callback
425+ // if result := r.server.denoResolveModule(...); result != nil { return result, nil }
426+ return r .inner .ResolveModuleName (moduleName , containingFile , importAttributeType , resolutionMode , redirectedReference )
427+ }
428+
429+ func (r * denoResolverWrapper ) ResolveTypeReferenceDirective (name string , containingFile string ,
430+ resolutionMode core.ResolutionMode ,
431+ redirectedReference module.ResolvedProjectReference ) (* module.ResolvedTypeReferenceDirective , []module.DiagAndArgs ) {
432+ // Hook point: Call Deno's custom resolution
433+ return r .inner .ResolveTypeReferenceDirective (name , containingFile , resolutionMode , redirectedReference )
434+ }
435+
436+ func (r * denoResolverWrapper ) ResolvePackageDirectory (moduleName string , containingFile string ,
437+ resolutionMode core.ResolutionMode ,
438+ redirectedReference module.ResolvedProjectReference ) * module.ResolvedModule {
439+ return r .inner .ResolvePackageDirectory (moduleName , containingFile , resolutionMode , redirectedReference )
440+ }
441+
442+ func (r * denoResolverWrapper ) ResolveJsxImportSource (referrer string ) string {
443+ return r .inner .ResolveJsxImportSource (referrer )
444+ }
445+
446+ func (r * denoResolverWrapper ) GetPackageScopeForPath (directory string ) * packagejson.InfoCacheEntry {
447+ return r .inner .GetPackageScopeForPath (directory )
448+ }
449+
450+ func (r * denoResolverWrapper ) GetImpliedNodeFormatForFile (path string , packageJsonType string ) core.ModuleKind {
451+ return r .inner .GetImpliedNodeFormatForFile (path , packageJsonType )
452+ }
453+
370454type Server struct {
371455 r Reader
372456 w Writer
@@ -1166,13 +1250,15 @@ func (s *Server) handleDenoRequest(ctx context.Context, params *lsproto.DenoRequ
11661250 updateProgram := func (pe * DenoProgramEntry ) {
11671251 if pe .program .GetSourceFileByPath (filePath ) != nil {
11681252 wrappedFS := bundled .WrapFS (pe .vfs )
1169- newHost := compiler .NewCompilerHost (
1253+ baseHost := compiler .NewCompilerHost (
11701254 s .cwd ,
11711255 wrappedFS ,
11721256 bundled .LibPath (),
11731257 nil ,
11741258 nil ,
11751259 )
1260+ // Wrap the host to intercept resolution
1261+ newHost := & denoCompilerHost {inner : baseHost , server : s }
11761262 newProgram , _ := pe .program .UpdateProgram (filePath , newHost )
11771263 pe .program = newProgram
11781264 }
@@ -1361,13 +1447,15 @@ func (s *Server) getDenoLanguageService(ctx context.Context, compilerOptionsKey
13611447func (s * Server ) createDenoProgramEntry (ctx context.Context , compilerOptionsKey string , notebookUri * string , projectConfig * lsproto.DenoProjectConfig ) (* DenoProgramEntry , error ) {
13621448 denoVFS := NewDenoVFS (s , ctx , compilerOptionsKey , notebookUri )
13631449 wrappedFS := bundled .WrapFS (denoVFS )
1364- compilerHost := compiler .NewCompilerHost (
1450+ baseHost := compiler .NewCompilerHost (
13651451 s .cwd ,
13661452 wrappedFS ,
13671453 bundled .LibPath (),
13681454 nil , // extendedConfigCache
13691455 nil , // trace
13701456 )
1457+ // Wrap the host to intercept resolution
1458+ compilerHost := & denoCompilerHost {inner : baseHost , server : s }
13711459 fileNames := make ([]string , len (projectConfig .Files ))
13721460 for i , file := range projectConfig .Files {
13731461 fileNames [i ] = file .FileName ()
0 commit comments