internal/imports: bump relevance for modules with higher major versions
This changes bumps relevance for modules with major versions >1 so the
results for unimported members are ordered by major version.
Updates golang/go#41800
Change-Id: I64f4a1cf78a101acf4229433d06b5793246962f5
Reviewed-on: https://go-review.googlesource.com/c/tools/+/261084
Run-TryBot: Danish Dua <danishdua@google.com>
Trust: Danish Dua <danishdua@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
diff --git a/internal/imports/fix.go b/internal/imports/fix.go
index 675d16c..0bd91a8 100644
--- a/internal/imports/fix.go
+++ b/internal/imports/fix.go
@@ -83,7 +83,7 @@
IdentName string
// FixType is the type of fix this is (AddImport, DeleteImport, SetImportName).
FixType ImportFixType
- Relevance int // see pkg
+ Relevance float64 // see pkg
}
// An ImportInfo represents a single import statement.
@@ -592,9 +592,9 @@
return fixes, nil
}
-// Highest relevance, used for the standard library. Chosen arbitrarily to
-// match pre-existing gopls code.
-const MaxRelevance = 7
+// MaxRelevance is the highest relevance, used for the standard library.
+// Chosen arbitrarily to match pre-existing gopls code.
+const MaxRelevance = 7.0
// getCandidatePkgs works with the passed callback to find all acceptable packages.
// It deduplicates by import path, and uses a cached stdlib rather than reading
@@ -658,8 +658,8 @@
return resolver.scan(ctx, scanFilter)
}
-func ScoreImportPaths(ctx context.Context, env *ProcessEnv, paths []string) (map[string]int, error) {
- result := make(map[string]int)
+func ScoreImportPaths(ctx context.Context, env *ProcessEnv, paths []string) (map[string]float64, error) {
+ result := make(map[string]float64)
resolver, err := env.GetResolver()
if err != nil {
return nil, err
@@ -995,7 +995,7 @@
// loadExports may be called concurrently.
loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []string, error)
// scoreImportPath returns the relevance for an import path.
- scoreImportPath(ctx context.Context, path string) int
+ scoreImportPath(ctx context.Context, path string) float64
ClearForNewScan()
}
@@ -1260,10 +1260,10 @@
}
type pkg struct {
- dir string // absolute file path to pkg directory ("/usr/lib/go/src/net/http")
- importPathShort string // vendorless import path ("net/http", "a/b")
- packageName string // package name loaded from source if requested
- relevance int // a weakly-defined score of how relevant a package is. 0 is most relevant.
+ dir string // absolute file path to pkg directory ("/usr/lib/go/src/net/http")
+ importPathShort string // vendorless import path ("net/http", "a/b")
+ packageName string // package name loaded from source if requested
+ relevance float64 // a weakly-defined score of how relevant a package is. 0 is most relevant.
}
type pkgDistance struct {
@@ -1389,7 +1389,7 @@
return nil
}
-func (r *gopathResolver) scoreImportPath(ctx context.Context, path string) int {
+func (r *gopathResolver) scoreImportPath(ctx context.Context, path string) float64 {
if _, ok := stdlib[path]; ok {
return MaxRelevance
}
diff --git a/internal/imports/fix_test.go b/internal/imports/fix_test.go
index 0bcbb88..005bf96 100644
--- a/internal/imports/fix_test.go
+++ b/internal/imports/fix_test.go
@@ -2564,7 +2564,7 @@
// with correct priorities.
func TestGetCandidates(t *testing.T) {
type res struct {
- relevance int
+ relevance float64
name, path string
}
want := []res{
@@ -2620,7 +2620,7 @@
func TestGetImportPaths(t *testing.T) {
type res struct {
- relevance int
+ relevance float64
name, path string
}
want := []res{
@@ -2670,7 +2670,7 @@
func TestGetPackageCompletions(t *testing.T) {
type res struct {
- relevance int
+ relevance float64
name, path, symbol string
}
want := []res{
diff --git a/internal/imports/mod.go b/internal/imports/mod.go
index 94880d6..6982121 100644
--- a/internal/imports/mod.go
+++ b/internal/imports/mod.go
@@ -487,7 +487,7 @@
return nil
}
-func (r *ModuleResolver) scoreImportPath(ctx context.Context, path string) int {
+func (r *ModuleResolver) scoreImportPath(ctx context.Context, path string) float64 {
if _, ok := stdlib[path]; ok {
return MaxRelevance
}
@@ -495,17 +495,31 @@
return modRelevance(mod)
}
-func modRelevance(mod *gocommand.ModuleJSON) int {
+func modRelevance(mod *gocommand.ModuleJSON) float64 {
+ var relevance float64
switch {
case mod == nil: // out of scope
return MaxRelevance - 4
case mod.Indirect:
- return MaxRelevance - 3
+ relevance = MaxRelevance - 3
case !mod.Main:
- return MaxRelevance - 2
+ relevance = MaxRelevance - 2
default:
- return MaxRelevance - 1 // main module ties with stdlib
+ relevance = MaxRelevance - 1 // main module ties with stdlib
}
+
+ _, versionString, ok := module.SplitPathVersion(mod.Path)
+ if ok {
+ index := strings.Index(versionString, "v")
+ if index == -1 {
+ return relevance
+ }
+ if versionNumber, err := strconv.ParseFloat(versionString[index+1:], 64); err == nil {
+ relevance += versionNumber / 1000
+ }
+ }
+
+ return relevance
}
// canonicalize gets the result of canonicalizing the packages using the results
diff --git a/internal/imports/mod_test.go b/internal/imports/mod_test.go
index 254bc28..5d73c88 100644
--- a/internal/imports/mod_test.go
+++ b/internal/imports/mod_test.go
@@ -890,10 +890,14 @@
module example.com
require rsc.io/quote v1.5.1
+require rsc.io/quote/v3 v3.0.0
-- rpackage/x.go --
package rpackage
-import _ "rsc.io/quote"
+import (
+ _ "rsc.io/quote"
+ _ "rsc.io/quote/v3"
+)
`, "")
defer mt.cleanup()
@@ -902,7 +906,7 @@
}
type res struct {
- relevance int
+ relevance float64
name, path string
}
want := []res{
@@ -911,6 +915,8 @@
{7, "http", "net/http"},
// Main module
{6, "rpackage", "example.com/rpackage"},
+ // Direct module deps with v2+ major version
+ {5.003, "quote", "rsc.io/quote/v3"},
// Direct module deps
{5, "quote", "rsc.io/quote"},
// Indirect deps
diff --git a/internal/lsp/source/completion/completion.go b/internal/lsp/source/completion/completion.go
index 7e932eb..8cee897 100644
--- a/internal/lsp/source/completion/completion.go
+++ b/internal/lsp/source/completion/completion.go
@@ -809,7 +809,7 @@
name = pkgToConsider
}
- score := float64(pkg.Relevance)
+ score := pkg.Relevance
if len(pkgDirList)-1 == depth {
score *= highScore
} else {
@@ -1102,7 +1102,7 @@
paths = append(paths, path)
}
- var relevances map[string]int
+ var relevances map[string]float64
if len(paths) != 0 {
if err := c.snapshot.RunProcessEnvFunc(ctx, func(opts *imports.Options) error {
var err error
@@ -1174,8 +1174,8 @@
// unimportedScore returns a score for an unimported package that is generally
// lower than other candidates.
-func unimportedScore(relevance int) float64 {
- return (stdScore + .1*float64(relevance)) / 2
+func unimportedScore(relevance float64) float64 {
+ return (stdScore + .1*relevance) / 2
}
func (c *completer) packageMembers(pkg *types.Package, score float64, imp *importInfo) []candidate {
@@ -1398,7 +1398,7 @@
paths = append(paths, path)
}
- var relevances map[string]int
+ var relevances map[string]float64
if len(paths) != 0 {
if err := c.snapshot.RunProcessEnvFunc(ctx, func(opts *imports.Options) error {
var err error