From 9882f1d1823da58283ff91ebbec3f7c0cc27cddc Mon Sep 17 00:00:00 2001 From: Danish Dua Date: Wed, 12 Aug 2020 12:05:41 -0400 Subject: [PATCH] internal/lsp: add initial workspace load notification Add workspace package load (IWL) notification. Closes golang/go#40632 Change-Id: I4d4c6fba1ece08bb0d6df52da2e6f08c959fd1ae Reviewed-on: https://go-review.googlesource.com/c/tools/+/248623 Run-TryBot: Danish Dua TryBot-Result: Gobot Gobot Reviewed-by: Heschi Kreinick --- internal/lsp/cache/snapshot.go | 6 +++--- internal/lsp/cache/view.go | 5 +++-- internal/lsp/general.go | 7 +++++++ internal/lsp/source/view.go | 3 +++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go index c8c4ea8005..3500bff5f0 100644 --- a/internal/lsp/cache/snapshot.go +++ b/internal/lsp/cache/snapshot.go @@ -488,7 +488,7 @@ func (s *snapshot) KnownPackages(ctx context.Context) ([]source.Package, error) func (s *snapshot) CachedImportPaths(ctx context.Context) (map[string]source.Package, error) { // Don't reload workspace package metadata. // This function is meant to only return currently cached information. - s.view.awaitInitialized(ctx) + s.view.AwaitInitialized(ctx) s.mu.Lock() defer s.mu.Unlock() @@ -667,7 +667,7 @@ func (s *snapshot) IsSaved(uri span.URI) bool { func (s *snapshot) awaitLoaded(ctx context.Context) error { // Do not return results until the snapshot's view has been initialized. - s.view.awaitInitialized(ctx) + s.view.AwaitInitialized(ctx) if err := s.reloadWorkspace(ctx); err != nil { return err @@ -1161,7 +1161,7 @@ func (s *snapshot) findWorkspaceDirectories(ctx context.Context, modFH source.Fi } func (s *snapshot) BuiltinPackage(ctx context.Context) (*source.BuiltinPackage, error) { - s.view.awaitInitialized(ctx) + s.view.AwaitInitialized(ctx) if s.builtin == nil { return nil, errors.Errorf("no builtin package for view %s", s.view.name) diff --git a/internal/lsp/cache/view.go b/internal/lsp/cache/view.go index cbb9d1ad87..48b3148eed 100644 --- a/internal/lsp/cache/view.go +++ b/internal/lsp/cache/view.go @@ -654,7 +654,8 @@ func (v *View) initialize(ctx context.Context, s *snapshot, firstAttempt bool) { }) } -func (v *View) awaitInitialized(ctx context.Context) { +// AwaitInitialized waits until a view is initialized +func (v *View) AwaitInitialized(ctx context.Context) { select { case <-ctx.Done(): return @@ -677,7 +678,7 @@ func (v *View) invalidateContent(ctx context.Context, uris map[span.URI]source.V v.cancelBackground() // Do not clone a snapshot until its view has finished initializing. - v.awaitInitialized(ctx) + v.AwaitInitialized(ctx) // This should be the only time we hold the view's snapshot lock for any period of time. v.snapshotMu.Lock() diff --git a/internal/lsp/general.go b/internal/lsp/general.go index 6661eb1bc0..d499d8f315 100644 --- a/internal/lsp/general.go +++ b/internal/lsp/general.go @@ -197,11 +197,18 @@ func (s *Server) addFolders(ctx context.Context, folders []protocol.WorkspaceFol dirsToWatch := map[span.URI]struct{}{} for _, folder := range folders { uri := span.URIFromURI(folder.URI) + work := s.progress.start(ctx, "Setting up workspace", "Loading packages...", nil, nil) view, snapshot, release, err := s.addView(ctx, folder.Name, uri) if err != nil { viewErrors[uri] = err + work.end(ctx, fmt.Sprintf("Error loading packages: %s", err)) continue } + go func() { + view.AwaitInitialized(ctx) + work.end(ctx, "Finished loading packages.") + }() + for _, dir := range snapshot.WorkspaceDirectories(ctx) { dirsToWatch[dir] = struct{}{} } diff --git a/internal/lsp/source/view.go b/internal/lsp/source/view.go index 6f84d4bf26..8515220af6 100644 --- a/internal/lsp/source/view.go +++ b/internal/lsp/source/view.go @@ -141,6 +141,9 @@ type View interface { // Shutdown closes this view, and detaches it from its session. Shutdown(ctx context.Context) + // AwaitInitialized waits until a view is initialized + AwaitInitialized(ctx context.Context) + // WriteEnv writes the view-specific environment to the io.Writer. WriteEnv(ctx context.Context, w io.Writer) error