diff --git a/gopls/internal/regtest/misc/multiple_adhoc_test.go b/gopls/internal/regtest/misc/multiple_adhoc_test.go new file mode 100644 index 0000000000..5f803e4e38 --- /dev/null +++ b/gopls/internal/regtest/misc/multiple_adhoc_test.go @@ -0,0 +1,44 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package misc + +import ( + "testing" + + . "golang.org/x/tools/internal/lsp/regtest" +) + +func TestMultipleAdHocPackages(t *testing.T) { + Run(t, ` +-- a/a.go -- +package main + +import "fmt" + +func main() { + fmt.Println("") +} +-- a/b.go -- +package main + +import "fmt" + +func main() () { + fmt.Println("") +} +`, func(t *testing.T, env *Env) { + env.OpenFile("a/a.go") + if list := env.Completion("a/a.go", env.RegexpSearch("a/a.go", "Println")); list == nil || len(list.Items) == 0 { + t.Fatal("expected completions, got none") + } + env.OpenFile("a/b.go") + if list := env.Completion("a/b.go", env.RegexpSearch("a/b.go", "Println")); list == nil || len(list.Items) == 0 { + t.Fatal("expected completions, got none") + } + if list := env.Completion("a/a.go", env.RegexpSearch("a/a.go", "Println")); list == nil || len(list.Items) == 0 { + t.Fatal("expected completions, got none") + } + }) +} diff --git a/internal/lsp/cache/load.go b/internal/lsp/cache/load.go index b13e4c0048..5c027e72df 100644 --- a/internal/lsp/cache/load.go +++ b/internal/lsp/cache/load.go @@ -205,7 +205,7 @@ func (s *snapshot) load(ctx context.Context, allowNetwork bool, scopes ...interf } // Set the metadata for this package. s.mu.Lock() - m, err := s.setMetadataLocked(ctx, packagePath(pkg.PkgPath), pkg, cfg, map[packageID]struct{}{}) + m, err := s.setMetadataLocked(ctx, packagePath(pkg.PkgPath), pkg, cfg, query, map[packageID]struct{}{}) s.mu.Unlock() if err != nil { return err @@ -403,8 +403,13 @@ func getWorkspaceDir(ctx context.Context, h *memoize.Handle, g *memoize.Generati // setMetadataLocked extracts metadata from pkg and records it in s. It // recurses through pkg.Imports to ensure that metadata exists for all // dependencies. -func (s *snapshot) setMetadataLocked(ctx context.Context, pkgPath packagePath, pkg *packages.Package, cfg *packages.Config, seen map[packageID]struct{}) (*metadata, error) { +func (s *snapshot) setMetadataLocked(ctx context.Context, pkgPath packagePath, pkg *packages.Package, cfg *packages.Config, query []string, seen map[packageID]struct{}) (*metadata, error) { id := packageID(pkg.ID) + if source.IsCommandLineArguments(pkg.ID) { + suffix := ":" + strings.Join(query, ",") + id = packageID(string(id) + suffix) + pkgPath = packagePath(string(pkgPath) + suffix) + } if _, ok := seen[id]; ok { return nil, errors.Errorf("import cycle detected: %q", id) } @@ -465,7 +470,7 @@ func (s *snapshot) setMetadataLocked(ctx context.Context, pkgPath packagePath, p continue } if s.noValidMetadataForIDLocked(importID) { - if _, err := s.setMetadataLocked(ctx, importPkgPath, importPkg, cfg, copied); err != nil { + if _, err := s.setMetadataLocked(ctx, importPkgPath, importPkg, cfg, query, copied); err != nil { event.Error(ctx, "error in dependency", err) } }