github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/internal/lsp/workspace.go (about) 1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package lsp 6 7 import ( 8 "context" 9 10 "github.com/powerman/golang-tools/internal/lsp/protocol" 11 "github.com/powerman/golang-tools/internal/lsp/source" 12 "github.com/powerman/golang-tools/internal/span" 13 errors "golang.org/x/xerrors" 14 ) 15 16 func (s *Server) didChangeWorkspaceFolders(ctx context.Context, params *protocol.DidChangeWorkspaceFoldersParams) error { 17 event := params.Event 18 for _, folder := range event.Removed { 19 view := s.session.View(folder.Name) 20 if view != nil { 21 view.Shutdown(ctx) 22 } else { 23 return errors.Errorf("view %s for %v not found", folder.Name, folder.URI) 24 } 25 } 26 return s.addFolders(ctx, event.Added) 27 } 28 29 func (s *Server) addView(ctx context.Context, name string, uri span.URI) (source.Snapshot, func(), error) { 30 s.stateMu.Lock() 31 state := s.state 32 s.stateMu.Unlock() 33 if state < serverInitialized { 34 return nil, func() {}, errors.Errorf("addView called before server initialized") 35 } 36 options := s.session.Options().Clone() 37 if err := s.fetchConfig(ctx, name, uri, options); err != nil { 38 return nil, func() {}, err 39 } 40 _, snapshot, release, err := s.session.NewView(ctx, name, uri, options) 41 return snapshot, release, err 42 } 43 44 func (s *Server) didChangeConfiguration(ctx context.Context, _ *protocol.DidChangeConfigurationParams) error { 45 // Apply any changes to the session-level settings. 46 options := s.session.Options().Clone() 47 semanticTokensRegistered := options.SemanticTokens 48 if err := s.fetchConfig(ctx, "", "", options); err != nil { 49 return err 50 } 51 s.session.SetOptions(options) 52 53 // Go through each view, getting and updating its configuration. 54 for _, view := range s.session.Views() { 55 options := s.session.Options().Clone() 56 if err := s.fetchConfig(ctx, view.Name(), view.Folder(), options); err != nil { 57 return err 58 } 59 view, err := view.SetOptions(ctx, options) 60 if err != nil { 61 return err 62 } 63 go func() { 64 snapshot, release := view.Snapshot(ctx) 65 defer release() 66 s.diagnoseDetached(snapshot) 67 }() 68 } 69 70 registration := semanticTokenRegistration(options.SemanticTypes, options.SemanticMods) 71 // Update any session-specific registrations or unregistrations. 72 if !semanticTokensRegistered && options.SemanticTokens { 73 if err := s.client.RegisterCapability(ctx, &protocol.RegistrationParams{ 74 Registrations: []protocol.Registration{registration}, 75 }); err != nil { 76 return err 77 } 78 } else if semanticTokensRegistered && !options.SemanticTokens { 79 if err := s.client.UnregisterCapability(ctx, &protocol.UnregistrationParams{ 80 Unregisterations: []protocol.Unregistration{ 81 { 82 ID: registration.ID, 83 Method: registration.Method, 84 }, 85 }, 86 }); err != nil { 87 return err 88 } 89 } 90 return nil 91 } 92 93 func semanticTokenRegistration(tokenTypes, tokenModifiers []string) protocol.Registration { 94 return protocol.Registration{ 95 ID: "textDocument/semanticTokens", 96 Method: "textDocument/semanticTokens", 97 RegisterOptions: &protocol.SemanticTokensOptions{ 98 Legend: protocol.SemanticTokensLegend{ 99 // TODO(pjw): trim these to what we use (and an unused one 100 // at position 0 of TokTypes, to catch typos) 101 TokenTypes: tokenTypes, 102 TokenModifiers: tokenModifiers, 103 }, 104 Full: true, 105 Range: true, 106 }, 107 } 108 }