@@ -505,8 +505,8 @@ var handlers = sync.OnceValue(func() handlerMap {
505505 registerLanguageServiceDocumentRequestHandler (handlers , lsproto .TextDocumentDocumentHighlightInfo , (* Server ).handleDocumentHighlight )
506506 registerLanguageServiceDocumentRequestHandler (handlers , lsproto .TextDocumentSelectionRangeInfo , (* Server ).handleSelectionRange )
507507
508- registerMultiProjectDocumentRequestHandler (handlers , lsproto .TextDocumentReferencesInfo , (* Server ).handleReferences )
509- registerMultiProjectDocumentRequestHandler (handlers , lsproto .TextDocumentRenameInfo , (* Server ).handleRename )
508+ registerMultiProjectDocumentRequestHandler (handlers , lsproto .TextDocumentReferencesInfo , (* Server ).handleReferences , combineReferences )
509+ registerMultiProjectDocumentRequestHandler (handlers , lsproto .TextDocumentRenameInfo , (* Server ).handleRename , combineRenameResponse )
510510
511511 registerRequestHandler (handlers , lsproto .WorkspaceSymbolInfo , (* Server ).handleWorkspaceSymbol )
512512 registerRequestHandler (handlers , lsproto .CompletionItemResolveInfo , (* Server ).handleCompletionItemResolve )
@@ -583,27 +583,69 @@ func registerLanguageServiceDocumentRequestHandler[Req lsproto.HasTextDocumentUR
583583 }
584584}
585585
586- func registerMultiProjectDocumentRequestHandler [Req lsproto.HasTextDocumentURI , Resp any ](handlers handlerMap , info lsproto.RequestInfo [Req , Resp ], fn func (* Server , context.Context , * ls.LanguageService , Req ) (Resp , error )) {
586+ func registerMultiProjectDocumentRequestHandler [Req lsproto.HasTextDocumentURI , Resp any ](
587+ handlers handlerMap ,
588+ info lsproto.RequestInfo [Req , Resp ],
589+ fn func (* Server , context.Context , * ls.LanguageService , Req ) (Resp , error ),
590+ combineResults func (* project.Project , * collections.SyncMap [tspath.Path , Resp ]) Resp ,
591+ ) {
587592 handlers [info .Method ] = func (s * Server , ctx context.Context , req * lsproto.RequestMessage ) error {
588593 var params Req
589594 // Ignore empty params.
590595 if req .Params != nil {
591596 params = req .Params .(Req )
592597 }
593598 // !!! sheetal: multiple projects that contain the file through symlinks
594- // !!! multiple projects that contain the file directly
595- ls , err := s .session .GetLanguageService (ctx , params .TextDocumentURI ())
599+ defaultProject , defaultLs , allProjects , err := s .session .GetProjectsForFile (ctx , params .TextDocumentURI ())
596600 if err != nil {
597601 return err
598602 }
599603 defer s .recover (req )
600- resp , err := fn (s , ctx , ls , params )
601- if err != nil {
602- return err
604+ var results collections.SyncMap [tspath.Path , Resp ]
605+ var workInProgress collections.SyncMap [tspath.Path , bool ]
606+ workInProgress .Store (defaultProject .Id (), true )
607+ wg := core .NewWorkGroup (false )
608+ enqueueWorkForNonDefaultProject := func (project * project.Project ) {
609+ if project == defaultProject {
610+ return
611+ }
612+ wg .Queue (func () {
613+ if ctx .Err () != nil {
614+ return
615+ }
616+ if _ , loaded := workInProgress .LoadOrStore (project .Id (), true ); loaded {
617+ return
618+ }
619+ ls := s .session .GetLanguageServiceForProjectWithFile (ctx , project , params .TextDocumentURI ())
620+ if ls != nil {
621+ resp , err1 := fn (s , ctx , ls , params )
622+ if err1 != nil {
623+ return
624+ }
625+ results .Store (project .Id (), resp )
626+ }
627+ })
603628 }
629+
630+ // Other projects
631+ for _ , project := range allProjects {
632+ enqueueWorkForNonDefaultProject (project )
633+ }
634+
635+ // Default projects
636+ wg .Queue (func () {
637+ resp , err1 := fn (s , ctx , defaultLs , params )
638+ if err1 != nil {
639+ return
640+ }
641+ results .Store (defaultProject .Id (), resp )
642+ // TODO:: if default location needs to be add more projects to request
643+ })
644+ wg .RunAndWait ()
604645 if ctx .Err () != nil {
605646 return ctx .Err ()
606647 }
648+ resp := combineResults (defaultProject , & results )
607649 s .sendResult (req .ID , resp )
608650 return nil
609651 }
@@ -879,9 +921,36 @@ func (s *Server) handleTypeDefinition(ctx context.Context, ls *ls.LanguageServic
879921 return ls .ProvideTypeDefinition (ctx , params .TextDocument .Uri , params .Position , getTypeDefinitionClientSupportsLink (s .initializeParams ))
880922}
881923
882- func (s * Server ) handleReferences (ctx context.Context , ls * ls.LanguageService , params * lsproto.ReferenceParams ) (lsproto.ReferencesResponse , error ) {
924+ func (s * Server ) handleReferences (ctx context.Context , defaultLs * ls.LanguageService , params * lsproto.ReferenceParams ) (lsproto.ReferencesResponse , error ) {
883925 // findAllReferences
884- return ls .ProvideReferences (ctx , params )
926+ return defaultLs .ProvideReferences (ctx , params )
927+ }
928+
929+ func combineReferences (defaultProject * project.Project , results * collections.SyncMap [tspath.Path , lsproto.ReferencesResponse ]) lsproto.ReferencesResponse {
930+ var combined []lsproto.Location
931+ var seenLocations collections.Set [lsproto.Location ]
932+ if resp , ok := results .Load (defaultProject .Id ()); ok {
933+ if resp .Locations != nil {
934+ for _ , loc := range * resp .Locations {
935+ seenLocations .Add (loc )
936+ combined = append (combined , loc )
937+ }
938+ }
939+ }
940+ results .Range (func (projectID tspath.Path , resp lsproto.ReferencesResponse ) bool {
941+ if projectID != defaultProject .Id () {
942+ if resp .Locations != nil {
943+ for _ , loc := range * resp .Locations {
944+ if ! seenLocations .Has (loc ) {
945+ seenLocations .Add (loc )
946+ combined = append (combined , loc )
947+ }
948+ }
949+ }
950+ }
951+ return true
952+ })
953+ return lsproto.LocationsOrNull {Locations : & combined }
885954}
886955
887956func (s * Server ) handleImplementations (ctx context.Context , ls * ls.LanguageService , params * lsproto.ImplementationParams ) (lsproto.ImplementationResponse , error ) {
@@ -961,6 +1030,62 @@ func (s *Server) handleRename(ctx context.Context, ls *ls.LanguageService, param
9611030 return ls .ProvideRename (ctx , params )
9621031}
9631032
1033+ func combineRenameResponse (defaultProject * project.Project , results * collections.SyncMap [tspath.Path , lsproto.RenameResponse ]) lsproto.RenameResponse {
1034+ combined := make (map [lsproto.DocumentUri ][]* lsproto.TextEdit )
1035+ seenChanges := make (map [lsproto.DocumentUri ]* collections.Set [lsproto.TextEdit ])
1036+ // !!! this is not used any more so we will skip this part of deduplication and combining
1037+ // DocumentChanges *[]TextDocumentEditOrCreateFileOrRenameFileOrDeleteFile `json:"documentChanges,omitzero"`
1038+ // ChangeAnnotations *map[string]*ChangeAnnotation `json:"changeAnnotations,omitzero"`
1039+
1040+ if resp , ok := results .Load (defaultProject .Id ()); ok {
1041+ if resp .WorkspaceEdit != nil {
1042+ for doc , changes := range * resp .WorkspaceEdit .Changes {
1043+ seenSet := collections.Set [lsproto.TextEdit ]{}
1044+ seenChanges [doc ] = & seenSet
1045+ var changesForDoc []* lsproto.TextEdit
1046+ for _ , change := range changes {
1047+ seenSet .Add (* change )
1048+ changesForDoc = append (changesForDoc , change )
1049+ }
1050+ combined [doc ] = changesForDoc
1051+ }
1052+ }
1053+ }
1054+ results .Range (func (projectID tspath.Path , resp lsproto.RenameResponse ) bool {
1055+ if projectID != defaultProject .Id () {
1056+ if resp .WorkspaceEdit != nil {
1057+ for doc , changes := range * resp .WorkspaceEdit .Changes {
1058+ seenSet , ok := seenChanges [doc ]
1059+ if ! ok {
1060+ seenSet = & collections.Set [lsproto.TextEdit ]{}
1061+ seenChanges [doc ] = seenSet
1062+ }
1063+ changesForDoc , exists := combined [doc ]
1064+ if ! exists {
1065+ changesForDoc = []* lsproto.TextEdit {}
1066+ }
1067+ for _ , change := range changes {
1068+ if ! seenSet .Has (* change ) {
1069+ seenSet .Add (* change )
1070+ changesForDoc = append (changesForDoc , change )
1071+ }
1072+ }
1073+ combined [doc ] = changesForDoc
1074+ }
1075+ }
1076+ }
1077+ return true
1078+ })
1079+ if len (combined ) > 0 {
1080+ return lsproto.RenameResponse {
1081+ WorkspaceEdit : & lsproto.WorkspaceEdit {
1082+ Changes : & combined ,
1083+ },
1084+ }
1085+ }
1086+ return lsproto.RenameResponse {}
1087+ }
1088+
9641089func (s * Server ) handleDocumentHighlight (ctx context.Context , ls * ls.LanguageService , params * lsproto.DocumentHighlightParams ) (lsproto.DocumentHighlightResponse , error ) {
9651090 return ls .ProvideDocumentHighlights (ctx , params .TextDocument .Uri , params .Position )
9661091}
0 commit comments