1
0
mirror of https://github.com/golang/go synced 2024-11-18 08:24:44 -07:00

internal/imports: support completing import paths

Add a new autocomplete function that completes based on import path
prefix rather than package name prefix.

Updates golang/go#35877.

Change-Id: Ib768080ee99debfff1c8c870d22dc7b7459deadd
Reviewed-on: https://go-review.googlesource.com/c/tools/+/249419
Run-TryBot: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Danish Dua <danishdua@google.com>
This commit is contained in:
Heschi Kreinick 2020-08-19 17:40:56 -04:00
parent b793a1359e
commit 9283e6ae95
2 changed files with 84 additions and 5 deletions

View File

@ -693,8 +693,8 @@ func candidateImportName(pkg *pkg) string {
return ""
}
// GetAllCandidates gets all of the packages starting with prefix that can be
// imported by filename, sorted by import path.
// GetAllCandidates calls wrapped for each package whose name starts with
// searchPrefix, and can be imported from filename with the package name filePkg.
func GetAllCandidates(ctx context.Context, wrapped func(ImportFix), searchPrefix, filename, filePkg string, env *ProcessEnv) error {
callback := &scanCallback{
rootFound: func(gopathwalk.Root) bool {
@ -728,6 +728,35 @@ func GetAllCandidates(ctx context.Context, wrapped func(ImportFix), searchPrefix
return getCandidatePkgs(ctx, callback, filename, filePkg, env)
}
// GetImportPaths calls wrapped for each package whose import path starts with
// searchPrefix, and can be imported from filename with the package name filePkg.
func GetImportPaths(ctx context.Context, wrapped func(ImportFix), searchPrefix, filename, filePkg string, env *ProcessEnv) error {
callback := &scanCallback{
rootFound: func(gopathwalk.Root) bool {
return true
},
dirFound: func(pkg *pkg) bool {
if !canUse(filename, pkg.dir) {
return false
}
return strings.HasPrefix(pkg.importPathShort, searchPrefix)
},
packageNameLoaded: func(pkg *pkg) bool {
wrapped(ImportFix{
StmtInfo: ImportInfo{
ImportPath: pkg.importPathShort,
Name: candidateImportName(pkg),
},
IdentName: pkg.packageName,
FixType: AddImport,
Relevance: pkg.relevance,
})
return false
},
}
return getCandidatePkgs(ctx, callback, filename, filePkg, env)
}
// A PackageExport is a package and its exports.
type PackageExport struct {
Fix *ImportFix

View File

@ -2560,7 +2560,7 @@ func TestX() {
}.processTest(t, "foo.com/a", "a_test.go", nil, nil, want)
}
// TestStdLibGetCandidates tests that get packages finds std library packages
// TestGetCandidates tests that get packages finds packages
// with correct priorities.
func TestGetCandidates(t *testing.T) {
type res struct {
@ -2613,7 +2613,57 @@ func TestGetCandidates(t *testing.T) {
got[i].relevance = 0
}
if !reflect.DeepEqual(want, got) {
t.Errorf("wanted stdlib results in order %v, got %v", want, got)
t.Errorf("wanted results in order %v, got %v", want, got)
}
})
}
func TestGetImportPaths(t *testing.T) {
type res struct {
relevance int
name, path string
}
want := []res{
{0, "http", "net/http"},
{0, "net", "net"},
{0, "neta", "neta.com/neta"},
}
testConfig{
modules: []packagestest.Module{
{
Name: "neta.com",
Files: fm{"neta/neta.go": "package neta\n"},
},
},
}.test(t, func(t *goimportTest) {
var mu sync.Mutex
var got []res
add := func(c ImportFix) {
mu.Lock()
defer mu.Unlock()
for _, w := range want {
if c.StmtInfo.ImportPath == w.path {
got = append(got, res{c.Relevance, c.IdentName, c.StmtInfo.ImportPath})
}
}
}
if err := GetImportPaths(context.Background(), add, "ne", "x.go", "x", t.env); err != nil {
t.Fatalf("GetImportPaths() = %v", err)
}
// Sort, then clear out relevance so it doesn't mess up the DeepEqual.
sort.Slice(got, func(i, j int) bool {
ri, rj := got[i], got[j]
if ri.relevance != rj.relevance {
return ri.relevance > rj.relevance // Highest first.
}
return ri.name < rj.name
})
for i := range got {
got[i].relevance = 0
}
if !reflect.DeepEqual(want, got) {
t.Errorf("wanted results in order %v, got %v", want, got)
}
})
}
@ -2664,7 +2714,7 @@ func TestGetPackageCompletions(t *testing.T) {
got[i].relevance = 0
}
if !reflect.DeepEqual(want, got) {
t.Errorf("wanted stdlib results in order %v, got %v", want, got)
t.Errorf("wanted results in order %v, got %v", want, got)
}
})
}