зеркало из https://github.com/golang/tools.git
x/tools: assume go1.22 and simplify
This CL does not include simplifications to gopls. Updates golang/go#65917 Updates golang/go#69095 Change-Id: I2b54992681e2c671324e22668d8401962a1d2363 Reviewed-on: https://go-review.googlesource.com/c/tools/+/593683 Reviewed-by: Robert Findley <rfindley@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Родитель
1d5e334177
Коммит
3bb0ed7baa
|
@ -1,13 +0,0 @@
|
|||
// Copyright 2023 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.
|
||||
|
||||
//go:build !go1.20
|
||||
|
||||
package main
|
||||
|
||||
import "os/exec"
|
||||
|
||||
func cmdInterrupt(cmd *exec.Cmd) {
|
||||
// cmd.Cancel and cmd.WaitDelay not available before Go 1.20.
|
||||
}
|
|
@ -2,8 +2,6 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.20
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright 2023 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.
|
||||
|
||||
// Starting in Go 1.20, the global rand is auto-seeded,
|
||||
// with a better value than the current Unix nanoseconds.
|
||||
// Only seed if we're using older versions of Go.
|
||||
|
||||
//go:build !go1.20
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
|
@ -2,8 +2,6 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.20
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.20
|
||||
|
||||
package main_test
|
||||
|
||||
import (
|
||||
|
|
|
@ -223,10 +223,6 @@ func NewT1() *T1 { return &T1{T} }
|
|||
// duplicate list errors with findings (issue #67790)
|
||||
{name: "list-error-findings", pattern: []string{cperrFile}, analyzers: []*analysis.Analyzer{renameAnalyzer}, code: 3},
|
||||
} {
|
||||
if test.name == "despite-error" && testenv.Go1Point() < 20 {
|
||||
// The behavior in the comment on the despite-error test only occurs for Go 1.20+.
|
||||
continue
|
||||
}
|
||||
if got := checker.Run(test.pattern, test.analyzers); got != test.code {
|
||||
t.Errorf("got incorrect exit code %d for test %s; want %d", got, test.name, test.code)
|
||||
}
|
||||
|
|
|
@ -10,11 +10,9 @@ import (
|
|||
"golang.org/x/tools/go/analysis"
|
||||
"golang.org/x/tools/go/analysis/analysistest"
|
||||
"golang.org/x/tools/go/analysis/passes/directive"
|
||||
"golang.org/x/tools/internal/testenv"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
testenv.NeedsGo1Point(t, 16)
|
||||
analyzer := *directive.Analyzer
|
||||
analyzer.Run = func(pass *analysis.Pass) (interface{}, error) {
|
||||
defer func() {
|
||||
|
|
|
@ -10,29 +10,10 @@ import (
|
|||
|
||||
"golang.org/x/tools/go/analysis/analysistest"
|
||||
"golang.org/x/tools/go/analysis/passes/loopclosure"
|
||||
"golang.org/x/tools/internal/testenv"
|
||||
"golang.org/x/tools/internal/testfiles"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
// legacy loopclosure test expectations are incorrect > 1.21.
|
||||
testenv.SkipAfterGo1Point(t, 21)
|
||||
|
||||
testdata := analysistest.TestData()
|
||||
analysistest.Run(t, testdata, loopclosure.Analyzer,
|
||||
"a", "golang.org/...", "subtests", "typeparams")
|
||||
}
|
||||
|
||||
func TestVersions22(t *testing.T) {
|
||||
t.Skip("Disabled for golang.org/cl/603895. Fix and re-enable.")
|
||||
testenv.NeedsGo1Point(t, 22)
|
||||
|
||||
func TestVersions(t *testing.T) {
|
||||
dir := testfiles.ExtractTxtarFileToTmp(t, filepath.Join(analysistest.TestData(), "src", "versions", "go22.txtar"))
|
||||
analysistest.Run(t, dir, loopclosure.Analyzer, "golang.org/fake/versions")
|
||||
}
|
||||
|
||||
func TestVersions18(t *testing.T) {
|
||||
t.Skip("Disabled for golang.org/cl/603895. Fix and re-enable.")
|
||||
dir := testfiles.ExtractTxtarFileToTmp(t, filepath.Join(analysistest.TestData(), "src", "versions", "go18.txtar"))
|
||||
analysistest.Run(t, dir, loopclosure.Analyzer, "golang.org/fake/versions")
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
Test loopclosure at go version go1.22.
|
||||
|
||||
The go1.19 build tag is necessary to force the file version.
|
||||
The go1.21 build tag is necessary to force the file version.
|
||||
|
||||
-- go.mod --
|
||||
module golang.org/fake/versions
|
||||
|
||||
go 1.22
|
||||
-- pre.go --
|
||||
//go:build go1.19
|
||||
//go:build go1.21
|
||||
|
||||
package versions
|
||||
|
||||
|
|
|
@ -8,11 +8,9 @@ import (
|
|||
"testing"
|
||||
|
||||
"golang.org/x/tools/go/analysis/analysistest"
|
||||
"golang.org/x/tools/internal/testenv"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
testenv.NeedsGo1Point(t, 21)
|
||||
testdata := analysistest.TestData()
|
||||
analysistest.Run(t, testdata, Analyzer, "a", "b")
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
|
||||
"golang.org/x/tools/go/analysis/analysistest"
|
||||
"golang.org/x/tools/go/analysis/passes/stdversion"
|
||||
"golang.org/x/tools/internal/testenv"
|
||||
"golang.org/x/tools/internal/testfiles"
|
||||
)
|
||||
|
||||
|
@ -18,8 +17,6 @@ func Test(t *testing.T) {
|
|||
t.Skip("Disabled for golang.org/cl/603895. Fix and re-enable.")
|
||||
// The test relies on go1.21 std symbols, but the analyzer
|
||||
// itself requires the go1.22 implementation of versions.FileVersions.
|
||||
testenv.NeedsGo1Point(t, 22)
|
||||
|
||||
dir := testfiles.ExtractTxtarFileToTmp(t, filepath.Join(analysistest.TestData(), "test.txtar"))
|
||||
analysistest.Run(t, dir, stdversion.Analyzer,
|
||||
"example.com/a",
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
// 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.
|
||||
|
||||
//go:build go1.20
|
||||
// +build go1.20
|
||||
|
||||
package interp_test
|
||||
|
||||
func init() {
|
||||
testdataTests = append(testdataTests, "slice2array.go")
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright 2023 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.
|
||||
|
||||
//go:build go1.21
|
||||
// +build go1.21
|
||||
|
||||
package interp_test
|
||||
|
||||
func init() {
|
||||
testdataTests = append(testdataTests, "minmax.go")
|
||||
}
|
|
@ -2,9 +2,6 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.22
|
||||
// +build go1.22
|
||||
|
||||
package interp_test
|
||||
|
||||
import (
|
||||
|
@ -19,13 +16,6 @@ import (
|
|||
"golang.org/x/tools/internal/testenv"
|
||||
)
|
||||
|
||||
func init() {
|
||||
testdataTests = append(testdataTests,
|
||||
"rangevarlifetime_go122.go",
|
||||
"forvarlifetime_go122.go",
|
||||
)
|
||||
}
|
||||
|
||||
// TestExperimentRange tests files in testdata with GOEXPERIMENT=range set.
|
||||
func TestExperimentRange(t *testing.T) {
|
||||
testenv.NeedsGoExperiment(t, "range")
|
||||
|
|
|
@ -137,6 +137,10 @@ var testdataTests = []string{
|
|||
"fixedbugs/issue66783.go",
|
||||
"typeassert.go",
|
||||
"zeros.go",
|
||||
"slice2array.go",
|
||||
"minmax.go",
|
||||
"rangevarlifetime_go122.go",
|
||||
"forvarlifetime_go122.go",
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.22
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.19
|
||||
//go:build go1.21
|
||||
|
||||
// goversion can be pinned to anything strictly before 1.22.
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.19
|
||||
//go:build go1.21
|
||||
|
||||
// goversion can be pinned to anything strictly before 1.22.
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ func TestNewAlias(t *testing.T) {
|
|||
t.Errorf("Expected Unalias(A)==%q. got %q", want, got)
|
||||
}
|
||||
|
||||
if testenv.Go1Point() >= 22 && godebug != "gotypesalias=0" {
|
||||
if godebug != "gotypesalias=0" {
|
||||
if _, ok := A.Type().(*types.Alias); !ok {
|
||||
t.Errorf("Expected A.Type() to be a types.Alias(). got %q", A.Type())
|
||||
}
|
||||
|
|
|
@ -415,8 +415,7 @@ func CheckReadable(pass *analysis.Pass, filename string) error {
|
|||
return nil
|
||||
}
|
||||
for _, f := range pass.Files {
|
||||
// TODO(adonovan): use go1.20 f.FileStart
|
||||
if pass.Fset.File(f.Pos()).Name() == filename {
|
||||
if pass.Fset.File(f.FileStart).Name() == filename {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,8 +138,13 @@ func predeclared() []types.Type {
|
|||
|
||||
// used internally by gc; never used by this package or in .a files
|
||||
anyType{},
|
||||
|
||||
// comparable
|
||||
types.Universe.Lookup("comparable").Type(),
|
||||
|
||||
// any
|
||||
types.Universe.Lookup("any").Type(),
|
||||
}
|
||||
predecl = append(predecl, additionalPredeclared()...)
|
||||
})
|
||||
return predecl
|
||||
}
|
||||
|
|
|
@ -232,14 +232,19 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func
|
|||
// Select appropriate importer.
|
||||
if len(data) > 0 {
|
||||
switch data[0] {
|
||||
case 'v', 'c', 'd': // binary, till go1.10
|
||||
case 'v', 'c', 'd':
|
||||
// binary: emitted by cmd/compile till go1.10; obsolete.
|
||||
return nil, fmt.Errorf("binary (%c) import format is no longer supported", data[0])
|
||||
|
||||
case 'i': // indexed, till go1.19
|
||||
case 'i':
|
||||
// indexed: emitted by cmd/compile till go1.19;
|
||||
// now used only for serializing go/types.
|
||||
// See https://github.com/golang/go/issues/69491.
|
||||
_, pkg, err := IImportData(fset, packages, data[1:], id)
|
||||
return pkg, err
|
||||
|
||||
case 'u': // unified, from go1.20
|
||||
case 'u':
|
||||
// unified: emitted by cmd/compile since go1.20.
|
||||
_, pkg, err := UImportData(fset, packages, data[1:size], id)
|
||||
return pkg, err
|
||||
|
||||
|
|
|
@ -242,7 +242,6 @@ import (
|
|||
|
||||
"golang.org/x/tools/go/types/objectpath"
|
||||
"golang.org/x/tools/internal/aliases"
|
||||
"golang.org/x/tools/internal/tokeninternal"
|
||||
)
|
||||
|
||||
// IExportShallow encodes "shallow" export data for the specified package.
|
||||
|
@ -441,7 +440,7 @@ func (p *iexporter) encodeFile(w *intWriter, file *token.File, needed []uint64)
|
|||
// Sort the set of needed offsets. Duplicates are harmless.
|
||||
sort.Slice(needed, func(i, j int) bool { return needed[i] < needed[j] })
|
||||
|
||||
lines := tokeninternal.GetLines(file) // byte offset of each line start
|
||||
lines := file.Lines() // byte offset of each line start
|
||||
w.uint64(uint64(len(lines)))
|
||||
|
||||
// Rather than record the entire array of line start offsets,
|
||||
|
|
|
@ -9,8 +9,4 @@ package gcimporter
|
|||
|
||||
var IExportCommon = iexportCommon
|
||||
|
||||
const (
|
||||
IExportVersion = iexportVersion
|
||||
IExportVersionGenerics = iexportVersionGenerics
|
||||
IExportVersionGo1_18 = iexportVersionGo1_18
|
||||
)
|
||||
const IExportVersion = iexportVersionGenerics
|
||||
|
|
|
@ -4,9 +4,6 @@
|
|||
|
||||
// This is a copy of bexport_test.go for iexport.go.
|
||||
|
||||
//go:build go1.11
|
||||
// +build go1.11
|
||||
|
||||
package gcimporter_test
|
||||
|
||||
import (
|
||||
|
|
|
@ -53,6 +53,7 @@ const (
|
|||
iexportVersionPosCol = 1
|
||||
iexportVersionGo1_18 = 2
|
||||
iexportVersionGenerics = 2
|
||||
iexportVersion = iexportVersionGenerics
|
||||
|
||||
iexportVersionCurrent = 2
|
||||
)
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
// 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 gcimporter
|
||||
|
||||
import "go/types"
|
||||
|
||||
const iexportVersion = iexportVersionGenerics
|
||||
|
||||
// additionalPredeclared returns additional predeclared types in go.1.18.
|
||||
func additionalPredeclared() []types.Type {
|
||||
return []types.Type{
|
||||
// comparable
|
||||
types.Universe.Lookup("comparable").Type(),
|
||||
|
||||
// any
|
||||
types.Universe.Lookup("any").Type(),
|
||||
}
|
||||
}
|
||||
|
||||
// See cmd/compile/internal/types.SplitVargenSuffix.
|
||||
func splitVargenSuffix(name string) (base, suffix string) {
|
||||
i := len(name)
|
||||
for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' {
|
||||
i--
|
||||
}
|
||||
const dot = "·"
|
||||
if i >= len(dot) && name[i-len(dot):i] == dot {
|
||||
i -= len(dot)
|
||||
return name[:i], name[i:]
|
||||
}
|
||||
return name, ""
|
||||
}
|
|
@ -738,3 +738,17 @@ func pkgScope(pkg *types.Package) *types.Scope {
|
|||
}
|
||||
return types.Universe
|
||||
}
|
||||
|
||||
// See cmd/compile/internal/types.SplitVargenSuffix.
|
||||
func splitVargenSuffix(name string) (base, suffix string) {
|
||||
i := len(name)
|
||||
for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' {
|
||||
i--
|
||||
}
|
||||
const dot = "·"
|
||||
if i >= len(dot) && name[i-len(dot):i] == dot {
|
||||
i -= len(dot)
|
||||
return name[:i], name[i:]
|
||||
}
|
||||
return name, ""
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
|
@ -250,16 +249,13 @@ func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error {
|
|||
cmd.Stdout = stdout
|
||||
cmd.Stderr = stderr
|
||||
|
||||
// cmd.WaitDelay was added only in go1.20 (see #50436).
|
||||
if waitDelay := reflect.ValueOf(cmd).Elem().FieldByName("WaitDelay"); waitDelay.IsValid() {
|
||||
// https://go.dev/issue/59541: don't wait forever copying stderr
|
||||
// after the command has exited.
|
||||
// After CL 484741 we copy stdout manually, so we we'll stop reading that as
|
||||
// soon as ctx is done. However, we also don't want to wait around forever
|
||||
// for stderr. Give a much-longer-than-reasonable delay and then assume that
|
||||
// something has wedged in the kernel or runtime.
|
||||
waitDelay.Set(reflect.ValueOf(30 * time.Second))
|
||||
}
|
||||
// https://go.dev/issue/59541: don't wait forever copying stderr
|
||||
// after the command has exited.
|
||||
// After CL 484741 we copy stdout manually, so we we'll stop reading that as
|
||||
// soon as ctx is done. However, we also don't want to wait around forever
|
||||
// for stderr. Give a much-longer-than-reasonable delay and then assume that
|
||||
// something has wedged in the kernel or runtime.
|
||||
cmd.WaitDelay = 30 * time.Second
|
||||
|
||||
// The cwd gets resolved to the real path. On Darwin, where
|
||||
// /tmp is a symlink, this breaks anything that expects the
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
// Copyright 2019 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.
|
||||
|
||||
//go:build go1.22
|
||||
// +build go1.22
|
||||
|
||||
package imports
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Tests that go.work files and vendor directory are respected.
|
||||
func TestModWorkspaceVendoring(t *testing.T) {
|
||||
mt := setup(t, nil, `
|
||||
-- go.work --
|
||||
go 1.22
|
||||
|
||||
use (
|
||||
./a
|
||||
./b
|
||||
)
|
||||
-- a/go.mod --
|
||||
module example.com/a
|
||||
|
||||
go 1.22
|
||||
|
||||
require rsc.io/sampler v1.3.1
|
||||
-- a/a.go --
|
||||
package a
|
||||
|
||||
import _ "rsc.io/sampler"
|
||||
-- b/go.mod --
|
||||
module example.com/b
|
||||
|
||||
go 1.22
|
||||
-- b/b.go --
|
||||
package b
|
||||
`, "")
|
||||
defer mt.cleanup()
|
||||
|
||||
// generate vendor directory
|
||||
if _, err := mt.env.invokeGo(context.Background(), "work", "vendor"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// update module resolver
|
||||
mt.env.ClearModuleInfo()
|
||||
mt.env.UpdateResolver(mt.env.resolver.ClearForNewScan())
|
||||
|
||||
mt.assertModuleFoundInDir("example.com/a", "a", `main/a$`)
|
||||
mt.assertScanFinds("example.com/a", "a")
|
||||
mt.assertModuleFoundInDir("example.com/b", "b", `main/b$`)
|
||||
mt.assertScanFinds("example.com/b", "b")
|
||||
mt.assertModuleFoundInDir("rsc.io/sampler", "sampler", `/vendor/`)
|
||||
}
|
|
@ -267,10 +267,7 @@ import _ "rsc.io/sampler"
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
wantDir := `pkg.*mod.*/sampler@.*$`
|
||||
if testenv.Go1Point() >= 14 {
|
||||
wantDir = `/vendor/`
|
||||
}
|
||||
wantDir := `/vendor/`
|
||||
|
||||
// Clear out the resolver's module info, since we've changed the environment.
|
||||
// (the presence of a /vendor directory affects `go list -m`).
|
||||
|
@ -1323,3 +1320,48 @@ func BenchmarkModuleResolver_InitialScan(b *testing.B) {
|
|||
scanToSlice(resolver, exclude)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that go.work files and vendor directory are respected.
|
||||
func TestModWorkspaceVendoring(t *testing.T) {
|
||||
mt := setup(t, nil, `
|
||||
-- go.work --
|
||||
go 1.22
|
||||
|
||||
use (
|
||||
./a
|
||||
./b
|
||||
)
|
||||
-- a/go.mod --
|
||||
module example.com/a
|
||||
|
||||
go 1.22
|
||||
|
||||
require rsc.io/sampler v1.3.1
|
||||
-- a/a.go --
|
||||
package a
|
||||
|
||||
import _ "rsc.io/sampler"
|
||||
-- b/go.mod --
|
||||
module example.com/b
|
||||
|
||||
go 1.22
|
||||
-- b/b.go --
|
||||
package b
|
||||
`, "")
|
||||
defer mt.cleanup()
|
||||
|
||||
// generate vendor directory
|
||||
if _, err := mt.env.invokeGo(context.Background(), "work", "vendor"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// update module resolver
|
||||
mt.env.ClearModuleInfo()
|
||||
mt.env.UpdateResolver(mt.env.resolver.ClearForNewScan())
|
||||
|
||||
mt.assertModuleFoundInDir("example.com/a", "a", `main/a$`)
|
||||
mt.assertScanFinds("example.com/a", "a")
|
||||
mt.assertModuleFoundInDir("example.com/b", "b", `main/b$`)
|
||||
mt.assertScanFinds("example.com/b", "b")
|
||||
mt.assertModuleFoundInDir("rsc.io/sampler", "sampler", `/vendor/`)
|
||||
}
|
||||
|
|
|
@ -14,8 +14,6 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/internal/testenv"
|
||||
)
|
||||
|
||||
// WriteModuleVersion creates a directory in the proxy dir for a module.
|
||||
|
@ -82,18 +80,10 @@ func checkClose(name string, closer io.Closer, err *error) {
|
|||
|
||||
// ToURL returns the file uri for a proxy directory.
|
||||
func ToURL(dir string) string {
|
||||
if testenv.Go1Point() >= 13 {
|
||||
// file URLs on Windows must start with file:///. See golang.org/issue/6027.
|
||||
path := filepath.ToSlash(dir)
|
||||
if !strings.HasPrefix(path, "/") {
|
||||
path = "/" + path
|
||||
}
|
||||
return "file://" + path
|
||||
} else {
|
||||
// Prior to go1.13, the Go command on Windows only accepted GOPROXY file URLs
|
||||
// of the form file://C:/path/to/proxy. This was incorrect: when parsed, "C:"
|
||||
// is interpreted as the host. See golang.org/issue/6027. This has been
|
||||
// fixed in go1.13, but we emit the old format for old releases.
|
||||
return "file://" + filepath.ToSlash(dir)
|
||||
// file URLs on Windows must start with file:///. See golang.org/issue/6027.
|
||||
path := filepath.ToSlash(dir)
|
||||
if !strings.HasPrefix(path, "/") {
|
||||
path = "/" + path
|
||||
}
|
||||
return "file://" + path
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.20
|
||||
|
||||
package analyzer
|
||||
|
||||
import (
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.20
|
||||
|
||||
package analyzer_test
|
||||
|
||||
import (
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"go/types"
|
||||
pathpkg "path"
|
||||
"reflect"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -151,7 +152,7 @@ func (st *state) inline() (*Result, error) {
|
|||
elideBraces := res.elideBraces
|
||||
if !elideBraces {
|
||||
if newBlock, ok := res.new.(*ast.BlockStmt); ok {
|
||||
i := nodeIndex(caller.path, res.old)
|
||||
i := slices.Index(caller.path, res.old)
|
||||
parent := caller.path[i+1]
|
||||
var body []ast.Stmt
|
||||
switch parent := parent.(type) {
|
||||
|
@ -2465,7 +2466,7 @@ func callStmt(callPath []ast.Node, unrestricted bool) *ast.ExprStmt {
|
|||
parent, _ := callContext(callPath)
|
||||
stmt, ok := parent.(*ast.ExprStmt)
|
||||
if ok && unrestricted {
|
||||
switch callPath[nodeIndex(callPath, stmt)+1].(type) {
|
||||
switch callPath[slices.Index(callPath, ast.Node(stmt))+1].(type) {
|
||||
case *ast.LabeledStmt,
|
||||
*ast.BlockStmt,
|
||||
*ast.CaseClause,
|
||||
|
@ -2775,7 +2776,7 @@ func consistentOffsets(caller *Caller) bool {
|
|||
// ancestor of the CallExpr identified by its PathEnclosingInterval).
|
||||
func needsParens(callPath []ast.Node, old, new ast.Node) bool {
|
||||
// Find enclosing old node and its parent.
|
||||
i := nodeIndex(callPath, old)
|
||||
i := slices.Index(callPath, old)
|
||||
if i == -1 {
|
||||
panic("not found")
|
||||
}
|
||||
|
@ -2837,16 +2838,6 @@ func needsParens(callPath []ast.Node, old, new ast.Node) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func nodeIndex(nodes []ast.Node, n ast.Node) int {
|
||||
// TODO(adonovan): Use index[ast.Node]() in go1.20.
|
||||
for i, node := range nodes {
|
||||
if node == n {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// declares returns the set of lexical names declared by a
|
||||
// sequence of statements from the same block, excluding sub-blocks.
|
||||
// (Lexical names do not include control labels.)
|
||||
|
|
|
@ -11,41 +11,10 @@ import (
|
|||
"go/token"
|
||||
"sort"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// GetLines returns the table of line-start offsets from a token.File.
|
||||
func GetLines(file *token.File) []int {
|
||||
// token.File has a Lines method on Go 1.21 and later.
|
||||
if file, ok := (interface{})(file).(interface{ Lines() []int }); ok {
|
||||
return file.Lines()
|
||||
}
|
||||
|
||||
// This declaration must match that of token.File.
|
||||
// This creates a risk of dependency skew.
|
||||
// For now we check that the size of the two
|
||||
// declarations is the same, on the (fragile) assumption
|
||||
// that future changes would add fields.
|
||||
type tokenFile119 struct {
|
||||
_ string
|
||||
_ int
|
||||
_ int
|
||||
mu sync.Mutex // we're not complete monsters
|
||||
lines []int
|
||||
_ []struct{}
|
||||
}
|
||||
|
||||
if unsafe.Sizeof(*file) != unsafe.Sizeof(tokenFile119{}) {
|
||||
panic("unexpected token.File size")
|
||||
}
|
||||
var ptr *tokenFile119
|
||||
type uP = unsafe.Pointer
|
||||
*(*uP)(uP(&ptr)) = uP(file)
|
||||
ptr.mu.Lock()
|
||||
defer ptr.mu.Unlock()
|
||||
return ptr.lines
|
||||
}
|
||||
|
||||
// AddExistingFiles adds the specified files to the FileSet if they
|
||||
// are not already present. It panics if any pair of files in the
|
||||
// resulting FileSet would overlap.
|
||||
|
@ -56,7 +25,7 @@ func AddExistingFiles(fset *token.FileSet, files []*token.File) {
|
|||
mutex sync.RWMutex
|
||||
base int
|
||||
files []*token.File
|
||||
_ *token.File // changed to atomic.Pointer[token.File] in go1.19
|
||||
_ atomic.Pointer[token.File]
|
||||
}
|
||||
|
||||
// If the size of token.FileSet changes, this will fail to compile.
|
||||
|
@ -116,8 +85,7 @@ func FileSetFor(files ...*token.File) *token.FileSet {
|
|||
fset := token.NewFileSet()
|
||||
for _, f := range files {
|
||||
f2 := fset.AddFile(f.Name(), f.Base(), f.Size())
|
||||
lines := GetLines(f)
|
||||
f2.SetLines(lines)
|
||||
f2.SetLines(f.Lines())
|
||||
}
|
||||
return fset
|
||||
}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright 2024 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 versions
|
||||
|
||||
// toolchain is maximum version (<1.22) that the go toolchain used
|
||||
// to build the current tool is known to support.
|
||||
//
|
||||
// When a tool is built with >=1.22, the value of toolchain is unused.
|
||||
//
|
||||
// x/tools does not support building with go <1.18. So we take this
|
||||
// as the minimum possible maximum.
|
||||
var toolchain string = Go1_18
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright 2024 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.
|
||||
|
||||
//go:build go1.19
|
||||
// +build go1.19
|
||||
|
||||
package versions
|
||||
|
||||
func init() {
|
||||
if Compare(toolchain, Go1_19) < 0 {
|
||||
toolchain = Go1_19
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright 2024 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.
|
||||
|
||||
//go:build go1.20
|
||||
// +build go1.20
|
||||
|
||||
package versions
|
||||
|
||||
func init() {
|
||||
if Compare(toolchain, Go1_20) < 0 {
|
||||
toolchain = Go1_20
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright 2024 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.
|
||||
|
||||
//go:build go1.21
|
||||
// +build go1.21
|
||||
|
||||
package versions
|
||||
|
||||
func init() {
|
||||
if Compare(toolchain, Go1_21) < 0 {
|
||||
toolchain = Go1_21
|
||||
}
|
||||
}
|
|
@ -5,15 +5,34 @@
|
|||
package versions
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/types"
|
||||
)
|
||||
|
||||
// GoVersion returns the Go version of the type package.
|
||||
// It returns zero if no version can be determined.
|
||||
func GoVersion(pkg *types.Package) string {
|
||||
// TODO(taking): x/tools can call GoVersion() [from 1.21] after 1.25.
|
||||
if pkg, ok := any(pkg).(interface{ GoVersion() string }); ok {
|
||||
return pkg.GoVersion()
|
||||
// FileVersion returns a file's Go version.
|
||||
// The reported version is an unknown Future version if a
|
||||
// version cannot be determined.
|
||||
func FileVersion(info *types.Info, file *ast.File) string {
|
||||
// In tools built with Go >= 1.22, the Go version of a file
|
||||
// follow a cascades of sources:
|
||||
// 1) types.Info.FileVersion, which follows the cascade:
|
||||
// 1.a) file version (ast.File.GoVersion),
|
||||
// 1.b) the package version (types.Config.GoVersion), or
|
||||
// 2) is some unknown Future version.
|
||||
//
|
||||
// File versions require a valid package version to be provided to types
|
||||
// in Config.GoVersion. Config.GoVersion is either from the package's module
|
||||
// or the toolchain (go run). This value should be provided by go/packages
|
||||
// or unitchecker.Config.GoVersion.
|
||||
if v := info.FileVersions[file]; IsValid(v) {
|
||||
return v
|
||||
}
|
||||
return ""
|
||||
// Note: we could instead return runtime.Version() [if valid].
|
||||
// This would act as a max version on what a tool can support.
|
||||
return Future
|
||||
}
|
||||
|
||||
// InitFileVersions initializes info to record Go versions for Go files.
|
||||
func InitFileVersions(info *types.Info) {
|
||||
info.FileVersions = make(map[*ast.File]string)
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright 2023 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.
|
||||
|
||||
//go:build !go1.22
|
||||
// +build !go1.22
|
||||
|
||||
package versions
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/types"
|
||||
)
|
||||
|
||||
// FileVersion returns a language version (<=1.21) derived from runtime.Version()
|
||||
// or an unknown future version.
|
||||
func FileVersion(info *types.Info, file *ast.File) string {
|
||||
// In x/tools built with Go <= 1.21, we do not have Info.FileVersions
|
||||
// available. We use a go version derived from the toolchain used to
|
||||
// compile the tool by default.
|
||||
// This will be <= go1.21. We take this as the maximum version that
|
||||
// this tool can support.
|
||||
//
|
||||
// There are no features currently in x/tools that need to tell fine grained
|
||||
// differences for versions <1.22.
|
||||
return toolchain
|
||||
}
|
||||
|
||||
// InitFileVersions is a noop when compiled with this Go version.
|
||||
func InitFileVersions(*types.Info) {}
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright 2023 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.
|
||||
|
||||
//go:build go1.22
|
||||
// +build go1.22
|
||||
|
||||
package versions
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/types"
|
||||
)
|
||||
|
||||
// FileVersion returns a file's Go version.
|
||||
// The reported version is an unknown Future version if a
|
||||
// version cannot be determined.
|
||||
func FileVersion(info *types.Info, file *ast.File) string {
|
||||
// In tools built with Go >= 1.22, the Go version of a file
|
||||
// follow a cascades of sources:
|
||||
// 1) types.Info.FileVersion, which follows the cascade:
|
||||
// 1.a) file version (ast.File.GoVersion),
|
||||
// 1.b) the package version (types.Config.GoVersion), or
|
||||
// 2) is some unknown Future version.
|
||||
//
|
||||
// File versions require a valid package version to be provided to types
|
||||
// in Config.GoVersion. Config.GoVersion is either from the package's module
|
||||
// or the toolchain (go run). This value should be provided by go/packages
|
||||
// or unitchecker.Config.GoVersion.
|
||||
if v := info.FileVersions[file]; IsValid(v) {
|
||||
return v
|
||||
}
|
||||
// Note: we could instead return runtime.Version() [if valid].
|
||||
// This would act as a max version on what a tool can support.
|
||||
return Future
|
||||
}
|
||||
|
||||
// InitFileVersions initializes info to record Go versions for Go files.
|
||||
func InitFileVersions(info *types.Info) {
|
||||
info.FileVersions = make(map[*ast.File]string)
|
||||
}
|
|
@ -13,13 +13,10 @@ import (
|
|||
"go/types"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/internal/testenv"
|
||||
"golang.org/x/tools/internal/versions"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
testenv.NeedsGo1Point(t, 22)
|
||||
|
||||
var contents = map[string]string{
|
||||
"gobuild.go": `
|
||||
//go:build go1.23
|
||||
|
@ -49,7 +46,7 @@ func Test(t *testing.T) {
|
|||
files[i] = parse(t, fset, test.fname, contents[test.fname])
|
||||
}
|
||||
pkg, info := typeCheck(t, fset, files, item.goversion)
|
||||
if got, want := versions.GoVersion(pkg), item.pversion; versions.Compare(got, want) != 0 {
|
||||
if got, want := pkg.GoVersion(), item.pversion; versions.Compare(got, want) != 0 {
|
||||
t.Errorf("GoVersion()=%q. expected %q", got, want)
|
||||
}
|
||||
if got := versions.FileVersion(info, nil); got != "" {
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"go/types"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/internal/testenv"
|
||||
"golang.org/x/tools/internal/versions"
|
||||
)
|
||||
|
||||
|
@ -192,9 +191,7 @@ func TestBefore(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestFileVersions122(t *testing.T) {
|
||||
testenv.NeedsGo1Point(t, 22)
|
||||
|
||||
func TestFileVersions(t *testing.T) {
|
||||
const source = `
|
||||
package P
|
||||
`
|
||||
|
@ -230,27 +227,3 @@ func TestFileVersions122(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileVersions121(t *testing.T) {
|
||||
testenv.SkipAfterGo1Point(t, 21)
|
||||
|
||||
// If <1.22, info and file are ignored.
|
||||
v := versions.FileVersion(nil, nil)
|
||||
oneof := map[string]bool{
|
||||
versions.Go1_18: true,
|
||||
versions.Go1_19: true,
|
||||
versions.Go1_20: true,
|
||||
versions.Go1_21: true,
|
||||
}
|
||||
if !oneof[v] {
|
||||
t.Errorf("FileVersion(...)=%q expected to be a known go version <1.22", v)
|
||||
}
|
||||
|
||||
if versions.AtLeast(v, versions.Go1_22) {
|
||||
t.Errorf("versions.AtLeast(%q, %q) expected to be false", v, versions.Go1_22)
|
||||
}
|
||||
|
||||
if !versions.Before(v, versions.Go1_22) {
|
||||
t.Errorf("versions.Before(%q, %q) expected to hold", v, versions.Go1_22)
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче