mirror of
https://github.com/golang/go
synced 2024-11-18 08:54:45 -07:00
internal/lsp/cache: support minimal module compatibility in GOPATH
In GOPATH mode, you can import example.com/foo even if it has a go.mod that says its path is example.com/foo/v2. Adjust our import path resolution to support that case. Fixes golang/go#39560. Change-Id: I758a2220c579c4374084365c3a78a3a2bbd14b01 Reviewed-on: https://go-review.googlesource.com/c/tools/+/238260 Run-TryBot: Heschi Kreinick <heschi@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
parent
dc31b401ab
commit
b7b89dcb81
55
internal/lsp/cache/check.go
vendored
55
internal/lsp/cache/check.go
vendored
@ -369,25 +369,7 @@ func typeCheck(ctx context.Context, fset *token.FileSet, m *metadata, mode sourc
|
||||
if ctx.Err() != nil {
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
dep := deps[packagePath(pkgPath)]
|
||||
if dep == nil {
|
||||
// We may be in GOPATH mode, in which case we need to check vendor dirs.
|
||||
searchDir := path.Dir(pkg.PkgPath())
|
||||
for {
|
||||
vdir := packagePath(path.Join(searchDir, "vendor", pkgPath))
|
||||
if vdep := deps[vdir]; vdep != nil {
|
||||
dep = vdep
|
||||
break
|
||||
}
|
||||
|
||||
// Search until Dir doesn't take us anywhere new, e.g. "." or "/".
|
||||
next := path.Dir(searchDir)
|
||||
if searchDir == next {
|
||||
break
|
||||
}
|
||||
searchDir = next
|
||||
}
|
||||
}
|
||||
dep := resolveImportPath(pkgPath, pkg, deps)
|
||||
if dep == nil {
|
||||
return nil, errors.Errorf("no package for import %s", pkgPath)
|
||||
}
|
||||
@ -433,6 +415,41 @@ func typeCheck(ctx context.Context, fset *token.FileSet, m *metadata, mode sourc
|
||||
return pkg, nil
|
||||
}
|
||||
|
||||
// resolveImportPath resolves an import path in pkg to a package from deps.
|
||||
// It should produce the same results as resolveImportPath:
|
||||
// https://cs.opensource.google/go/go/+/master:src/cmd/go/internal/load/pkg.go;drc=641918ee09cb44d282a30ee8b66f99a0b63eaef9;l=990.
|
||||
func resolveImportPath(importPath string, pkg *pkg, deps map[packagePath]*packageHandle) *packageHandle {
|
||||
if dep := deps[packagePath(importPath)]; dep != nil {
|
||||
return dep
|
||||
}
|
||||
// We may be in GOPATH mode, in which case we need to check vendor dirs.
|
||||
searchDir := path.Dir(pkg.PkgPath())
|
||||
for {
|
||||
vdir := packagePath(path.Join(searchDir, "vendor", importPath))
|
||||
if vdep := deps[vdir]; vdep != nil {
|
||||
return vdep
|
||||
}
|
||||
|
||||
// Search until Dir doesn't take us anywhere new, e.g. "." or "/".
|
||||
next := path.Dir(searchDir)
|
||||
if searchDir == next {
|
||||
break
|
||||
}
|
||||
searchDir = next
|
||||
}
|
||||
|
||||
// Vendor didn't work. Let's try minimal module compatibility mode.
|
||||
// In MMC, the packagePath is the canonical (.../vN/...) path, which
|
||||
// is hard to calculate. But the go command has already resolved the ID
|
||||
// to the non-versioned path, and we can take advantage of that.
|
||||
for _, dep := range deps {
|
||||
if dep.ID() == importPath {
|
||||
return dep
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isValidImport(pkgPath, importPkgPath packagePath) bool {
|
||||
i := strings.LastIndex(string(importPkgPath), "/internal/")
|
||||
if i == -1 {
|
||||
|
Loading…
Reference in New Issue
Block a user