cuelang.org/go@v0.13.0/internal/golangorgx/gopls/server/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 server
     6  
     7  import (
     8  	"context"
     9  	"fmt"
    10  	"sync"
    11  
    12  	"cuelang.org/go/internal/golangorgx/gopls/cache"
    13  	"cuelang.org/go/internal/golangorgx/gopls/protocol"
    14  	"cuelang.org/go/internal/golangorgx/tools/event"
    15  )
    16  
    17  func (s *server) DidChangeWorkspaceFolders(ctx context.Context, params *protocol.DidChangeWorkspaceFoldersParams) error {
    18  	// Per the comment in [server.Initialize], we only support a single
    19  	// WorkspaceFolder for now. More precisely, the call to Initialize must have
    20  	// a single WorkspaceFolder. Therefore a notification via
    21  	// DidChangeWorkspaceFolders must not cause that folder to change (because
    22  	// that is the invariant we are maintaining for now).
    23  	//
    24  	// So for now we simply error in case there is any DidChangeWorkspaceFolders
    25  	// notification, rather than trying to be smart and work out "has the folder
    26  	// change?". If this proves to be too simplistic or restrictive, then we can
    27  	// revisit as part of removing this constraint.
    28  	//
    29  	// When we do add such support, we need to be how/if/where logic for
    30  	// deduping views comes in.
    31  	//
    32  	// Ensure this logic is consistent with [server.Initialize].
    33  	return fmt.Errorf("cue lsp only supports a single WorkspaceFolder for now")
    34  }
    35  
    36  // addView returns a Snapshot and a release function that must be called when
    37  // the snapshot is no longer needed.
    38  func (s *server) addView(ctx context.Context, name string, dir protocol.DocumentURI) (*cache.Snapshot, func(), error) {
    39  	s.stateMu.Lock()
    40  	state := s.state
    41  	s.stateMu.Unlock()
    42  	if state < serverInitialized {
    43  		return nil, nil, fmt.Errorf("addView called before server initialized")
    44  	}
    45  	folder, err := s.newFolder(ctx, dir, name)
    46  	if err != nil {
    47  		return nil, nil, err
    48  	}
    49  	_, snapshot, release, err := s.session.NewView(ctx, folder)
    50  	return snapshot, release, err
    51  }
    52  
    53  func (s *server) DidChangeConfiguration(ctx context.Context, _ *protocol.DidChangeConfigurationParams) error {
    54  	ctx, done := event.Start(ctx, "lsp.Server.didChangeConfiguration")
    55  	defer done()
    56  
    57  	var wg sync.WaitGroup
    58  	wg.Add(1)
    59  	defer wg.Done()
    60  	if s.Options().VerboseWorkDoneProgress {
    61  		work := s.progress.Start(ctx, DiagnosticWorkTitle(FromDidChangeConfiguration), "Calculating diagnostics...", nil, nil)
    62  		go func() {
    63  			wg.Wait()
    64  			work.End(ctx, "Done.")
    65  		}()
    66  	}
    67  
    68  	// Apply any changes to the session-level settings.
    69  	options, err := s.fetchFolderOptions(ctx, "")
    70  	if err != nil {
    71  		return err
    72  	}
    73  	s.SetOptions(options)
    74  
    75  	// Collect options for all workspace folders.
    76  	seen := make(map[protocol.DocumentURI]bool)
    77  	var newFolders []*cache.Folder
    78  	for _, view := range s.session.Views() {
    79  		folder := view.Folder()
    80  		if seen[folder.Dir] {
    81  			continue
    82  		}
    83  		seen[folder.Dir] = true
    84  		newFolder, err := s.newFolder(ctx, folder.Dir, folder.Name)
    85  		if err != nil {
    86  			return err
    87  		}
    88  		newFolders = append(newFolders, newFolder)
    89  	}
    90  	s.session.UpdateFolders(ctx, newFolders)
    91  
    92  	// The view set may have been updated above.
    93  	viewsToDiagnose := make(map[*cache.View][]protocol.DocumentURI)
    94  	for _, view := range s.session.Views() {
    95  		viewsToDiagnose[view] = nil
    96  	}
    97  
    98  	modCtx, modID := s.needsDiagnosis(ctx, viewsToDiagnose)
    99  	wg.Add(1)
   100  	go func() {
   101  		s.diagnoseChangedViews(modCtx, modID, viewsToDiagnose, FromDidChangeConfiguration)
   102  		wg.Done()
   103  	}()
   104  
   105  	return nil
   106  }