build(deps): bump the golang group with 5 updates
Bumps the golang group with 5 updates: | Package | From | To | | --- | --- | --- | | [github.com/Microsoft/hcsshim](https://github.com/Microsoft/hcsshim) | `0.11.4` | `0.12.0` | | [github.com/alexflint/go-filemutex](https://github.com/alexflint/go-filemutex) | `1.2.0` | `1.3.0` | | [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) | `2.13.2` | `2.16.0` | | [github.com/onsi/gomega](https://github.com/onsi/gomega) | `1.30.0` | `1.31.1` | | [golang.org/x/sys](https://github.com/golang/sys) | `0.15.0` | `0.17.0` | Updates `github.com/Microsoft/hcsshim` from 0.11.4 to 0.12.0 - [Release notes](https://github.com/Microsoft/hcsshim/releases) - [Commits](https://github.com/Microsoft/hcsshim/compare/v0.11.4...v0.12.0) Updates `github.com/alexflint/go-filemutex` from 1.2.0 to 1.3.0 - [Release notes](https://github.com/alexflint/go-filemutex/releases) - [Commits](https://github.com/alexflint/go-filemutex/compare/v1.2.0...v1.3.0) Updates `github.com/onsi/ginkgo/v2` from 2.13.2 to 2.16.0 - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v2.13.2...v2.16.0) Updates `github.com/onsi/gomega` from 1.30.0 to 1.31.1 - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.30.0...v1.31.1) Updates `golang.org/x/sys` from 0.15.0 to 0.17.0 - [Commits](https://github.com/golang/sys/compare/v0.15.0...v0.17.0) --- updated-dependencies: - dependency-name: github.com/Microsoft/hcsshim dependency-type: direct:production update-type: version-update:semver-minor dependency-group: golang - dependency-name: github.com/alexflint/go-filemutex dependency-type: direct:production update-type: version-update:semver-minor dependency-group: golang - dependency-name: github.com/onsi/ginkgo/v2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: golang - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor dependency-group: golang - dependency-name: golang.org/x/sys dependency-type: direct:production update-type: version-update:semver-minor dependency-group: golang ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
266
vendor/golang.org/x/tools/cover/profile.go
generated
vendored
Normal file
266
vendor/golang.org/x/tools/cover/profile.go
generated
vendored
Normal file
@ -0,0 +1,266 @@
|
||||
// Copyright 2013 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 cover provides support for parsing coverage profiles
|
||||
// generated by "go test -coverprofile=cover.out".
|
||||
package cover // import "golang.org/x/tools/cover"
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Profile represents the profiling data for a specific file.
|
||||
type Profile struct {
|
||||
FileName string
|
||||
Mode string
|
||||
Blocks []ProfileBlock
|
||||
}
|
||||
|
||||
// ProfileBlock represents a single block of profiling data.
|
||||
type ProfileBlock struct {
|
||||
StartLine, StartCol int
|
||||
EndLine, EndCol int
|
||||
NumStmt, Count int
|
||||
}
|
||||
|
||||
type byFileName []*Profile
|
||||
|
||||
func (p byFileName) Len() int { return len(p) }
|
||||
func (p byFileName) Less(i, j int) bool { return p[i].FileName < p[j].FileName }
|
||||
func (p byFileName) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
// ParseProfiles parses profile data in the specified file and returns a
|
||||
// Profile for each source file described therein.
|
||||
func ParseProfiles(fileName string) ([]*Profile, error) {
|
||||
pf, err := os.Open(fileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer pf.Close()
|
||||
return ParseProfilesFromReader(pf)
|
||||
}
|
||||
|
||||
// ParseProfilesFromReader parses profile data from the Reader and
|
||||
// returns a Profile for each source file described therein.
|
||||
func ParseProfilesFromReader(rd io.Reader) ([]*Profile, error) {
|
||||
// First line is "mode: foo", where foo is "set", "count", or "atomic".
|
||||
// Rest of file is in the format
|
||||
// encoding/base64/base64.go:34.44,37.40 3 1
|
||||
// where the fields are: name.go:line.column,line.column numberOfStatements count
|
||||
files := make(map[string]*Profile)
|
||||
s := bufio.NewScanner(rd)
|
||||
mode := ""
|
||||
for s.Scan() {
|
||||
line := s.Text()
|
||||
if mode == "" {
|
||||
const p = "mode: "
|
||||
if !strings.HasPrefix(line, p) || line == p {
|
||||
return nil, fmt.Errorf("bad mode line: %v", line)
|
||||
}
|
||||
mode = line[len(p):]
|
||||
continue
|
||||
}
|
||||
fn, b, err := parseLine(line)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("line %q doesn't match expected format: %v", line, err)
|
||||
}
|
||||
p := files[fn]
|
||||
if p == nil {
|
||||
p = &Profile{
|
||||
FileName: fn,
|
||||
Mode: mode,
|
||||
}
|
||||
files[fn] = p
|
||||
}
|
||||
p.Blocks = append(p.Blocks, b)
|
||||
}
|
||||
if err := s.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, p := range files {
|
||||
sort.Sort(blocksByStart(p.Blocks))
|
||||
// Merge samples from the same location.
|
||||
j := 1
|
||||
for i := 1; i < len(p.Blocks); i++ {
|
||||
b := p.Blocks[i]
|
||||
last := p.Blocks[j-1]
|
||||
if b.StartLine == last.StartLine &&
|
||||
b.StartCol == last.StartCol &&
|
||||
b.EndLine == last.EndLine &&
|
||||
b.EndCol == last.EndCol {
|
||||
if b.NumStmt != last.NumStmt {
|
||||
return nil, fmt.Errorf("inconsistent NumStmt: changed from %d to %d", last.NumStmt, b.NumStmt)
|
||||
}
|
||||
if mode == "set" {
|
||||
p.Blocks[j-1].Count |= b.Count
|
||||
} else {
|
||||
p.Blocks[j-1].Count += b.Count
|
||||
}
|
||||
continue
|
||||
}
|
||||
p.Blocks[j] = b
|
||||
j++
|
||||
}
|
||||
p.Blocks = p.Blocks[:j]
|
||||
}
|
||||
// Generate a sorted slice.
|
||||
profiles := make([]*Profile, 0, len(files))
|
||||
for _, profile := range files {
|
||||
profiles = append(profiles, profile)
|
||||
}
|
||||
sort.Sort(byFileName(profiles))
|
||||
return profiles, nil
|
||||
}
|
||||
|
||||
// parseLine parses a line from a coverage file.
|
||||
// It is equivalent to the regex
|
||||
// ^(.+):([0-9]+)\.([0-9]+),([0-9]+)\.([0-9]+) ([0-9]+) ([0-9]+)$
|
||||
//
|
||||
// However, it is much faster: https://golang.org/cl/179377
|
||||
func parseLine(l string) (fileName string, block ProfileBlock, err error) {
|
||||
end := len(l)
|
||||
|
||||
b := ProfileBlock{}
|
||||
b.Count, end, err = seekBack(l, ' ', end, "Count")
|
||||
if err != nil {
|
||||
return "", b, err
|
||||
}
|
||||
b.NumStmt, end, err = seekBack(l, ' ', end, "NumStmt")
|
||||
if err != nil {
|
||||
return "", b, err
|
||||
}
|
||||
b.EndCol, end, err = seekBack(l, '.', end, "EndCol")
|
||||
if err != nil {
|
||||
return "", b, err
|
||||
}
|
||||
b.EndLine, end, err = seekBack(l, ',', end, "EndLine")
|
||||
if err != nil {
|
||||
return "", b, err
|
||||
}
|
||||
b.StartCol, end, err = seekBack(l, '.', end, "StartCol")
|
||||
if err != nil {
|
||||
return "", b, err
|
||||
}
|
||||
b.StartLine, end, err = seekBack(l, ':', end, "StartLine")
|
||||
if err != nil {
|
||||
return "", b, err
|
||||
}
|
||||
fn := l[0:end]
|
||||
if fn == "" {
|
||||
return "", b, errors.New("a FileName cannot be blank")
|
||||
}
|
||||
return fn, b, nil
|
||||
}
|
||||
|
||||
// seekBack searches backwards from end to find sep in l, then returns the
|
||||
// value between sep and end as an integer.
|
||||
// If seekBack fails, the returned error will reference what.
|
||||
func seekBack(l string, sep byte, end int, what string) (value int, nextSep int, err error) {
|
||||
// Since we're seeking backwards and we know only ASCII is legal for these values,
|
||||
// we can ignore the possibility of non-ASCII characters.
|
||||
for start := end - 1; start >= 0; start-- {
|
||||
if l[start] == sep {
|
||||
i, err := strconv.Atoi(l[start+1 : end])
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("couldn't parse %q: %v", what, err)
|
||||
}
|
||||
if i < 0 {
|
||||
return 0, 0, fmt.Errorf("negative values are not allowed for %s, found %d", what, i)
|
||||
}
|
||||
return i, start, nil
|
||||
}
|
||||
}
|
||||
return 0, 0, fmt.Errorf("couldn't find a %s before %s", string(sep), what)
|
||||
}
|
||||
|
||||
type blocksByStart []ProfileBlock
|
||||
|
||||
func (b blocksByStart) Len() int { return len(b) }
|
||||
func (b blocksByStart) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
|
||||
func (b blocksByStart) Less(i, j int) bool {
|
||||
bi, bj := b[i], b[j]
|
||||
return bi.StartLine < bj.StartLine || bi.StartLine == bj.StartLine && bi.StartCol < bj.StartCol
|
||||
}
|
||||
|
||||
// Boundary represents the position in a source file of the beginning or end of a
|
||||
// block as reported by the coverage profile. In HTML mode, it will correspond to
|
||||
// the opening or closing of a <span> tag and will be used to colorize the source
|
||||
type Boundary struct {
|
||||
Offset int // Location as a byte offset in the source file.
|
||||
Start bool // Is this the start of a block?
|
||||
Count int // Event count from the cover profile.
|
||||
Norm float64 // Count normalized to [0..1].
|
||||
Index int // Order in input file.
|
||||
}
|
||||
|
||||
// Boundaries returns a Profile as a set of Boundary objects within the provided src.
|
||||
func (p *Profile) Boundaries(src []byte) (boundaries []Boundary) {
|
||||
// Find maximum count.
|
||||
max := 0
|
||||
for _, b := range p.Blocks {
|
||||
if b.Count > max {
|
||||
max = b.Count
|
||||
}
|
||||
}
|
||||
// Divisor for normalization.
|
||||
divisor := math.Log(float64(max))
|
||||
|
||||
// boundary returns a Boundary, populating the Norm field with a normalized Count.
|
||||
index := 0
|
||||
boundary := func(offset int, start bool, count int) Boundary {
|
||||
b := Boundary{Offset: offset, Start: start, Count: count, Index: index}
|
||||
index++
|
||||
if !start || count == 0 {
|
||||
return b
|
||||
}
|
||||
if max <= 1 {
|
||||
b.Norm = 0.8 // Profile is in"set" mode; we want a heat map. Use cov8 in the CSS.
|
||||
} else if count > 0 {
|
||||
b.Norm = math.Log(float64(count)) / divisor
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
line, col := 1, 2 // TODO: Why is this 2?
|
||||
for si, bi := 0, 0; si < len(src) && bi < len(p.Blocks); {
|
||||
b := p.Blocks[bi]
|
||||
if b.StartLine == line && b.StartCol == col {
|
||||
boundaries = append(boundaries, boundary(si, true, b.Count))
|
||||
}
|
||||
if b.EndLine == line && b.EndCol == col || line > b.EndLine {
|
||||
boundaries = append(boundaries, boundary(si, false, 0))
|
||||
bi++
|
||||
continue // Don't advance through src; maybe the next block starts here.
|
||||
}
|
||||
if src[si] == '\n' {
|
||||
line++
|
||||
col = 0
|
||||
}
|
||||
col++
|
||||
si++
|
||||
}
|
||||
sort.Sort(boundariesByPos(boundaries))
|
||||
return
|
||||
}
|
||||
|
||||
type boundariesByPos []Boundary
|
||||
|
||||
func (b boundariesByPos) Len() int { return len(b) }
|
||||
func (b boundariesByPos) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
|
||||
func (b boundariesByPos) Less(i, j int) bool {
|
||||
if b[i].Offset == b[j].Offset {
|
||||
// Boundaries at the same offset should be ordered according to
|
||||
// their original position.
|
||||
return b[i].Index < b[j].Index
|
||||
}
|
||||
return b[i].Offset < b[j].Offset
|
||||
}
|
4
vendor/golang.org/x/tools/go/ast/inspector/typeof.go
generated
vendored
4
vendor/golang.org/x/tools/go/ast/inspector/typeof.go
generated
vendored
@ -12,8 +12,6 @@ package inspector
|
||||
import (
|
||||
"go/ast"
|
||||
"math"
|
||||
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -171,7 +169,7 @@ func typeOf(n ast.Node) uint64 {
|
||||
return 1 << nIncDecStmt
|
||||
case *ast.IndexExpr:
|
||||
return 1 << nIndexExpr
|
||||
case *typeparams.IndexListExpr:
|
||||
case *ast.IndexListExpr:
|
||||
return 1 << nIndexListExpr
|
||||
case *ast.InterfaceType:
|
||||
return 1 << nInterfaceType
|
||||
|
15
vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
generated
vendored
15
vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
generated
vendored
@ -13,16 +13,17 @@ import (
|
||||
"golang.org/x/tools/internal/gocommand"
|
||||
)
|
||||
|
||||
var debug = false
|
||||
|
||||
func GetSizesForArgsGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) {
|
||||
inv.Verb = "list"
|
||||
inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"}
|
||||
stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv)
|
||||
var goarch, compiler string
|
||||
if rawErr != nil {
|
||||
if rawErrMsg := rawErr.Error(); strings.Contains(rawErrMsg, "cannot find main module") || strings.Contains(rawErrMsg, "go.mod file not found") {
|
||||
// User's running outside of a module. All bets are off. Get GOARCH and guess compiler is gc.
|
||||
rawErrMsg := rawErr.Error()
|
||||
if strings.Contains(rawErrMsg, "cannot find main module") ||
|
||||
strings.Contains(rawErrMsg, "go.mod file not found") {
|
||||
// User's running outside of a module.
|
||||
// All bets are off. Get GOARCH and guess compiler is gc.
|
||||
// TODO(matloob): Is this a problem in practice?
|
||||
inv.Verb = "env"
|
||||
inv.Args = []string{"GOARCH"}
|
||||
@ -32,8 +33,12 @@ func GetSizesForArgsGolist(ctx context.Context, inv gocommand.Invocation, gocmdR
|
||||
}
|
||||
goarch = strings.TrimSpace(envout.String())
|
||||
compiler = "gc"
|
||||
} else {
|
||||
} else if friendlyErr != nil {
|
||||
return "", "", friendlyErr
|
||||
} else {
|
||||
// This should be unreachable, but be defensive
|
||||
// in case RunRaw's error results are inconsistent.
|
||||
return "", "", rawErr
|
||||
}
|
||||
} else {
|
||||
fields := strings.Fields(stdout.String())
|
||||
|
32
vendor/golang.org/x/tools/go/packages/doc.go
generated
vendored
32
vendor/golang.org/x/tools/go/packages/doc.go
generated
vendored
@ -5,12 +5,32 @@
|
||||
/*
|
||||
Package packages loads Go packages for inspection and analysis.
|
||||
|
||||
The Load function takes as input a list of patterns and return a list of Package
|
||||
structs describing individual packages matched by those patterns.
|
||||
The LoadMode controls the amount of detail in the loaded packages.
|
||||
The [Load] function takes as input a list of patterns and returns a
|
||||
list of [Package] values describing individual packages matched by those
|
||||
patterns.
|
||||
A [Config] specifies configuration options, the most important of which is
|
||||
the [LoadMode], which controls the amount of detail in the loaded packages.
|
||||
|
||||
Load passes most patterns directly to the underlying build tool,
|
||||
but all patterns with the prefix "query=", where query is a
|
||||
Load passes most patterns directly to the underlying build tool.
|
||||
The default build tool is the go command.
|
||||
Its supported patterns are described at
|
||||
https://pkg.go.dev/cmd/go#hdr-Package_lists_and_patterns.
|
||||
|
||||
Load may be used in Go projects that use alternative build systems, by
|
||||
installing an appropriate "driver" program for the build system and
|
||||
specifying its location in the GOPACKAGESDRIVER environment variable.
|
||||
For example,
|
||||
https://github.com/bazelbuild/rules_go/wiki/Editor-and-tool-integration
|
||||
explains how to use the driver for Bazel.
|
||||
The driver program is responsible for interpreting patterns in its
|
||||
preferred notation and reporting information about the packages that
|
||||
they identify.
|
||||
(See driverRequest and driverResponse types for the JSON
|
||||
schema used by the protocol.
|
||||
Though the protocol is supported, these types are currently unexported;
|
||||
see #64608 for a proposal to publish them.)
|
||||
|
||||
Regardless of driver, all patterns with the prefix "query=", where query is a
|
||||
non-empty string of letters from [a-z], are reserved and may be
|
||||
interpreted as query operators.
|
||||
|
||||
@ -64,7 +84,7 @@ reported about the loaded packages. See the documentation for type LoadMode
|
||||
for details.
|
||||
|
||||
Most tools should pass their command-line arguments (after any flags)
|
||||
uninterpreted to the loader, so that the loader can interpret them
|
||||
uninterpreted to [Load], so that it can interpret them
|
||||
according to the conventions of the underlying build system.
|
||||
See the Example function for typical usage.
|
||||
*/
|
||||
|
2
vendor/golang.org/x/tools/go/packages/external.go
generated
vendored
2
vendor/golang.org/x/tools/go/packages/external.go
generated
vendored
@ -12,8 +12,8 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
exec "golang.org/x/sys/execabs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
76
vendor/golang.org/x/tools/go/packages/golist.go
generated
vendored
76
vendor/golang.org/x/tools/go/packages/golist.go
generated
vendored
@ -11,6 +11,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
@ -20,7 +21,6 @@ import (
|
||||
"sync"
|
||||
"unicode"
|
||||
|
||||
exec "golang.org/x/sys/execabs"
|
||||
"golang.org/x/tools/go/internal/packagesdriver"
|
||||
"golang.org/x/tools/internal/gocommand"
|
||||
"golang.org/x/tools/internal/packagesinternal"
|
||||
@ -208,62 +208,6 @@ extractQueries:
|
||||
}
|
||||
}
|
||||
|
||||
// Only use go/packages' overlay processing if we're using a Go version
|
||||
// below 1.16. Otherwise, go list handles it.
|
||||
if goVersion, err := state.getGoVersion(); err == nil && goVersion < 16 {
|
||||
modifiedPkgs, needPkgs, err := state.processGolistOverlay(response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var containsCandidates []string
|
||||
if len(containFiles) > 0 {
|
||||
containsCandidates = append(containsCandidates, modifiedPkgs...)
|
||||
containsCandidates = append(containsCandidates, needPkgs...)
|
||||
}
|
||||
if err := state.addNeededOverlayPackages(response, needPkgs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Check candidate packages for containFiles.
|
||||
if len(containFiles) > 0 {
|
||||
for _, id := range containsCandidates {
|
||||
pkg, ok := response.seenPackages[id]
|
||||
if !ok {
|
||||
response.addPackage(&Package{
|
||||
ID: id,
|
||||
Errors: []Error{{
|
||||
Kind: ListError,
|
||||
Msg: fmt.Sprintf("package %s expected but not seen", id),
|
||||
}},
|
||||
})
|
||||
continue
|
||||
}
|
||||
for _, f := range containFiles {
|
||||
for _, g := range pkg.GoFiles {
|
||||
if sameFile(f, g) {
|
||||
response.addRoot(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add root for any package that matches a pattern. This applies only to
|
||||
// packages that are modified by overlays, since they are not added as
|
||||
// roots automatically.
|
||||
for _, pattern := range restPatterns {
|
||||
match := matchPattern(pattern)
|
||||
for _, pkgID := range modifiedPkgs {
|
||||
pkg, ok := response.seenPackages[pkgID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if match(pkg.PkgPath) {
|
||||
response.addRoot(pkg.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sizeswg.Wait()
|
||||
if sizeserr != nil {
|
||||
return nil, sizeserr
|
||||
@ -271,24 +215,6 @@ extractQueries:
|
||||
return response.dr, nil
|
||||
}
|
||||
|
||||
func (state *golistState) addNeededOverlayPackages(response *responseDeduper, pkgs []string) error {
|
||||
if len(pkgs) == 0 {
|
||||
return nil
|
||||
}
|
||||
dr, err := state.createDriverResponse(pkgs...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, pkg := range dr.Packages {
|
||||
response.addPackage(pkg)
|
||||
}
|
||||
_, needPkgs, err := state.processGolistOverlay(response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return state.addNeededOverlayPackages(response, needPkgs)
|
||||
}
|
||||
|
||||
func (state *golistState) runContainsQueries(response *responseDeduper, queries []string) error {
|
||||
for _, query := range queries {
|
||||
// TODO(matloob): Do only one query per directory.
|
||||
|
492
vendor/golang.org/x/tools/go/packages/golist_overlay.go
generated
vendored
492
vendor/golang.org/x/tools/go/packages/golist_overlay.go
generated
vendored
@ -6,314 +6,11 @@ package packages
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/internal/gocommand"
|
||||
)
|
||||
|
||||
// processGolistOverlay provides rudimentary support for adding
|
||||
// files that don't exist on disk to an overlay. The results can be
|
||||
// sometimes incorrect.
|
||||
// TODO(matloob): Handle unsupported cases, including the following:
|
||||
// - determining the correct package to add given a new import path
|
||||
func (state *golistState) processGolistOverlay(response *responseDeduper) (modifiedPkgs, needPkgs []string, err error) {
|
||||
havePkgs := make(map[string]string) // importPath -> non-test package ID
|
||||
needPkgsSet := make(map[string]bool)
|
||||
modifiedPkgsSet := make(map[string]bool)
|
||||
|
||||
pkgOfDir := make(map[string][]*Package)
|
||||
for _, pkg := range response.dr.Packages {
|
||||
// This is an approximation of import path to id. This can be
|
||||
// wrong for tests, vendored packages, and a number of other cases.
|
||||
havePkgs[pkg.PkgPath] = pkg.ID
|
||||
dir, err := commonDir(pkg.GoFiles)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if dir != "" {
|
||||
pkgOfDir[dir] = append(pkgOfDir[dir], pkg)
|
||||
}
|
||||
}
|
||||
|
||||
// If no new imports are added, it is safe to avoid loading any needPkgs.
|
||||
// Otherwise, it's hard to tell which package is actually being loaded
|
||||
// (due to vendoring) and whether any modified package will show up
|
||||
// in the transitive set of dependencies (because new imports are added,
|
||||
// potentially modifying the transitive set of dependencies).
|
||||
var overlayAddsImports bool
|
||||
|
||||
// If both a package and its test package are created by the overlay, we
|
||||
// need the real package first. Process all non-test files before test
|
||||
// files, and make the whole process deterministic while we're at it.
|
||||
var overlayFiles []string
|
||||
for opath := range state.cfg.Overlay {
|
||||
overlayFiles = append(overlayFiles, opath)
|
||||
}
|
||||
sort.Slice(overlayFiles, func(i, j int) bool {
|
||||
iTest := strings.HasSuffix(overlayFiles[i], "_test.go")
|
||||
jTest := strings.HasSuffix(overlayFiles[j], "_test.go")
|
||||
if iTest != jTest {
|
||||
return !iTest // non-tests are before tests.
|
||||
}
|
||||
return overlayFiles[i] < overlayFiles[j]
|
||||
})
|
||||
for _, opath := range overlayFiles {
|
||||
contents := state.cfg.Overlay[opath]
|
||||
base := filepath.Base(opath)
|
||||
dir := filepath.Dir(opath)
|
||||
var pkg *Package // if opath belongs to both a package and its test variant, this will be the test variant
|
||||
var testVariantOf *Package // if opath is a test file, this is the package it is testing
|
||||
var fileExists bool
|
||||
isTestFile := strings.HasSuffix(opath, "_test.go")
|
||||
pkgName, ok := extractPackageName(opath, contents)
|
||||
if !ok {
|
||||
// Don't bother adding a file that doesn't even have a parsable package statement
|
||||
// to the overlay.
|
||||
continue
|
||||
}
|
||||
// If all the overlay files belong to a different package, change the
|
||||
// package name to that package.
|
||||
maybeFixPackageName(pkgName, isTestFile, pkgOfDir[dir])
|
||||
nextPackage:
|
||||
for _, p := range response.dr.Packages {
|
||||
if pkgName != p.Name && p.ID != "command-line-arguments" {
|
||||
continue
|
||||
}
|
||||
for _, f := range p.GoFiles {
|
||||
if !sameFile(filepath.Dir(f), dir) {
|
||||
continue
|
||||
}
|
||||
// Make sure to capture information on the package's test variant, if needed.
|
||||
if isTestFile && !hasTestFiles(p) {
|
||||
// TODO(matloob): Are there packages other than the 'production' variant
|
||||
// of a package that this can match? This shouldn't match the test main package
|
||||
// because the file is generated in another directory.
|
||||
testVariantOf = p
|
||||
continue nextPackage
|
||||
} else if !isTestFile && hasTestFiles(p) {
|
||||
// We're examining a test variant, but the overlaid file is
|
||||
// a non-test file. Because the overlay implementation
|
||||
// (currently) only adds a file to one package, skip this
|
||||
// package, so that we can add the file to the production
|
||||
// variant of the package. (https://golang.org/issue/36857
|
||||
// tracks handling overlays on both the production and test
|
||||
// variant of a package).
|
||||
continue nextPackage
|
||||
}
|
||||
if pkg != nil && p != pkg && pkg.PkgPath == p.PkgPath {
|
||||
// We have already seen the production version of the
|
||||
// for which p is a test variant.
|
||||
if hasTestFiles(p) {
|
||||
testVariantOf = pkg
|
||||
}
|
||||
}
|
||||
pkg = p
|
||||
if filepath.Base(f) == base {
|
||||
fileExists = true
|
||||
}
|
||||
}
|
||||
}
|
||||
// The overlay could have included an entirely new package or an
|
||||
// ad-hoc package. An ad-hoc package is one that we have manually
|
||||
// constructed from inadequate `go list` results for a file= query.
|
||||
// It will have the ID command-line-arguments.
|
||||
if pkg == nil || pkg.ID == "command-line-arguments" {
|
||||
// Try to find the module or gopath dir the file is contained in.
|
||||
// Then for modules, add the module opath to the beginning.
|
||||
pkgPath, ok, err := state.getPkgPath(dir)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
var forTest string // only set for x tests
|
||||
isXTest := strings.HasSuffix(pkgName, "_test")
|
||||
if isXTest {
|
||||
forTest = pkgPath
|
||||
pkgPath += "_test"
|
||||
}
|
||||
id := pkgPath
|
||||
if isTestFile {
|
||||
if isXTest {
|
||||
id = fmt.Sprintf("%s [%s.test]", pkgPath, forTest)
|
||||
} else {
|
||||
id = fmt.Sprintf("%s [%s.test]", pkgPath, pkgPath)
|
||||
}
|
||||
}
|
||||
if pkg != nil {
|
||||
// TODO(rstambler): We should change the package's path and ID
|
||||
// here. The only issue is that this messes with the roots.
|
||||
} else {
|
||||
// Try to reclaim a package with the same ID, if it exists in the response.
|
||||
for _, p := range response.dr.Packages {
|
||||
if reclaimPackage(p, id, opath, contents) {
|
||||
pkg = p
|
||||
break
|
||||
}
|
||||
}
|
||||
// Otherwise, create a new package.
|
||||
if pkg == nil {
|
||||
pkg = &Package{
|
||||
PkgPath: pkgPath,
|
||||
ID: id,
|
||||
Name: pkgName,
|
||||
Imports: make(map[string]*Package),
|
||||
}
|
||||
response.addPackage(pkg)
|
||||
havePkgs[pkg.PkgPath] = id
|
||||
// Add the production package's sources for a test variant.
|
||||
if isTestFile && !isXTest && testVariantOf != nil {
|
||||
pkg.GoFiles = append(pkg.GoFiles, testVariantOf.GoFiles...)
|
||||
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, testVariantOf.CompiledGoFiles...)
|
||||
// Add the package under test and its imports to the test variant.
|
||||
pkg.forTest = testVariantOf.PkgPath
|
||||
for k, v := range testVariantOf.Imports {
|
||||
pkg.Imports[k] = &Package{ID: v.ID}
|
||||
}
|
||||
}
|
||||
if isXTest {
|
||||
pkg.forTest = forTest
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !fileExists {
|
||||
pkg.GoFiles = append(pkg.GoFiles, opath)
|
||||
// TODO(matloob): Adding the file to CompiledGoFiles can exhibit the wrong behavior
|
||||
// if the file will be ignored due to its build tags.
|
||||
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, opath)
|
||||
modifiedPkgsSet[pkg.ID] = true
|
||||
}
|
||||
imports, err := extractImports(opath, contents)
|
||||
if err != nil {
|
||||
// Let the parser or type checker report errors later.
|
||||
continue
|
||||
}
|
||||
for _, imp := range imports {
|
||||
// TODO(rstambler): If the package is an x test and the import has
|
||||
// a test variant, make sure to replace it.
|
||||
if _, found := pkg.Imports[imp]; found {
|
||||
continue
|
||||
}
|
||||
overlayAddsImports = true
|
||||
id, ok := havePkgs[imp]
|
||||
if !ok {
|
||||
var err error
|
||||
id, err = state.resolveImport(dir, imp)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
pkg.Imports[imp] = &Package{ID: id}
|
||||
// Add dependencies to the non-test variant version of this package as well.
|
||||
if testVariantOf != nil {
|
||||
testVariantOf.Imports[imp] = &Package{ID: id}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// toPkgPath guesses the package path given the id.
|
||||
toPkgPath := func(sourceDir, id string) (string, error) {
|
||||
if i := strings.IndexByte(id, ' '); i >= 0 {
|
||||
return state.resolveImport(sourceDir, id[:i])
|
||||
}
|
||||
return state.resolveImport(sourceDir, id)
|
||||
}
|
||||
|
||||
// Now that new packages have been created, do another pass to determine
|
||||
// the new set of missing packages.
|
||||
for _, pkg := range response.dr.Packages {
|
||||
for _, imp := range pkg.Imports {
|
||||
if len(pkg.GoFiles) == 0 {
|
||||
return nil, nil, fmt.Errorf("cannot resolve imports for package %q with no Go files", pkg.PkgPath)
|
||||
}
|
||||
pkgPath, err := toPkgPath(filepath.Dir(pkg.GoFiles[0]), imp.ID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if _, ok := havePkgs[pkgPath]; !ok {
|
||||
needPkgsSet[pkgPath] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if overlayAddsImports {
|
||||
needPkgs = make([]string, 0, len(needPkgsSet))
|
||||
for pkg := range needPkgsSet {
|
||||
needPkgs = append(needPkgs, pkg)
|
||||
}
|
||||
}
|
||||
modifiedPkgs = make([]string, 0, len(modifiedPkgsSet))
|
||||
for pkg := range modifiedPkgsSet {
|
||||
modifiedPkgs = append(modifiedPkgs, pkg)
|
||||
}
|
||||
return modifiedPkgs, needPkgs, err
|
||||
}
|
||||
|
||||
// resolveImport finds the ID of a package given its import path.
|
||||
// In particular, it will find the right vendored copy when in GOPATH mode.
|
||||
func (state *golistState) resolveImport(sourceDir, importPath string) (string, error) {
|
||||
env, err := state.getEnv()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if env["GOMOD"] != "" {
|
||||
return importPath, nil
|
||||
}
|
||||
|
||||
searchDir := sourceDir
|
||||
for {
|
||||
vendorDir := filepath.Join(searchDir, "vendor")
|
||||
exists, ok := state.vendorDirs[vendorDir]
|
||||
if !ok {
|
||||
info, err := os.Stat(vendorDir)
|
||||
exists = err == nil && info.IsDir()
|
||||
state.vendorDirs[vendorDir] = exists
|
||||
}
|
||||
|
||||
if exists {
|
||||
vendoredPath := filepath.Join(vendorDir, importPath)
|
||||
if info, err := os.Stat(vendoredPath); err == nil && info.IsDir() {
|
||||
// We should probably check for .go files here, but shame on anyone who fools us.
|
||||
path, ok, err := state.getPkgPath(vendoredPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if ok {
|
||||
return path, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We know we've hit the top of the filesystem when we Dir / and get /,
|
||||
// or C:\ and get C:\, etc.
|
||||
next := filepath.Dir(searchDir)
|
||||
if next == searchDir {
|
||||
break
|
||||
}
|
||||
searchDir = next
|
||||
}
|
||||
return importPath, nil
|
||||
}
|
||||
|
||||
func hasTestFiles(p *Package) bool {
|
||||
for _, f := range p.GoFiles {
|
||||
if strings.HasSuffix(f, "_test.go") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// determineRootDirs returns a mapping from absolute directories that could
|
||||
// contain code to their corresponding import path prefixes.
|
||||
func (state *golistState) determineRootDirs() (map[string]string, error) {
|
||||
@ -384,192 +81,3 @@ func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) {
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func extractImports(filename string, contents []byte) ([]string, error) {
|
||||
f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.ImportsOnly) // TODO(matloob): reuse fileset?
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []string
|
||||
for _, imp := range f.Imports {
|
||||
quotedPath := imp.Path.Value
|
||||
path, err := strconv.Unquote(quotedPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = append(res, path)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// reclaimPackage attempts to reuse a package that failed to load in an overlay.
|
||||
//
|
||||
// If the package has errors and has no Name, GoFiles, or Imports,
|
||||
// then it's possible that it doesn't yet exist on disk.
|
||||
func reclaimPackage(pkg *Package, id string, filename string, contents []byte) bool {
|
||||
// TODO(rstambler): Check the message of the actual error?
|
||||
// It differs between $GOPATH and module mode.
|
||||
if pkg.ID != id {
|
||||
return false
|
||||
}
|
||||
if len(pkg.Errors) != 1 {
|
||||
return false
|
||||
}
|
||||
if pkg.Name != "" || pkg.ExportFile != "" {
|
||||
return false
|
||||
}
|
||||
if len(pkg.GoFiles) > 0 || len(pkg.CompiledGoFiles) > 0 || len(pkg.OtherFiles) > 0 {
|
||||
return false
|
||||
}
|
||||
if len(pkg.Imports) > 0 {
|
||||
return false
|
||||
}
|
||||
pkgName, ok := extractPackageName(filename, contents)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
pkg.Name = pkgName
|
||||
pkg.Errors = nil
|
||||
return true
|
||||
}
|
||||
|
||||
func extractPackageName(filename string, contents []byte) (string, bool) {
|
||||
// TODO(rstambler): Check the message of the actual error?
|
||||
// It differs between $GOPATH and module mode.
|
||||
f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.PackageClauseOnly) // TODO(matloob): reuse fileset?
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
return f.Name.Name, true
|
||||
}
|
||||
|
||||
// commonDir returns the directory that all files are in, "" if files is empty,
|
||||
// or an error if they aren't in the same directory.
|
||||
func commonDir(files []string) (string, error) {
|
||||
seen := make(map[string]bool)
|
||||
for _, f := range files {
|
||||
seen[filepath.Dir(f)] = true
|
||||
}
|
||||
if len(seen) > 1 {
|
||||
return "", fmt.Errorf("files (%v) are in more than one directory: %v", files, seen)
|
||||
}
|
||||
for k := range seen {
|
||||
// seen has only one element; return it.
|
||||
return k, nil
|
||||
}
|
||||
return "", nil // no files
|
||||
}
|
||||
|
||||
// It is possible that the files in the disk directory dir have a different package
|
||||
// name from newName, which is deduced from the overlays. If they all have a different
|
||||
// package name, and they all have the same package name, then that name becomes
|
||||
// the package name.
|
||||
// It returns true if it changes the package name, false otherwise.
|
||||
func maybeFixPackageName(newName string, isTestFile bool, pkgsOfDir []*Package) {
|
||||
names := make(map[string]int)
|
||||
for _, p := range pkgsOfDir {
|
||||
names[p.Name]++
|
||||
}
|
||||
if len(names) != 1 {
|
||||
// some files are in different packages
|
||||
return
|
||||
}
|
||||
var oldName string
|
||||
for k := range names {
|
||||
oldName = k
|
||||
}
|
||||
if newName == oldName {
|
||||
return
|
||||
}
|
||||
// We might have a case where all of the package names in the directory are
|
||||
// the same, but the overlay file is for an x test, which belongs to its
|
||||
// own package. If the x test does not yet exist on disk, we may not yet
|
||||
// have its package name on disk, but we should not rename the packages.
|
||||
//
|
||||
// We use a heuristic to determine if this file belongs to an x test:
|
||||
// The test file should have a package name whose package name has a _test
|
||||
// suffix or looks like "newName_test".
|
||||
maybeXTest := strings.HasPrefix(oldName+"_test", newName) || strings.HasSuffix(newName, "_test")
|
||||
if isTestFile && maybeXTest {
|
||||
return
|
||||
}
|
||||
for _, p := range pkgsOfDir {
|
||||
p.Name = newName
|
||||
}
|
||||
}
|
||||
|
||||
// This function is copy-pasted from
|
||||
// https://github.com/golang/go/blob/9706f510a5e2754595d716bd64be8375997311fb/src/cmd/go/internal/search/search.go#L360.
|
||||
// It should be deleted when we remove support for overlays from go/packages.
|
||||
//
|
||||
// NOTE: This does not handle any ./... or ./ style queries, as this function
|
||||
// doesn't know the working directory.
|
||||
//
|
||||
// matchPattern(pattern)(name) reports whether
|
||||
// name matches pattern. Pattern is a limited glob
|
||||
// pattern in which '...' means 'any string' and there
|
||||
// is no other special syntax.
|
||||
// Unfortunately, there are two special cases. Quoting "go help packages":
|
||||
//
|
||||
// First, /... at the end of the pattern can match an empty string,
|
||||
// so that net/... matches both net and packages in its subdirectories, like net/http.
|
||||
// Second, any slash-separated pattern element containing a wildcard never
|
||||
// participates in a match of the "vendor" element in the path of a vendored
|
||||
// package, so that ./... does not match packages in subdirectories of
|
||||
// ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do.
|
||||
// Note, however, that a directory named vendor that itself contains code
|
||||
// is not a vendored package: cmd/vendor would be a command named vendor,
|
||||
// and the pattern cmd/... matches it.
|
||||
func matchPattern(pattern string) func(name string) bool {
|
||||
// Convert pattern to regular expression.
|
||||
// The strategy for the trailing /... is to nest it in an explicit ? expression.
|
||||
// The strategy for the vendor exclusion is to change the unmatchable
|
||||
// vendor strings to a disallowed code point (vendorChar) and to use
|
||||
// "(anything but that codepoint)*" as the implementation of the ... wildcard.
|
||||
// This is a bit complicated but the obvious alternative,
|
||||
// namely a hand-written search like in most shell glob matchers,
|
||||
// is too easy to make accidentally exponential.
|
||||
// Using package regexp guarantees linear-time matching.
|
||||
|
||||
const vendorChar = "\x00"
|
||||
|
||||
if strings.Contains(pattern, vendorChar) {
|
||||
return func(name string) bool { return false }
|
||||
}
|
||||
|
||||
re := regexp.QuoteMeta(pattern)
|
||||
re = replaceVendor(re, vendorChar)
|
||||
switch {
|
||||
case strings.HasSuffix(re, `/`+vendorChar+`/\.\.\.`):
|
||||
re = strings.TrimSuffix(re, `/`+vendorChar+`/\.\.\.`) + `(/vendor|/` + vendorChar + `/\.\.\.)`
|
||||
case re == vendorChar+`/\.\.\.`:
|
||||
re = `(/vendor|/` + vendorChar + `/\.\.\.)`
|
||||
case strings.HasSuffix(re, `/\.\.\.`):
|
||||
re = strings.TrimSuffix(re, `/\.\.\.`) + `(/\.\.\.)?`
|
||||
}
|
||||
re = strings.ReplaceAll(re, `\.\.\.`, `[^`+vendorChar+`]*`)
|
||||
|
||||
reg := regexp.MustCompile(`^` + re + `$`)
|
||||
|
||||
return func(name string) bool {
|
||||
if strings.Contains(name, vendorChar) {
|
||||
return false
|
||||
}
|
||||
return reg.MatchString(replaceVendor(name, vendorChar))
|
||||
}
|
||||
}
|
||||
|
||||
// replaceVendor returns the result of replacing
|
||||
// non-trailing vendor path elements in x with repl.
|
||||
func replaceVendor(x, repl string) string {
|
||||
if !strings.Contains(x, "vendor") {
|
||||
return x
|
||||
}
|
||||
elem := strings.Split(x, "/")
|
||||
for i := 0; i < len(elem)-1; i++ {
|
||||
if elem[i] == "vendor" {
|
||||
elem[i] = repl
|
||||
}
|
||||
}
|
||||
return strings.Join(elem, "/")
|
||||
}
|
||||
|
176
vendor/golang.org/x/tools/go/packages/packages.go
generated
vendored
176
vendor/golang.org/x/tools/go/packages/packages.go
generated
vendored
@ -27,8 +27,8 @@ import (
|
||||
"golang.org/x/tools/go/gcexportdata"
|
||||
"golang.org/x/tools/internal/gocommand"
|
||||
"golang.org/x/tools/internal/packagesinternal"
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
"golang.org/x/tools/internal/typesinternal"
|
||||
"golang.org/x/tools/internal/versions"
|
||||
)
|
||||
|
||||
// A LoadMode controls the amount of detail to return when loading.
|
||||
@ -258,31 +258,52 @@ type driverResponse struct {
|
||||
// proceeding with further analysis. The PrintErrors function is
|
||||
// provided for convenient display of all errors.
|
||||
func Load(cfg *Config, patterns ...string) ([]*Package, error) {
|
||||
l := newLoader(cfg)
|
||||
response, err := defaultDriver(&l.Config, patterns...)
|
||||
ld := newLoader(cfg)
|
||||
response, external, err := defaultDriver(&ld.Config, patterns...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l.sizes = types.SizesFor(response.Compiler, response.Arch)
|
||||
return l.refine(response)
|
||||
|
||||
ld.sizes = types.SizesFor(response.Compiler, response.Arch)
|
||||
if ld.sizes == nil && ld.Config.Mode&(NeedTypes|NeedTypesSizes|NeedTypesInfo) != 0 {
|
||||
// Type size information is needed but unavailable.
|
||||
if external {
|
||||
// An external driver may fail to populate the Compiler/GOARCH fields,
|
||||
// especially since they are relatively new (see #63700).
|
||||
// Provide a sensible fallback in this case.
|
||||
ld.sizes = types.SizesFor("gc", runtime.GOARCH)
|
||||
if ld.sizes == nil { // gccgo-only arch
|
||||
ld.sizes = types.SizesFor("gc", "amd64")
|
||||
}
|
||||
} else {
|
||||
// Go list should never fail to deliver accurate size information.
|
||||
// Reject the whole Load since the error is the same for every package.
|
||||
return nil, fmt.Errorf("can't determine type sizes for compiler %q on GOARCH %q",
|
||||
response.Compiler, response.Arch)
|
||||
}
|
||||
}
|
||||
|
||||
return ld.refine(response)
|
||||
}
|
||||
|
||||
// defaultDriver is a driver that implements go/packages' fallback behavior.
|
||||
// It will try to request to an external driver, if one exists. If there's
|
||||
// no external driver, or the driver returns a response with NotHandled set,
|
||||
// defaultDriver will fall back to the go list driver.
|
||||
func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
|
||||
driver := findExternalDriver(cfg)
|
||||
if driver == nil {
|
||||
driver = goListDriver
|
||||
// The boolean result indicates that an external driver handled the request.
|
||||
func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, bool, error) {
|
||||
if driver := findExternalDriver(cfg); driver != nil {
|
||||
response, err := driver(cfg, patterns...)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
} else if !response.NotHandled {
|
||||
return response, true, nil
|
||||
}
|
||||
// (fall through)
|
||||
}
|
||||
response, err := driver(cfg, patterns...)
|
||||
if err != nil {
|
||||
return response, err
|
||||
} else if response.NotHandled {
|
||||
return goListDriver(cfg, patterns...)
|
||||
}
|
||||
return response, nil
|
||||
|
||||
response, err := goListDriver(cfg, patterns...)
|
||||
return response, false, err
|
||||
}
|
||||
|
||||
// A Package describes a loaded Go package.
|
||||
@ -411,12 +432,6 @@ func init() {
|
||||
packagesinternal.GetDepsErrors = func(p interface{}) []*packagesinternal.PackageError {
|
||||
return p.(*Package).depsErrors
|
||||
}
|
||||
packagesinternal.GetGoCmdRunner = func(config interface{}) *gocommand.Runner {
|
||||
return config.(*Config).gocmdRunner
|
||||
}
|
||||
packagesinternal.SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {
|
||||
config.(*Config).gocmdRunner = runner
|
||||
}
|
||||
packagesinternal.SetModFile = func(config interface{}, value string) {
|
||||
config.(*Config).modFile = value
|
||||
}
|
||||
@ -553,7 +568,7 @@ type loaderPackage struct {
|
||||
type loader struct {
|
||||
pkgs map[string]*loaderPackage
|
||||
Config
|
||||
sizes types.Sizes
|
||||
sizes types.Sizes // non-nil if needed by mode
|
||||
parseCache map[string]*parseValue
|
||||
parseCacheMu sync.Mutex
|
||||
exportMu sync.Mutex // enforces mutual exclusion of exportdata operations
|
||||
@ -678,39 +693,38 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Materialize the import graph.
|
||||
if ld.Mode&NeedImports != 0 {
|
||||
// Materialize the import graph.
|
||||
|
||||
const (
|
||||
white = 0 // new
|
||||
grey = 1 // in progress
|
||||
black = 2 // complete
|
||||
)
|
||||
const (
|
||||
white = 0 // new
|
||||
grey = 1 // in progress
|
||||
black = 2 // complete
|
||||
)
|
||||
|
||||
// visit traverses the import graph, depth-first,
|
||||
// and materializes the graph as Packages.Imports.
|
||||
//
|
||||
// Valid imports are saved in the Packages.Import map.
|
||||
// Invalid imports (cycles and missing nodes) are saved in the importErrors map.
|
||||
// Thus, even in the presence of both kinds of errors, the Import graph remains a DAG.
|
||||
//
|
||||
// visit returns whether the package needs src or has a transitive
|
||||
// dependency on a package that does. These are the only packages
|
||||
// for which we load source code.
|
||||
var stack []*loaderPackage
|
||||
var visit func(lpkg *loaderPackage) bool
|
||||
var srcPkgs []*loaderPackage
|
||||
visit = func(lpkg *loaderPackage) bool {
|
||||
switch lpkg.color {
|
||||
case black:
|
||||
return lpkg.needsrc
|
||||
case grey:
|
||||
panic("internal error: grey node")
|
||||
}
|
||||
lpkg.color = grey
|
||||
stack = append(stack, lpkg) // push
|
||||
stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports
|
||||
// If NeedImports isn't set, the imports fields will all be zeroed out.
|
||||
if ld.Mode&NeedImports != 0 {
|
||||
// visit traverses the import graph, depth-first,
|
||||
// and materializes the graph as Packages.Imports.
|
||||
//
|
||||
// Valid imports are saved in the Packages.Import map.
|
||||
// Invalid imports (cycles and missing nodes) are saved in the importErrors map.
|
||||
// Thus, even in the presence of both kinds of errors,
|
||||
// the Import graph remains a DAG.
|
||||
//
|
||||
// visit returns whether the package needs src or has a transitive
|
||||
// dependency on a package that does. These are the only packages
|
||||
// for which we load source code.
|
||||
var stack []*loaderPackage
|
||||
var visit func(lpkg *loaderPackage) bool
|
||||
visit = func(lpkg *loaderPackage) bool {
|
||||
switch lpkg.color {
|
||||
case black:
|
||||
return lpkg.needsrc
|
||||
case grey:
|
||||
panic("internal error: grey node")
|
||||
}
|
||||
lpkg.color = grey
|
||||
stack = append(stack, lpkg) // push
|
||||
stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports
|
||||
lpkg.Imports = make(map[string]*Package, len(stubs))
|
||||
for importPath, ipkg := range stubs {
|
||||
var importErr error
|
||||
@ -734,40 +748,39 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) {
|
||||
}
|
||||
lpkg.Imports[importPath] = imp.Package
|
||||
}
|
||||
}
|
||||
if lpkg.needsrc {
|
||||
srcPkgs = append(srcPkgs, lpkg)
|
||||
}
|
||||
if ld.Mode&NeedTypesSizes != 0 {
|
||||
lpkg.TypesSizes = ld.sizes
|
||||
}
|
||||
stack = stack[:len(stack)-1] // pop
|
||||
lpkg.color = black
|
||||
|
||||
return lpkg.needsrc
|
||||
}
|
||||
// Complete type information is required for the
|
||||
// immediate dependencies of each source package.
|
||||
if lpkg.needsrc && ld.Mode&NeedTypes != 0 {
|
||||
for _, ipkg := range lpkg.Imports {
|
||||
ld.pkgs[ipkg.ID].needtypes = true
|
||||
}
|
||||
}
|
||||
|
||||
if ld.Mode&NeedImports == 0 {
|
||||
// We do this to drop the stub import packages that we are not even going to try to resolve.
|
||||
for _, lpkg := range initial {
|
||||
lpkg.Imports = nil
|
||||
// NeedTypeSizes causes TypeSizes to be set even
|
||||
// on packages for which types aren't needed.
|
||||
if ld.Mode&NeedTypesSizes != 0 {
|
||||
lpkg.TypesSizes = ld.sizes
|
||||
}
|
||||
stack = stack[:len(stack)-1] // pop
|
||||
lpkg.color = black
|
||||
|
||||
return lpkg.needsrc
|
||||
}
|
||||
} else {
|
||||
|
||||
// For each initial package, create its import DAG.
|
||||
for _, lpkg := range initial {
|
||||
visit(lpkg)
|
||||
}
|
||||
}
|
||||
if ld.Mode&NeedImports != 0 && ld.Mode&NeedTypes != 0 {
|
||||
for _, lpkg := range srcPkgs {
|
||||
// Complete type information is required for the
|
||||
// immediate dependencies of each source package.
|
||||
for _, ipkg := range lpkg.Imports {
|
||||
imp := ld.pkgs[ipkg.ID]
|
||||
imp.needtypes = true
|
||||
}
|
||||
|
||||
} else {
|
||||
// !NeedImports: drop the stub (ID-only) import packages
|
||||
// that we are not even going to try to resolve.
|
||||
for _, lpkg := range initial {
|
||||
lpkg.Imports = nil
|
||||
}
|
||||
}
|
||||
|
||||
// Load type data and syntax if needed, starting at
|
||||
// the initial packages (roots of the import DAG).
|
||||
if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 {
|
||||
@ -1001,10 +1014,11 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
||||
Defs: make(map[*ast.Ident]types.Object),
|
||||
Uses: make(map[*ast.Ident]types.Object),
|
||||
Implicits: make(map[ast.Node]types.Object),
|
||||
Instances: make(map[*ast.Ident]types.Instance),
|
||||
Scopes: make(map[ast.Node]*types.Scope),
|
||||
Selections: make(map[*ast.SelectorExpr]*types.Selection),
|
||||
}
|
||||
typeparams.InitInstanceInfo(lpkg.TypesInfo)
|
||||
versions.InitFileVersions(lpkg.TypesInfo)
|
||||
lpkg.TypesSizes = ld.sizes
|
||||
|
||||
importer := importerFunc(func(path string) (*types.Package, error) {
|
||||
@ -1042,7 +1056,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
||||
IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial,
|
||||
|
||||
Error: appendError,
|
||||
Sizes: ld.sizes,
|
||||
Sizes: ld.sizes, // may be nil
|
||||
}
|
||||
if lpkg.Module != nil && lpkg.Module.GoVersion != "" {
|
||||
typesinternal.SetGoVersion(tc, "go"+lpkg.Module.GoVersion)
|
||||
|
131
vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
generated
vendored
131
vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
generated
vendored
@ -26,13 +26,10 @@ package objectpath
|
||||
import (
|
||||
"fmt"
|
||||
"go/types"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
_ "unsafe"
|
||||
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
"golang.org/x/tools/internal/typesinternal"
|
||||
)
|
||||
|
||||
// A Path is an opaque name that identifies a types.Object
|
||||
@ -123,20 +120,7 @@ func For(obj types.Object) (Path, error) {
|
||||
// An Encoder amortizes the cost of encoding the paths of multiple objects.
|
||||
// The zero value of an Encoder is ready to use.
|
||||
type Encoder struct {
|
||||
scopeMemo map[*types.Scope][]types.Object // memoization of scopeObjects
|
||||
namedMethodsMemo map[*types.Named][]*types.Func // memoization of namedMethods()
|
||||
skipMethodSorting bool
|
||||
}
|
||||
|
||||
// Expose back doors so that gopls can avoid method sorting, which can dominate
|
||||
// analysis on certain repositories.
|
||||
//
|
||||
// TODO(golang/go#61443): remove this.
|
||||
func init() {
|
||||
typesinternal.SkipEncoderMethodSorting = func(enc interface{}) {
|
||||
enc.(*Encoder).skipMethodSorting = true
|
||||
}
|
||||
typesinternal.ObjectpathObject = object
|
||||
scopeMemo map[*types.Scope][]types.Object // memoization of scopeObjects
|
||||
}
|
||||
|
||||
// For returns the path to an object relative to its package,
|
||||
@ -239,7 +223,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
|
||||
// Reject obviously non-viable cases.
|
||||
switch obj := obj.(type) {
|
||||
case *types.TypeName:
|
||||
if _, ok := obj.Type().(*typeparams.TypeParam); !ok {
|
||||
if _, ok := obj.Type().(*types.TypeParam); !ok {
|
||||
// With the exception of type parameters, only package-level type names
|
||||
// have a path.
|
||||
return "", fmt.Errorf("no path for %v", obj)
|
||||
@ -299,7 +283,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
|
||||
}
|
||||
} else {
|
||||
if named, _ := T.(*types.Named); named != nil {
|
||||
if r := findTypeParam(obj, typeparams.ForNamed(named), path, nil); r != nil {
|
||||
if r := findTypeParam(obj, named.TypeParams(), path, nil); r != nil {
|
||||
// generic named type
|
||||
return Path(r), nil
|
||||
}
|
||||
@ -328,31 +312,18 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
|
||||
// Inspect declared methods of defined types.
|
||||
if T, ok := o.Type().(*types.Named); ok {
|
||||
path = append(path, opType)
|
||||
if !enc.skipMethodSorting {
|
||||
// Note that method index here is always with respect
|
||||
// to canonical ordering of methods, regardless of how
|
||||
// they appear in the underlying type.
|
||||
for i, m := range enc.namedMethods(T) {
|
||||
path2 := appendOpArg(path, opMethod, i)
|
||||
if m == obj {
|
||||
return Path(path2), nil // found declared method
|
||||
}
|
||||
if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
|
||||
return Path(r), nil
|
||||
}
|
||||
// The method index here is always with respect
|
||||
// to the underlying go/types data structures,
|
||||
// which ultimately derives from source order
|
||||
// and must be preserved by export data.
|
||||
for i := 0; i < T.NumMethods(); i++ {
|
||||
m := T.Method(i)
|
||||
path2 := appendOpArg(path, opMethod, i)
|
||||
if m == obj {
|
||||
return Path(path2), nil // found declared method
|
||||
}
|
||||
} else {
|
||||
// This branch must match the logic in the branch above, using go/types
|
||||
// APIs without sorting.
|
||||
for i := 0; i < T.NumMethods(); i++ {
|
||||
m := T.Method(i)
|
||||
path2 := appendOpArg(path, opMethod, i)
|
||||
if m == obj {
|
||||
return Path(path2), nil // found declared method
|
||||
}
|
||||
if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
|
||||
return Path(r), nil
|
||||
}
|
||||
if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
|
||||
return Path(r), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -448,22 +419,13 @@ func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) {
|
||||
path = append(path, name...)
|
||||
path = append(path, opType)
|
||||
|
||||
if !enc.skipMethodSorting {
|
||||
for i, m := range enc.namedMethods(named) {
|
||||
if m == meth {
|
||||
path = appendOpArg(path, opMethod, i)
|
||||
return Path(path), true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// This branch must match the logic of the branch above, using go/types
|
||||
// APIs without sorting.
|
||||
for i := 0; i < named.NumMethods(); i++ {
|
||||
m := named.Method(i)
|
||||
if m == meth {
|
||||
path = appendOpArg(path, opMethod, i)
|
||||
return Path(path), true
|
||||
}
|
||||
// Method indices are w.r.t. the go/types data structures,
|
||||
// ultimately deriving from source order,
|
||||
// which is preserved by export data.
|
||||
for i := 0; i < named.NumMethods(); i++ {
|
||||
if named.Method(i) == meth {
|
||||
path = appendOpArg(path, opMethod, i)
|
||||
return Path(path), true
|
||||
}
|
||||
}
|
||||
|
||||
@ -500,7 +462,7 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]
|
||||
}
|
||||
return find(obj, T.Elem(), append(path, opElem), seen)
|
||||
case *types.Signature:
|
||||
if r := findTypeParam(obj, typeparams.ForSignature(T), path, seen); r != nil {
|
||||
if r := findTypeParam(obj, T.TypeParams(), path, seen); r != nil {
|
||||
return r
|
||||
}
|
||||
if r := find(obj, T.Params(), append(path, opParams), seen); r != nil {
|
||||
@ -543,7 +505,7 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case *typeparams.TypeParam:
|
||||
case *types.TypeParam:
|
||||
name := T.Obj()
|
||||
if name == obj {
|
||||
return append(path, opObj)
|
||||
@ -563,7 +525,7 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]
|
||||
panic(T)
|
||||
}
|
||||
|
||||
func findTypeParam(obj types.Object, list *typeparams.TypeParamList, path []byte, seen map[*types.TypeName]bool) []byte {
|
||||
func findTypeParam(obj types.Object, list *types.TypeParamList, path []byte, seen map[*types.TypeName]bool) []byte {
|
||||
for i := 0; i < list.Len(); i++ {
|
||||
tparam := list.At(i)
|
||||
path2 := appendOpArg(path, opTypeParam, i)
|
||||
@ -576,12 +538,7 @@ func findTypeParam(obj types.Object, list *typeparams.TypeParamList, path []byte
|
||||
|
||||
// Object returns the object denoted by path p within the package pkg.
|
||||
func Object(pkg *types.Package, p Path) (types.Object, error) {
|
||||
return object(pkg, string(p), false)
|
||||
}
|
||||
|
||||
// Note: the skipMethodSorting parameter must match the value of
|
||||
// Encoder.skipMethodSorting used during encoding.
|
||||
func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.Object, error) {
|
||||
pathstr := string(p)
|
||||
if pathstr == "" {
|
||||
return nil, fmt.Errorf("empty path")
|
||||
}
|
||||
@ -605,7 +562,7 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O
|
||||
}
|
||||
// abstraction of *types.{Named,Signature}
|
||||
type hasTypeParams interface {
|
||||
TypeParams() *typeparams.TypeParamList
|
||||
TypeParams() *types.TypeParamList
|
||||
}
|
||||
// abstraction of *types.{Named,TypeParam}
|
||||
type hasObj interface {
|
||||
@ -707,7 +664,7 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O
|
||||
t = tparams.At(index)
|
||||
|
||||
case opConstraint:
|
||||
tparam, ok := t.(*typeparams.TypeParam)
|
||||
tparam, ok := t.(*types.TypeParam)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want type parameter)", code, t, t)
|
||||
}
|
||||
@ -747,12 +704,7 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O
|
||||
if index >= t.NumMethods() {
|
||||
return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods())
|
||||
}
|
||||
if skipMethodSorting {
|
||||
obj = t.Method(index)
|
||||
} else {
|
||||
methods := namedMethods(t) // (unmemoized)
|
||||
obj = methods[index] // Id-ordered
|
||||
}
|
||||
obj = t.Method(index)
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want interface or named)", code, t, t)
|
||||
@ -779,33 +731,6 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O
|
||||
return obj, nil // success
|
||||
}
|
||||
|
||||
// namedMethods returns the methods of a Named type in ascending Id order.
|
||||
func namedMethods(named *types.Named) []*types.Func {
|
||||
methods := make([]*types.Func, named.NumMethods())
|
||||
for i := range methods {
|
||||
methods[i] = named.Method(i)
|
||||
}
|
||||
sort.Slice(methods, func(i, j int) bool {
|
||||
return methods[i].Id() < methods[j].Id()
|
||||
})
|
||||
return methods
|
||||
}
|
||||
|
||||
// namedMethods is a memoization of the namedMethods function. Callers must not modify the result.
|
||||
func (enc *Encoder) namedMethods(named *types.Named) []*types.Func {
|
||||
m := enc.namedMethodsMemo
|
||||
if m == nil {
|
||||
m = make(map[*types.Named][]*types.Func)
|
||||
enc.namedMethodsMemo = m
|
||||
}
|
||||
methods, ok := m[named]
|
||||
if !ok {
|
||||
methods = namedMethods(named) // allocates and sorts
|
||||
m[named] = methods
|
||||
}
|
||||
return methods
|
||||
}
|
||||
|
||||
// scopeObjects is a memoization of scope objects.
|
||||
// Callers must not modify the result.
|
||||
func (enc *Encoder) scopeObjects(scope *types.Scope) []types.Object {
|
||||
|
21
vendor/golang.org/x/tools/internal/event/keys/util.go
generated
vendored
Normal file
21
vendor/golang.org/x/tools/internal/event/keys/util.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
// 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.
|
||||
|
||||
package keys
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Join returns a canonical join of the keys in S:
|
||||
// a sorted comma-separated string list.
|
||||
func Join[S ~[]T, T ~string](s S) string {
|
||||
strs := make([]string, 0, len(s))
|
||||
for _, v := range s {
|
||||
strs = append(strs, string(v))
|
||||
}
|
||||
sort.Strings(strs)
|
||||
return strings.Join(strs, ",")
|
||||
}
|
31
vendor/golang.org/x/tools/internal/gcimporter/iexport.go
generated
vendored
31
vendor/golang.org/x/tools/internal/gcimporter/iexport.go
generated
vendored
@ -24,7 +24,6 @@ import (
|
||||
|
||||
"golang.org/x/tools/go/types/objectpath"
|
||||
"golang.org/x/tools/internal/tokeninternal"
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
)
|
||||
|
||||
// IExportShallow encodes "shallow" export data for the specified package.
|
||||
@ -481,7 +480,7 @@ func (p *iexporter) doDecl(obj types.Object) {
|
||||
}
|
||||
|
||||
// Function.
|
||||
if typeparams.ForSignature(sig).Len() == 0 {
|
||||
if sig.TypeParams().Len() == 0 {
|
||||
w.tag('F')
|
||||
} else {
|
||||
w.tag('G')
|
||||
@ -494,7 +493,7 @@ func (p *iexporter) doDecl(obj types.Object) {
|
||||
//
|
||||
// While importing the type parameters, tparamList computes and records
|
||||
// their export name, so that it can be later used when writing the index.
|
||||
if tparams := typeparams.ForSignature(sig); tparams.Len() > 0 {
|
||||
if tparams := sig.TypeParams(); tparams.Len() > 0 {
|
||||
w.tparamList(obj.Name(), tparams, obj.Pkg())
|
||||
}
|
||||
w.signature(sig)
|
||||
@ -507,14 +506,14 @@ func (p *iexporter) doDecl(obj types.Object) {
|
||||
case *types.TypeName:
|
||||
t := obj.Type()
|
||||
|
||||
if tparam, ok := t.(*typeparams.TypeParam); ok {
|
||||
if tparam, ok := t.(*types.TypeParam); ok {
|
||||
w.tag('P')
|
||||
w.pos(obj.Pos())
|
||||
constraint := tparam.Constraint()
|
||||
if p.version >= iexportVersionGo1_18 {
|
||||
implicit := false
|
||||
if iface, _ := constraint.(*types.Interface); iface != nil {
|
||||
implicit = typeparams.IsImplicit(iface)
|
||||
implicit = iface.IsImplicit()
|
||||
}
|
||||
w.bool(implicit)
|
||||
}
|
||||
@ -535,17 +534,17 @@ func (p *iexporter) doDecl(obj types.Object) {
|
||||
panic(internalErrorf("%s is not a defined type", t))
|
||||
}
|
||||
|
||||
if typeparams.ForNamed(named).Len() == 0 {
|
||||
if named.TypeParams().Len() == 0 {
|
||||
w.tag('T')
|
||||
} else {
|
||||
w.tag('U')
|
||||
}
|
||||
w.pos(obj.Pos())
|
||||
|
||||
if typeparams.ForNamed(named).Len() > 0 {
|
||||
if named.TypeParams().Len() > 0 {
|
||||
// While importing the type parameters, tparamList computes and records
|
||||
// their export name, so that it can be later used when writing the index.
|
||||
w.tparamList(obj.Name(), typeparams.ForNamed(named), obj.Pkg())
|
||||
w.tparamList(obj.Name(), named.TypeParams(), obj.Pkg())
|
||||
}
|
||||
|
||||
underlying := obj.Type().Underlying()
|
||||
@ -565,7 +564,7 @@ func (p *iexporter) doDecl(obj types.Object) {
|
||||
|
||||
// Receiver type parameters are type arguments of the receiver type, so
|
||||
// their name must be qualified before exporting recv.
|
||||
if rparams := typeparams.RecvTypeParams(sig); rparams.Len() > 0 {
|
||||
if rparams := sig.RecvTypeParams(); rparams.Len() > 0 {
|
||||
prefix := obj.Name() + "." + m.Name()
|
||||
for i := 0; i < rparams.Len(); i++ {
|
||||
rparam := rparams.At(i)
|
||||
@ -740,19 +739,19 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
|
||||
}
|
||||
switch t := t.(type) {
|
||||
case *types.Named:
|
||||
if targs := typeparams.NamedTypeArgs(t); targs.Len() > 0 {
|
||||
if targs := t.TypeArgs(); targs.Len() > 0 {
|
||||
w.startType(instanceType)
|
||||
// TODO(rfindley): investigate if this position is correct, and if it
|
||||
// matters.
|
||||
w.pos(t.Obj().Pos())
|
||||
w.typeList(targs, pkg)
|
||||
w.typ(typeparams.NamedTypeOrigin(t), pkg)
|
||||
w.typ(t.Origin(), pkg)
|
||||
return
|
||||
}
|
||||
w.startType(definedType)
|
||||
w.qualifiedType(t.Obj())
|
||||
|
||||
case *typeparams.TypeParam:
|
||||
case *types.TypeParam:
|
||||
w.startType(typeParamType)
|
||||
w.qualifiedType(t.Obj())
|
||||
|
||||
@ -868,7 +867,7 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
|
||||
w.signature(sig)
|
||||
}
|
||||
|
||||
case *typeparams.Union:
|
||||
case *types.Union:
|
||||
w.startType(unionType)
|
||||
nt := t.Len()
|
||||
w.uint64(uint64(nt))
|
||||
@ -948,14 +947,14 @@ func (w *exportWriter) signature(sig *types.Signature) {
|
||||
}
|
||||
}
|
||||
|
||||
func (w *exportWriter) typeList(ts *typeparams.TypeList, pkg *types.Package) {
|
||||
func (w *exportWriter) typeList(ts *types.TypeList, pkg *types.Package) {
|
||||
w.uint64(uint64(ts.Len()))
|
||||
for i := 0; i < ts.Len(); i++ {
|
||||
w.typ(ts.At(i), pkg)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *exportWriter) tparamList(prefix string, list *typeparams.TypeParamList, pkg *types.Package) {
|
||||
func (w *exportWriter) tparamList(prefix string, list *types.TypeParamList, pkg *types.Package) {
|
||||
ll := uint64(list.Len())
|
||||
w.uint64(ll)
|
||||
for i := 0; i < list.Len(); i++ {
|
||||
@ -973,7 +972,7 @@ const blankMarker = "$"
|
||||
// differs from its actual object name: it is prefixed with a qualifier, and
|
||||
// blank type parameter names are disambiguated by their index in the type
|
||||
// parameter list.
|
||||
func tparamExportName(prefix string, tparam *typeparams.TypeParam) string {
|
||||
func tparamExportName(prefix string, tparam *types.TypeParam) string {
|
||||
assert(prefix != "")
|
||||
name := tparam.Obj().Name()
|
||||
if name == "_" {
|
||||
|
39
vendor/golang.org/x/tools/internal/gcimporter/iimport.go
generated
vendored
39
vendor/golang.org/x/tools/internal/gcimporter/iimport.go
generated
vendored
@ -22,7 +22,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/go/types/objectpath"
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
)
|
||||
|
||||
type intReader struct {
|
||||
@ -321,7 +320,7 @@ func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte
|
||||
// Therefore, we defer calling SetConstraint there, and call it here instead
|
||||
// after all types are complete.
|
||||
for _, d := range p.later {
|
||||
typeparams.SetTypeParamConstraint(d.t, d.constraint)
|
||||
d.t.SetConstraint(d.constraint)
|
||||
}
|
||||
|
||||
for _, typ := range p.interfaceList {
|
||||
@ -339,7 +338,7 @@ func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte
|
||||
}
|
||||
|
||||
type setConstraintArgs struct {
|
||||
t *typeparams.TypeParam
|
||||
t *types.TypeParam
|
||||
constraint types.Type
|
||||
}
|
||||
|
||||
@ -549,7 +548,7 @@ func (r *importReader) obj(name string) {
|
||||
r.declare(types.NewConst(pos, r.currPkg, name, typ, val))
|
||||
|
||||
case 'F', 'G':
|
||||
var tparams []*typeparams.TypeParam
|
||||
var tparams []*types.TypeParam
|
||||
if tag == 'G' {
|
||||
tparams = r.tparamList()
|
||||
}
|
||||
@ -566,7 +565,7 @@ func (r *importReader) obj(name string) {
|
||||
r.declare(obj)
|
||||
if tag == 'U' {
|
||||
tparams := r.tparamList()
|
||||
typeparams.SetForNamed(named, tparams)
|
||||
named.SetTypeParams(tparams)
|
||||
}
|
||||
|
||||
underlying := r.p.typAt(r.uint64(), named).Underlying()
|
||||
@ -583,12 +582,12 @@ func (r *importReader) obj(name string) {
|
||||
// typeparams being used in the method sig/body).
|
||||
base := baseType(recv.Type())
|
||||
assert(base != nil)
|
||||
targs := typeparams.NamedTypeArgs(base)
|
||||
var rparams []*typeparams.TypeParam
|
||||
targs := base.TypeArgs()
|
||||
var rparams []*types.TypeParam
|
||||
if targs.Len() > 0 {
|
||||
rparams = make([]*typeparams.TypeParam, targs.Len())
|
||||
rparams = make([]*types.TypeParam, targs.Len())
|
||||
for i := range rparams {
|
||||
rparams[i] = targs.At(i).(*typeparams.TypeParam)
|
||||
rparams[i] = targs.At(i).(*types.TypeParam)
|
||||
}
|
||||
}
|
||||
msig := r.signature(recv, rparams, nil)
|
||||
@ -606,7 +605,7 @@ func (r *importReader) obj(name string) {
|
||||
}
|
||||
name0 := tparamName(name)
|
||||
tn := types.NewTypeName(pos, r.currPkg, name0, nil)
|
||||
t := typeparams.NewTypeParam(tn, nil)
|
||||
t := types.NewTypeParam(tn, nil)
|
||||
|
||||
// To handle recursive references to the typeparam within its
|
||||
// bound, save the partial type in tparamIndex before reading the bounds.
|
||||
@ -622,7 +621,7 @@ func (r *importReader) obj(name string) {
|
||||
if iface == nil {
|
||||
errorf("non-interface constraint marked implicit")
|
||||
}
|
||||
typeparams.MarkImplicit(iface)
|
||||
iface.MarkImplicit()
|
||||
}
|
||||
// The constraint type may not be complete, if we
|
||||
// are in the middle of a type recursion involving type
|
||||
@ -966,7 +965,7 @@ func (r *importReader) doType(base *types.Named) (res types.Type) {
|
||||
// The imported instantiated type doesn't include any methods, so
|
||||
// we must always use the methods of the base (orig) type.
|
||||
// TODO provide a non-nil *Environment
|
||||
t, _ := typeparams.Instantiate(nil, baseType, targs, false)
|
||||
t, _ := types.Instantiate(nil, baseType, targs, false)
|
||||
|
||||
// Workaround for golang/go#61561. See the doc for instanceList for details.
|
||||
r.p.instanceList = append(r.p.instanceList, t)
|
||||
@ -976,11 +975,11 @@ func (r *importReader) doType(base *types.Named) (res types.Type) {
|
||||
if r.p.version < iexportVersionGenerics {
|
||||
errorf("unexpected instantiation type")
|
||||
}
|
||||
terms := make([]*typeparams.Term, r.uint64())
|
||||
terms := make([]*types.Term, r.uint64())
|
||||
for i := range terms {
|
||||
terms[i] = typeparams.NewTerm(r.bool(), r.typ())
|
||||
terms[i] = types.NewTerm(r.bool(), r.typ())
|
||||
}
|
||||
return typeparams.NewUnion(terms)
|
||||
return types.NewUnion(terms)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1008,23 +1007,23 @@ func (r *importReader) objectPathObject() types.Object {
|
||||
return obj
|
||||
}
|
||||
|
||||
func (r *importReader) signature(recv *types.Var, rparams []*typeparams.TypeParam, tparams []*typeparams.TypeParam) *types.Signature {
|
||||
func (r *importReader) signature(recv *types.Var, rparams []*types.TypeParam, tparams []*types.TypeParam) *types.Signature {
|
||||
params := r.paramList()
|
||||
results := r.paramList()
|
||||
variadic := params.Len() > 0 && r.bool()
|
||||
return typeparams.NewSignatureType(recv, rparams, tparams, params, results, variadic)
|
||||
return types.NewSignatureType(recv, rparams, tparams, params, results, variadic)
|
||||
}
|
||||
|
||||
func (r *importReader) tparamList() []*typeparams.TypeParam {
|
||||
func (r *importReader) tparamList() []*types.TypeParam {
|
||||
n := r.uint64()
|
||||
if n == 0 {
|
||||
return nil
|
||||
}
|
||||
xs := make([]*typeparams.TypeParam, n)
|
||||
xs := make([]*types.TypeParam, n)
|
||||
for i := range xs {
|
||||
// Note: the standard library importer is tolerant of nil types here,
|
||||
// though would panic in SetTypeParams.
|
||||
xs[i] = r.typ().(*typeparams.TypeParam)
|
||||
xs[i] = r.typ().(*types.TypeParam)
|
||||
}
|
||||
return xs
|
||||
}
|
||||
|
29
vendor/golang.org/x/tools/internal/gocommand/invoke.go
generated
vendored
29
vendor/golang.org/x/tools/internal/gocommand/invoke.go
generated
vendored
@ -13,6 +13,7 @@ import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
@ -21,8 +22,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
exec "golang.org/x/sys/execabs"
|
||||
|
||||
"golang.org/x/tools/internal/event"
|
||||
"golang.org/x/tools/internal/event/keys"
|
||||
"golang.org/x/tools/internal/event/label"
|
||||
@ -85,6 +84,7 @@ func (runner *Runner) RunPiped(ctx context.Context, inv Invocation, stdout, stde
|
||||
|
||||
// RunRaw runs the invocation, serializing requests only if they fight over
|
||||
// go.mod changes.
|
||||
// Postcondition: both error results have same nilness.
|
||||
func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) {
|
||||
ctx, done := event.Start(ctx, "gocommand.Runner.RunRaw", invLabels(inv)...)
|
||||
defer done()
|
||||
@ -95,23 +95,24 @@ func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer
|
||||
stdout, stderr, friendlyErr, err := runner.runConcurrent(ctx, inv)
|
||||
|
||||
// If we encounter a load concurrency error, we need to retry serially.
|
||||
if friendlyErr == nil || !modConcurrencyError.MatchString(friendlyErr.Error()) {
|
||||
return stdout, stderr, friendlyErr, err
|
||||
}
|
||||
event.Error(ctx, "Load concurrency error, will retry serially", err)
|
||||
if friendlyErr != nil && modConcurrencyError.MatchString(friendlyErr.Error()) {
|
||||
event.Error(ctx, "Load concurrency error, will retry serially", err)
|
||||
|
||||
// Run serially by calling runPiped.
|
||||
stdout.Reset()
|
||||
stderr.Reset()
|
||||
friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr)
|
||||
}
|
||||
|
||||
// Run serially by calling runPiped.
|
||||
stdout.Reset()
|
||||
stderr.Reset()
|
||||
friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr)
|
||||
return stdout, stderr, friendlyErr, err
|
||||
}
|
||||
|
||||
// Postcondition: both error results have same nilness.
|
||||
func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) {
|
||||
// Wait for 1 worker to become available.
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, nil, nil, ctx.Err()
|
||||
return nil, nil, ctx.Err(), ctx.Err()
|
||||
case runner.inFlight <- struct{}{}:
|
||||
defer func() { <-runner.inFlight }()
|
||||
}
|
||||
@ -121,6 +122,7 @@ func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes
|
||||
return stdout, stderr, friendlyErr, err
|
||||
}
|
||||
|
||||
// Postcondition: both error results have same nilness.
|
||||
func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) (error, error) {
|
||||
// Make sure the runner is always initialized.
|
||||
runner.initialize()
|
||||
@ -129,7 +131,7 @@ func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stde
|
||||
// runPiped commands.
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
return ctx.Err(), ctx.Err()
|
||||
case runner.serialized <- struct{}{}:
|
||||
defer func() { <-runner.serialized }()
|
||||
}
|
||||
@ -139,7 +141,7 @@ func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stde
|
||||
for i := 0; i < maxInFlight; i++ {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
return ctx.Err(), ctx.Err()
|
||||
case runner.inFlight <- struct{}{}:
|
||||
// Make sure we always "return" any workers we took.
|
||||
defer func() { <-runner.inFlight }()
|
||||
@ -172,6 +174,7 @@ type Invocation struct {
|
||||
Logf func(format string, args ...interface{})
|
||||
}
|
||||
|
||||
// Postcondition: both error results have same nilness.
|
||||
func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io.Writer) (friendlyError error, rawError error) {
|
||||
rawError = i.run(ctx, stdout, stderr)
|
||||
if rawError != nil {
|
||||
|
8
vendor/golang.org/x/tools/internal/packagesinternal/packages.go
generated
vendored
8
vendor/golang.org/x/tools/internal/packagesinternal/packages.go
generated
vendored
@ -5,10 +5,6 @@
|
||||
// Package packagesinternal exposes internal-only fields from go/packages.
|
||||
package packagesinternal
|
||||
|
||||
import (
|
||||
"golang.org/x/tools/internal/gocommand"
|
||||
)
|
||||
|
||||
var GetForTest = func(p interface{}) string { return "" }
|
||||
var GetDepsErrors = func(p interface{}) []*PackageError { return nil }
|
||||
|
||||
@ -18,10 +14,6 @@ type PackageError struct {
|
||||
Err string // the error itself
|
||||
}
|
||||
|
||||
var GetGoCmdRunner = func(config interface{}) *gocommand.Runner { return nil }
|
||||
|
||||
var SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {}
|
||||
|
||||
var TypecheckCgo int
|
||||
var DepsErrors int // must be set as a LoadMode to call GetDepsErrors
|
||||
var ForTest int // must be set as a LoadMode to call GetForTest
|
||||
|
24
vendor/golang.org/x/tools/internal/typeparams/common.go
generated
vendored
24
vendor/golang.org/x/tools/internal/typeparams/common.go
generated
vendored
@ -42,7 +42,7 @@ func UnpackIndexExpr(n ast.Node) (x ast.Expr, lbrack token.Pos, indices []ast.Ex
|
||||
switch e := n.(type) {
|
||||
case *ast.IndexExpr:
|
||||
return e.X, e.Lbrack, []ast.Expr{e.Index}, e.Rbrack
|
||||
case *IndexListExpr:
|
||||
case *ast.IndexListExpr:
|
||||
return e.X, e.Lbrack, e.Indices, e.Rbrack
|
||||
}
|
||||
return nil, token.NoPos, nil, token.NoPos
|
||||
@ -63,7 +63,7 @@ func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack toke
|
||||
Rbrack: rbrack,
|
||||
}
|
||||
default:
|
||||
return &IndexListExpr{
|
||||
return &ast.IndexListExpr{
|
||||
X: x,
|
||||
Lbrack: lbrack,
|
||||
Indices: indices,
|
||||
@ -74,7 +74,7 @@ func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack toke
|
||||
|
||||
// IsTypeParam reports whether t is a type parameter.
|
||||
func IsTypeParam(t types.Type) bool {
|
||||
_, ok := t.(*TypeParam)
|
||||
_, ok := t.(*types.TypeParam)
|
||||
return ok
|
||||
}
|
||||
|
||||
@ -100,11 +100,11 @@ func OriginMethod(fn *types.Func) *types.Func {
|
||||
// Receiver is a *types.Interface.
|
||||
return fn
|
||||
}
|
||||
if ForNamed(named).Len() == 0 {
|
||||
if named.TypeParams().Len() == 0 {
|
||||
// Receiver base has no type parameters, so we can avoid the lookup below.
|
||||
return fn
|
||||
}
|
||||
orig := NamedTypeOrigin(named)
|
||||
orig := named.Origin()
|
||||
gfn, _, _ := types.LookupFieldOrMethod(orig, true, fn.Pkg(), fn.Name())
|
||||
|
||||
// This is a fix for a gopls crash (#60628) due to a go/types bug (#60634). In:
|
||||
@ -157,7 +157,7 @@ func OriginMethod(fn *types.Func) *types.Func {
|
||||
//
|
||||
// In this case, GenericAssignableTo reports that instantiations of Container
|
||||
// are assignable to the corresponding instantiation of Interface.
|
||||
func GenericAssignableTo(ctxt *Context, V, T types.Type) bool {
|
||||
func GenericAssignableTo(ctxt *types.Context, V, T types.Type) bool {
|
||||
// If V and T are not both named, or do not have matching non-empty type
|
||||
// parameter lists, fall back on types.AssignableTo.
|
||||
|
||||
@ -167,9 +167,9 @@ func GenericAssignableTo(ctxt *Context, V, T types.Type) bool {
|
||||
return types.AssignableTo(V, T)
|
||||
}
|
||||
|
||||
vtparams := ForNamed(VN)
|
||||
ttparams := ForNamed(TN)
|
||||
if vtparams.Len() == 0 || vtparams.Len() != ttparams.Len() || NamedTypeArgs(VN).Len() != 0 || NamedTypeArgs(TN).Len() != 0 {
|
||||
vtparams := VN.TypeParams()
|
||||
ttparams := TN.TypeParams()
|
||||
if vtparams.Len() == 0 || vtparams.Len() != ttparams.Len() || VN.TypeArgs().Len() != 0 || TN.TypeArgs().Len() != 0 {
|
||||
return types.AssignableTo(V, T)
|
||||
}
|
||||
|
||||
@ -182,7 +182,7 @@ func GenericAssignableTo(ctxt *Context, V, T types.Type) bool {
|
||||
// Minor optimization: ensure we share a context across the two
|
||||
// instantiations below.
|
||||
if ctxt == nil {
|
||||
ctxt = NewContext()
|
||||
ctxt = types.NewContext()
|
||||
}
|
||||
|
||||
var targs []types.Type
|
||||
@ -190,12 +190,12 @@ func GenericAssignableTo(ctxt *Context, V, T types.Type) bool {
|
||||
targs = append(targs, vtparams.At(i))
|
||||
}
|
||||
|
||||
vinst, err := Instantiate(ctxt, V, targs, true)
|
||||
vinst, err := types.Instantiate(ctxt, V, targs, true)
|
||||
if err != nil {
|
||||
panic("type parameters should satisfy their own constraints")
|
||||
}
|
||||
|
||||
tinst, err := Instantiate(ctxt, T, targs, true)
|
||||
tinst, err := types.Instantiate(ctxt, T, targs, true)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
8
vendor/golang.org/x/tools/internal/typeparams/coretype.go
generated
vendored
8
vendor/golang.org/x/tools/internal/typeparams/coretype.go
generated
vendored
@ -108,15 +108,15 @@ func CoreType(T types.Type) types.Type {
|
||||
//
|
||||
// _NormalTerms makes no guarantees about the order of terms, except that it
|
||||
// is deterministic.
|
||||
func _NormalTerms(typ types.Type) ([]*Term, error) {
|
||||
func _NormalTerms(typ types.Type) ([]*types.Term, error) {
|
||||
switch typ := typ.(type) {
|
||||
case *TypeParam:
|
||||
case *types.TypeParam:
|
||||
return StructuralTerms(typ)
|
||||
case *Union:
|
||||
case *types.Union:
|
||||
return UnionTermSet(typ)
|
||||
case *types.Interface:
|
||||
return InterfaceTermSet(typ)
|
||||
default:
|
||||
return []*Term{NewTerm(false, typ)}, nil
|
||||
return []*types.Term{types.NewTerm(false, typ)}, nil
|
||||
}
|
||||
}
|
||||
|
12
vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go
generated
vendored
12
vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go
generated
vendored
@ -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.18
|
||||
// +build !go1.18
|
||||
|
||||
package typeparams
|
||||
|
||||
// Enabled reports whether type parameters are enabled in the current build
|
||||
// environment.
|
||||
const Enabled = false
|
15
vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go
generated
vendored
15
vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go
generated
vendored
@ -1,15 +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.18
|
||||
// +build go1.18
|
||||
|
||||
package typeparams
|
||||
|
||||
// Note: this constant is in a separate file as this is the only acceptable
|
||||
// diff between the <1.18 API of this package and the 1.18 API.
|
||||
|
||||
// Enabled reports whether type parameters are enabled in the current build
|
||||
// environment.
|
||||
const Enabled = true
|
20
vendor/golang.org/x/tools/internal/typeparams/normalize.go
generated
vendored
20
vendor/golang.org/x/tools/internal/typeparams/normalize.go
generated
vendored
@ -60,7 +60,7 @@ var ErrEmptyTypeSet = errors.New("empty type set")
|
||||
//
|
||||
// StructuralTerms makes no guarantees about the order of terms, except that it
|
||||
// is deterministic.
|
||||
func StructuralTerms(tparam *TypeParam) ([]*Term, error) {
|
||||
func StructuralTerms(tparam *types.TypeParam) ([]*types.Term, error) {
|
||||
constraint := tparam.Constraint()
|
||||
if constraint == nil {
|
||||
return nil, fmt.Errorf("%s has nil constraint", tparam)
|
||||
@ -78,7 +78,7 @@ func StructuralTerms(tparam *TypeParam) ([]*Term, error) {
|
||||
//
|
||||
// See the documentation of StructuralTerms for more information on
|
||||
// normalization.
|
||||
func InterfaceTermSet(iface *types.Interface) ([]*Term, error) {
|
||||
func InterfaceTermSet(iface *types.Interface) ([]*types.Term, error) {
|
||||
return computeTermSet(iface)
|
||||
}
|
||||
|
||||
@ -88,11 +88,11 @@ func InterfaceTermSet(iface *types.Interface) ([]*Term, error) {
|
||||
//
|
||||
// See the documentation of StructuralTerms for more information on
|
||||
// normalization.
|
||||
func UnionTermSet(union *Union) ([]*Term, error) {
|
||||
func UnionTermSet(union *types.Union) ([]*types.Term, error) {
|
||||
return computeTermSet(union)
|
||||
}
|
||||
|
||||
func computeTermSet(typ types.Type) ([]*Term, error) {
|
||||
func computeTermSet(typ types.Type) ([]*types.Term, error) {
|
||||
tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -103,9 +103,9 @@ func computeTermSet(typ types.Type) ([]*Term, error) {
|
||||
if tset.terms.isAll() {
|
||||
return nil, nil
|
||||
}
|
||||
var terms []*Term
|
||||
var terms []*types.Term
|
||||
for _, term := range tset.terms {
|
||||
terms = append(terms, NewTerm(term.tilde, term.typ))
|
||||
terms = append(terms, types.NewTerm(term.tilde, term.typ))
|
||||
}
|
||||
return terms, nil
|
||||
}
|
||||
@ -162,7 +162,7 @@ func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth in
|
||||
tset.terms = allTermlist
|
||||
for i := 0; i < u.NumEmbeddeds(); i++ {
|
||||
embedded := u.EmbeddedType(i)
|
||||
if _, ok := embedded.Underlying().(*TypeParam); ok {
|
||||
if _, ok := embedded.Underlying().(*types.TypeParam); ok {
|
||||
return nil, fmt.Errorf("invalid embedded type %T", embedded)
|
||||
}
|
||||
tset2, err := computeTermSetInternal(embedded, seen, depth+1)
|
||||
@ -171,7 +171,7 @@ func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth in
|
||||
}
|
||||
tset.terms = tset.terms.intersect(tset2.terms)
|
||||
}
|
||||
case *Union:
|
||||
case *types.Union:
|
||||
// The term set of a union is the union of term sets of its terms.
|
||||
tset.terms = nil
|
||||
for i := 0; i < u.Len(); i++ {
|
||||
@ -184,7 +184,7 @@ func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth in
|
||||
return nil, err
|
||||
}
|
||||
terms = tset2.terms
|
||||
case *TypeParam, *Union:
|
||||
case *types.TypeParam, *types.Union:
|
||||
// A stand-alone type parameter or union is not permitted as union
|
||||
// term.
|
||||
return nil, fmt.Errorf("invalid union term %T", t)
|
||||
@ -199,7 +199,7 @@ func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth in
|
||||
return nil, fmt.Errorf("exceeded max term count %d", maxTermCount)
|
||||
}
|
||||
}
|
||||
case *TypeParam:
|
||||
case *types.TypeParam:
|
||||
panic("unreachable")
|
||||
default:
|
||||
// For all other types, the term set is just a single non-tilde term
|
||||
|
197
vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go
generated
vendored
197
vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go
generated
vendored
@ -1,197 +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.18
|
||||
// +build !go1.18
|
||||
|
||||
package typeparams
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"go/types"
|
||||
)
|
||||
|
||||
func unsupported() {
|
||||
panic("type parameters are unsupported at this go version")
|
||||
}
|
||||
|
||||
// IndexListExpr is a placeholder type, as type parameters are not supported at
|
||||
// this Go version. Its methods panic on use.
|
||||
type IndexListExpr struct {
|
||||
ast.Expr
|
||||
X ast.Expr // expression
|
||||
Lbrack token.Pos // position of "["
|
||||
Indices []ast.Expr // index expressions
|
||||
Rbrack token.Pos // position of "]"
|
||||
}
|
||||
|
||||
// ForTypeSpec returns an empty field list, as type parameters on not supported
|
||||
// at this Go version.
|
||||
func ForTypeSpec(*ast.TypeSpec) *ast.FieldList {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ForFuncType returns an empty field list, as type parameters are not
|
||||
// supported at this Go version.
|
||||
func ForFuncType(*ast.FuncType) *ast.FieldList {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TypeParam is a placeholder type, as type parameters are not supported at
|
||||
// this Go version. Its methods panic on use.
|
||||
type TypeParam struct{ types.Type }
|
||||
|
||||
func (*TypeParam) Index() int { unsupported(); return 0 }
|
||||
func (*TypeParam) Constraint() types.Type { unsupported(); return nil }
|
||||
func (*TypeParam) Obj() *types.TypeName { unsupported(); return nil }
|
||||
|
||||
// TypeParamList is a placeholder for an empty type parameter list.
|
||||
type TypeParamList struct{}
|
||||
|
||||
func (*TypeParamList) Len() int { return 0 }
|
||||
func (*TypeParamList) At(int) *TypeParam { unsupported(); return nil }
|
||||
|
||||
// TypeList is a placeholder for an empty type list.
|
||||
type TypeList struct{}
|
||||
|
||||
func (*TypeList) Len() int { return 0 }
|
||||
func (*TypeList) At(int) types.Type { unsupported(); return nil }
|
||||
|
||||
// NewTypeParam is unsupported at this Go version, and panics.
|
||||
func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam {
|
||||
unsupported()
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetTypeParamConstraint is unsupported at this Go version, and panics.
|
||||
func SetTypeParamConstraint(tparam *TypeParam, constraint types.Type) {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
// NewSignatureType calls types.NewSignature, panicking if recvTypeParams or
|
||||
// typeParams is non-empty.
|
||||
func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature {
|
||||
if len(recvTypeParams) != 0 || len(typeParams) != 0 {
|
||||
panic("signatures cannot have type parameters at this Go version")
|
||||
}
|
||||
return types.NewSignature(recv, params, results, variadic)
|
||||
}
|
||||
|
||||
// ForSignature returns an empty slice.
|
||||
func ForSignature(*types.Signature) *TypeParamList {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RecvTypeParams returns a nil slice.
|
||||
func RecvTypeParams(sig *types.Signature) *TypeParamList {
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsComparable returns false, as no interfaces are type-restricted at this Go
|
||||
// version.
|
||||
func IsComparable(*types.Interface) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsMethodSet returns true, as no interfaces are type-restricted at this Go
|
||||
// version.
|
||||
func IsMethodSet(*types.Interface) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsImplicit returns false, as no interfaces are implicit at this Go version.
|
||||
func IsImplicit(*types.Interface) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// MarkImplicit does nothing, because this Go version does not have implicit
|
||||
// interfaces.
|
||||
func MarkImplicit(*types.Interface) {}
|
||||
|
||||
// ForNamed returns an empty type parameter list, as type parameters are not
|
||||
// supported at this Go version.
|
||||
func ForNamed(*types.Named) *TypeParamList {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetForNamed panics if tparams is non-empty.
|
||||
func SetForNamed(_ *types.Named, tparams []*TypeParam) {
|
||||
if len(tparams) > 0 {
|
||||
unsupported()
|
||||
}
|
||||
}
|
||||
|
||||
// NamedTypeArgs returns nil.
|
||||
func NamedTypeArgs(*types.Named) *TypeList {
|
||||
return nil
|
||||
}
|
||||
|
||||
// NamedTypeOrigin is the identity method at this Go version.
|
||||
func NamedTypeOrigin(named *types.Named) *types.Named {
|
||||
return named
|
||||
}
|
||||
|
||||
// Term holds information about a structural type restriction.
|
||||
type Term struct {
|
||||
tilde bool
|
||||
typ types.Type
|
||||
}
|
||||
|
||||
func (m *Term) Tilde() bool { return m.tilde }
|
||||
func (m *Term) Type() types.Type { return m.typ }
|
||||
func (m *Term) String() string {
|
||||
pre := ""
|
||||
if m.tilde {
|
||||
pre = "~"
|
||||
}
|
||||
return pre + m.typ.String()
|
||||
}
|
||||
|
||||
// NewTerm is unsupported at this Go version, and panics.
|
||||
func NewTerm(tilde bool, typ types.Type) *Term {
|
||||
return &Term{tilde, typ}
|
||||
}
|
||||
|
||||
// Union is a placeholder type, as type parameters are not supported at this Go
|
||||
// version. Its methods panic on use.
|
||||
type Union struct{ types.Type }
|
||||
|
||||
func (*Union) Len() int { return 0 }
|
||||
func (*Union) Term(i int) *Term { unsupported(); return nil }
|
||||
|
||||
// NewUnion is unsupported at this Go version, and panics.
|
||||
func NewUnion(terms []*Term) *Union {
|
||||
unsupported()
|
||||
return nil
|
||||
}
|
||||
|
||||
// InitInstanceInfo is a noop at this Go version.
|
||||
func InitInstanceInfo(*types.Info) {}
|
||||
|
||||
// Instance is a placeholder type, as type parameters are not supported at this
|
||||
// Go version.
|
||||
type Instance struct {
|
||||
TypeArgs *TypeList
|
||||
Type types.Type
|
||||
}
|
||||
|
||||
// GetInstances returns a nil map, as type parameters are not supported at this
|
||||
// Go version.
|
||||
func GetInstances(info *types.Info) map[*ast.Ident]Instance { return nil }
|
||||
|
||||
// Context is a placeholder type, as type parameters are not supported at
|
||||
// this Go version.
|
||||
type Context struct{}
|
||||
|
||||
// NewContext returns a placeholder Context instance.
|
||||
func NewContext() *Context {
|
||||
return &Context{}
|
||||
}
|
||||
|
||||
// Instantiate is unsupported on this Go version, and panics.
|
||||
func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) {
|
||||
unsupported()
|
||||
return nil, nil
|
||||
}
|
151
vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go
generated
vendored
151
vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go
generated
vendored
@ -1,151 +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.18
|
||||
// +build go1.18
|
||||
|
||||
package typeparams
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/types"
|
||||
)
|
||||
|
||||
// IndexListExpr is an alias for ast.IndexListExpr.
|
||||
type IndexListExpr = ast.IndexListExpr
|
||||
|
||||
// ForTypeSpec returns n.TypeParams.
|
||||
func ForTypeSpec(n *ast.TypeSpec) *ast.FieldList {
|
||||
if n == nil {
|
||||
return nil
|
||||
}
|
||||
return n.TypeParams
|
||||
}
|
||||
|
||||
// ForFuncType returns n.TypeParams.
|
||||
func ForFuncType(n *ast.FuncType) *ast.FieldList {
|
||||
if n == nil {
|
||||
return nil
|
||||
}
|
||||
return n.TypeParams
|
||||
}
|
||||
|
||||
// TypeParam is an alias for types.TypeParam
|
||||
type TypeParam = types.TypeParam
|
||||
|
||||
// TypeParamList is an alias for types.TypeParamList
|
||||
type TypeParamList = types.TypeParamList
|
||||
|
||||
// TypeList is an alias for types.TypeList
|
||||
type TypeList = types.TypeList
|
||||
|
||||
// NewTypeParam calls types.NewTypeParam.
|
||||
func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam {
|
||||
return types.NewTypeParam(name, constraint)
|
||||
}
|
||||
|
||||
// SetTypeParamConstraint calls tparam.SetConstraint(constraint).
|
||||
func SetTypeParamConstraint(tparam *TypeParam, constraint types.Type) {
|
||||
tparam.SetConstraint(constraint)
|
||||
}
|
||||
|
||||
// NewSignatureType calls types.NewSignatureType.
|
||||
func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature {
|
||||
return types.NewSignatureType(recv, recvTypeParams, typeParams, params, results, variadic)
|
||||
}
|
||||
|
||||
// ForSignature returns sig.TypeParams()
|
||||
func ForSignature(sig *types.Signature) *TypeParamList {
|
||||
return sig.TypeParams()
|
||||
}
|
||||
|
||||
// RecvTypeParams returns sig.RecvTypeParams().
|
||||
func RecvTypeParams(sig *types.Signature) *TypeParamList {
|
||||
return sig.RecvTypeParams()
|
||||
}
|
||||
|
||||
// IsComparable calls iface.IsComparable().
|
||||
func IsComparable(iface *types.Interface) bool {
|
||||
return iface.IsComparable()
|
||||
}
|
||||
|
||||
// IsMethodSet calls iface.IsMethodSet().
|
||||
func IsMethodSet(iface *types.Interface) bool {
|
||||
return iface.IsMethodSet()
|
||||
}
|
||||
|
||||
// IsImplicit calls iface.IsImplicit().
|
||||
func IsImplicit(iface *types.Interface) bool {
|
||||
return iface.IsImplicit()
|
||||
}
|
||||
|
||||
// MarkImplicit calls iface.MarkImplicit().
|
||||
func MarkImplicit(iface *types.Interface) {
|
||||
iface.MarkImplicit()
|
||||
}
|
||||
|
||||
// ForNamed extracts the (possibly empty) type parameter object list from
|
||||
// named.
|
||||
func ForNamed(named *types.Named) *TypeParamList {
|
||||
return named.TypeParams()
|
||||
}
|
||||
|
||||
// SetForNamed sets the type params tparams on n. Each tparam must be of
|
||||
// dynamic type *types.TypeParam.
|
||||
func SetForNamed(n *types.Named, tparams []*TypeParam) {
|
||||
n.SetTypeParams(tparams)
|
||||
}
|
||||
|
||||
// NamedTypeArgs returns named.TypeArgs().
|
||||
func NamedTypeArgs(named *types.Named) *TypeList {
|
||||
return named.TypeArgs()
|
||||
}
|
||||
|
||||
// NamedTypeOrigin returns named.Orig().
|
||||
func NamedTypeOrigin(named *types.Named) *types.Named {
|
||||
return named.Origin()
|
||||
}
|
||||
|
||||
// Term is an alias for types.Term.
|
||||
type Term = types.Term
|
||||
|
||||
// NewTerm calls types.NewTerm.
|
||||
func NewTerm(tilde bool, typ types.Type) *Term {
|
||||
return types.NewTerm(tilde, typ)
|
||||
}
|
||||
|
||||
// Union is an alias for types.Union
|
||||
type Union = types.Union
|
||||
|
||||
// NewUnion calls types.NewUnion.
|
||||
func NewUnion(terms []*Term) *Union {
|
||||
return types.NewUnion(terms)
|
||||
}
|
||||
|
||||
// InitInstanceInfo initializes info to record information about type and
|
||||
// function instances.
|
||||
func InitInstanceInfo(info *types.Info) {
|
||||
info.Instances = make(map[*ast.Ident]types.Instance)
|
||||
}
|
||||
|
||||
// Instance is an alias for types.Instance.
|
||||
type Instance = types.Instance
|
||||
|
||||
// GetInstances returns info.Instances.
|
||||
func GetInstances(info *types.Info) map[*ast.Ident]Instance {
|
||||
return info.Instances
|
||||
}
|
||||
|
||||
// Context is an alias for types.Context.
|
||||
type Context = types.Context
|
||||
|
||||
// NewContext calls types.NewContext.
|
||||
func NewContext() *Context {
|
||||
return types.NewContext()
|
||||
}
|
||||
|
||||
// Instantiate calls types.Instantiate.
|
||||
func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) {
|
||||
return types.Instantiate(ctxt, typ, targs, validate)
|
||||
}
|
24
vendor/golang.org/x/tools/internal/typesinternal/objectpath.go
generated
vendored
24
vendor/golang.org/x/tools/internal/typesinternal/objectpath.go
generated
vendored
@ -1,24 +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.
|
||||
|
||||
package typesinternal
|
||||
|
||||
import "go/types"
|
||||
|
||||
// This file contains back doors that allow gopls to avoid method sorting when
|
||||
// using the objectpath package.
|
||||
//
|
||||
// This is performance-critical in certain repositories, but changing the
|
||||
// behavior of the objectpath package is still being discussed in
|
||||
// golang/go#61443. If we decide to remove the sorting in objectpath we can
|
||||
// simply delete these back doors. Otherwise, we should add a new API to
|
||||
// objectpath that allows controlling the sorting.
|
||||
|
||||
// SkipEncoderMethodSorting marks enc (which must be an *objectpath.Encoder) as
|
||||
// not requiring sorted methods.
|
||||
var SkipEncoderMethodSorting func(enc interface{})
|
||||
|
||||
// ObjectpathObject is like objectpath.Object, but allows suppressing method
|
||||
// sorting.
|
||||
var ObjectpathObject func(pkg *types.Package, p string, skipMethodSorting bool) (types.Object, error)
|
172
vendor/golang.org/x/tools/internal/versions/gover.go
generated
vendored
Normal file
172
vendor/golang.org/x/tools/internal/versions/gover.go
generated
vendored
Normal file
@ -0,0 +1,172 @@
|
||||
// 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.
|
||||
|
||||
// This is a fork of internal/gover for use by x/tools until
|
||||
// go1.21 and earlier are no longer supported by x/tools.
|
||||
|
||||
package versions
|
||||
|
||||
import "strings"
|
||||
|
||||
// A gover is a parsed Go gover: major[.Minor[.Patch]][kind[pre]]
|
||||
// The numbers are the original decimal strings to avoid integer overflows
|
||||
// and since there is very little actual math. (Probably overflow doesn't matter in practice,
|
||||
// but at the time this code was written, there was an existing test that used
|
||||
// go1.99999999999, which does not fit in an int on 32-bit platforms.
|
||||
// The "big decimal" representation avoids the problem entirely.)
|
||||
type gover struct {
|
||||
major string // decimal
|
||||
minor string // decimal or ""
|
||||
patch string // decimal or ""
|
||||
kind string // "", "alpha", "beta", "rc"
|
||||
pre string // decimal or ""
|
||||
}
|
||||
|
||||
// compare returns -1, 0, or +1 depending on whether
|
||||
// x < y, x == y, or x > y, interpreted as toolchain versions.
|
||||
// The versions x and y must not begin with a "go" prefix: just "1.21" not "go1.21".
|
||||
// Malformed versions compare less than well-formed versions and equal to each other.
|
||||
// The language version "1.21" compares less than the release candidate and eventual releases "1.21rc1" and "1.21.0".
|
||||
func compare(x, y string) int {
|
||||
vx := parse(x)
|
||||
vy := parse(y)
|
||||
|
||||
if c := cmpInt(vx.major, vy.major); c != 0 {
|
||||
return c
|
||||
}
|
||||
if c := cmpInt(vx.minor, vy.minor); c != 0 {
|
||||
return c
|
||||
}
|
||||
if c := cmpInt(vx.patch, vy.patch); c != 0 {
|
||||
return c
|
||||
}
|
||||
if c := strings.Compare(vx.kind, vy.kind); c != 0 { // "" < alpha < beta < rc
|
||||
return c
|
||||
}
|
||||
if c := cmpInt(vx.pre, vy.pre); c != 0 {
|
||||
return c
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// lang returns the Go language version. For example, lang("1.2.3") == "1.2".
|
||||
func lang(x string) string {
|
||||
v := parse(x)
|
||||
if v.minor == "" || v.major == "1" && v.minor == "0" {
|
||||
return v.major
|
||||
}
|
||||
return v.major + "." + v.minor
|
||||
}
|
||||
|
||||
// isValid reports whether the version x is valid.
|
||||
func isValid(x string) bool {
|
||||
return parse(x) != gover{}
|
||||
}
|
||||
|
||||
// parse parses the Go version string x into a version.
|
||||
// It returns the zero version if x is malformed.
|
||||
func parse(x string) gover {
|
||||
var v gover
|
||||
|
||||
// Parse major version.
|
||||
var ok bool
|
||||
v.major, x, ok = cutInt(x)
|
||||
if !ok {
|
||||
return gover{}
|
||||
}
|
||||
if x == "" {
|
||||
// Interpret "1" as "1.0.0".
|
||||
v.minor = "0"
|
||||
v.patch = "0"
|
||||
return v
|
||||
}
|
||||
|
||||
// Parse . before minor version.
|
||||
if x[0] != '.' {
|
||||
return gover{}
|
||||
}
|
||||
|
||||
// Parse minor version.
|
||||
v.minor, x, ok = cutInt(x[1:])
|
||||
if !ok {
|
||||
return gover{}
|
||||
}
|
||||
if x == "" {
|
||||
// Patch missing is same as "0" for older versions.
|
||||
// Starting in Go 1.21, patch missing is different from explicit .0.
|
||||
if cmpInt(v.minor, "21") < 0 {
|
||||
v.patch = "0"
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Parse patch if present.
|
||||
if x[0] == '.' {
|
||||
v.patch, x, ok = cutInt(x[1:])
|
||||
if !ok || x != "" {
|
||||
// Note that we are disallowing prereleases (alpha, beta, rc) for patch releases here (x != "").
|
||||
// Allowing them would be a bit confusing because we already have:
|
||||
// 1.21 < 1.21rc1
|
||||
// But a prerelease of a patch would have the opposite effect:
|
||||
// 1.21.3rc1 < 1.21.3
|
||||
// We've never needed them before, so let's not start now.
|
||||
return gover{}
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Parse prerelease.
|
||||
i := 0
|
||||
for i < len(x) && (x[i] < '0' || '9' < x[i]) {
|
||||
if x[i] < 'a' || 'z' < x[i] {
|
||||
return gover{}
|
||||
}
|
||||
i++
|
||||
}
|
||||
if i == 0 {
|
||||
return gover{}
|
||||
}
|
||||
v.kind, x = x[:i], x[i:]
|
||||
if x == "" {
|
||||
return v
|
||||
}
|
||||
v.pre, x, ok = cutInt(x)
|
||||
if !ok || x != "" {
|
||||
return gover{}
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// cutInt scans the leading decimal number at the start of x to an integer
|
||||
// and returns that value and the rest of the string.
|
||||
func cutInt(x string) (n, rest string, ok bool) {
|
||||
i := 0
|
||||
for i < len(x) && '0' <= x[i] && x[i] <= '9' {
|
||||
i++
|
||||
}
|
||||
if i == 0 || x[0] == '0' && i != 1 { // no digits or unnecessary leading zero
|
||||
return "", "", false
|
||||
}
|
||||
return x[:i], x[i:], true
|
||||
}
|
||||
|
||||
// cmpInt returns cmp.Compare(x, y) interpreting x and y as decimal numbers.
|
||||
// (Copied from golang.org/x/mod/semver's compareInt.)
|
||||
func cmpInt(x, y string) int {
|
||||
if x == y {
|
||||
return 0
|
||||
}
|
||||
if len(x) < len(y) {
|
||||
return -1
|
||||
}
|
||||
if len(x) > len(y) {
|
||||
return +1
|
||||
}
|
||||
if x < y {
|
||||
return -1
|
||||
} else {
|
||||
return +1
|
||||
}
|
||||
}
|
19
vendor/golang.org/x/tools/internal/versions/types.go
generated
vendored
Normal file
19
vendor/golang.org/x/tools/internal/versions/types.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
// 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.
|
||||
|
||||
package versions
|
||||
|
||||
import (
|
||||
"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()
|
||||
}
|
||||
return ""
|
||||
}
|
20
vendor/golang.org/x/tools/internal/versions/types_go121.go
generated
vendored
Normal file
20
vendor/golang.org/x/tools/internal/versions/types_go121.go
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// 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"
|
||||
)
|
||||
|
||||
// FileVersions always reports the a file's Go version as the
|
||||
// zero version at this Go version.
|
||||
func FileVersions(info *types.Info, file *ast.File) string { return "" }
|
||||
|
||||
// InitFileVersions is a noop at this Go version.
|
||||
func InitFileVersions(*types.Info) {}
|
24
vendor/golang.org/x/tools/internal/versions/types_go122.go
generated
vendored
Normal file
24
vendor/golang.org/x/tools/internal/versions/types_go122.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
// 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"
|
||||
)
|
||||
|
||||
// FileVersions maps a file to the file's semantic Go version.
|
||||
// The reported version is the zero version if a version cannot be determined.
|
||||
func FileVersions(info *types.Info, file *ast.File) string {
|
||||
return info.FileVersions[file]
|
||||
}
|
||||
|
||||
// InitFileVersions initializes info to record Go versions for Go files.
|
||||
func InitFileVersions(info *types.Info) {
|
||||
info.FileVersions = make(map[*ast.File]string)
|
||||
}
|
52
vendor/golang.org/x/tools/internal/versions/versions.go
generated
vendored
Normal file
52
vendor/golang.org/x/tools/internal/versions/versions.go
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
// 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.
|
||||
|
||||
package versions
|
||||
|
||||
// Note: If we use build tags to use go/versions when go >=1.22,
|
||||
// we run into go.dev/issue/53737. Under some operations users would see an
|
||||
// import of "go/versions" even if they would not compile the file.
|
||||
// For example, during `go get -u ./...` (go.dev/issue/64490) we do not try to include
|
||||
// For this reason, this library just a clone of go/versions for the moment.
|
||||
|
||||
// Lang returns the Go language version for version x.
|
||||
// If x is not a valid version, Lang returns the empty string.
|
||||
// For example:
|
||||
//
|
||||
// Lang("go1.21rc2") = "go1.21"
|
||||
// Lang("go1.21.2") = "go1.21"
|
||||
// Lang("go1.21") = "go1.21"
|
||||
// Lang("go1") = "go1"
|
||||
// Lang("bad") = ""
|
||||
// Lang("1.21") = ""
|
||||
func Lang(x string) string {
|
||||
v := lang(stripGo(x))
|
||||
if v == "" {
|
||||
return ""
|
||||
}
|
||||
return x[:2+len(v)] // "go"+v without allocation
|
||||
}
|
||||
|
||||
// Compare returns -1, 0, or +1 depending on whether
|
||||
// x < y, x == y, or x > y, interpreted as Go versions.
|
||||
// The versions x and y must begin with a "go" prefix: "go1.21" not "1.21".
|
||||
// Invalid versions, including the empty string, compare less than
|
||||
// valid versions and equal to each other.
|
||||
// The language version "go1.21" compares less than the
|
||||
// release candidate and eventual releases "go1.21rc1" and "go1.21.0".
|
||||
// Custom toolchain suffixes are ignored during comparison:
|
||||
// "go1.21.0" and "go1.21.0-bigcorp" are equal.
|
||||
func Compare(x, y string) int { return compare(stripGo(x), stripGo(y)) }
|
||||
|
||||
// IsValid reports whether the version x is valid.
|
||||
func IsValid(x string) bool { return isValid(stripGo(x)) }
|
||||
|
||||
// stripGo converts from a "go1.21" version to a "1.21" version.
|
||||
// If v does not start with "go", stripGo returns the empty string (a known invalid version).
|
||||
func stripGo(v string) string {
|
||||
if len(v) < 2 || v[:2] != "go" {
|
||||
return ""
|
||||
}
|
||||
return v[2:]
|
||||
}
|
Reference in New Issue
Block a user