summaryrefslogtreecommitdiffstats
path: root/vendor
diff options
context:
space:
mode:
author6543 <6543@obermui.de>2020-08-15 19:13:07 +0200
committerGitHub <noreply@github.com>2020-08-15 13:13:07 -0400
commitee97e6a66a7bec9547af31c93a5eef7c19a32c54 (patch)
tree1143ebd8f6abd6027c52e99d71534f141eaecd8e /vendor
parenteb60a5d05478f56bf15220f49ed78f0f72af5698 (diff)
downloadgitea-ee97e6a66a7bec9547af31c93a5eef7c19a32c54.tar.gz
gitea-ee97e6a66a7bec9547af31c93a5eef7c19a32c54.zip
Update gitea-vet to v0.2.1 (#12282)
* change to new code location * vendor * tagged version v0.2.0 * gitea-vet v0.2.1 Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Diffstat (limited to 'vendor')
-rw-r--r--vendor/code.gitea.io/gitea-vet/.changelog.yml30
-rw-r--r--vendor/code.gitea.io/gitea-vet/.drone.yml45
-rw-r--r--vendor/code.gitea.io/gitea-vet/.gitignore (renamed from vendor/gitea.com/jolheiser/gitea-vet/.gitignore)0
-rw-r--r--vendor/code.gitea.io/gitea-vet/.golangci.yml23
-rw-r--r--vendor/code.gitea.io/gitea-vet/CHANGELOG.md11
-rw-r--r--vendor/code.gitea.io/gitea-vet/LICENSE (renamed from vendor/gitea.com/jolheiser/gitea-vet/LICENSE)0
-rw-r--r--vendor/code.gitea.io/gitea-vet/Makefile22
-rw-r--r--vendor/code.gitea.io/gitea-vet/README.md11
-rw-r--r--vendor/code.gitea.io/gitea-vet/checks/imports.go (renamed from vendor/gitea.com/jolheiser/gitea-vet/checks/imports.go)18
-rw-r--r--vendor/code.gitea.io/gitea-vet/checks/license.go (renamed from vendor/gitea.com/jolheiser/gitea-vet/checks/license.go)2
-rw-r--r--vendor/code.gitea.io/gitea-vet/checks/migrations.go77
-rw-r--r--vendor/code.gitea.io/gitea-vet/go.mod (renamed from vendor/gitea.com/jolheiser/gitea-vet/go.mod)2
-rw-r--r--vendor/code.gitea.io/gitea-vet/go.sum (renamed from vendor/gitea.com/jolheiser/gitea-vet/go.sum)0
-rw-r--r--vendor/code.gitea.io/gitea-vet/main.go (renamed from vendor/gitea.com/jolheiser/gitea-vet/main.go)4
-rw-r--r--vendor/gitea.com/jolheiser/gitea-vet/Makefile7
-rw-r--r--vendor/gitea.com/jolheiser/gitea-vet/README.md7
-rw-r--r--vendor/golang.org/x/tools/go/analysis/analysis.go16
-rw-r--r--vendor/golang.org/x/tools/go/analysis/doc.go9
-rw-r--r--vendor/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go2
-rw-r--r--vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go11
-rw-r--r--vendor/golang.org/x/tools/go/packages/golist.go142
-rw-r--r--vendor/golang.org/x/tools/go/packages/golist_overlay.go145
-rw-r--r--vendor/golang.org/x/tools/go/packages/loadmode_string.go2
-rw-r--r--vendor/golang.org/x/tools/go/packages/packages.go80
-rw-r--r--vendor/golang.org/x/tools/go/types/objectpath/objectpath.go5
-rw-r--r--vendor/golang.org/x/tools/imports/forward.go35
-rw-r--r--vendor/golang.org/x/tools/internal/analysisinternal/analysis.go421
-rw-r--r--vendor/golang.org/x/tools/internal/event/core/event.go85
-rw-r--r--vendor/golang.org/x/tools/internal/event/core/export.go70
-rw-r--r--vendor/golang.org/x/tools/internal/event/core/fast.go77
-rw-r--r--vendor/golang.org/x/tools/internal/event/doc.go7
-rw-r--r--vendor/golang.org/x/tools/internal/event/event.go127
-rw-r--r--vendor/golang.org/x/tools/internal/event/keys/keys.go564
-rw-r--r--vendor/golang.org/x/tools/internal/event/keys/standard.go22
-rw-r--r--vendor/golang.org/x/tools/internal/event/label/label.go213
-rw-r--r--vendor/golang.org/x/tools/internal/gocommand/invoke.go142
-rw-r--r--vendor/golang.org/x/tools/internal/gocommand/vendor.go102
-rw-r--r--vendor/golang.org/x/tools/internal/gopathwalk/walk.go11
-rw-r--r--vendor/golang.org/x/tools/internal/imports/fix.go237
-rw-r--r--vendor/golang.org/x/tools/internal/imports/imports.go88
-rw-r--r--vendor/golang.org/x/tools/internal/imports/mod.go121
-rw-r--r--vendor/golang.org/x/tools/internal/imports/sortimports.go20
-rw-r--r--vendor/golang.org/x/tools/internal/imports/zstdlib.go139
-rw-r--r--vendor/golang.org/x/tools/internal/lsp/fuzzy/input.go168
-rw-r--r--vendor/golang.org/x/tools/internal/lsp/fuzzy/matcher.go398
-rw-r--r--vendor/golang.org/x/tools/internal/packagesinternal/packages.go29
-rw-r--r--vendor/golang.org/x/tools/internal/typesinternal/types.go28
-rw-r--r--vendor/modules.txt19
48 files changed, 3402 insertions, 392 deletions
diff --git a/vendor/code.gitea.io/gitea-vet/.changelog.yml b/vendor/code.gitea.io/gitea-vet/.changelog.yml
new file mode 100644
index 0000000000..b3e6446b71
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/.changelog.yml
@@ -0,0 +1,30 @@
+# The full repository name
+repo: gitea/gitea-vet
+
+# Service type (gitea or github)
+service: gitea
+
+# Base URL for Gitea instance if using gitea service type (optional)
+base-url: https://gitea.com
+
+# Changelog groups and which labeled PRs to add to each group
+groups:
+ -
+ name: BREAKING
+ labels:
+ - breaking
+ -
+ name: FEATURES
+ labels:
+ - feature
+ -
+ name: BUGFIXES
+ labels:
+ - bug
+ -
+ name: ENHANCEMENTS
+ labels:
+ - enhancement
+
+# regex indicating which labels to skip for the changelog
+skip-labels: skip-changelog|backport\/.+
diff --git a/vendor/code.gitea.io/gitea-vet/.drone.yml b/vendor/code.gitea.io/gitea-vet/.drone.yml
new file mode 100644
index 0000000000..dd0fc13f9d
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/.drone.yml
@@ -0,0 +1,45 @@
+---
+kind: pipeline
+name: compliance
+
+platform:
+ os: linux
+ arch: arm64
+
+trigger:
+ event:
+ - pull_request
+
+steps:
+ - name: check
+ pull: always
+ image: golang:1.14
+ environment:
+ GOPROXY: https://goproxy.cn
+ commands:
+ - make build
+ - make lint
+ - make vet
+
+---
+kind: pipeline
+name: build-master
+
+platform:
+ os: linux
+ arch: amd64
+
+trigger:
+ branch:
+ - master
+ event:
+ - push
+
+steps:
+ - name: build
+ pull: always
+ image: techknowlogick/xgo:latest
+ environment:
+ GOPROXY: https://goproxy.cn
+ commands:
+ - make build \ No newline at end of file
diff --git a/vendor/gitea.com/jolheiser/gitea-vet/.gitignore b/vendor/code.gitea.io/gitea-vet/.gitignore
index b89cc42a23..b89cc42a23 100644
--- a/vendor/gitea.com/jolheiser/gitea-vet/.gitignore
+++ b/vendor/code.gitea.io/gitea-vet/.gitignore
diff --git a/vendor/code.gitea.io/gitea-vet/.golangci.yml b/vendor/code.gitea.io/gitea-vet/.golangci.yml
new file mode 100644
index 0000000000..704d99a1d3
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/.golangci.yml
@@ -0,0 +1,23 @@
+linters:
+ enable:
+ - deadcode
+ - dogsled
+ - dupl
+ - errcheck
+ - gocognit
+ - goconst
+ - gocritic
+ - gocyclo
+ - gofmt
+ - golint
+ - gosimple
+ - govet
+ - maligned
+ - misspell
+ - prealloc
+ - staticcheck
+ - structcheck
+ - typecheck
+ - unparam
+ - unused
+ - varcheck \ No newline at end of file
diff --git a/vendor/code.gitea.io/gitea-vet/CHANGELOG.md b/vendor/code.gitea.io/gitea-vet/CHANGELOG.md
new file mode 100644
index 0000000000..295456bb6b
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/CHANGELOG.md
@@ -0,0 +1,11 @@
+## [v0.2.1](https://gitea.com/gitea/gitea-vet/releases/tag/v0.2.1) - 2020-08-15
+
+* BUGFIXES
+ * Split migration check to Deps and Imports (#9)
+
+## [0.2.0](https://gitea.com/gitea/gitea-vet/pulls?q=&type=all&state=closed&milestone=1272) - 2020-07-20
+
+* FEATURES
+ * Add migrations check (#5)
+* BUGFIXES
+ * Correct Import Paths (#6)
diff --git a/vendor/gitea.com/jolheiser/gitea-vet/LICENSE b/vendor/code.gitea.io/gitea-vet/LICENSE
index a39c526bbe..a39c526bbe 100644
--- a/vendor/gitea.com/jolheiser/gitea-vet/LICENSE
+++ b/vendor/code.gitea.io/gitea-vet/LICENSE
diff --git a/vendor/code.gitea.io/gitea-vet/Makefile b/vendor/code.gitea.io/gitea-vet/Makefile
new file mode 100644
index 0000000000..e9c9f4f70c
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/Makefile
@@ -0,0 +1,22 @@
+GO ?= go
+
+.PHONY: build
+build:
+ $(GO) build
+
+.PHONY: fmt
+fmt:
+ $(GO) fmt ./...
+
+.PHONY: vet
+vet: build
+ $(GO) vet ./...
+ $(GO) vet -vettool=gitea-vet ./...
+
+.PHONY: lint
+lint:
+ @hash golangci-lint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
+ export BINARY="golangci-lint"; \
+ curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(shell $(GO) env GOPATH)/bin v1.24.0; \
+ fi
+ golangci-lint run --timeout 5m \ No newline at end of file
diff --git a/vendor/code.gitea.io/gitea-vet/README.md b/vendor/code.gitea.io/gitea-vet/README.md
new file mode 100644
index 0000000000..5d3d09742b
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/README.md
@@ -0,0 +1,11 @@
+# gitea-vet
+
+[![Build Status](https://drone.gitea.com/api/badges/gitea/gitea-vet/status.svg)](https://drone.gitea.com/gitea/gitea-vet)
+
+`go vet` tool for Gitea
+
+| Analyzer | Description |
+|------------|-----------------------------------------------------------------------------|
+| Imports | Checks for import sorting. stdlib->code.gitea.io->other |
+| License | Checks file headers for some form of `Copyright...YYYY...Gitea/Gogs` |
+| Migrations | Checks for black-listed packages in `code.gitea.io/gitea/models/migrations` |
diff --git a/vendor/gitea.com/jolheiser/gitea-vet/checks/imports.go b/vendor/code.gitea.io/gitea-vet/checks/imports.go
index 6ef5975e2e..15563c8543 100644
--- a/vendor/gitea.com/jolheiser/gitea-vet/checks/imports.go
+++ b/vendor/code.gitea.io/gitea-vet/checks/imports.go
@@ -12,7 +12,7 @@ import (
var Imports = &analysis.Analyzer{
Name: "imports",
- Doc: "check for import order.",
+ Doc: "check for import order",
Run: runImports,
}
@@ -22,11 +22,12 @@ func runImports(pass *analysis.Pass) (interface{}, error) {
for _, im := range file.Imports {
var lvl int
val := im.Path.Value
- if importHasPrefix(val, "code.gitea.io") {
+ switch {
+ case importHasPrefix(val, "code.gitea.io"):
lvl = 2
- } else if strings.Contains(val, ".") {
+ case strings.Contains(val, "."):
lvl = 3
- } else {
+ default:
lvl = 1
}
@@ -43,12 +44,3 @@ func runImports(pass *analysis.Pass) (interface{}, error) {
func importHasPrefix(s, p string) bool {
return strings.HasPrefix(s, "\""+p)
}
-
-func sliceHasPrefix(s string, prefixes ...string) bool {
- for _, p := range prefixes {
- if importHasPrefix(s, p) {
- return true
- }
- }
- return false
-}
diff --git a/vendor/gitea.com/jolheiser/gitea-vet/checks/license.go b/vendor/code.gitea.io/gitea-vet/checks/license.go
index 83f9e3ca03..a3ae04767b 100644
--- a/vendor/gitea.com/jolheiser/gitea-vet/checks/license.go
+++ b/vendor/code.gitea.io/gitea-vet/checks/license.go
@@ -19,7 +19,7 @@ var (
var License = &analysis.Analyzer{
Name: "license",
- Doc: "check for a copyright header.",
+ Doc: "check for a copyright header",
Run: runLicense,
}
diff --git a/vendor/code.gitea.io/gitea-vet/checks/migrations.go b/vendor/code.gitea.io/gitea-vet/checks/migrations.go
new file mode 100644
index 0000000000..e3fe570f75
--- /dev/null
+++ b/vendor/code.gitea.io/gitea-vet/checks/migrations.go
@@ -0,0 +1,77 @@
+// Copyright 2020 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package checks
+
+import (
+ "errors"
+ "os/exec"
+ "strings"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+var Migrations = &analysis.Analyzer{
+ Name: "migrations",
+ Doc: "check migrations for black-listed packages.",
+ Run: checkMigrations,
+}
+
+var (
+ migrationDepBlockList = []string{
+ "code.gitea.io/gitea/models",
+ }
+ migrationImpBlockList = []string{
+ "code.gitea.io/gitea/modules/structs",
+ }
+)
+
+func checkMigrations(pass *analysis.Pass) (interface{}, error) {
+ if !strings.EqualFold(pass.Pkg.Path(), "code.gitea.io/gitea/models/migrations") {
+ return nil, nil
+ }
+
+ if _, err := exec.LookPath("go"); err != nil {
+ return nil, errors.New("go was not found in the PATH")
+ }
+
+ depsCmd := exec.Command("go", "list", "-f", `{{join .Deps "\n"}}`, "code.gitea.io/gitea/models/migrations")
+ depsOut, err := depsCmd.Output()
+ if err != nil {
+ return nil, err
+ }
+
+ deps := strings.Split(string(depsOut), "\n")
+ for _, dep := range deps {
+ if stringInSlice(dep, migrationDepBlockList) {
+ pass.Reportf(0, "code.gitea.io/gitea/models/migrations cannot depend on the following packages: %s", migrationDepBlockList)
+ return nil, nil
+ }
+ }
+
+ impsCmd := exec.Command("go", "list", "-f", `{{join .Imports "\n"}}`, "code.gitea.io/gitea/models/migrations")
+ impsOut, err := impsCmd.Output()
+ if err != nil {
+ return nil, err
+ }
+
+ imps := strings.Split(string(impsOut), "\n")
+ for _, imp := range imps {
+ if stringInSlice(imp, migrationImpBlockList) {
+ pass.Reportf(0, "code.gitea.io/gitea/models/migrations cannot import the following packages: %s", migrationImpBlockList)
+ return nil, nil
+ }
+ }
+
+ return nil, nil
+}
+
+func stringInSlice(needle string, haystack []string) bool {
+ for _, h := range haystack {
+ if strings.EqualFold(needle, h) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/gitea.com/jolheiser/gitea-vet/go.mod b/vendor/code.gitea.io/gitea-vet/go.mod
index 241ed5ca07..ed0987cc61 100644
--- a/vendor/gitea.com/jolheiser/gitea-vet/go.mod
+++ b/vendor/code.gitea.io/gitea-vet/go.mod
@@ -1,4 +1,4 @@
-module gitea.com/jolheiser/gitea-vet
+module code.gitea.io/gitea-vet
go 1.14
diff --git a/vendor/gitea.com/jolheiser/gitea-vet/go.sum b/vendor/code.gitea.io/gitea-vet/go.sum
index 5feddd059c..5feddd059c 100644
--- a/vendor/gitea.com/jolheiser/gitea-vet/go.sum
+++ b/vendor/code.gitea.io/gitea-vet/go.sum
diff --git a/vendor/gitea.com/jolheiser/gitea-vet/main.go b/vendor/code.gitea.io/gitea-vet/main.go
index 9b8b000065..4894055086 100644
--- a/vendor/gitea.com/jolheiser/gitea-vet/main.go
+++ b/vendor/code.gitea.io/gitea-vet/main.go
@@ -5,7 +5,8 @@
package main
import (
- "gitea.com/jolheiser/gitea-vet/checks"
+ "code.gitea.io/gitea-vet/checks"
+
"golang.org/x/tools/go/analysis/unitchecker"
)
@@ -13,5 +14,6 @@ func main() {
unitchecker.Main(
checks.Imports,
checks.License,
+ checks.Migrations,
)
}
diff --git a/vendor/gitea.com/jolheiser/gitea-vet/Makefile b/vendor/gitea.com/jolheiser/gitea-vet/Makefile
deleted file mode 100644
index 5305662b61..0000000000
--- a/vendor/gitea.com/jolheiser/gitea-vet/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-.PHONY: build
-build:
- go build
-
-.PHONY: fmt
-fmt:
- go fmt ./... \ No newline at end of file
diff --git a/vendor/gitea.com/jolheiser/gitea-vet/README.md b/vendor/gitea.com/jolheiser/gitea-vet/README.md
deleted file mode 100644
index 5fc03e0ebf..0000000000
--- a/vendor/gitea.com/jolheiser/gitea-vet/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# gitea-vet
-`go vet` tool for Gitea
-
-| Analyzer | Description |
-|----------|---------------------------------------------------------------------|
-| Imports | Checks for import sorting. stdlib->code.gitea.io->other |
-| License | Checks file headers for some form of `Copyright...YYYY...Gitea/Gogs`|
diff --git a/vendor/golang.org/x/tools/go/analysis/analysis.go b/vendor/golang.org/x/tools/go/analysis/analysis.go
index ea605f4fd4..8c9977355c 100644
--- a/vendor/golang.org/x/tools/go/analysis/analysis.go
+++ b/vendor/golang.org/x/tools/go/analysis/analysis.go
@@ -7,6 +7,8 @@ import (
"go/token"
"go/types"
"reflect"
+
+ "golang.org/x/tools/internal/analysisinternal"
)
// An Analyzer describes an analysis function and its options.
@@ -69,6 +71,17 @@ type Analyzer struct {
func (a *Analyzer) String() string { return a.Name }
+func init() {
+ // Set the analysisinternal functions to be able to pass type errors
+ // to the Pass type without modifying the go/analysis API.
+ analysisinternal.SetTypeErrors = func(p interface{}, errors []types.Error) {
+ p.(*Pass).typeErrors = errors
+ }
+ analysisinternal.GetTypeErrors = func(p interface{}) []types.Error {
+ return p.(*Pass).typeErrors
+ }
+}
+
// A Pass provides information to the Run function that
// applies a specific analyzer to a single Go package.
//
@@ -138,6 +151,9 @@ type Pass struct {
// WARNING: This is an experimental API and may change in the future.
AllObjectFacts func() []ObjectFact
+ // typeErrors contains types.Errors that are associated with the pkg.
+ typeErrors []types.Error
+
/* Further fields may be added in future. */
// For example, suggested or applied refactorings.
}
diff --git a/vendor/golang.org/x/tools/go/analysis/doc.go b/vendor/golang.org/x/tools/go/analysis/doc.go
index ea56b724e8..fb17a0e415 100644
--- a/vendor/golang.org/x/tools/go/analysis/doc.go
+++ b/vendor/golang.org/x/tools/go/analysis/doc.go
@@ -170,6 +170,15 @@ Diagnostic is defined as:
The optional Category field is a short identifier that classifies the
kind of message when an analysis produces several kinds of diagnostic.
+Many analyses want to associate diagnostics with a severity level.
+Because Diagnostic does not have a severity level field, an Analyzer's
+diagnostics effectively all have the same severity level. To separate which
+diagnostics are high severity and which are low severity, expose multiple
+Analyzers instead. Analyzers should also be separated when their
+diagnostics belong in different groups, or could be tagged differently
+before being shown to the end user. Analyzers should document their severity
+level to help downstream tools surface diagnostics properly.
+
Most Analyzers inspect typed Go syntax trees, but a few, such as asmdecl
and buildtag, inspect the raw text of Go source files or even non-Go
files such as assembly. To report a diagnostic against a line of a
diff --git a/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go b/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go
index 0778f42207..4b7be2d1f5 100644
--- a/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go
+++ b/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go
@@ -382,7 +382,7 @@ func (tree JSONTree) Add(fset *token.FileSet, id, name string, diags []analysis.
func (tree JSONTree) Print() {
data, err := json.MarshalIndent(tree, "", "\t")
if err != nil {
- log.Panicf("internal error: JSON marshalling failed: %v", err)
+ log.Panicf("internal error: JSON marshaling failed: %v", err)
}
fmt.Printf("%s\n", data)
}
diff --git a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
index 5ee692d383..dc6177c122 100644
--- a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
+++ b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
@@ -19,8 +19,7 @@ import (
var debug = false
-// GetSizes returns the sizes used by the underlying driver with the given parameters.
-func GetSizes(ctx context.Context, buildFlags, env []string, dir string, usesExportData bool) (types.Sizes, error) {
+func GetSizes(ctx context.Context, buildFlags, env []string, gocmdRunner *gocommand.Runner, dir string) (types.Sizes, error) {
// TODO(matloob): Clean this up. This code is mostly a copy of packages.findExternalDriver.
const toolPrefix = "GOPACKAGESDRIVER="
tool := ""
@@ -40,7 +39,7 @@ func GetSizes(ctx context.Context, buildFlags, env []string, dir string, usesExp
}
if tool == "off" {
- return GetSizesGolist(ctx, buildFlags, env, dir, usesExportData)
+ return GetSizesGolist(ctx, buildFlags, env, gocmdRunner, dir)
}
req, err := json.Marshal(struct {
@@ -76,7 +75,7 @@ func GetSizes(ctx context.Context, buildFlags, env []string, dir string, usesExp
return response.Sizes, nil
}
-func GetSizesGolist(ctx context.Context, buildFlags, env []string, dir string, usesExportData bool) (types.Sizes, error) {
+func GetSizesGolist(ctx context.Context, buildFlags, env []string, gocmdRunner *gocommand.Runner, dir string) (types.Sizes, error) {
inv := gocommand.Invocation{
Verb: "list",
Args: []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"},
@@ -84,7 +83,7 @@ func GetSizesGolist(ctx context.Context, buildFlags, env []string, dir string, u
BuildFlags: buildFlags,
WorkingDir: dir,
}
- stdout, stderr, friendlyErr, rawErr := inv.RunRaw(ctx)
+ stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv)
var goarch, compiler string
if rawErr != nil {
if strings.Contains(rawErr.Error(), "cannot find main module") {
@@ -96,7 +95,7 @@ func GetSizesGolist(ctx context.Context, buildFlags, env []string, dir string, u
Env: env,
WorkingDir: dir,
}
- envout, enverr := inv.Run(ctx)
+ envout, enverr := gocmdRunner.Run(ctx, inv)
if enverr != nil {
return nil, enverr
}
diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go
index b4a13ef454..b4d232be70 100644
--- a/vendor/golang.org/x/tools/go/packages/golist.go
+++ b/vendor/golang.org/x/tools/go/packages/golist.go
@@ -24,7 +24,7 @@ import (
"golang.org/x/tools/go/internal/packagesdriver"
"golang.org/x/tools/internal/gocommand"
- "golang.org/x/tools/internal/packagesinternal"
+ "golang.org/x/xerrors"
)
// debug controls verbose logging.
@@ -89,6 +89,10 @@ type golistState struct {
rootDirsError error
rootDirs map[string]string
+ goVersionOnce sync.Once
+ goVersionError error
+ goVersion string // third field of 'go version'
+
// vendorDirs caches the (non)existence of vendor directories.
vendorDirs map[string]bool
}
@@ -142,7 +146,7 @@ func goListDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
sizeswg.Add(1)
go func() {
var sizes types.Sizes
- sizes, sizeserr = packagesdriver.GetSizesGolist(ctx, cfg.BuildFlags, cfg.Env, cfg.Dir, usesExportData(cfg))
+ sizes, sizeserr = packagesdriver.GetSizesGolist(ctx, cfg.BuildFlags, cfg.Env, cfg.gocmdRunner, cfg.Dir)
// types.SizesFor always returns nil or a *types.StdSizes.
response.dr.Sizes, _ = sizes.(*types.StdSizes)
sizeswg.Done()
@@ -381,7 +385,7 @@ type jsonPackage struct {
Imports []string
ImportMap map[string]string
Deps []string
- Module *packagesinternal.Module
+ Module *Module
TestGoFiles []string
TestImports []string
XTestGoFiles []string
@@ -502,10 +506,19 @@ func (state *golistState) createDriverResponse(words ...string) (*driverResponse
errkind = "use of internal package not allowed"
}
if errkind != "" {
- if len(old.Error.ImportStack) < 2 {
- return nil, fmt.Errorf(`internal error: go list gave a %q error with an import stack with fewer than two elements`, errkind)
+ if len(old.Error.ImportStack) < 1 {
+ return nil, fmt.Errorf(`internal error: go list gave a %q error with empty import stack`, errkind)
+ }
+ importingPkg := old.Error.ImportStack[len(old.Error.ImportStack)-1]
+ if importingPkg == old.ImportPath {
+ // Using an older version of Go which put this package itself on top of import
+ // stack, instead of the importer. Look for importer in second from top
+ // position.
+ if len(old.Error.ImportStack) < 2 {
+ return nil, fmt.Errorf(`internal error: go list gave a %q error with an import stack without importing package`, errkind)
+ }
+ importingPkg = old.Error.ImportStack[len(old.Error.ImportStack)-2]
}
- importingPkg := old.Error.ImportStack[len(old.Error.ImportStack)-2]
additionalErrors[importingPkg] = append(additionalErrors[importingPkg], Error{
Pos: old.Error.Pos,
Msg: old.Error.Err,
@@ -531,7 +544,26 @@ func (state *golistState) createDriverResponse(words ...string) (*driverResponse
CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles),
OtherFiles: absJoin(p.Dir, otherFiles(p)...),
forTest: p.ForTest,
- module: p.Module,
+ Module: p.Module,
+ }
+
+ if (state.cfg.Mode&typecheckCgo) != 0 && len(p.CgoFiles) != 0 {
+ if len(p.CompiledGoFiles) > len(p.GoFiles) {
+ // We need the cgo definitions, which are in the first
+ // CompiledGoFile after the non-cgo ones. This is a hack but there
+ // isn't currently a better way to find it. We also need the pure
+ // Go files and unprocessed cgo files, all of which are already
+ // in pkg.GoFiles.
+ cgoTypes := p.CompiledGoFiles[len(p.GoFiles)]
+ pkg.CompiledGoFiles = append([]string{cgoTypes}, pkg.GoFiles...)
+ } else {
+ // golang/go#38990: go list silently fails to do cgo processing
+ pkg.CompiledGoFiles = nil
+ pkg.Errors = append(pkg.Errors, Error{
+ Msg: "go list failed to return CompiledGoFiles; https://golang.org/issue/38990?",
+ Kind: ListError,
+ })
+ }
}
// Work around https://golang.org/issue/28749:
@@ -607,6 +639,39 @@ func (state *golistState) createDriverResponse(words ...string) (*driverResponse
pkg.CompiledGoFiles = pkg.GoFiles
}
+ // Temporary work-around for golang/go#39986. Parse filenames out of
+ // error messages. This happens if there are unrecoverable syntax
+ // errors in the source, so we can't match on a specific error message.
+ if err := p.Error; err != nil && state.shouldAddFilenameFromError(p) {
+ addFilenameFromPos := func(pos string) bool {
+ split := strings.Split(pos, ":")
+ if len(split) < 1 {
+ return false
+ }
+ filename := strings.TrimSpace(split[0])
+ if filename == "" {
+ return false
+ }
+ if !filepath.IsAbs(filename) {
+ filename = filepath.Join(state.cfg.Dir, filename)
+ }
+ info, _ := os.Stat(filename)
+ if info == nil {
+ return false
+ }
+ pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, filename)
+ pkg.GoFiles = append(pkg.GoFiles, filename)
+ return true
+ }
+ found := addFilenameFromPos(err.Pos)
+ // In some cases, go list only reports the error position in the
+ // error text, not the error position. One such case is when the
+ // file's package name is a keyword (see golang.org/issue/39763).
+ if !found {
+ addFilenameFromPos(err.Err)
+ }
+ }
+
if p.Error != nil {
msg := strings.TrimSpace(p.Error.Err) // Trim to work around golang.org/issue/32363.
// Address golang.org/issue/35964 by appending import stack to error message.
@@ -636,6 +701,58 @@ func (state *golistState) createDriverResponse(words ...string) (*driverResponse
return &response, nil
}
+func (state *golistState) shouldAddFilenameFromError(p *jsonPackage) bool {
+ if len(p.GoFiles) > 0 || len(p.CompiledGoFiles) > 0 {
+ return false
+ }
+
+ goV, err := state.getGoVersion()
+ if err != nil {
+ return false
+ }
+
+ // On Go 1.14 and earlier, only add filenames from errors if the import stack is empty.
+ // The import stack behaves differently for these versions than newer Go versions.
+ if strings.HasPrefix(goV, "go1.13") || strings.HasPrefix(goV, "go1.14") {
+ return len(p.Error.ImportStack) == 0
+ }
+
+ // On Go 1.15 and later, only parse filenames out of error if there's no import stack,
+ // or the current package is at the top of the import stack. This is not guaranteed
+ // to work perfectly, but should avoid some cases where files in errors don't belong to this
+ // package.
+ return len(p.Error.ImportStack) == 0 || p.Error.ImportStack[len(p.Error.ImportStack)-1] == p.ImportPath
+}
+
+func (state *golistState) getGoVersion() (string, error) {
+ state.goVersionOnce.Do(func() {
+ var b *bytes.Buffer
+ // Invoke go version. Don't use invokeGo because it will supply build flags, and
+ // go version doesn't expect build flags.
+ inv := gocommand.Invocation{
+ Verb: "version",
+ Env: state.cfg.Env,
+ Logf: state.cfg.Logf,
+ }
+ gocmdRunner := state.cfg.gocmdRunner
+ if gocmdRunner == nil {
+ gocmdRunner = &gocommand.Runner{}
+ }
+ b, _, _, state.goVersionError = gocmdRunner.RunRaw(state.cfg.Context, inv)
+ if state.goVersionError != nil {
+ return
+ }
+
+ sp := strings.Split(b.String(), " ")
+ if len(sp) < 3 {
+ state.goVersionError = fmt.Errorf("go version output: expected 'go version <version>', got '%s'", b.String())
+ return
+ }
+ state.goVersion = sp[2]
+ })
+ return state.goVersion, state.goVersionError
+}
+
// getPkgPath finds the package path of a directory if it's relative to a root directory.
func (state *golistState) getPkgPath(dir string) (string, bool, error) {
absDir, err := filepath.Abs(dir)
@@ -707,7 +824,7 @@ func golistargs(cfg *Config, words []string) []string {
func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, error) {
cfg := state.cfg
- inv := &gocommand.Invocation{
+ inv := gocommand.Invocation{
Verb: verb,
Args: args,
BuildFlags: cfg.BuildFlags,
@@ -715,8 +832,11 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer,
Logf: cfg.Logf,
WorkingDir: cfg.Dir,
}
-
- stdout, stderr, _, err := inv.RunRaw(cfg.Context)
+ gocmdRunner := cfg.gocmdRunner
+ if gocmdRunner == nil {
+ gocmdRunner = &gocommand.Runner{}
+ }
+ stdout, stderr, _, err := gocmdRunner.RunRaw(cfg.Context, inv)
if err != nil {
// Check for 'go' executable not being found.
if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound {
@@ -727,7 +847,7 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer,
if !ok {
// Catastrophic error:
// - context cancellation
- return nil, fmt.Errorf("couldn't run 'go': %v", err)
+ return nil, xerrors.Errorf("couldn't run 'go': %w", err)
}
// Old go version?
diff --git a/vendor/golang.org/x/tools/go/packages/golist_overlay.go b/vendor/golang.org/x/tools/go/packages/golist_overlay.go
index 7974a6c9bb..4eabfd98c6 100644
--- a/vendor/golang.org/x/tools/go/packages/golist_overlay.go
+++ b/vendor/golang.org/x/tools/go/packages/golist_overlay.go
@@ -5,6 +5,7 @@ import (
"fmt"
"go/parser"
"go/token"
+ "log"
"os"
"path/filepath"
"sort"
@@ -22,10 +23,15 @@ func (state *golistState) processGolistOverlay(response *responseDeduper) (modif
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
+ x := commonDir(pkg.GoFiles)
+ if x != "" {
+ pkgOfDir[x] = append(pkgOfDir[x], pkg)
+ }
}
// If no new imports are added, it is safe to avoid loading any needPkgs.
@@ -64,6 +70,9 @@ func (state *golistState) processGolistOverlay(response *responseDeduper) (modif
// 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" {
@@ -93,8 +102,11 @@ func (state *golistState) processGolistOverlay(response *responseDeduper) (modif
}
}
}
- // The overlay could have included an entirely new package.
- if pkg == nil {
+ // 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)
@@ -104,34 +116,53 @@ func (state *golistState) processGolistOverlay(response *responseDeduper) (modif
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 && !isXTest {
- id = fmt.Sprintf("%s [%s.test]", pkgPath, pkgPath)
- }
- // 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
+ if isTestFile {
+ if isXTest {
+ id = fmt.Sprintf("%s [%s.test]", pkgPath, forTest)
+ } else {
+ id = fmt.Sprintf("%s [%s.test]", pkgPath, pkgPath)
}
}
- // 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 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
}
}
}
@@ -149,6 +180,8 @@ func (state *golistState) processGolistOverlay(response *responseDeduper) (modif
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
}
@@ -282,7 +315,17 @@ func (state *golistState) determineRootDirs() (map[string]string, error) {
}
func (state *golistState) determineRootDirsModules() (map[string]string, error) {
- out, err := state.invokeGo("list", "-m", "-json", "all")
+ // This will only return the root directory for the main module.
+ // For now we only support overlays in main modules.
+ // Editing files in the module cache isn't a great idea, so we don't
+ // plan to ever support that, but editing files in replaced modules
+ // is something we may want to support. To do that, we'll want to
+ // do a go list -m to determine the replaced module's module path and
+ // directory, and then a go list -m {{with .Replace}}{{.Dir}}{{end}} <replaced module's path>
+ // from the main module to determine if that module is actually a replacement.
+ // See bcmills's comment here: https://github.com/golang/go/issues/37629#issuecomment-594179751
+ // for more information.
+ out, err := state.invokeGo("list", "-m", "-json")
if err != nil {
return nil, err
}
@@ -374,3 +417,57 @@ func extractPackageName(filename string, contents []byte) (string, bool) {
}
return f.Name.Name, true
}
+
+func commonDir(a []string) string {
+ seen := make(map[string]bool)
+ x := append([]string{}, a...)
+ for _, f := range x {
+ seen[filepath.Dir(f)] = true
+ }
+ if len(seen) > 1 {
+ log.Fatalf("commonDir saw %v for %v", seen, x)
+ }
+ for k := range seen {
+ // len(seen) == 1
+ return k
+ }
+ return "" // 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
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/packages/loadmode_string.go b/vendor/golang.org/x/tools/go/packages/loadmode_string.go
index aff94a3fe9..7ea37e7eea 100644
--- a/vendor/golang.org/x/tools/go/packages/loadmode_string.go
+++ b/vendor/golang.org/x/tools/go/packages/loadmode_string.go
@@ -38,7 +38,7 @@ var modeStrings = []string{
func (mod LoadMode) String() string {
m := mod
if m == 0 {
- return fmt.Sprintf("LoadMode(0)")
+ return "LoadMode(0)"
}
var out []string
for i, x := range allModes {
diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go
index 1ac6558c1d..04053f1e7d 100644
--- a/vendor/golang.org/x/tools/go/packages/packages.go
+++ b/vendor/golang.org/x/tools/go/packages/packages.go
@@ -21,9 +21,12 @@ import (
"path/filepath"
"strings"
"sync"
+ "time"
"golang.org/x/tools/go/gcexportdata"
+ "golang.org/x/tools/internal/gocommand"
"golang.org/x/tools/internal/packagesinternal"
+ "golang.org/x/tools/internal/typesinternal"
)
// A LoadMode controls the amount of detail to return when loading.
@@ -69,6 +72,13 @@ const (
// NeedTypesSizes adds TypesSizes.
NeedTypesSizes
+
+ // typecheckCgo enables full support for type checking cgo. Requires Go 1.15+.
+ // Modifies CompiledGoFiles and Types, and has no effect on its own.
+ typecheckCgo
+
+ // NeedModule adds Module.
+ NeedModule
)
const (
@@ -127,6 +137,9 @@ type Config struct {
//
Env []string
+ // gocmdRunner guards go command calls from concurrency errors.
+ gocmdRunner *gocommand.Runner
+
// BuildFlags is a list of command-line flags to be passed through to
// the build system's query tool.
BuildFlags []string
@@ -178,6 +191,13 @@ type driver func(cfg *Config, patterns ...string) (*driverResponse, error)
// driverResponse contains the results for a driver query.
type driverResponse struct {
+ // NotHandled is returned if the request can't be handled by the current
+ // driver. If an external driver returns a response with NotHandled, the
+ // rest of the driverResponse is ignored, and go/packages will fallback
+ // to the next driver. If go/packages is extended in the future to support
+ // lists of multiple drivers, go/packages will fall back to the next driver.
+ NotHandled bool
+
// Sizes, if not nil, is the types.Sizes to use when type checking.
Sizes *types.StdSizes
@@ -219,14 +239,22 @@ func Load(cfg *Config, patterns ...string) ([]*Package, error) {
return l.refine(response.Roots, response.Packages...)
}
-// defaultDriver is a driver that looks for an external driver binary, and if
-// it does not find it falls back to the built in go list driver.
+// 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
}
- return driver(cfg, patterns...)
+ response, err := driver(cfg, patterns...)
+ if err != nil {
+ return response, err
+ } else if response.NotHandled {
+ return goListDriver(cfg, patterns...)
+ }
+ return response, nil
}
// A Package describes a loaded Go package.
@@ -253,7 +281,7 @@ type Package struct {
GoFiles []string
// CompiledGoFiles lists the absolute file paths of the package's source
- // files that were presented to the compiler.
+ // files that are suitable for type checking.
// This may differ from GoFiles if files are processed before compilation.
CompiledGoFiles []string
@@ -301,16 +329,39 @@ type Package struct {
forTest string
// module is the module information for the package if it exists.
- module *packagesinternal.Module
+ Module *Module
+}
+
+// Module provides module information for a package.
+type Module struct {
+ Path string // module path
+ Version string // module version
+ Replace *Module // replaced by this module
+ Time *time.Time // time version was created
+ Main bool // is this the main module?
+ Indirect bool // is this module only an indirect dependency of main module?
+ Dir string // directory holding files for this module, if any
+ GoMod string // path to go.mod file used when loading this module, if any
+ GoVersion string // go version used in module
+ Error *ModuleError // error loading module
+}
+
+// ModuleError holds errors loading a module.
+type ModuleError struct {
+ Err string // the error itself
}
func init() {
packagesinternal.GetForTest = func(p interface{}) string {
return p.(*Package).forTest
}
- packagesinternal.GetModule = func(p interface{}) *packagesinternal.Module {
- return p.(*Package).module
+ packagesinternal.GetGoCmdRunner = func(config interface{}) *gocommand.Runner {
+ return config.(*Config).gocmdRunner
}
+ packagesinternal.SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {
+ config.(*Config).gocmdRunner = runner
+ }
+ packagesinternal.TypecheckCgo = int(typecheckCgo)
}
// An Error describes a problem with a package's metadata, syntax, or types.
@@ -473,6 +524,9 @@ func newLoader(cfg *Config) *loader {
if ld.Config.Env == nil {
ld.Config.Env = os.Environ()
}
+ if ld.Config.gocmdRunner == nil {
+ ld.Config.gocmdRunner = &gocommand.Runner{}
+ }
if ld.Context == nil {
ld.Context = context.Background()
}
@@ -690,6 +744,9 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
if ld.requestedMode&NeedTypesSizes == 0 {
ld.pkgs[i].TypesSizes = nil
}
+ if ld.requestedMode&NeedModule == 0 {
+ ld.pkgs[i].Module = nil
+ }
}
return result, nil
@@ -865,6 +922,15 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
Error: appendError,
Sizes: ld.sizes,
}
+ if (ld.Mode & typecheckCgo) != 0 {
+ if !typesinternal.SetUsesCgo(tc) {
+ appendError(Error{
+ Msg: "typecheckCgo requires Go 1.15+",
+ Kind: ListError,
+ })
+ return
+ }
+ }
types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax)
lpkg.importErrors = nil // no longer needed
diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
index 882e3b3d8a..cffd7acbee 100644
--- a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
+++ b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
@@ -226,7 +226,8 @@ func For(obj types.Object) (Path, error) {
// the best paths because non-types may
// refer to types, but not the reverse.
empty := make([]byte, 0, 48) // initial space
- for _, name := range scope.Names() {
+ names := scope.Names()
+ for _, name := range names {
o := scope.Lookup(name)
tname, ok := o.(*types.TypeName)
if !ok {
@@ -253,7 +254,7 @@ func For(obj types.Object) (Path, error) {
// Then inspect everything else:
// non-types, and declared methods of defined types.
- for _, name := range scope.Names() {
+ for _, name := range names {
o := scope.Lookup(name)
path := append(empty, name...)
if _, ok := o.(*types.TypeName); !ok {
diff --git a/vendor/golang.org/x/tools/imports/forward.go b/vendor/golang.org/x/tools/imports/forward.go
index dbe5b49a9f..a4e40adba0 100644
--- a/vendor/golang.org/x/tools/imports/forward.go
+++ b/vendor/golang.org/x/tools/imports/forward.go
@@ -3,10 +3,10 @@
package imports // import "golang.org/x/tools/imports"
import (
- "go/build"
+ "io/ioutil"
"log"
- "os"
+ "golang.org/x/tools/internal/gocommand"
intimp "golang.org/x/tools/internal/imports"
)
@@ -31,31 +31,34 @@ var Debug = false
var LocalPrefix string
// Process formats and adjusts imports for the provided file.
-// If opt is nil the defaults are used.
+// If opt is nil the defaults are used, and if src is nil the source
+// is read from the filesystem.
//
// Note that filename's directory influences which imports can be chosen,
// so it is important that filename be accurate.
// To process data ``as if'' it were in filename, pass the data as a non-nil src.
func Process(filename string, src []byte, opt *Options) ([]byte, error) {
+ var err error
+ if src == nil {
+ src, err = ioutil.ReadFile(filename)
+ if err != nil {
+ return nil, err
+ }
+ }
if opt == nil {
opt = &Options{Comments: true, TabIndent: true, TabWidth: 8}
}
intopt := &intimp.Options{
Env: &intimp.ProcessEnv{
- GOPATH: build.Default.GOPATH,
- GOROOT: build.Default.GOROOT,
- GOFLAGS: os.Getenv("GOFLAGS"),
- GO111MODULE: os.Getenv("GO111MODULE"),
- GOPROXY: os.Getenv("GOPROXY"),
- GOSUMDB: os.Getenv("GOSUMDB"),
- LocalPrefix: LocalPrefix,
+ GocmdRunner: &gocommand.Runner{},
},
- AllErrors: opt.AllErrors,
- Comments: opt.Comments,
- FormatOnly: opt.FormatOnly,
- Fragment: opt.Fragment,
- TabIndent: opt.TabIndent,
- TabWidth: opt.TabWidth,
+ LocalPrefix: LocalPrefix,
+ AllErrors: opt.AllErrors,
+ Comments: opt.Comments,
+ FormatOnly: opt.FormatOnly,
+ Fragment: opt.Fragment,
+ TabIndent: opt.TabIndent,
+ TabWidth: opt.TabWidth,
}
if Debug {
intopt.Env.Logf = log.Printf
diff --git a/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go b/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go
new file mode 100644
index 0000000000..e25f4a4096
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go
@@ -0,0 +1,421 @@
+// Copyright 2020 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 analysisinternal exposes internal-only fields from go/analysis.
+package analysisinternal
+
+import (
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/token"
+ "go/types"
+ "strings"
+
+ "golang.org/x/tools/go/ast/astutil"
+ "golang.org/x/tools/internal/lsp/fuzzy"
+)
+
+var (
+ GetTypeErrors func(p interface{}) []types.Error
+ SetTypeErrors func(p interface{}, errors []types.Error)
+)
+
+func TypeErrorEndPos(fset *token.FileSet, src []byte, start token.Pos) token.Pos {
+ // Get the end position for the type error.
+ offset, end := fset.PositionFor(start, false).Offset, start
+ if offset >= len(src) {
+ return end
+ }
+ if width := bytes.IndexAny(src[offset:], " \n,():;[]+-*"); width > 0 {
+ end = start + token.Pos(width)
+ }
+ return end
+}
+
+func ZeroValue(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Type) ast.Expr {
+ under := typ
+ if n, ok := typ.(*types.Named); ok {
+ under = n.Underlying()
+ }
+ switch u := under.(type) {
+ case *types.Basic:
+ switch {
+ case u.Info()&types.IsNumeric != 0:
+ return &ast.BasicLit{Kind: token.INT, Value: "0"}
+ case u.Info()&types.IsBoolean != 0:
+ return &ast.Ident{Name: "false"}
+ case u.Info()&types.IsString != 0:
+ return &ast.BasicLit{Kind: token.STRING, Value: `""`}
+ default:
+ panic("unknown basic type")
+ }
+ case *types.Chan, *types.Interface, *types.Map, *types.Pointer, *types.Signature, *types.Slice, *types.Array:
+ return ast.NewIdent("nil")
+ case *types.Struct:
+ texpr := TypeExpr(fset, f, pkg, typ) // typ because we want the name here.
+ if texpr == nil {
+ return nil
+ }
+ return &ast.CompositeLit{
+ Type: texpr,
+ }
+ }
+ return nil
+}
+
+// IsZeroValue checks whether the given expression is a 'zero value' (as determined by output of
+// analysisinternal.ZeroValue)
+func IsZeroValue(expr ast.Expr) bool {
+ switch e := expr.(type) {
+ case *ast.BasicLit:
+ return e.Value == "0" || e.Value == `""`
+ case *ast.Ident:
+ return e.Name == "nil" || e.Name == "false"
+ default:
+ return false
+ }
+}
+
+func TypeExpr(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Type) ast.Expr {
+ switch t := typ.(type) {
+ case *types.Basic:
+ switch t.Kind() {
+ case types.UnsafePointer:
+ return &ast.SelectorExpr{X: ast.NewIdent("unsafe"), Sel: ast.NewIdent("Pointer")}
+ default:
+ return ast.NewIdent(t.Name())
+ }
+ case *types.Pointer:
+ x := TypeExpr(fset, f, pkg, t.Elem())
+ if x == nil {
+ return nil
+ }
+ return &ast.UnaryExpr{
+ Op: token.MUL,
+ X: x,
+ }
+ case *types.Array:
+ elt := TypeExpr(fset, f, pkg, t.Elem())
+ if elt == nil {
+ return nil
+ }
+ return &ast.ArrayType{
+ Len: &ast.BasicLit{
+ Kind: token.INT,
+ Value: fmt.Sprintf("%d", t.Len()),
+ },
+ Elt: elt,
+ }
+ case *types.Slice:
+ elt := TypeExpr(fset, f, pkg, t.Elem())
+ if elt == nil {
+ return nil
+ }
+ return &ast.ArrayType{
+ Elt: elt,
+ }
+ case *types.Map:
+ key := TypeExpr(fset, f, pkg, t.Key())
+ value := TypeExpr(fset, f, pkg, t.Elem())
+ if key == nil || value == nil {
+ return nil
+ }
+ return &ast.MapType{
+ Key: key,
+ Value: value,
+ }
+ case *types.Chan:
+ dir := ast.ChanDir(t.Dir())
+ if t.Dir() == types.SendRecv {
+ dir = ast.SEND | ast.RECV
+ }
+ value := TypeExpr(fset, f, pkg, t.Elem())
+ if value == nil {
+ return nil
+ }
+ return &ast.ChanType{
+ Dir: dir,
+ Value: value,
+ }
+ case *types.Signature:
+ var params []*ast.Field
+ for i := 0; i < t.Params().Len(); i++ {
+ p := TypeExpr(fset, f, pkg, t.Params().At(i).Type())
+ if p == nil {
+ return nil
+ }
+ params = append(params, &ast.Field{
+ Type: p,
+ Names: []*ast.Ident{
+ {
+ Name: t.Params().At(i).Name(),
+ },
+ },
+ })
+ }
+ var returns []*ast.Field
+ for i := 0; i < t.Results().Len(); i++ {
+ r := TypeExpr(fset, f, pkg, t.Results().At(i).Type())
+ if r == nil {
+ return nil
+ }
+ returns = append(returns, &ast.Field{
+ Type: r,
+ })
+ }
+ return &ast.FuncType{
+ Params: &ast.FieldList{
+ List: params,
+ },
+ Results: &ast.FieldList{
+ List: returns,
+ },
+ }
+ case *types.Named:
+ if t.Obj().Pkg() == nil {
+ return ast.NewIdent(t.Obj().Name())
+ }
+ if t.Obj().Pkg() == pkg {
+ return ast.NewIdent(t.Obj().Name())
+ }
+ pkgName := t.Obj().Pkg().Name()
+ // If the file already imports the package under another name, use that.
+ for _, group := range astutil.Imports(fset, f) {
+ for _, cand := range group {
+ if strings.Trim(cand.Path.Value, `"`) == t.Obj().Pkg().Path() {
+ if cand.Name != nil && cand.Name.Name != "" {
+ pkgName = cand.Name.Name
+ }
+ }
+ }
+ }
+ if pkgName == "." {
+ return ast.NewIdent(t.Obj().Name())
+ }
+ return &ast.SelectorExpr{
+ X: ast.NewIdent(pkgName),
+ Sel: ast.NewIdent(t.Obj().Name()),
+ }
+ default:
+ return nil // TODO: anonymous structs, but who does that
+ }
+}
+
+type TypeErrorPass string
+
+const (
+ NoNewVars TypeErrorPass = "nonewvars"
+ NoResultValues TypeErrorPass = "noresultvalues"
+ UndeclaredName TypeErrorPass = "undeclaredname"
+)
+
+// StmtToInsertVarBefore returns the ast.Stmt before which we can safely insert a new variable.
+// Some examples:
+//
+// Basic Example:
+// z := 1
+// y := z + x
+// If x is undeclared, then this function would return `y := z + x`, so that we
+// can insert `x := ` on the line before `y := z + x`.
+//
+// If stmt example:
+// if z == 1 {
+// } else if z == y {}
+// If y is undeclared, then this function would return `if z == 1 {`, because we cannot
+// insert a statement between an if and an else if statement. As a result, we need to find
+// the top of the if chain to insert `y := ` before.
+func StmtToInsertVarBefore(path []ast.Node) ast.Stmt {
+ enclosingIndex := -1
+ for i, p := range path {
+ if _, ok := p.(ast.Stmt); ok {
+ enclosingIndex = i
+ break
+ }
+ }
+ if enclosingIndex == -1 {
+ return nil
+ }
+ enclosingStmt := path[enclosingIndex]
+ switch enclosingStmt.(type) {
+ case *ast.IfStmt:
+ // The enclosingStmt is inside of the if declaration,
+ // We need to check if we are in an else-if stmt and
+ // get the base if statement.
+ return baseIfStmt(path, enclosingIndex)
+ case *ast.CaseClause:
+ // Get the enclosing switch stmt if the enclosingStmt is
+ // inside of the case statement.
+ for i := enclosingIndex + 1; i < len(path); i++ {
+ if node, ok := path[i].(*ast.SwitchStmt); ok {
+ return node
+ } else if node, ok := path[i].(*ast.TypeSwitchStmt); ok {
+ return node
+ }
+ }
+ }
+ if len(path) <= enclosingIndex+1 {
+ return enclosingStmt.(ast.Stmt)
+ }
+ // Check if the enclosing statement is inside another node.
+ switch expr := path[enclosingIndex+1].(type) {
+ case *ast.IfStmt:
+ // Get the base if statement.
+ return baseIfStmt(path, enclosingIndex+1)
+ case *ast.ForStmt:
+ if expr.Init == enclosingStmt || expr.Post == enclosingStmt {
+ return expr
+ }
+ }
+ return enclosingStmt.(ast.Stmt)
+}
+
+// baseIfStmt walks up the if/else-if chain until we get to
+// the top of the current if chain.
+func baseIfStmt(path []ast.Node, index int) ast.Stmt {
+ stmt := path[index]
+ for i := index + 1; i < len(path); i++ {
+ if node, ok := path[i].(*ast.IfStmt); ok && node.Else == stmt {
+ stmt = node
+ continue
+ }
+ break
+ }
+ return stmt.(ast.Stmt)
+}
+
+// WalkASTWithParent walks the AST rooted at n. The semantics are
+// similar to ast.Inspect except it does not call f(nil).
+func WalkASTWithParent(n ast.Node, f func(n ast.Node, parent ast.Node) bool) {
+ var ancestors []ast.Node
+ ast.Inspect(n, func(n ast.Node) (recurse bool) {
+ if n == nil {
+ ancestors = ancestors[:len(ancestors)-1]
+ return false
+ }
+
+ var parent ast.Node
+ if len(ancestors) > 0 {
+ parent = ancestors[len(ancestors)-1]
+ }
+ ancestors = append(ancestors, n)
+ return f(n, parent)
+ })
+}
+
+// FindMatchingIdents finds all identifiers in 'node' that match any of the given types.
+// 'pos' represents the position at which the identifiers may be inserted. 'pos' must be within
+// the scope of each of identifier we select. Otherwise, we will insert a variable at 'pos' that
+// is unrecognized.
+func FindMatchingIdents(typs []types.Type, node ast.Node, pos token.Pos, info *types.Info, pkg *types.Package) map[types.Type][]*ast.Ident {
+ matches := map[types.Type][]*ast.Ident{}
+ // Initialize matches to contain the variable types we are searching for.
+ for _, typ := range typs {
+ if typ == nil {
+ continue
+ }
+ matches[typ] = []*ast.Ident{}
+ }
+ seen := map[types.Object]struct{}{}
+ ast.Inspect(node, func(n ast.Node) bool {
+ if n == nil {
+ return false
+ }
+ // Prevent circular definitions. If 'pos' is within an assignment statement, do not
+ // allow any identifiers in that assignment statement to be selected. Otherwise,
+ // we could do the following, where 'x' satisfies the type of 'f0':
+ //
+ // x := fakeStruct{f0: x}
+ //
+ assignment, ok := n.(*ast.AssignStmt)
+ if ok && pos > assignment.Pos() && pos <= assignment.End() {
+ return false
+ }
+ if n.End() > pos {
+ return n.Pos() <= pos
+ }
+ ident, ok := n.(*ast.Ident)
+ if !ok || ident.Name == "_" {
+ return true
+ }
+ obj := info.Defs[ident]
+ if obj == nil || obj.Type() == nil {
+ return true
+ }
+ if _, ok := obj.(*types.TypeName); ok {
+ return true
+ }
+ // Prevent duplicates in matches' values.
+ if _, ok = seen[obj]; ok {
+ return true
+ }
+ seen[obj] = struct{}{}
+ // Find the scope for the given position. Then, check whether the object
+ // exists within the scope.
+ innerScope := pkg.Scope().Innermost(pos)
+ if innerScope == nil {
+ return true
+ }
+ _, foundObj := innerScope.LookupParent(ident.Name, pos)
+ if foundObj != obj {
+ return true
+ }
+ // The object must match one of the types that we are searching for.
+ if idents, ok := matches[obj.Type()]; ok {
+ matches[obj.Type()] = append(idents, ast.NewIdent(ident.Name))
+ }
+ // If the object type does not exactly match any of the target types, greedily
+ // find the first target type that the object type can satisfy.
+ for typ := range matches {
+ if obj.Type() == typ {
+ continue
+ }
+ if equivalentTypes(obj.Type(), typ) {
+ matches[typ] = append(matches[typ], ast.NewIdent(ident.Name))
+ }
+ }
+ return true
+ })
+ return matches
+}
+
+func equivalentTypes(want, got types.Type) bool {
+ if want == got || types.Identical(want, got) {
+ return true
+ }
+ // Code segment to help check for untyped equality from (golang/go#32146).
+ if rhs, ok := want.(*types.Basic); ok && rhs.Info()&types.IsUntyped > 0 {
+ if lhs, ok := got.Underlying().(*types.Basic); ok {
+ return rhs.Info()&types.IsConstType == lhs.Info()&types.IsConstType
+ }
+ }
+ return types.AssignableTo(want, got)
+}
+
+// FindBestMatch employs fuzzy matching to evaluate the similarity of each given identifier to the
+// given pattern. We return the identifier whose name is most similar to the pattern.
+func FindBestMatch(pattern string, idents []*ast.Ident) ast.Expr {
+ fuzz := fuzzy.NewMatcher(pattern)
+ var bestFuzz ast.Expr
+ highScore := float32(-1) // minimum score is -1 (no match)
+ for _, ident := range idents {
+ // TODO: Improve scoring algorithm.
+ score := fuzz.Score(ident.Name)
+ if score > highScore {
+ highScore = score
+ bestFuzz = ident
+ } else if score == -1 {
+ // Order matters in the fuzzy matching algorithm. If we find no match
+ // when matching the target to the identifier, try matching the identifier
+ // to the target.
+ revFuzz := fuzzy.NewMatcher(ident.Name)
+ revScore := revFuzz.Score(pattern)
+ if revScore > highScore {
+ highScore = revScore
+ bestFuzz = ident
+ }
+ }
+ }
+ return bestFuzz
+}
diff --git a/vendor/golang.org/x/tools/internal/event/core/event.go b/vendor/golang.org/x/tools/internal/event/core/event.go
new file mode 100644
index 0000000000..e37b494915
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/core/event.go
@@ -0,0 +1,85 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package core provides support for event based telemetry.
+package core
+
+import (
+ "fmt"
+ "time"
+
+ "golang.org/x/tools/internal/event/label"
+)
+
+// Event holds the information about an event of note that ocurred.
+type Event struct {
+ at time.Time
+
+ // As events are often on the stack, storing the first few labels directly
+ // in the event can avoid an allocation at all for the very common cases of
+ // simple events.
+ // The length needs to be large enough to cope with the majority of events
+ // but no so large as to cause undue stack pressure.
+ // A log message with two values will use 3 labels (one for each value and
+ // one for the message itself).
+
+ static [3]label.Label // inline storage for the first few labels
+ dynamic []label.Label // dynamically sized storage for remaining labels
+}
+
+// eventLabelMap implements label.Map for a the labels of an Event.
+type eventLabelMap struct {
+ event Event
+}
+
+func (ev Event) At() time.Time { return ev.at }
+
+func (ev Event) Format(f fmt.State, r rune) {
+ if !ev.at.IsZero() {
+ fmt.Fprint(f, ev.at.Format("2006/01/02 15:04:05 "))
+ }
+ for index := 0; ev.Valid(index); index++ {
+ if l := ev.Label(index); l.Valid() {
+ fmt.Fprintf(f, "\n\t%v", l)
+ }
+ }
+}
+
+func (ev Event) Valid(index int) bool {
+ return index >= 0 && index < len(ev.static)+len(ev.dynamic)
+}
+
+func (ev Event) Label(index int) label.Label {
+ if index < len(ev.static) {
+ return ev.static[index]
+ }
+ return ev.dynamic[index-len(ev.static)]
+}
+
+func (ev Event) Find(key label.Key) label.Label {
+ for _, l := range ev.static {
+ if l.Key() == key {
+ return l
+ }
+ }
+ for _, l := range ev.dynamic {
+ if l.Key() == key {
+ return l
+ }
+ }
+ return label.Label{}
+}
+
+func MakeEvent(static [3]label.Label, labels []label.Label) Event {
+ return Event{
+ static: static,
+ dynamic: labels,
+ }
+}
+
+// CloneEvent event returns a copy of the event with the time adjusted to at.
+func CloneEvent(ev Event, at time.Time) Event {
+ ev.at = at
+ return ev
+}
diff --git a/vendor/golang.org/x/tools/internal/event/core/export.go b/vendor/golang.org/x/tools/internal/event/core/export.go
new file mode 100644
index 0000000000..05f3a9a579
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/core/export.go
@@ -0,0 +1,70 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package core
+
+import (
+ "context"
+ "sync/atomic"
+ "time"
+ "unsafe"
+
+ "golang.org/x/tools/internal/event/label"
+)
+
+// Exporter is a function that handles events.
+// It may return a modified context and event.
+type Exporter func(context.Context, Event, label.Map) context.Context
+
+var (
+ exporter unsafe.Pointer
+)
+
+// SetExporter sets the global exporter function that handles all events.
+// The exporter is called synchronously from the event call site, so it should
+// return quickly so as not to hold up user code.
+func SetExporter(e Exporter) {
+ p := unsafe.Pointer(&e)
+ if e == nil {
+ // &e is always valid, and so p is always valid, but for the early abort
+ // of ProcessEvent to be efficient it needs to make the nil check on the
+ // pointer without having to dereference it, so we make the nil function
+ // also a nil pointer
+ p = nil
+ }
+ atomic.StorePointer(&exporter, p)
+}
+
+// deliver is called to deliver an event to the supplied exporter.
+// it will fill in the time.
+func deliver(ctx context.Context, exporter Exporter, ev Event) context.Context {
+ // add the current time to the event
+ ev.at = time.Now()
+ // hand the event off to the current exporter
+ return exporter(ctx, ev, ev)
+}
+
+// Export is called to deliver an event to the global exporter if set.
+func Export(ctx context.Context, ev Event) context.Context {
+ // get the global exporter and abort early if there is not one
+ exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
+ if exporterPtr == nil {
+ return ctx
+ }
+ return deliver(ctx, *exporterPtr, ev)
+}
+
+// ExportPair is called to deliver a start event to the supplied exporter.
+// It also returns a function that will deliver the end event to the same
+// exporter.
+// It will fill in the time.
+func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) {
+ // get the global exporter and abort early if there is not one
+ exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
+ if exporterPtr == nil {
+ return ctx, func() {}
+ }
+ ctx = deliver(ctx, *exporterPtr, begin)
+ return ctx, func() { deliver(ctx, *exporterPtr, end) }
+}
diff --git a/vendor/golang.org/x/tools/internal/event/core/fast.go b/vendor/golang.org/x/tools/internal/event/core/fast.go
new file mode 100644
index 0000000000..06c1d4615e
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/core/fast.go
@@ -0,0 +1,77 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package core
+
+import (
+ "context"
+
+ "golang.org/x/tools/internal/event/keys"
+ "golang.org/x/tools/internal/event/label"
+)
+
+// Log1 takes a message and one label delivers a log event to the exporter.
+// It is a customized version of Print that is faster and does no allocation.
+func Log1(ctx context.Context, message string, t1 label.Label) {
+ Export(ctx, MakeEvent([3]label.Label{
+ keys.Msg.Of(message),
+ t1,
+ }, nil))
+}
+
+// Log2 takes a message and two labels and delivers a log event to the exporter.
+// It is a customized version of Print that is faster and does no allocation.
+func Log2(ctx context.Context, message string, t1 label.Label, t2 label.Label) {
+ Export(ctx, MakeEvent([3]label.Label{
+ keys.Msg.Of(message),
+ t1,
+ t2,
+ }, nil))
+}
+
+// Metric1 sends a label event to the exporter with the supplied labels.
+func Metric1(ctx context.Context, t1 label.Label) context.Context {
+ return Export(ctx, MakeEvent([3]label.Label{
+ keys.Metric.New(),
+ t1,
+ }, nil))
+}
+
+// Metric2 sends a label event to the exporter with the supplied labels.
+func Metric2(ctx context.Context, t1, t2 label.Label) context.Context {
+ return Export(ctx, MakeEvent([3]label.Label{
+ keys.Metric.New(),
+ t1,
+ t2,
+ }, nil))
+}
+
+// Start1 sends a span start event with the supplied label list to the exporter.
+// It also returns a function that will end the span, which should normally be
+// deferred.
+func Start1(ctx context.Context, name string, t1 label.Label) (context.Context, func()) {
+ return ExportPair(ctx,
+ MakeEvent([3]label.Label{
+ keys.Start.Of(name),
+ t1,
+ }, nil),
+ MakeEvent([3]label.Label{
+ keys.End.New(),
+ }, nil))
+}
+
+// Start2 sends a span start event with the supplied label list to the exporter.
+// It also returns a function that will end the span, which should normally be
+// deferred.
+func Start2(ctx context.Context, name string, t1, t2 label.Label) (context.Context, func()) {
+ return ExportPair(ctx,
+ MakeEvent([3]label.Label{
+ keys.Start.Of(name),
+ t1,
+ t2,
+ }, nil),
+ MakeEvent([3]label.Label{
+ keys.End.New(),
+ }, nil))
+}
diff --git a/vendor/golang.org/x/tools/internal/event/doc.go b/vendor/golang.org/x/tools/internal/event/doc.go
new file mode 100644
index 0000000000..5dc6e6babe
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/doc.go
@@ -0,0 +1,7 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package event provides a set of packages that cover the main
+// concepts of telemetry in an implementation agnostic way.
+package event
diff --git a/vendor/golang.org/x/tools/internal/event/event.go b/vendor/golang.org/x/tools/internal/event/event.go
new file mode 100644
index 0000000000..4d55e577d1
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/event.go
@@ -0,0 +1,127 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package event
+
+import (
+ "context"
+
+ "golang.org/x/tools/internal/event/core"
+ "golang.org/x/tools/internal/event/keys"
+ "golang.org/x/tools/internal/event/label"
+)
+
+// Exporter is a function that handles events.
+// It may return a modified context and event.
+type Exporter func(context.Context, core.Event, label.Map) context.Context
+
+// SetExporter sets the global exporter function that handles all events.
+// The exporter is called synchronously from the event call site, so it should
+// return quickly so as not to hold up user code.
+func SetExporter(e Exporter) {
+ core.SetExporter(core.Exporter(e))
+}
+
+// Log takes a message and a label list and combines them into a single event
+// before delivering them to the exporter.
+func Log(ctx context.Context, message string, labels ...label.Label) {
+ core.Export(ctx, core.MakeEvent([3]label.Label{
+ keys.Msg.Of(message),
+ }, labels))
+}
+
+// IsLog returns true if the event was built by the Log function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsLog(ev core.Event) bool {
+ return ev.Label(0).Key() == keys.Msg
+}
+
+// Error takes a message and a label list and combines them into a single event
+// before delivering them to the exporter. It captures the error in the
+// delivered event.
+func Error(ctx context.Context, message string, err error, labels ...label.Label) {
+ core.Export(ctx, core.MakeEvent([3]label.Label{
+ keys.Msg.Of(message),
+ keys.Err.Of(err),
+ }, labels))
+}
+
+// IsError returns true if the event was built by the Error function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsError(ev core.Event) bool {
+ return ev.Label(0).Key() == keys.Msg &&
+ ev.Label(1).Key() == keys.Err
+}
+
+// Metric sends a label event to the exporter with the supplied labels.
+func Metric(ctx context.Context, labels ...label.Label) {
+ core.Export(ctx, core.MakeEvent([3]label.Label{
+ keys.Metric.New(),
+ }, labels))
+}
+
+// IsMetric returns true if the event was built by the Metric function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsMetric(ev core.Event) bool {
+ return ev.Label(0).Key() == keys.Metric
+}
+
+// Label sends a label event to the exporter with the supplied labels.
+func Label(ctx context.Context, labels ...label.Label) context.Context {
+ return core.Export(ctx, core.MakeEvent([3]label.Label{
+ keys.Label.New(),
+ }, labels))
+}
+
+// IsLabel returns true if the event was built by the Label function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsLabel(ev core.Event) bool {
+ return ev.Label(0).Key() == keys.Label
+}
+
+// Start sends a span start event with the supplied label list to the exporter.
+// It also returns a function that will end the span, which should normally be
+// deferred.
+func Start(ctx context.Context, name string, labels ...label.Label) (context.Context, func()) {
+ return core.ExportPair(ctx,
+ core.MakeEvent([3]label.Label{
+ keys.Start.Of(name),
+ }, labels),
+ core.MakeEvent([3]label.Label{
+ keys.End.New(),
+ }, nil))
+}
+
+// IsStart returns true if the event was built by the Start function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsStart(ev core.Event) bool {
+ return ev.Label(0).Key() == keys.Start
+}
+
+// IsEnd returns true if the event was built by the End function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsEnd(ev core.Event) bool {
+ return ev.Label(0).Key() == keys.End
+}
+
+// Detach returns a context without an associated span.
+// This allows the creation of spans that are not children of the current span.
+func Detach(ctx context.Context) context.Context {
+ return core.Export(ctx, core.MakeEvent([3]label.Label{
+ keys.Detach.New(),
+ }, nil))
+}
+
+// IsDetach returns true if the event was built by the Detach function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsDetach(ev core.Event) bool {
+ return ev.Label(0).Key() == keys.Detach
+}
diff --git a/vendor/golang.org/x/tools/internal/event/keys/keys.go b/vendor/golang.org/x/tools/internal/event/keys/keys.go
new file mode 100644
index 0000000000..a02206e301
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/keys/keys.go
@@ -0,0 +1,564 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package keys
+
+import (
+ "fmt"
+ "io"
+ "math"
+ "strconv"
+
+ "golang.org/x/tools/internal/event/label"
+)
+
+// Value represents a key for untyped values.
+type Value struct {
+ name string
+ description string
+}
+
+// New creates a new Key for untyped values.
+func New(name, description string) *Value {
+ return &Value{name: name, description: description}
+}
+
+func (k *Value) Name() string { return k.name }
+func (k *Value) Description() string { return k.description }
+
+func (k *Value) Format(w io.Writer, buf []byte, l label.Label) {
+ fmt.Fprint(w, k.From(l))
+}
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Value) Get(lm label.Map) interface{} {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return nil
+}
+
+// From can be used to get a value from a Label.
+func (k *Value) From(t label.Label) interface{} { return t.UnpackValue() }
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Value) Of(value interface{}) label.Label { return label.OfValue(k, value) }
+
+// Tag represents a key for tagging labels that have no value.
+// These are used when the existence of the label is the entire information it
+// carries, such as marking events to be of a specific kind, or from a specific
+// package.
+type Tag struct {
+ name string
+ description string
+}
+
+// NewTag creates a new Key for tagging labels.
+func NewTag(name, description string) *Tag {
+ return &Tag{name: name, description: description}
+}
+
+func (k *Tag) Name() string { return k.name }
+func (k *Tag) Description() string { return k.description }
+
+func (k *Tag) Format(w io.Writer, buf []byte, l label.Label) {}
+
+// New creates a new Label with this key.
+func (k *Tag) New() label.Label { return label.OfValue(k, nil) }
+
+// Int represents a key
+type Int struct {
+ name string
+ description string
+}
+
+// NewInt creates a new Key for int values.
+func NewInt(name, description string) *Int {
+ return &Int{name: name, description: description}
+}
+
+func (k *Int) Name() string { return k.name }
+func (k *Int) Description() string { return k.description }
+
+func (k *Int) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Int) Of(v int) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Int) Get(lm label.Map) int {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Int) From(t label.Label) int { return int(t.Unpack64()) }
+
+// Int8 represents a key
+type Int8 struct {
+ name string
+ description string
+}
+
+// NewInt8 creates a new Key for int8 values.
+func NewInt8(name, description string) *Int8 {
+ return &Int8{name: name, description: description}
+}
+
+func (k *Int8) Name() string { return k.name }
+func (k *Int8) Description() string { return k.description }
+
+func (k *Int8) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Int8) Of(v int8) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Int8) Get(lm label.Map) int8 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Int8) From(t label.Label) int8 { return int8(t.Unpack64()) }
+
+// Int16 represents a key
+type Int16 struct {
+ name string
+ description string
+}
+
+// NewInt16 creates a new Key for int16 values.
+func NewInt16(name, description string) *Int16 {
+ return &Int16{name: name, description: description}
+}
+
+func (k *Int16) Name() string { return k.name }
+func (k *Int16) Description() string { return k.description }
+
+func (k *Int16) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Int16) Of(v int16) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Int16) Get(lm label.Map) int16 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Int16) From(t label.Label) int16 { return int16(t.Unpack64()) }
+
+// Int32 represents a key
+type Int32 struct {
+ name string
+ description string
+}
+
+// NewInt32 creates a new Key for int32 values.
+func NewInt32(name, description string) *Int32 {
+ return &Int32{name: name, description: description}
+}
+
+func (k *Int32) Name() string { return k.name }
+func (k *Int32) Description() string { return k.description }
+
+func (k *Int32) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Int32) Of(v int32) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Int32) Get(lm label.Map) int32 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Int32) From(t label.Label) int32 { return int32(t.Unpack64()) }
+
+// Int64 represents a key
+type Int64 struct {
+ name string
+ description string
+}
+
+// NewInt64 creates a new Key for int64 values.
+func NewInt64(name, description string) *Int64 {
+ return &Int64{name: name, description: description}
+}
+
+func (k *Int64) Name() string { return k.name }
+func (k *Int64) Description() string { return k.description }
+
+func (k *Int64) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendInt(buf, k.From(l), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Int64) Of(v int64) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Int64) Get(lm label.Map) int64 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Int64) From(t label.Label) int64 { return int64(t.Unpack64()) }
+
+// UInt represents a key
+type UInt struct {
+ name string
+ description string
+}
+
+// NewUInt creates a new Key for uint values.
+func NewUInt(name, description string) *UInt {
+ return &UInt{name: name, description: description}
+}
+
+func (k *UInt) Name() string { return k.name }
+func (k *UInt) Description() string { return k.description }
+
+func (k *UInt) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *UInt) Of(v uint) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *UInt) Get(lm label.Map) uint {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *UInt) From(t label.Label) uint { return uint(t.Unpack64()) }
+
+// UInt8 represents a key
+type UInt8 struct {
+ name string
+ description string
+}
+
+// NewUInt8 creates a new Key for uint8 values.
+func NewUInt8(name, description string) *UInt8 {
+ return &UInt8{name: name, description: description}
+}
+
+func (k *UInt8) Name() string { return k.name }
+func (k *UInt8) Description() string { return k.description }
+
+func (k *UInt8) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *UInt8) Of(v uint8) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *UInt8) Get(lm label.Map) uint8 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *UInt8) From(t label.Label) uint8 { return uint8(t.Unpack64()) }
+
+// UInt16 represents a key
+type UInt16 struct {
+ name string
+ description string
+}
+
+// NewUInt16 creates a new Key for uint16 values.
+func NewUInt16(name, description string) *UInt16 {
+ return &UInt16{name: name, description: description}
+}
+
+func (k *UInt16) Name() string { return k.name }
+func (k *UInt16) Description() string { return k.description }
+
+func (k *UInt16) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *UInt16) Of(v uint16) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *UInt16) Get(lm label.Map) uint16 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *UInt16) From(t label.Label) uint16 { return uint16(t.Unpack64()) }
+
+// UInt32 represents a key
+type UInt32 struct {
+ name string
+ description string
+}
+
+// NewUInt32 creates a new Key for uint32 values.
+func NewUInt32(name, description string) *UInt32 {
+ return &UInt32{name: name, description: description}
+}
+
+func (k *UInt32) Name() string { return k.name }
+func (k *UInt32) Description() string { return k.description }
+
+func (k *UInt32) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *UInt32) Of(v uint32) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *UInt32) Get(lm label.Map) uint32 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *UInt32) From(t label.Label) uint32 { return uint32(t.Unpack64()) }
+
+// UInt64 represents a key
+type UInt64 struct {
+ name string
+ description string
+}
+
+// NewUInt64 creates a new Key for uint64 values.
+func NewUInt64(name, description string) *UInt64 {
+ return &UInt64{name: name, description: description}
+}
+
+func (k *UInt64) Name() string { return k.name }
+func (k *UInt64) Description() string { return k.description }
+
+func (k *UInt64) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendUint(buf, k.From(l), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *UInt64) Of(v uint64) label.Label { return label.Of64(k, v) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *UInt64) Get(lm label.Map) uint64 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *UInt64) From(t label.Label) uint64 { return t.Unpack64() }
+
+// Float32 represents a key
+type Float32 struct {
+ name string
+ description string
+}
+
+// NewFloat32 creates a new Key for float32 values.
+func NewFloat32(name, description string) *Float32 {
+ return &Float32{name: name, description: description}
+}
+
+func (k *Float32) Name() string { return k.name }
+func (k *Float32) Description() string { return k.description }
+
+func (k *Float32) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendFloat(buf, float64(k.From(l)), 'E', -1, 32))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Float32) Of(v float32) label.Label {
+ return label.Of64(k, uint64(math.Float32bits(v)))
+}
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Float32) Get(lm label.Map) float32 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Float32) From(t label.Label) float32 {
+ return math.Float32frombits(uint32(t.Unpack64()))
+}
+
+// Float64 represents a key
+type Float64 struct {
+ name string
+ description string
+}
+
+// NewFloat64 creates a new Key for int64 values.
+func NewFloat64(name, description string) *Float64 {
+ return &Float64{name: name, description: description}
+}
+
+func (k *Float64) Name() string { return k.name }
+func (k *Float64) Description() string { return k.description }
+
+func (k *Float64) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendFloat(buf, k.From(l), 'E', -1, 64))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Float64) Of(v float64) label.Label {
+ return label.Of64(k, math.Float64bits(v))
+}
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Float64) Get(lm label.Map) float64 {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Float64) From(t label.Label) float64 {
+ return math.Float64frombits(t.Unpack64())
+}
+
+// String represents a key
+type String struct {
+ name string
+ description string
+}
+
+// NewString creates a new Key for int64 values.
+func NewString(name, description string) *String {
+ return &String{name: name, description: description}
+}
+
+func (k *String) Name() string { return k.name }
+func (k *String) Description() string { return k.description }
+
+func (k *String) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendQuote(buf, k.From(l)))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *String) Of(v string) label.Label { return label.OfString(k, v) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *String) Get(lm label.Map) string {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return ""
+}
+
+// From can be used to get a value from a Label.
+func (k *String) From(t label.Label) string { return t.UnpackString() }
+
+// Boolean represents a key
+type Boolean struct {
+ name string
+ description string
+}
+
+// NewBoolean creates a new Key for bool values.
+func NewBoolean(name, description string) *Boolean {
+ return &Boolean{name: name, description: description}
+}
+
+func (k *Boolean) Name() string { return k.name }
+func (k *Boolean) Description() string { return k.description }
+
+func (k *Boolean) Format(w io.Writer, buf []byte, l label.Label) {
+ w.Write(strconv.AppendBool(buf, k.From(l)))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Boolean) Of(v bool) label.Label {
+ if v {
+ return label.Of64(k, 1)
+ }
+ return label.Of64(k, 0)
+}
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Boolean) Get(lm label.Map) bool {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return false
+}
+
+// From can be used to get a value from a Label.
+func (k *Boolean) From(t label.Label) bool { return t.Unpack64() > 0 }
+
+// Error represents a key
+type Error struct {
+ name string
+ description string
+}
+
+// NewError creates a new Key for int64 values.
+func NewError(name, description string) *Error {
+ return &Error{name: name, description: description}
+}
+
+func (k *Error) Name() string { return k.name }
+func (k *Error) Description() string { return k.description }
+
+func (k *Error) Format(w io.Writer, buf []byte, l label.Label) {
+ io.WriteString(w, k.From(l).Error())
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Error) Of(v error) label.Label { return label.OfValue(k, v) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Error) Get(lm label.Map) error {
+ if t := lm.Find(k); t.Valid() {
+ return k.From(t)
+ }
+ return nil
+}
+
+// From can be used to get a value from a Label.
+func (k *Error) From(t label.Label) error {
+ err, _ := t.UnpackValue().(error)
+ return err
+}
diff --git a/vendor/golang.org/x/tools/internal/event/keys/standard.go b/vendor/golang.org/x/tools/internal/event/keys/standard.go
new file mode 100644
index 0000000000..7e95866592
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/keys/standard.go
@@ -0,0 +1,22 @@
+// Copyright 2020 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
+
+var (
+ // Msg is a key used to add message strings to label lists.
+ Msg = NewString("message", "a readable message")
+ // Label is a key used to indicate an event adds labels to the context.
+ Label = NewTag("label", "a label context marker")
+ // Start is used for things like traces that have a name.
+ Start = NewString("start", "span start")
+ // Metric is a key used to indicate an event records metrics.
+ End = NewTag("end", "a span end marker")
+ // Metric is a key used to indicate an event records metrics.
+ Detach = NewTag("detach", "a span detach marker")
+ // Err is a key used to add error values to label lists.
+ Err = NewError("error", "an error that occurred")
+ // Metric is a key used to indicate an event records metrics.
+ Metric = NewTag("metric", "a metric event marker")
+)
diff --git a/vendor/golang.org/x/tools/internal/event/label/label.go b/vendor/golang.org/x/tools/internal/event/label/label.go
new file mode 100644
index 0000000000..b55c12eb25
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/label/label.go
@@ -0,0 +1,213 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package label
+
+import (
+ "fmt"
+ "io"
+ "reflect"
+ "unsafe"
+)
+
+// Key is used as the identity of a Label.
+// Keys are intended to be compared by pointer only, the name should be unique
+// for communicating with external systems, but it is not required or enforced.
+type Key interface {
+ // Name returns the key name.
+ Name() string
+ // Description returns a string that can be used to describe the value.
+ Description() string
+
+ // Format is used in formatting to append the value of the label to the
+ // supplied buffer.
+ // The formatter may use the supplied buf as a scratch area to avoid
+ // allocations.
+ Format(w io.Writer, buf []byte, l Label)
+}
+
+// Label holds a key and value pair.
+// It is normally used when passing around lists of labels.
+type Label struct {
+ key Key
+ packed uint64
+ untyped interface{}
+}
+
+// Map is the interface to a collection of Labels indexed by key.
+type Map interface {
+ // Find returns the label that matches the supplied key.
+ Find(key Key) Label
+}
+
+// List is the interface to something that provides an iterable
+// list of labels.
+// Iteration should start from 0 and continue until Valid returns false.
+type List interface {
+ // Valid returns true if the index is within range for the list.
+ // It does not imply the label at that index will itself be valid.
+ Valid(index int) bool
+ // Label returns the label at the given index.
+ Label(index int) Label
+}
+
+// list implements LabelList for a list of Labels.
+type list struct {
+ labels []Label
+}
+
+// filter wraps a LabelList filtering out specific labels.
+type filter struct {
+ keys []Key
+ underlying List
+}
+
+// listMap implements LabelMap for a simple list of labels.
+type listMap struct {
+ labels []Label
+}
+
+// mapChain implements LabelMap for a list of underlying LabelMap.
+type mapChain struct {
+ maps []Map
+}
+
+// OfValue creates a new label from the key and value.
+// This method is for implementing new key types, label creation should
+// normally be done with the Of method of the key.
+func OfValue(k Key, value interface{}) Label { return Label{key: k, untyped: value} }
+
+// UnpackValue assumes the label was built using LabelOfValue and returns the value
+// that was passed to that constructor.
+// This method is for implementing new key types, for type safety normal
+// access should be done with the From method of the key.
+func (t Label) UnpackValue() interface{} { return t.untyped }
+
+// Of64 creates a new label from a key and a uint64. This is often
+// used for non uint64 values that can be packed into a uint64.
+// This method is for implementing new key types, label creation should
+// normally be done with the Of method of the key.
+func Of64(k Key, v uint64) Label { return Label{key: k, packed: v} }
+
+// Unpack64 assumes the label was built using LabelOf64 and returns the value that
+// was passed to that constructor.
+// This method is for implementing new key types, for type safety normal
+// access should be done with the From method of the key.
+func (t Label) Unpack64() uint64 { return t.packed }
+
+// OfString creates a new label from a key and a string.
+// This method is for implementing new key types, label creation should
+// normally be done with the Of method of the key.
+func OfString(k Key, v string) Label {
+ hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
+ return Label{
+ key: k,
+ packed: uint64(hdr.Len),
+ untyped: unsafe.Pointer(hdr.Data),
+ }
+}
+
+// UnpackString assumes the label was built using LabelOfString and returns the
+// value that was passed to that constructor.
+// This method is for implementing new key types, for type safety normal
+// access should be done with the From method of the key.
+func (t Label) UnpackString() string {
+ var v string
+ hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
+ hdr.Data = uintptr(t.untyped.(unsafe.Pointer))
+ hdr.Len = int(t.packed)
+ return *(*string)(unsafe.Pointer(hdr))
+}
+
+// Valid returns true if the Label is a valid one (it has a key).
+func (t Label) Valid() bool { return t.key != nil }
+
+// Key returns the key of this Label.
+func (t Label) Key() Key { return t.key }
+
+// Format is used for debug printing of labels.
+func (t Label) Format(f fmt.State, r rune) {
+ if !t.Valid() {
+ io.WriteString(f, `nil`)
+ return
+ }
+ io.WriteString(f, t.Key().Name())
+ io.WriteString(f, "=")
+ var buf [128]byte
+ t.Key().Format(f, buf[:0], t)
+}
+
+func (l *list) Valid(index int) bool {
+ return index >= 0 && index < len(l.labels)
+}
+
+func (l *list) Label(index int) Label {
+ return l.labels[index]
+}
+
+func (f *filter) Valid(index int) bool {
+ return f.underlying.Valid(index)
+}
+
+func (f *filter) Label(index int) Label {
+ l := f.underlying.Label(index)
+ for _, f := range f.keys {
+ if l.Key() == f {
+ return Label{}
+ }
+ }
+ return l
+}
+
+func (lm listMap) Find(key Key) Label {
+ for _, l := range lm.labels {
+ if l.Key() == key {
+ return l
+ }
+ }
+ return Label{}
+}
+
+func (c mapChain) Find(key Key) Label {
+ for _, src := range c.maps {
+ l := src.Find(key)
+ if l.Valid() {
+ return l
+ }
+ }
+ return Label{}
+}
+
+var emptyList = &list{}
+
+func NewList(labels ...Label) List {
+ if len(labels) == 0 {
+ return emptyList
+ }
+ return &list{labels: labels}
+}
+
+func Filter(l List, keys ...Key) List {
+ if len(keys) == 0 {
+ return l
+ }
+ return &filter{keys: keys, underlying: l}
+}
+
+func NewMap(labels ...Label) Map {
+ return listMap{labels: labels}
+}
+
+func MergeMaps(srcs ...Map) Map {
+ var nonNil []Map
+ for _, src := range srcs {
+ if src != nil {
+ nonNil = append(nonNil, src)
+ }
+ }
+ if len(nonNil) == 1 {
+ return nonNil[0]
+ }
+ return mapChain{maps: nonNil}
+}
diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go
index 468db40104..f516e17623 100644
--- a/vendor/golang.org/x/tools/internal/gocommand/invoke.go
+++ b/vendor/golang.org/x/tools/internal/gocommand/invoke.go
@@ -1,3 +1,7 @@
+// Copyright 2020 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 gocommand is a helper for calling the go command.
package gocommand
@@ -8,10 +12,119 @@ import (
"io"
"os"
"os/exec"
+ "regexp"
"strings"
+ "sync"
"time"
+
+ "golang.org/x/tools/internal/event"
)
+// An Runner will run go command invocations and serialize
+// them if it sees a concurrency error.
+type Runner struct {
+ // once guards the runner initialization.
+ once sync.Once
+
+ // inFlight tracks available workers.
+ inFlight chan struct{}
+
+ // serialized guards the ability to run a go command serially,
+ // to avoid deadlocks when claiming workers.
+ serialized chan struct{}
+}
+
+const maxInFlight = 10
+
+func (runner *Runner) initialize() {
+ runner.once.Do(func() {
+ runner.inFlight = make(chan struct{}, maxInFlight)
+ runner.serialized = make(chan struct{}, 1)
+ })
+}
+
+// 1.13: go: updates to go.mod needed, but contents have changed
+// 1.14: go: updating go.mod: existing contents have changed since last read
+var modConcurrencyError = regexp.MustCompile(`go:.*go.mod.*contents have changed`)
+
+// Run is a convenience wrapper around RunRaw.
+// It returns only stdout and a "friendly" error.
+func (runner *Runner) Run(ctx context.Context, inv Invocation) (*bytes.Buffer, error) {
+ stdout, _, friendly, _ := runner.RunRaw(ctx, inv)
+ return stdout, friendly
+}
+
+// RunPiped runs the invocation serially, always waiting for any concurrent
+// invocations to complete first.
+func (runner *Runner) RunPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) error {
+ _, err := runner.runPiped(ctx, inv, stdout, stderr)
+ return err
+}
+
+// RunRaw runs the invocation, serializing requests only if they fight over
+// go.mod changes.
+func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) {
+ // Make sure the runner is always initialized.
+ runner.initialize()
+
+ // First, try to run the go command concurrently.
+ 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)
+
+ // Run serially by calling runPiped.
+ stdout.Reset()
+ stderr.Reset()
+ friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr)
+ return stdout, stderr, friendlyErr, err
+}
+
+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()
+ case runner.inFlight <- struct{}{}:
+ defer func() { <-runner.inFlight }()
+ }
+
+ stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
+ friendlyErr, err := inv.runWithFriendlyError(ctx, stdout, stderr)
+ return stdout, stderr, friendlyErr, err
+}
+
+func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) (error, error) {
+ // Make sure the runner is always initialized.
+ runner.initialize()
+
+ // Acquire the serialization lock. This avoids deadlocks between two
+ // runPiped commands.
+ select {
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ case runner.serialized <- struct{}{}:
+ defer func() { <-runner.serialized }()
+ }
+
+ // Wait for all in-progress go commands to return before proceeding,
+ // to avoid load concurrency errors.
+ for i := 0; i < maxInFlight; i++ {
+ select {
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ case runner.inFlight <- struct{}{}:
+ // Make sure we always "return" any workers we took.
+ defer func() { <-runner.inFlight }()
+ }
+ }
+
+ return inv.runWithFriendlyError(ctx, stdout, stderr)
+}
+
// An Invocation represents a call to the go command.
type Invocation struct {
Verb string
@@ -22,20 +135,10 @@ type Invocation struct {
Logf func(format string, args ...interface{})
}
-// Run runs the invocation, returning its stdout and an error suitable for
-// human consumption, including stderr.
-func (i *Invocation) Run(ctx context.Context) (*bytes.Buffer, error) {
- stdout, _, friendly, _ := i.RunRaw(ctx)
- return stdout, friendly
-}
-
-// RunRaw is like RunPiped, but also returns the raw stderr and error for callers
-// that want to do low-level error handling/recovery.
-func (i *Invocation) RunRaw(ctx context.Context) (stdout *bytes.Buffer, stderr *bytes.Buffer, friendlyError error, rawError error) {
- stdout = &bytes.Buffer{}
- stderr = &bytes.Buffer{}
- rawError = i.RunPiped(ctx, stdout, stderr)
+func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io.Writer) (friendlyError error, rawError error) {
+ rawError = i.run(ctx, stdout, stderr)
if rawError != nil {
+ friendlyError = rawError
// Check for 'go' executable not being found.
if ee, ok := rawError.(*exec.Error); ok && ee.Err == exec.ErrNotFound {
friendlyError = fmt.Errorf("go command required, not found: %v", ee)
@@ -43,13 +146,12 @@ func (i *Invocation) RunRaw(ctx context.Context) (stdout *bytes.Buffer, stderr *
if ctx.Err() != nil {
friendlyError = ctx.Err()
}
- friendlyError = fmt.Errorf("err: %v: stderr: %s", rawError, stderr)
+ friendlyError = fmt.Errorf("err: %v: stderr: %s", friendlyError, stderr)
}
return
}
-// RunPiped is like Run, but relies on the given stdout/stderr
-func (i *Invocation) RunPiped(ctx context.Context, stdout, stderr io.Writer) error {
+func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error {
log := i.Logf
if log == nil {
log = func(string, ...interface{}) {}
@@ -78,9 +180,11 @@ func (i *Invocation) RunPiped(ctx context.Context, stdout, stderr io.Writer) err
// The Go stdlib has a special feature where if the cwd and the PWD are the
// same node then it trusts the PWD, so by setting it in the env for the child
// process we fix up all the paths returned by the go command.
- cmd.Env = append(append([]string{}, i.Env...), "PWD="+i.WorkingDir)
- cmd.Dir = i.WorkingDir
-
+ cmd.Env = append(os.Environ(), i.Env...)
+ if i.WorkingDir != "" {
+ cmd.Env = append(cmd.Env, "PWD="+i.WorkingDir)
+ cmd.Dir = i.WorkingDir
+ }
defer func(start time.Time) { log("%s for %v", time.Since(start), cmdDebugStr(cmd)) }(time.Now())
return runCmdContext(ctx, cmd)
diff --git a/vendor/golang.org/x/tools/internal/gocommand/vendor.go b/vendor/golang.org/x/tools/internal/gocommand/vendor.go
new file mode 100644
index 0000000000..1cd8d8473e
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gocommand/vendor.go
@@ -0,0 +1,102 @@
+// Copyright 2020 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 gocommand
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+
+ "golang.org/x/mod/semver"
+)
+
+// ModuleJSON holds information about a module.
+type ModuleJSON struct {
+ Path string // module path
+ Replace *ModuleJSON // replaced by this module
+ Main bool // is this the main module?
+ Indirect bool // is this module only an indirect dependency of main module?
+ Dir string // directory holding files for this module, if any
+ GoMod string // path to go.mod file for this module, if any
+ GoVersion string // go version used in module
+}
+
+var modFlagRegexp = regexp.MustCompile(`-mod[ =](\w+)`)
+
+// VendorEnabled reports whether vendoring is enabled. It takes a *Runner to execute Go commands
+// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields,
+// of which only Verb and Args are modified to run the appropriate Go command.
+// Inspired by setDefaultBuildMod in modload/init.go
+func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) {
+ mainMod, go114, err := getMainModuleAnd114(ctx, inv, r)
+ if err != nil {
+ return nil, false, err
+ }
+
+ // We check the GOFLAGS to see if there is anything overridden or not.
+ inv.Verb = "env"
+ inv.Args = []string{"GOFLAGS"}
+ stdout, err := r.Run(ctx, inv)
+ if err != nil {
+ return nil, false, err
+ }
+ goflags := string(bytes.TrimSpace(stdout.Bytes()))
+ matches := modFlagRegexp.FindStringSubmatch(goflags)
+ var modFlag string
+ if len(matches) != 0 {
+ modFlag = matches[1]
+ }
+ if modFlag != "" {
+ // Don't override an explicit '-mod=' argument.
+ return mainMod, modFlag == "vendor", nil
+ }
+ if mainMod == nil || !go114 {
+ return mainMod, false, nil
+ }
+ // Check 1.14's automatic vendor mode.
+ if fi, err := os.Stat(filepath.Join(mainMod.Dir, "vendor")); err == nil && fi.IsDir() {
+ if mainMod.GoVersion != "" && semver.Compare("v"+mainMod.GoVersion, "v1.14") >= 0 {
+ // The Go version is at least 1.14, and a vendor directory exists.
+ // Set -mod=vendor by default.
+ return mainMod, true, nil
+ }
+ }
+ return mainMod, false, nil
+}
+
+// getMainModuleAnd114 gets the main module's information and whether the
+// go command in use is 1.14+. This is the information needed to figure out
+// if vendoring should be enabled.
+func getMainModuleAnd114(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) {
+ const format = `{{.Path}}
+{{.Dir}}
+{{.GoMod}}
+{{.GoVersion}}
+{{range context.ReleaseTags}}{{if eq . "go1.14"}}{{.}}{{end}}{{end}}
+`
+ inv.Verb = "list"
+ inv.Args = []string{"-m", "-f", format}
+ stdout, err := r.Run(ctx, inv)
+ if err != nil {
+ return nil, false, err
+ }
+
+ lines := strings.Split(stdout.String(), "\n")
+ if len(lines) < 5 {
+ return nil, false, fmt.Errorf("unexpected stdout: %q", stdout.String())
+ }
+ mod := &ModuleJSON{
+ Path: lines[0],
+ Dir: lines[1],
+ GoMod: lines[2],
+ GoVersion: lines[3],
+ Main: true,
+ }
+ return mod, lines[4] == "go1.14", nil
+}
diff --git a/vendor/golang.org/x/tools/internal/gopathwalk/walk.go b/vendor/golang.org/x/tools/internal/gopathwalk/walk.go
index 390cb9db79..925ff53560 100644
--- a/vendor/golang.org/x/tools/internal/gopathwalk/walk.go
+++ b/vendor/golang.org/x/tools/internal/gopathwalk/walk.go
@@ -10,7 +10,6 @@ import (
"bufio"
"bytes"
"fmt"
- "go/build"
"io/ioutil"
"log"
"os"
@@ -47,16 +46,6 @@ type Root struct {
Type RootType
}
-// SrcDirsRoots returns the roots from build.Default.SrcDirs(). Not modules-compatible.
-func SrcDirsRoots(ctx *build.Context) []Root {
- var roots []Root
- roots = append(roots, Root{filepath.Join(ctx.GOROOT, "src"), RootGOROOT})
- for _, p := range filepath.SplitList(ctx.GOPATH) {
- roots = append(roots, Root{filepath.Join(p, "src"), RootGOPATH})
- }
- return roots
-}
-
// Walk walks Go source directories ($GOROOT, $GOPATH, etc) to find packages.
// For each package found, add will be called (concurrently) with the absolute
// paths of the containing source directory and the package directory.
diff --git a/vendor/golang.org/x/tools/internal/imports/fix.go b/vendor/golang.org/x/tools/internal/imports/fix.go
index 92a23439ff..0cb09e26a9 100644
--- a/vendor/golang.org/x/tools/internal/imports/fix.go
+++ b/vendor/golang.org/x/tools/internal/imports/fix.go
@@ -7,6 +7,7 @@ package imports
import (
"bytes"
"context"
+ "encoding/json"
"fmt"
"go/ast"
"go/build"
@@ -31,35 +32,36 @@ import (
// importToGroup is a list of functions which map from an import path to
// a group number.
-var importToGroup = []func(env *ProcessEnv, importPath string) (num int, ok bool){
- func(env *ProcessEnv, importPath string) (num int, ok bool) {
- if env.LocalPrefix == "" {
+var importToGroup = []func(localPrefix, importPath string) (num int, ok bool){
+ func(localPrefix, importPath string) (num int, ok bool) {
+ if localPrefix == "" {
return
}
- for _, p := range strings.Split(env.LocalPrefix, ",") {
+ for _, p := range strings.Split(localPrefix, ",") {
if strings.HasPrefix(importPath, p) || strings.TrimSuffix(p, "/") == importPath {
return 3, true
}
}
return
},
- func(_ *ProcessEnv, importPath string) (num int, ok bool) {
+ func(_, importPath string) (num int, ok bool) {
if strings.HasPrefix(importPath, "appengine") {
return 2, true
}
return
},
- func(_ *ProcessEnv, importPath string) (num int, ok bool) {
- if strings.Contains(importPath, ".") {
+ func(_, importPath string) (num int, ok bool) {
+ firstComponent := strings.Split(importPath, "/")[0]
+ if strings.Contains(firstComponent, ".") {
return 1, true
}
return
},
}
-func importGroup(env *ProcessEnv, importPath string) int {
+func importGroup(localPrefix, importPath string) int {
for _, fn := range importToGroup {
- if n, ok := fn(env, importPath); ok {
+ if n, ok := fn(localPrefix, importPath); ok {
return n
}
}
@@ -276,7 +278,12 @@ func (p *pass) loadPackageNames(imports []*ImportInfo) error {
unknown = append(unknown, imp.ImportPath)
}
- names, err := p.env.GetResolver().loadPackageNames(unknown, p.srcDir)
+ resolver, err := p.env.GetResolver()
+ if err != nil {
+ return err
+ }
+
+ names, err := resolver.loadPackageNames(unknown, p.srcDir)
if err != nil {
return err
}
@@ -566,7 +573,9 @@ func getFixes(fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv
return fixes, nil
}
- addStdlibCandidates(p, p.missingRefs)
+ if err := addStdlibCandidates(p, p.missingRefs); err != nil {
+ return nil, err
+ }
p.assumeSiblingImportsValid()
if fixes, done := p.fix(); done {
return fixes, nil
@@ -594,10 +603,14 @@ func getCandidatePkgs(ctx context.Context, wrappedCallback *scanCallback, filena
notSelf := func(p *pkg) bool {
return p.packageName != filePkg || p.dir != filepath.Dir(filename)
}
+ goenv, err := env.goEnv()
+ if err != nil {
+ return err
+ }
// Start off with the standard library.
for importPath, exports := range stdlib {
p := &pkg{
- dir: filepath.Join(env.GOROOT, "src", importPath),
+ dir: filepath.Join(goenv["GOROOT"], "src", importPath),
importPathShort: importPath,
packageName: path.Base(importPath),
relevance: MaxRelevance,
@@ -638,15 +651,23 @@ func getCandidatePkgs(ctx context.Context, wrappedCallback *scanCallback, filena
wrappedCallback.exportsLoaded(pkg, exports)
},
}
- return env.GetResolver().scan(ctx, scanFilter)
+ resolver, err := env.GetResolver()
+ if err != nil {
+ return err
+ }
+ return resolver.scan(ctx, scanFilter)
}
-func ScoreImportPaths(ctx context.Context, env *ProcessEnv, paths []string) map[string]int {
+func ScoreImportPaths(ctx context.Context, env *ProcessEnv, paths []string) (map[string]int, error) {
result := make(map[string]int)
+ resolver, err := env.GetResolver()
+ if err != nil {
+ return nil, err
+ }
for _, path := range paths {
- result[path] = env.GetResolver().scoreImportPath(ctx, path)
+ result[path] = resolver.scoreImportPath(ctx, path)
}
- return result
+ return result, nil
}
func PrimeCache(ctx context.Context, env *ProcessEnv) error {
@@ -672,8 +693,9 @@ func candidateImportName(pkg *pkg) string {
return ""
}
-// getAllCandidates gets all of the candidates to be imported, regardless of if they are needed.
-func getAllCandidates(ctx context.Context, wrapped func(ImportFix), searchPrefix, filename, filePkg string, env *ProcessEnv) error {
+// GetAllCandidates gets all of the packages starting with prefix that can be
+// imported by filename, sorted by import path.
+func GetAllCandidates(ctx context.Context, wrapped func(ImportFix), searchPrefix, filename, filePkg string, env *ProcessEnv) error {
callback := &scanCallback{
rootFound: func(gopathwalk.Root) bool {
return true
@@ -712,7 +734,8 @@ type PackageExport struct {
Exports []string
}
-func getPackageExports(ctx context.Context, wrapped func(PackageExport), searchPkg, filename, filePkg string, env *ProcessEnv) error {
+// GetPackageExports returns all known packages with name pkg and their exports.
+func GetPackageExports(ctx context.Context, wrapped func(PackageExport), searchPkg, filename, filePkg string, env *ProcessEnv) error {
callback := &scanCallback{
rootFound: func(gopathwalk.Root) bool {
return true
@@ -742,67 +765,126 @@ func getPackageExports(ctx context.Context, wrapped func(PackageExport), searchP
return getCandidatePkgs(ctx, callback, filename, filePkg, env)
}
+var RequiredGoEnvVars = []string{"GO111MODULE", "GOFLAGS", "GOINSECURE", "GOMOD", "GOMODCACHE", "GONOPROXY", "GONOSUMDB", "GOPATH", "GOPROXY", "GOROOT", "GOSUMDB"}
+
// ProcessEnv contains environment variables and settings that affect the use of
// the go command, the go/build package, etc.
type ProcessEnv struct {
- LocalPrefix string
+ GocmdRunner *gocommand.Runner
BuildFlags []string
- // If non-empty, these will be used instead of the
- // process-wide values.
- GOPATH, GOROOT, GO111MODULE, GOPROXY, GOFLAGS, GOSUMDB string
- WorkingDir string
+ // Env overrides the OS environment, and can be used to specify
+ // GOPROXY, GO111MODULE, etc. PATH cannot be set here, because
+ // exec.Command will not honor it.
+ // Specifying all of RequiredGoEnvVars avoids a call to `go env`.
+ Env map[string]string
+
+ WorkingDir string
// If Logf is non-nil, debug logging is enabled through this function.
Logf func(format string, args ...interface{})
+ initialized bool
+
resolver Resolver
}
+func (e *ProcessEnv) goEnv() (map[string]string, error) {
+ if err := e.init(); err != nil {
+ return nil, err
+ }
+ return e.Env, nil
+}
+
+func (e *ProcessEnv) matchFile(dir, name string) (bool, error) {
+ return build.Default.MatchFile(dir, name)
+}
+
// CopyConfig copies the env's configuration into a new env.
func (e *ProcessEnv) CopyConfig() *ProcessEnv {
- copy := *e
- copy.resolver = nil
- return &copy
+ copy := &ProcessEnv{
+ GocmdRunner: e.GocmdRunner,
+ initialized: e.initialized,
+ BuildFlags: e.BuildFlags,
+ Logf: e.Logf,
+ WorkingDir: e.WorkingDir,
+ resolver: nil,
+ Env: map[string]string{},
+ }
+ for k, v := range e.Env {
+ copy.Env[k] = v
+ }
+ return copy
}
-func (e *ProcessEnv) env() []string {
- env := os.Environ()
- add := func(k, v string) {
- if v != "" {
- env = append(env, k+"="+v)
+func (e *ProcessEnv) init() error {
+ if e.initialized {
+ return nil
+ }
+
+ foundAllRequired := true
+ for _, k := range RequiredGoEnvVars {
+ if _, ok := e.Env[k]; !ok {
+ foundAllRequired = false
+ break
}
}
- add("GOPATH", e.GOPATH)
- add("GOROOT", e.GOROOT)
- add("GO111MODULE", e.GO111MODULE)
- add("GOPROXY", e.GOPROXY)
- add("GOFLAGS", e.GOFLAGS)
- add("GOSUMDB", e.GOSUMDB)
- if e.WorkingDir != "" {
- add("PWD", e.WorkingDir)
+ if foundAllRequired {
+ e.initialized = true
+ return nil
+ }
+
+ if e.Env == nil {
+ e.Env = map[string]string{}
+ }
+
+ goEnv := map[string]string{}
+ stdout, err := e.invokeGo(context.TODO(), "env", append([]string{"-json"}, RequiredGoEnvVars...)...)
+ if err != nil {
+ return err
+ }
+ if err := json.Unmarshal(stdout.Bytes(), &goEnv); err != nil {
+ return err
+ }
+ for k, v := range goEnv {
+ e.Env[k] = v
+ }
+ e.initialized = true
+ return nil
+}
+
+func (e *ProcessEnv) env() []string {
+ var env []string // the gocommand package will prepend os.Environ.
+ for k, v := range e.Env {
+ env = append(env, k+"="+v)
}
return env
}
-func (e *ProcessEnv) GetResolver() Resolver {
+func (e *ProcessEnv) GetResolver() (Resolver, error) {
if e.resolver != nil {
- return e.resolver
+ return e.resolver, nil
}
- out, err := e.invokeGo(context.TODO(), "env", "GOMOD")
- if err != nil || len(bytes.TrimSpace(out.Bytes())) == 0 {
+ if err := e.init(); err != nil {
+ return nil, err
+ }
+ if len(e.Env["GOMOD"]) == 0 {
e.resolver = newGopathResolver(e)
- return e.resolver
+ return e.resolver, nil
}
e.resolver = newModuleResolver(e)
- return e.resolver
+ return e.resolver, nil
}
-func (e *ProcessEnv) buildContext() *build.Context {
+func (e *ProcessEnv) buildContext() (*build.Context, error) {
ctx := build.Default
- ctx.GOROOT = e.GOROOT
- ctx.GOPATH = e.GOPATH
+ goenv, err := e.goEnv()
+ if err != nil {
+ return nil, err
+ }
+ ctx.GOROOT = goenv["GOROOT"]
+ ctx.GOPATH = goenv["GOPATH"]
// As of Go 1.14, build.Context has a Dir field
// (see golang.org/issue/34860).
@@ -818,7 +900,7 @@ func (e *ProcessEnv) buildContext() *build.Context {
dir.SetString(e.WorkingDir)
}
- return &ctx
+ return &ctx, nil
}
func (e *ProcessEnv) invokeGo(ctx context.Context, verb string, args ...string) (*bytes.Buffer, error) {
@@ -830,13 +912,17 @@ func (e *ProcessEnv) invokeGo(ctx context.Context, verb string, args ...string)
Logf: e.Logf,
WorkingDir: e.WorkingDir,
}
- return inv.Run(ctx)
+ return e.GocmdRunner.Run(ctx, inv)
}
-func addStdlibCandidates(pass *pass, refs references) {
+func addStdlibCandidates(pass *pass, refs references) error {
+ goenv, err := pass.env.goEnv()
+ if err != nil {
+ return err
+ }
add := func(pkg string) {
// Prevent self-imports.
- if path.Base(pkg) == pass.f.Name.Name && filepath.Join(pass.env.GOROOT, "src", pkg) == pass.srcDir {
+ if path.Base(pkg) == pass.f.Name.Name && filepath.Join(goenv["GOROOT"], "src", pkg) == pass.srcDir {
return
}
exports := copyExports(stdlib[pkg])
@@ -857,6 +943,7 @@ func addStdlibCandidates(pass *pass, refs references) {
}
}
}
+ return nil
}
// A Resolver does the build-system-specific parts of goimports.
@@ -921,10 +1008,13 @@ func addExternalCandidates(pass *pass, refs references, filename string) error {
return false // We'll do our own loading after we sort.
},
}
- err := pass.env.GetResolver().scan(context.Background(), callback)
+ resolver, err := pass.env.GetResolver()
if err != nil {
return err
}
+ if err = resolver.scan(context.Background(), callback); err != nil {
+ return err
+ }
// Search for imports matching potential package references.
type result struct {
@@ -1050,21 +1140,24 @@ func (r *gopathResolver) ClearForNewScan() {
func (r *gopathResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) {
names := map[string]string{}
+ bctx, err := r.env.buildContext()
+ if err != nil {
+ return nil, err
+ }
for _, path := range importPaths {
- names[path] = importPathToName(r.env, path, srcDir)
+ names[path] = importPathToName(bctx, path, srcDir)
}
return names, nil
}
// importPathToName finds out the actual package name, as declared in its .go files.
-// If there's a problem, it returns "".
-func importPathToName(env *ProcessEnv, importPath, srcDir string) (packageName string) {
+func importPathToName(bctx *build.Context, importPath, srcDir string) string {
// Fast path for standard library without going to disk.
if _, ok := stdlib[importPath]; ok {
return path.Base(importPath) // stdlib packages always match their paths.
}
- buildPkg, err := env.buildContext().Import(importPath, srcDir, build.FindOnly)
+ buildPkg, err := bctx.Import(importPath, srcDir, build.FindOnly)
if err != nil {
return ""
}
@@ -1225,8 +1318,18 @@ func (r *gopathResolver) scan(ctx context.Context, callback *scanCallback) error
}
stop := r.cache.ScanAndListen(ctx, processDir)
defer stop()
+
+ goenv, err := r.env.goEnv()
+ if err != nil {
+ return err
+ }
+ var roots []gopathwalk.Root
+ roots = append(roots, gopathwalk.Root{filepath.Join(goenv["GOROOT"], "src"), gopathwalk.RootGOROOT})
+ for _, p := range filepath.SplitList(goenv["GOPATH"]) {
+ roots = append(roots, gopathwalk.Root{filepath.Join(p, "src"), gopathwalk.RootGOPATH})
+ }
// The callback is not necessarily safe to use in the goroutine below. Process roots eagerly.
- roots := filterRoots(gopathwalk.SrcDirsRoots(r.env.buildContext()), callback.rootFound)
+ roots = filterRoots(roots, callback.rootFound)
// We can't cancel walks, because we need them to finish to have a usable
// cache. Instead, run them in a separate goroutine and detach.
scanDone := make(chan struct{})
@@ -1286,8 +1389,6 @@ func VendorlessPath(ipath string) string {
}
func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, dir string, includeTest bool) (string, []string, error) {
- var exports []string
-
// Look for non-test, buildable .go files which could provide exports.
all, err := ioutil.ReadDir(dir)
if err != nil {
@@ -1299,7 +1400,7 @@ func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, dir string, incl
if !strings.HasSuffix(name, ".go") || (!includeTest && strings.HasSuffix(name, "_test.go")) {
continue
}
- match, err := env.buildContext().MatchFile(dir, fi.Name())
+ match, err := env.matchFile(dir, fi.Name())
if err != nil || !match {
continue
}
@@ -1311,6 +1412,7 @@ func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, dir string, incl
}
var pkgName string
+ var exports []string
fset := token.NewFileSet()
for _, fi := range files {
select {
@@ -1322,7 +1424,10 @@ func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, dir string, incl
fullFile := filepath.Join(dir, fi.Name())
f, err := parser.ParseFile(fset, fullFile, nil, 0)
if err != nil {
- return "", nil, fmt.Errorf("parsing %s: %v", fullFile, err)
+ if env.Logf != nil {
+ env.Logf("error parsing %v: %v", fullFile, err)
+ }
+ continue
}
if f.Name.Name == "documentation" {
// Special case from go/build.ImportDir, not
@@ -1362,6 +1467,10 @@ func findImport(ctx context.Context, pass *pass, candidates []pkgDistance, pkgNa
pass.env.Logf("%s candidate %d/%d: %v in %v", pkgName, i+1, len(candidates), c.pkg.importPathShort, c.pkg.dir)
}
}
+ resolver, err := pass.env.GetResolver()
+ if err != nil {
+ return nil, err
+ }
// Collect exports for packages with matching names.
rescv := make([]chan *pkg, len(candidates))
@@ -1400,7 +1509,7 @@ func findImport(ctx context.Context, pass *pass, candidates []pkgDistance, pkgNa
}
// If we're an x_test, load the package under test's test variant.
includeTest := strings.HasSuffix(pass.f.Name.Name, "_test") && c.pkg.dir == pass.srcDir
- _, exports, err := pass.env.GetResolver().loadExports(ctx, c.pkg, includeTest)
+ _, exports, err := resolver.loadExports(ctx, c.pkg, includeTest)
if err != nil {
if pass.env.Logf != nil {
pass.env.Logf("loading exports in dir %s (seeking package %s): %v", c.pkg.dir, pkgName, err)
diff --git a/vendor/golang.org/x/tools/internal/imports/imports.go b/vendor/golang.org/x/tools/internal/imports/imports.go
index b18daea290..2815edc33d 100644
--- a/vendor/golang.org/x/tools/internal/imports/imports.go
+++ b/vendor/golang.org/x/tools/internal/imports/imports.go
@@ -11,17 +11,13 @@ package imports
import (
"bufio"
"bytes"
- "context"
"fmt"
"go/ast"
- "go/build"
"go/format"
"go/parser"
"go/printer"
"go/token"
"io"
- "io/ioutil"
- "os"
"regexp"
"strconv"
"strings"
@@ -33,6 +29,11 @@ import (
type Options struct {
Env *ProcessEnv // The environment to use. Note: this contains the cached module and filesystem state.
+ // LocalPrefix is a comma-separated string of import path prefixes, which, if
+ // set, instructs Process to sort the import paths with the given prefixes
+ // into another group after 3rd-party packages.
+ LocalPrefix string
+
Fragment bool // Accept fragment of a source file (no package statement)
AllErrors bool // Report all errors (not just the first 10 on different lines)
@@ -43,13 +44,8 @@ type Options struct {
FormatOnly bool // Disable the insertion and deletion of imports
}
-// Process implements golang.org/x/tools/imports.Process with explicit context in env.
+// Process implements golang.org/x/tools/imports.Process with explicit context in opt.Env.
func Process(filename string, src []byte, opt *Options) (formatted []byte, err error) {
- src, opt, err = initialize(filename, src, opt)
- if err != nil {
- return nil, err
- }
-
fileSet := token.NewFileSet()
file, adjust, err := parse(fileSet, filename, src, opt)
if err != nil {
@@ -65,16 +61,12 @@ func Process(filename string, src []byte, opt *Options) (formatted []byte, err e
}
// FixImports returns a list of fixes to the imports that, when applied,
-// will leave the imports in the same state as Process.
+// will leave the imports in the same state as Process. src and opt must
+// be specified.
//
// Note that filename's directory influences which imports can be chosen,
// so it is important that filename be accurate.
func FixImports(filename string, src []byte, opt *Options) (fixes []*ImportFix, err error) {
- src, opt, err = initialize(filename, src, opt)
- if err != nil {
- return nil, err
- }
-
fileSet := token.NewFileSet()
file, _, err := parse(fileSet, filename, src, opt)
if err != nil {
@@ -85,13 +77,9 @@ func FixImports(filename string, src []byte, opt *Options) (fixes []*ImportFix,
}
// ApplyFixes applies all of the fixes to the file and formats it. extraMode
-// is added in when parsing the file.
+// is added in when parsing the file. src and opts must be specified, but no
+// env is needed.
func ApplyFixes(fixes []*ImportFix, filename string, src []byte, opt *Options, extraMode parser.Mode) (formatted []byte, err error) {
- src, opt, err = initialize(filename, src, opt)
- if err != nil {
- return nil, err
- }
-
// Don't use parse() -- we don't care about fragments or statement lists
// here, and we need to work with unparseable files.
fileSet := token.NewFileSet()
@@ -115,59 +103,9 @@ func ApplyFixes(fixes []*ImportFix, filename string, src []byte, opt *Options, e
return formatFile(fileSet, file, src, nil, opt)
}
-// GetAllCandidates gets all of the packages starting with prefix that can be
-// imported by filename, sorted by import path.
-func GetAllCandidates(ctx context.Context, callback func(ImportFix), searchPrefix, filename, filePkg string, opt *Options) error {
- _, opt, err := initialize(filename, []byte{}, opt)
- if err != nil {
- return err
- }
- return getAllCandidates(ctx, callback, searchPrefix, filename, filePkg, opt.Env)
-}
-
-// GetPackageExports returns all known packages with name pkg and their exports.
-func GetPackageExports(ctx context.Context, callback func(PackageExport), searchPkg, filename, filePkg string, opt *Options) error {
- _, opt, err := initialize(filename, []byte{}, opt)
- if err != nil {
- return err
- }
- return getPackageExports(ctx, callback, searchPkg, filename, filePkg, opt.Env)
-}
-
-// initialize sets the values for opt and src.
-// If they are provided, they are not changed. Otherwise opt is set to the
-// default values and src is read from the file system.
-func initialize(filename string, src []byte, opt *Options) ([]byte, *Options, error) {
- // Use defaults if opt is nil.
- if opt == nil {
- opt = &Options{Comments: true, TabIndent: true, TabWidth: 8}
- }
-
- // Set the env if the user has not provided it.
- if opt.Env == nil {
- opt.Env = &ProcessEnv{
- GOPATH: build.Default.GOPATH,
- GOROOT: build.Default.GOROOT,
- GOFLAGS: os.Getenv("GOFLAGS"),
- GO111MODULE: os.Getenv("GO111MODULE"),
- GOPROXY: os.Getenv("GOPROXY"),
- GOSUMDB: os.Getenv("GOSUMDB"),
- }
- }
- if src == nil {
- b, err := ioutil.ReadFile(filename)
- if err != nil {
- return nil, nil, err
- }
- src = b
- }
-
- return src, opt, nil
-}
-
func formatFile(fileSet *token.FileSet, file *ast.File, src []byte, adjust func(orig []byte, src []byte) []byte, opt *Options) ([]byte, error) {
- mergeImports(opt.Env, fileSet, file)
- sortImports(opt.Env, fileSet, file)
+ mergeImports(fileSet, file)
+ sortImports(opt.LocalPrefix, fileSet, file)
imps := astutil.Imports(fileSet, file)
var spacesBefore []string // import paths we need spaces before
for _, impSection := range imps {
@@ -178,7 +116,7 @@ func formatFile(fileSet *token.FileSet, file *ast.File, src []byte, adjust func(
lastGroup := -1
for _, importSpec := range impSection {
importPath, _ := strconv.Unquote(importSpec.Path.Value)
- groupNum := importGroup(opt.Env, importPath)
+ groupNum := importGroup(opt.LocalPrefix, importPath)
if groupNum != lastGroup && lastGroup != -1 {
spacesBefore = append(spacesBefore, importPath)
}
diff --git a/vendor/golang.org/x/tools/internal/imports/mod.go b/vendor/golang.org/x/tools/internal/imports/mod.go
index 69e3eecc4c..94880d6160 100644
--- a/vendor/golang.org/x/tools/internal/imports/mod.go
+++ b/vendor/golang.org/x/tools/internal/imports/mod.go
@@ -15,7 +15,7 @@ import (
"strings"
"golang.org/x/mod/module"
- "golang.org/x/mod/semver"
+ "golang.org/x/tools/internal/gocommand"
"golang.org/x/tools/internal/gopathwalk"
)
@@ -24,31 +24,21 @@ import (
type ModuleResolver struct {
env *ProcessEnv
moduleCacheDir string
- dummyVendorMod *ModuleJSON // If vendoring is enabled, the pseudo-module that represents the /vendor directory.
+ dummyVendorMod *gocommand.ModuleJSON // If vendoring is enabled, the pseudo-module that represents the /vendor directory.
roots []gopathwalk.Root
scanSema chan struct{} // scanSema prevents concurrent scans and guards scannedRoots.
scannedRoots map[gopathwalk.Root]bool
initialized bool
- main *ModuleJSON
- modsByModPath []*ModuleJSON // All modules, ordered by # of path components in module Path...
- modsByDir []*ModuleJSON // ...or Dir.
+ main *gocommand.ModuleJSON
+ modsByModPath []*gocommand.ModuleJSON // All modules, ordered by # of path components in module Path...
+ modsByDir []*gocommand.ModuleJSON // ...or Dir.
// moduleCacheCache stores information about the module cache.
moduleCacheCache *dirInfoCache
otherCache *dirInfoCache
}
-type ModuleJSON struct {
- Path string // module path
- Replace *ModuleJSON // replaced by this module
- Main bool // is this the main module?
- Indirect bool // is this module only an indirect dependency of main module?
- Dir string // directory holding files for this module, if any
- GoMod string // path to go.mod file for this module, if any
- GoVersion string // go version used in module
-}
-
func newModuleResolver(e *ProcessEnv) *ModuleResolver {
r := &ModuleResolver{
env: e,
@@ -62,7 +52,18 @@ func (r *ModuleResolver) init() error {
if r.initialized {
return nil
}
- mainMod, vendorEnabled, err := vendorEnabled(r.env)
+
+ goenv, err := r.env.goEnv()
+ if err != nil {
+ return err
+ }
+ inv := gocommand.Invocation{
+ BuildFlags: r.env.BuildFlags,
+ Env: r.env.env(),
+ Logf: r.env.Logf,
+ WorkingDir: r.env.WorkingDir,
+ }
+ mainMod, vendorEnabled, err := gocommand.VendorEnabled(context.TODO(), inv, r.env.GocmdRunner)
if err != nil {
return err
}
@@ -71,18 +72,22 @@ func (r *ModuleResolver) init() error {
// Vendor mode is on, so all the non-Main modules are irrelevant,
// and we need to search /vendor for everything.
r.main = mainMod
- r.dummyVendorMod = &ModuleJSON{
+ r.dummyVendorMod = &gocommand.ModuleJSON{
Path: "",
Dir: filepath.Join(mainMod.Dir, "vendor"),
}
- r.modsByModPath = []*ModuleJSON{mainMod, r.dummyVendorMod}
- r.modsByDir = []*ModuleJSON{mainMod, r.dummyVendorMod}
+ r.modsByModPath = []*gocommand.ModuleJSON{mainMod, r.dummyVendorMod}
+ r.modsByDir = []*gocommand.ModuleJSON{mainMod, r.dummyVendorMod}
} else {
// Vendor mode is off, so run go list -m ... to find everything.
r.initAllMods()
}
- r.moduleCacheDir = filepath.Join(filepath.SplitList(r.env.GOPATH)[0], "/pkg/mod")
+ if gmc := r.env.Env["GOMODCACHE"]; gmc != "" {
+ r.moduleCacheDir = gmc
+ } else {
+ r.moduleCacheDir = filepath.Join(filepath.SplitList(goenv["GOPATH"])[0], "/pkg/mod")
+ }
sort.Slice(r.modsByModPath, func(i, j int) bool {
count := func(x int) int {
@@ -98,7 +103,7 @@ func (r *ModuleResolver) init() error {
})
r.roots = []gopathwalk.Root{
- {filepath.Join(r.env.GOROOT, "/src"), gopathwalk.RootGOROOT},
+ {filepath.Join(goenv["GOROOT"], "/src"), gopathwalk.RootGOROOT},
}
if r.main != nil {
r.roots = append(r.roots, gopathwalk.Root{r.main.Dir, gopathwalk.RootCurrentModule})
@@ -106,7 +111,7 @@ func (r *ModuleResolver) init() error {
if vendorEnabled {
r.roots = append(r.roots, gopathwalk.Root{r.dummyVendorMod.Dir, gopathwalk.RootOther})
} else {
- addDep := func(mod *ModuleJSON) {
+ addDep := func(mod *gocommand.ModuleJSON) {
if mod.Replace == nil {
// This is redundant with the cache, but we'll skip it cheaply enough.
r.roots = append(r.roots, gopathwalk.Root{mod.Dir, gopathwalk.RootModuleCache})
@@ -151,7 +156,7 @@ func (r *ModuleResolver) initAllMods() error {
return err
}
for dec := json.NewDecoder(stdout); dec.More(); {
- mod := &ModuleJSON{}
+ mod := &gocommand.ModuleJSON{}
if err := dec.Decode(mod); err != nil {
return err
}
@@ -197,7 +202,7 @@ func (r *ModuleResolver) ClearForNewMod() {
// findPackage returns the module and directory that contains the package at
// the given import path, or returns nil, "" if no module is in scope.
-func (r *ModuleResolver) findPackage(importPath string) (*ModuleJSON, string) {
+func (r *ModuleResolver) findPackage(importPath string) (*gocommand.ModuleJSON, string) {
// This can't find packages in the stdlib, but that's harmless for all
// the existing code paths.
for _, m := range r.modsByModPath {
@@ -239,7 +244,7 @@ func (r *ModuleResolver) findPackage(importPath string) (*ModuleJSON, string) {
// files in that directory. If not, it could be provided by an
// outer module. See #29736.
for _, fi := range pkgFiles {
- if ok, _ := r.env.buildContext().MatchFile(pkgDir, fi.Name()); ok {
+ if ok, _ := r.env.matchFile(pkgDir, fi.Name()); ok {
return m, pkgDir
}
}
@@ -283,7 +288,7 @@ func (r *ModuleResolver) cacheExports(ctx context.Context, env *ProcessEnv, info
// findModuleByDir returns the module that contains dir, or nil if no such
// module is in scope.
-func (r *ModuleResolver) findModuleByDir(dir string) *ModuleJSON {
+func (r *ModuleResolver) findModuleByDir(dir string) *gocommand.ModuleJSON {
// This is quite tricky and may not be correct. dir could be:
// - a package in the main module.
// - a replace target underneath the main module's directory.
@@ -310,7 +315,7 @@ func (r *ModuleResolver) findModuleByDir(dir string) *ModuleJSON {
// dirIsNestedModule reports if dir is contained in a nested module underneath
// mod, not actually in mod.
-func (r *ModuleResolver) dirIsNestedModule(dir string, mod *ModuleJSON) bool {
+func (r *ModuleResolver) dirIsNestedModule(dir string, mod *gocommand.ModuleJSON) bool {
if !strings.HasPrefix(dir, mod.Dir) {
return false
}
@@ -490,7 +495,7 @@ func (r *ModuleResolver) scoreImportPath(ctx context.Context, path string) int {
return modRelevance(mod)
}
-func modRelevance(mod *ModuleJSON) int {
+func modRelevance(mod *gocommand.ModuleJSON) int {
switch {
case mod == nil: // out of scope
return MaxRelevance - 4
@@ -656,63 +661,3 @@ func modulePath(mod []byte) string {
}
return "" // missing module path
}
-
-var modFlagRegexp = regexp.MustCompile(`-mod[ =](\w+)`)
-
-// vendorEnabled indicates if vendoring is enabled.
-// Inspired by setDefaultBuildMod in modload/init.go
-func vendorEnabled(env *ProcessEnv) (*ModuleJSON, bool, error) {
- mainMod, go114, err := getMainModuleAnd114(env)
- if err != nil {
- return nil, false, err
- }
- matches := modFlagRegexp.FindStringSubmatch(env.GOFLAGS)
- var modFlag string
- if len(matches) != 0 {
- modFlag = matches[1]
- }
- if modFlag != "" {
- // Don't override an explicit '-mod=' argument.
- return mainMod, modFlag == "vendor", nil
- }
- if mainMod == nil || !go114 {
- return mainMod, false, nil
- }
- // Check 1.14's automatic vendor mode.
- if fi, err := os.Stat(filepath.Join(mainMod.Dir, "vendor")); err == nil && fi.IsDir() {
- if mainMod.GoVersion != "" && semver.Compare("v"+mainMod.GoVersion, "v1.14") >= 0 {
- // The Go version is at least 1.14, and a vendor directory exists.
- // Set -mod=vendor by default.
- return mainMod, true, nil
- }
- }
- return mainMod, false, nil
-}
-
-// getMainModuleAnd114 gets the main module's information and whether the
-// go command in use is 1.14+. This is the information needed to figure out
-// if vendoring should be enabled.
-func getMainModuleAnd114(env *ProcessEnv) (*ModuleJSON, bool, error) {
- const format = `{{.Path}}
-{{.Dir}}
-{{.GoMod}}
-{{.GoVersion}}
-{{range context.ReleaseTags}}{{if eq . "go1.14"}}{{.}}{{end}}{{end}}
-`
- stdout, err := env.invokeGo(context.TODO(), "list", "-m", "-f", format)
- if err != nil {
- return nil, false, nil
- }
- lines := strings.Split(stdout.String(), "\n")
- if len(lines) < 5 {
- return nil, false, fmt.Errorf("unexpected stdout: %q", stdout)
- }
- mod := &ModuleJSON{
- Path: lines[0],
- Dir: lines[1],
- GoMod: lines[2],
- GoVersion: lines[3],
- Main: true,
- }
- return mod, lines[4] == "go1.14", nil
-}
diff --git a/vendor/golang.org/x/tools/internal/imports/sortimports.go b/vendor/golang.org/x/tools/internal/imports/sortimports.go
index 226279471d..be8ffa25fe 100644
--- a/vendor/golang.org/x/tools/internal/imports/sortimports.go
+++ b/vendor/golang.org/x/tools/internal/imports/sortimports.go
@@ -15,7 +15,7 @@ import (
// sortImports sorts runs of consecutive import lines in import blocks in f.
// It also removes duplicate imports when it is possible to do so without data loss.
-func sortImports(env *ProcessEnv, fset *token.FileSet, f *ast.File) {
+func sortImports(localPrefix string, fset *token.FileSet, f *ast.File) {
for i, d := range f.Decls {
d, ok := d.(*ast.GenDecl)
if !ok || d.Tok != token.IMPORT {
@@ -40,11 +40,11 @@ func sortImports(env *ProcessEnv, fset *token.FileSet, f *ast.File) {
for j, s := range d.Specs {
if j > i && fset.Position(s.Pos()).Line > 1+fset.Position(d.Specs[j-1].End()).Line {
// j begins a new run. End this one.
- specs = append(specs, sortSpecs(env, fset, f, d.Specs[i:j])...)
+ specs = append(specs, sortSpecs(localPrefix, fset, f, d.Specs[i:j])...)
i = j
}
}
- specs = append(specs, sortSpecs(env, fset, f, d.Specs[i:])...)
+ specs = append(specs, sortSpecs(localPrefix, fset, f, d.Specs[i:])...)
d.Specs = specs
// Deduping can leave a blank line before the rparen; clean that up.
@@ -60,7 +60,7 @@ func sortImports(env *ProcessEnv, fset *token.FileSet, f *ast.File) {
// mergeImports merges all the import declarations into the first one.
// Taken from golang.org/x/tools/ast/astutil.
-func mergeImports(env *ProcessEnv, fset *token.FileSet, f *ast.File) {
+func mergeImports(fset *token.FileSet, f *ast.File) {
if len(f.Decls) <= 1 {
return
}
@@ -142,7 +142,7 @@ type posSpan struct {
End token.Pos
}
-func sortSpecs(env *ProcessEnv, fset *token.FileSet, f *ast.File, specs []ast.Spec) []ast.Spec {
+func sortSpecs(localPrefix string, fset *token.FileSet, f *ast.File, specs []ast.Spec) []ast.Spec {
// Can't short-circuit here even if specs are already sorted,
// since they might yet need deduplication.
// A lone import, however, may be safely ignored.
@@ -191,7 +191,7 @@ func sortSpecs(env *ProcessEnv, fset *token.FileSet, f *ast.File, specs []ast.Sp
// Reassign the import paths to have the same position sequence.
// Reassign each comment to abut the end of its spec.
// Sort the comments by new position.
- sort.Sort(byImportSpec{env, specs})
+ sort.Sort(byImportSpec{localPrefix, specs})
// Dedup. Thanks to our sorting, we can just consider
// adjacent pairs of imports.
@@ -245,8 +245,8 @@ func sortSpecs(env *ProcessEnv, fset *token.FileSet, f *ast.File, specs []ast.Sp
}
type byImportSpec struct {
- env *ProcessEnv
- specs []ast.Spec // slice of *ast.ImportSpec
+ localPrefix string
+ specs []ast.Spec // slice of *ast.ImportSpec
}
func (x byImportSpec) Len() int { return len(x.specs) }
@@ -255,8 +255,8 @@ func (x byImportSpec) Less(i, j int) bool {
ipath := importPath(x.specs[i])
jpath := importPath(x.specs[j])
- igroup := importGroup(x.env, ipath)
- jgroup := importGroup(x.env, jpath)
+ igroup := importGroup(x.localPrefix, ipath)
+ jgroup := importGroup(x.localPrefix, jpath)
if igroup != jgroup {
return igroup < jgroup
}
diff --git a/vendor/golang.org/x/tools/internal/imports/zstdlib.go b/vendor/golang.org/x/tools/internal/imports/zstdlib.go
index 7e60eb04e5..7b573b9830 100644
--- a/vendor/golang.org/x/tools/internal/imports/zstdlib.go
+++ b/vendor/golang.org/x/tools/internal/imports/zstdlib.go
@@ -56,6 +56,7 @@ var stdlib = map[string][]string{
},
"bufio": []string{
"ErrAdvanceTooFar",
+ "ErrBadReadCount",
"ErrBufferFull",
"ErrFinalToken",
"ErrInvalidUnreadByte",
@@ -303,7 +304,9 @@ var stdlib = map[string][]string{
"PrivateKey",
"PublicKey",
"Sign",
+ "SignASN1",
"Verify",
+ "VerifyASN1",
},
"crypto/ed25519": []string{
"GenerateKey",
@@ -322,11 +325,13 @@ var stdlib = map[string][]string{
"CurveParams",
"GenerateKey",
"Marshal",
+ "MarshalCompressed",
"P224",
"P256",
"P384",
"P521",
"Unmarshal",
+ "UnmarshalCompressed",
},
"crypto/hmac": []string{
"Equal",
@@ -415,6 +420,9 @@ var stdlib = map[string][]string{
"crypto/tls": []string{
"Certificate",
"CertificateRequestInfo",
+ "CipherSuite",
+ "CipherSuiteName",
+ "CipherSuites",
"Client",
"ClientAuthType",
"ClientHelloInfo",
@@ -429,11 +437,13 @@ var stdlib = map[string][]string{
"CurveP521",
"Dial",
"DialWithDialer",
+ "Dialer",
"ECDSAWithP256AndSHA256",
"ECDSAWithP384AndSHA384",
"ECDSAWithP521AndSHA512",
"ECDSAWithSHA1",
"Ed25519",
+ "InsecureCipherSuites",
"Listen",
"LoadX509KeyPair",
"NewLRUClientSessionCache",
@@ -465,6 +475,7 @@ var stdlib = map[string][]string{
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
+ "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
@@ -473,6 +484,7 @@ var stdlib = map[string][]string{
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
+ "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_RSA_WITH_RC4_128_SHA",
"TLS_FALLBACK_SCSV",
"TLS_RSA_WITH_3DES_EDE_CBC_SHA",
@@ -501,6 +513,7 @@ var stdlib = map[string][]string{
"ConstraintViolationError",
"CreateCertificate",
"CreateCertificateRequest",
+ "CreateRevocationList",
"DSA",
"DSAWithSHA1",
"DSAWithSHA256",
@@ -575,6 +588,7 @@ var stdlib = map[string][]string{
"PublicKeyAlgorithm",
"PureEd25519",
"RSA",
+ "RevocationList",
"SHA1WithRSA",
"SHA256WithRSA",
"SHA256WithRSAPSS",
@@ -688,6 +702,7 @@ var stdlib = map[string][]string{
"String",
"Tx",
"TxOptions",
+ "Validator",
"Value",
"ValueConverter",
"Valuer",
@@ -698,36 +713,65 @@ var stdlib = map[string][]string{
"Attr",
"AttrAbstractOrigin",
"AttrAccessibility",
+ "AttrAddrBase",
"AttrAddrClass",
+ "AttrAlignment",
"AttrAllocated",
"AttrArtificial",
"AttrAssociated",
"AttrBaseTypes",
+ "AttrBinaryScale",
"AttrBitOffset",
"AttrBitSize",
"AttrByteSize",
+ "AttrCallAllCalls",
+ "AttrCallAllSourceCalls",
+ "AttrCallAllTailCalls",
"AttrCallColumn",
+ "AttrCallDataLocation",
+ "AttrCallDataValue",
"AttrCallFile",
"AttrCallLine",
+ "AttrCallOrigin",
+ "AttrCallPC",
+ "AttrCallParameter",
+ "AttrCallReturnPC",
+ "AttrCallTailCall",
+ "AttrCallTarget",
+ "AttrCallTargetClobbered",
+ "AttrCallValue",
"AttrCalling",
"AttrCommonRef",
"AttrCompDir",
+ "AttrConstExpr",
"AttrConstValue",
"AttrContainingType",
"AttrCount",
+ "AttrDataBitOffset",
"AttrDataLocation",
"AttrDataMemberLoc",
+ "AttrDecimalScale",
+ "AttrDecimalSign",
"AttrDeclColumn",
"AttrDeclFile",
"AttrDeclLine",
"AttrDeclaration",
"AttrDefaultValue",
+ "AttrDefaulted",
+ "AttrDeleted",
"AttrDescription",
+ "AttrDigitCount",
"AttrDiscr",
"AttrDiscrList",
"AttrDiscrValue",
+ "AttrDwoName",
+ "AttrElemental",
"AttrEncoding",
+ "AttrEndianity",
"AttrEntrypc",
+ "AttrEnumClass",
+ "AttrExplicit",
+ "AttrExportSymbols",
"AttrExtension",
"AttrExternal",
"AttrFrameBase",
@@ -738,27 +782,47 @@ var stdlib = map[string][]string{
"AttrInline",
"AttrIsOptional",
"AttrLanguage",
+ "AttrLinkageName",
"AttrLocation",
+ "AttrLoclistsBase",
"AttrLowerBound",
"AttrLowpc",
"AttrMacroInfo",
+ "AttrMacros",
+ "AttrMainSubprogram",
+ "AttrMutable",
"AttrName",
"AttrNamelistItem",
+ "AttrNoreturn",
+ "AttrObjectPointer",
"AttrOrdering",
+ "AttrPictureString",
"AttrPriority",
"AttrProducer",
"AttrPrototyped",
+ "AttrPure",
"AttrRanges",
+ "AttrRank",
+ "AttrRecursive",
+ "AttrReference",
"AttrReturnAddr",
+ "AttrRnglistsBase",
+ "AttrRvalueReference",
"AttrSegment",
"AttrSibling",
+ "AttrSignature",
+ "AttrSmall",
"AttrSpecification",
"AttrStartScope",
"AttrStaticLink",
"AttrStmtList",
+ "AttrStrOffsetsBase",
"AttrStride",
"AttrStrideSize",
"AttrStringLength",
+ "AttrStringLengthBitSize",
+ "AttrStringLengthByteSize",
+ "AttrThreadsScaled",
"AttrTrampoline",
"AttrType",
"AttrUpperBound",
@@ -772,18 +836,23 @@ var stdlib = map[string][]string{
"BoolType",
"CharType",
"Class",
+ "ClassAddrPtr",
"ClassAddress",
"ClassBlock",
"ClassConstant",
"ClassExprLoc",
"ClassFlag",
"ClassLinePtr",
+ "ClassLocList",
"ClassLocListPtr",
"ClassMacPtr",
"ClassRangeListPtr",
"ClassReference",
"ClassReferenceAlt",
"ClassReferenceSig",
+ "ClassRngList",
+ "ClassRngListsPtr",
+ "ClassStrOffsetsPtr",
"ClassString",
"ClassStringAlt",
"ClassUnknown",
@@ -814,9 +883,13 @@ var stdlib = map[string][]string{
"Tag",
"TagAccessDeclaration",
"TagArrayType",
+ "TagAtomicType",
"TagBaseType",
+ "TagCallSite",
+ "TagCallSiteParameter",
"TagCatchDwarfBlock",
"TagClassType",
+ "TagCoarrayType",
"TagCommonDwarfBlock",
"TagCommonInclusion",
"TagCompileUnit",
@@ -824,12 +897,15 @@ var stdlib = map[string][]string{
"TagConstType",
"TagConstant",
"TagDwarfProcedure",
+ "TagDynamicType",
"TagEntryPoint",
"TagEnumerationType",
"TagEnumerator",
"TagFileType",
"TagFormalParameter",
"TagFriend",
+ "TagGenericSubrange",
+ "TagImmutableType",
"TagImportedDeclaration",
"TagImportedModule",
"TagImportedUnit",
@@ -853,6 +929,7 @@ var stdlib = map[string][]string{
"TagRvalueReferenceType",
"TagSetType",
"TagSharedType",
+ "TagSkeletonUnit",
"TagStringType",
"TagStructType",
"TagSubprogram",
@@ -2281,6 +2358,27 @@ var stdlib = map[string][]string{
"IMAGE_DIRECTORY_ENTRY_RESOURCE",
"IMAGE_DIRECTORY_ENTRY_SECURITY",
"IMAGE_DIRECTORY_ENTRY_TLS",
+ "IMAGE_DLLCHARACTERISTICS_APPCONTAINER",
+ "IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE",
+ "IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY",
+ "IMAGE_DLLCHARACTERISTICS_GUARD_CF",
+ "IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA",
+ "IMAGE_DLLCHARACTERISTICS_NO_BIND",
+ "IMAGE_DLLCHARACTERISTICS_NO_ISOLATION",
+ "IMAGE_DLLCHARACTERISTICS_NO_SEH",
+ "IMAGE_DLLCHARACTERISTICS_NX_COMPAT",
+ "IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE",
+ "IMAGE_DLLCHARACTERISTICS_WDM_DRIVER",
+ "IMAGE_FILE_32BIT_MACHINE",
+ "IMAGE_FILE_AGGRESIVE_WS_TRIM",
+ "IMAGE_FILE_BYTES_REVERSED_HI",
+ "IMAGE_FILE_BYTES_REVERSED_LO",
+ "IMAGE_FILE_DEBUG_STRIPPED",
+ "IMAGE_FILE_DLL",
+ "IMAGE_FILE_EXECUTABLE_IMAGE",
+ "IMAGE_FILE_LARGE_ADDRESS_AWARE",
+ "IMAGE_FILE_LINE_NUMS_STRIPPED",
+ "IMAGE_FILE_LOCAL_SYMS_STRIPPED",
"IMAGE_FILE_MACHINE_AM33",
"IMAGE_FILE_MACHINE_AMD64",
"IMAGE_FILE_MACHINE_ARM",
@@ -2303,6 +2401,25 @@ var stdlib = map[string][]string{
"IMAGE_FILE_MACHINE_THUMB",
"IMAGE_FILE_MACHINE_UNKNOWN",
"IMAGE_FILE_MACHINE_WCEMIPSV2",
+ "IMAGE_FILE_NET_RUN_FROM_SWAP",
+ "IMAGE_FILE_RELOCS_STRIPPED",
+ "IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP",
+ "IMAGE_FILE_SYSTEM",
+ "IMAGE_FILE_UP_SYSTEM_ONLY",
+ "IMAGE_SUBSYSTEM_EFI_APPLICATION",
+ "IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER",
+ "IMAGE_SUBSYSTEM_EFI_ROM",
+ "IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER",
+ "IMAGE_SUBSYSTEM_NATIVE",
+ "IMAGE_SUBSYSTEM_NATIVE_WINDOWS",
+ "IMAGE_SUBSYSTEM_OS2_CUI",
+ "IMAGE_SUBSYSTEM_POSIX_CUI",
+ "IMAGE_SUBSYSTEM_UNKNOWN",
+ "IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION",
+ "IMAGE_SUBSYSTEM_WINDOWS_CE_GUI",
+ "IMAGE_SUBSYSTEM_WINDOWS_CUI",
+ "IMAGE_SUBSYSTEM_WINDOWS_GUI",
+ "IMAGE_SUBSYSTEM_XBOX",
"ImportDirectory",
"NewFile",
"Open",
@@ -2359,6 +2476,7 @@ var stdlib = map[string][]string{
"RawValue",
"StructuralError",
"SyntaxError",
+ "TagBMPString",
"TagBitString",
"TagBoolean",
"TagEnum",
@@ -2787,6 +2905,7 @@ var stdlib = map[string][]string{
"IsPredeclared",
"Mode",
"New",
+ "NewFromFiles",
"Note",
"Package",
"PreserveAST",
@@ -3115,6 +3234,11 @@ var stdlib = map[string][]string{
"New64",
"New64a",
},
+ "hash/maphash": []string{
+ "Hash",
+ "MakeSeed",
+ "Seed",
+ },
"html": []string{
"EscapeString",
"UnescapeString",
@@ -3367,6 +3491,7 @@ var stdlib = map[string][]string{
"Ldate",
"Llongfile",
"Lmicroseconds",
+ "Lmsgprefix",
"Logger",
"Lshortfile",
"LstdFlags",
@@ -3443,6 +3568,7 @@ var stdlib = map[string][]string{
"Exp",
"Exp2",
"Expm1",
+ "FMA",
"Float32bits",
"Float32frombits",
"Float64bits",
@@ -3567,6 +3693,9 @@ var stdlib = map[string][]string{
"OnesCount32",
"OnesCount64",
"OnesCount8",
+ "Rem",
+ "Rem32",
+ "Rem64",
"Reverse",
"Reverse16",
"Reverse32",
@@ -4108,6 +4237,7 @@ var stdlib = map[string][]string{
"DevNull",
"Environ",
"ErrClosed",
+ "ErrDeadlineExceeded",
"ErrExist",
"ErrInvalid",
"ErrNoDeadline",
@@ -4566,6 +4696,7 @@ var stdlib = map[string][]string{
"ErrRange",
"ErrSyntax",
"FormatBool",
+ "FormatComplex",
"FormatFloat",
"FormatInt",
"FormatUint",
@@ -4575,6 +4706,7 @@ var stdlib = map[string][]string{
"Itoa",
"NumError",
"ParseBool",
+ "ParseComplex",
"ParseFloat",
"ParseInt",
"ParseUint",
@@ -5140,7 +5272,10 @@ var stdlib = map[string][]string{
"CTL_NET",
"CTL_QUERY",
"CTRL_BREAK_EVENT",
+ "CTRL_CLOSE_EVENT",
"CTRL_C_EVENT",
+ "CTRL_LOGOFF_EVENT",
+ "CTRL_SHUTDOWN_EVENT",
"CancelIo",
"CancelIoEx",
"CertAddCertificateContextToStore",
@@ -10112,6 +10247,7 @@ var stdlib = map[string][]string{
"Duployan",
"Egyptian_Hieroglyphs",
"Elbasan",
+ "Elymaic",
"Ethiopic",
"Extender",
"FoldCategory",
@@ -10215,6 +10351,7 @@ var stdlib = map[string][]string{
"Myanmar",
"N",
"Nabataean",
+ "Nandinagari",
"Nd",
"New_Tai_Lue",
"Newa",
@@ -10224,6 +10361,7 @@ var stdlib = map[string][]string{
"Noncharacter_Code_Point",
"Number",
"Nushu",
+ "Nyiakeng_Puachue_Hmong",
"Ogham",
"Ol_Chiki",
"Old_Hungarian",
@@ -10331,6 +10469,7 @@ var stdlib = map[string][]string{
"Vai",
"Variation_Selector",
"Version",
+ "Wancho",
"Warang_Citi",
"White_Space",
"Yi",
diff --git a/vendor/golang.org/x/tools/internal/lsp/fuzzy/input.go b/vendor/golang.org/x/tools/internal/lsp/fuzzy/input.go
new file mode 100644
index 0000000000..ac377035ec
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/lsp/fuzzy/input.go
@@ -0,0 +1,168 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fuzzy
+
+import (
+ "unicode"
+)
+
+// RuneRole specifies the role of a rune in the context of an input.
+type RuneRole byte
+
+const (
+ // RNone specifies a rune without any role in the input (i.e., whitespace/non-ASCII).
+ RNone RuneRole = iota
+ // RSep specifies a rune with the role of segment separator.
+ RSep
+ // RTail specifies a rune which is a lower-case tail in a word in the input.
+ RTail
+ // RUCTail specifies a rune which is an upper-case tail in a word in the input.
+ RUCTail
+ // RHead specifies a rune which is the first character in a word in the input.
+ RHead
+)
+
+// RuneRoles detects the roles of each byte rune in an input string and stores it in the output
+// slice. The rune role depends on the input type. Stops when it parsed all the runes in the string
+// or when it filled the output. If output is nil, then it gets created.
+func RuneRoles(str string, reuse []RuneRole) []RuneRole {
+ var output []RuneRole
+ if cap(reuse) < len(str) {
+ output = make([]RuneRole, 0, len(str))
+ } else {
+ output = reuse[:0]
+ }
+
+ prev, prev2 := rtNone, rtNone
+ for i := 0; i < len(str); i++ {
+ r := rune(str[i])
+
+ role := RNone
+
+ curr := rtLower
+ if str[i] <= unicode.MaxASCII {
+ curr = runeType(rt[str[i]] - '0')
+ }
+
+ if curr == rtLower {
+ if prev == rtNone || prev == rtPunct {
+ role = RHead
+ } else {
+ role = RTail
+ }
+ } else if curr == rtUpper {
+ role = RHead
+
+ if prev == rtUpper {
+ // This and previous characters are both upper case.
+
+ if i+1 == len(str) {
+ // This is last character, previous was also uppercase -> this is UCTail
+ // i.e., (current char is C): aBC / BC / ABC
+ role = RUCTail
+ }
+ }
+ } else if curr == rtPunct {
+ switch r {
+ case '.', ':':
+ role = RSep
+ }
+ }
+ if curr != rtLower {
+ if i > 1 && output[i-1] == RHead && prev2 == rtUpper && (output[i-2] == RHead || output[i-2] == RUCTail) {
+ // The previous two characters were uppercase. The current one is not a lower case, so the
+ // previous one can't be a HEAD. Make it a UCTail.
+ // i.e., (last char is current char - B must be a UCTail): ABC / ZABC / AB.
+ output[i-1] = RUCTail
+ }
+ }
+
+ output = append(output, role)
+ prev2 = prev
+ prev = curr
+ }
+ return output
+}
+
+type runeType byte
+
+const (
+ rtNone runeType = iota
+ rtPunct
+ rtLower
+ rtUpper
+)
+
+const rt = "00000000000000000000000000000000000000000000001122222222221000000333333333333333333333333330000002222222222222222222222222200000"
+
+// LastSegment returns the substring representing the last segment from the input, where each
+// byte has an associated RuneRole in the roles slice. This makes sense only for inputs of Symbol
+// or Filename type.
+func LastSegment(input string, roles []RuneRole) string {
+ // Exclude ending separators.
+ end := len(input) - 1
+ for end >= 0 && roles[end] == RSep {
+ end--
+ }
+ if end < 0 {
+ return ""
+ }
+
+ start := end - 1
+ for start >= 0 && roles[start] != RSep {
+ start--
+ }
+
+ return input[start+1 : end+1]
+}
+
+// ToLower transforms the input string to lower case, which is stored in the output byte slice.
+// The lower casing considers only ASCII values - non ASCII values are left unmodified.
+// Stops when parsed all input or when it filled the output slice. If output is nil, then it gets
+// created.
+func ToLower(input string, reuse []byte) []byte {
+ output := reuse
+ if cap(reuse) < len(input) {
+ output = make([]byte, len(input))
+ }
+
+ for i := 0; i < len(input); i++ {
+ r := rune(input[i])
+ if r <= unicode.MaxASCII {
+ if 'A' <= r && r <= 'Z' {
+ r += 'a' - 'A'
+ }
+ }
+ output[i] = byte(r)
+ }
+ return output[:len(input)]
+}
+
+// WordConsumer defines a consumer for a word delimited by the [start,end) byte offsets in an input
+// (start is inclusive, end is exclusive).
+type WordConsumer func(start, end int)
+
+// Words find word delimiters in an input based on its bytes' mappings to rune roles. The offset
+// delimiters for each word are fed to the provided consumer function.
+func Words(roles []RuneRole, consume WordConsumer) {
+ var wordStart int
+ for i, r := range roles {
+ switch r {
+ case RUCTail, RTail:
+ case RHead, RNone, RSep:
+ if i != wordStart {
+ consume(wordStart, i)
+ }
+ wordStart = i
+ if r != RHead {
+ // Skip this character.
+ wordStart = i + 1
+ }
+ }
+ }
+ if wordStart != len(roles) {
+ consume(wordStart, len(roles))
+ }
+}
diff --git a/vendor/golang.org/x/tools/internal/lsp/fuzzy/matcher.go b/vendor/golang.org/x/tools/internal/lsp/fuzzy/matcher.go
new file mode 100644
index 0000000000..f39f7ef65e
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/lsp/fuzzy/matcher.go
@@ -0,0 +1,398 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package fuzzy implements a fuzzy matching algorithm.
+package fuzzy
+
+import (
+ "bytes"
+ "fmt"
+)
+
+const (
+ // MaxInputSize is the maximum size of the input scored against the fuzzy matcher. Longer inputs
+ // will be truncated to this size.
+ MaxInputSize = 127
+ // MaxPatternSize is the maximum size of the pattern used to construct the fuzzy matcher. Longer
+ // inputs are truncated to this size.
+ MaxPatternSize = 63
+)
+
+type scoreVal int
+
+func (s scoreVal) val() int {
+ return int(s) >> 1
+}
+
+func (s scoreVal) prevK() int {
+ return int(s) & 1
+}
+
+func score(val int, prevK int /*0 or 1*/) scoreVal {
+ return scoreVal(val<<1 + prevK)
+}
+
+// Matcher implements a fuzzy matching algorithm for scoring candidates against a pattern.
+// The matcher does not support parallel usage.
+type Matcher struct {
+ pattern string
+ patternLower []byte // lower-case version of the pattern
+ patternShort []byte // first characters of the pattern
+ caseSensitive bool // set if the pattern is mix-cased
+
+ patternRoles []RuneRole // the role of each character in the pattern
+ roles []RuneRole // the role of each character in the tested string
+
+ scores [MaxInputSize + 1][MaxPatternSize + 1][2]scoreVal
+
+ scoreScale float32
+
+ lastCandidateLen int // in bytes
+ lastCandidateMatched bool
+
+ // Here we save the last candidate in lower-case. This is basically a byte slice we reuse for
+ // performance reasons, so the slice is not reallocated for every candidate.
+ lowerBuf [MaxInputSize]byte
+ rolesBuf [MaxInputSize]RuneRole
+}
+
+func (m *Matcher) bestK(i, j int) int {
+ if m.scores[i][j][0].val() < m.scores[i][j][1].val() {
+ return 1
+ }
+ return 0
+}
+
+// NewMatcher returns a new fuzzy matcher for scoring candidates against the provided pattern.
+func NewMatcher(pattern string) *Matcher {
+ if len(pattern) > MaxPatternSize {
+ pattern = pattern[:MaxPatternSize]
+ }
+
+ m := &Matcher{
+ pattern: pattern,
+ patternLower: ToLower(pattern, nil),
+ }
+
+ for i, c := range m.patternLower {
+ if pattern[i] != c {
+ m.caseSensitive = true
+ break
+ }
+ }
+
+ if len(pattern) > 3 {
+ m.patternShort = m.patternLower[:3]
+ } else {
+ m.patternShort = m.patternLower
+ }
+
+ m.patternRoles = RuneRoles(pattern, nil)
+
+ if len(pattern) > 0 {
+ maxCharScore := 4
+ m.scoreScale = 1 / float32(maxCharScore*len(pattern))
+ }
+
+ return m
+}
+
+// Score returns the score returned by matching the candidate to the pattern.
+// This is not designed for parallel use. Multiple candidates must be scored sequentially.
+// Returns a score between 0 and 1 (0 - no match, 1 - perfect match).
+func (m *Matcher) Score(candidate string) float32 {
+ if len(candidate) > MaxInputSize {
+ candidate = candidate[:MaxInputSize]
+ }
+ lower := ToLower(candidate, m.lowerBuf[:])
+ m.lastCandidateLen = len(candidate)
+
+ if len(m.pattern) == 0 {
+ // Empty patterns perfectly match candidates.
+ return 1
+ }
+
+ if m.match(candidate, lower) {
+ sc := m.computeScore(candidate, lower)
+ if sc > minScore/2 && !m.poorMatch() {
+ m.lastCandidateMatched = true
+ if len(m.pattern) == len(candidate) {
+ // Perfect match.
+ return 1
+ }
+
+ if sc < 0 {
+ sc = 0
+ }
+ normalizedScore := float32(sc) * m.scoreScale
+ if normalizedScore > 1 {
+ normalizedScore = 1
+ }
+
+ return normalizedScore
+ }
+ }
+
+ m.lastCandidateMatched = false
+ return -1
+}
+
+const minScore = -10000
+
+// MatchedRanges returns matches ranges for the last scored string as a flattened array of
+// [begin, end) byte offset pairs.
+func (m *Matcher) MatchedRanges() []int {
+ if len(m.pattern) == 0 || !m.lastCandidateMatched {
+ return nil
+ }
+ i, j := m.lastCandidateLen, len(m.pattern)
+ if m.scores[i][j][0].val() < minScore/2 && m.scores[i][j][1].val() < minScore/2 {
+ return nil
+ }
+
+ var ret []int
+ k := m.bestK(i, j)
+ for i > 0 {
+ take := (k == 1)
+ k = m.scores[i][j][k].prevK()
+ if take {
+ if len(ret) == 0 || ret[len(ret)-1] != i {
+ ret = append(ret, i)
+ ret = append(ret, i-1)
+ } else {
+ ret[len(ret)-1] = i - 1
+ }
+ j--
+ }
+ i--
+ }
+ // Reverse slice.
+ for i := 0; i < len(ret)/2; i++ {
+ ret[i], ret[len(ret)-1-i] = ret[len(ret)-1-i], ret[i]
+ }
+ return ret
+}
+
+func (m *Matcher) match(candidate string, candidateLower []byte) bool {
+ i, j := 0, 0
+ for ; i < len(candidateLower) && j < len(m.patternLower); i++ {
+ if candidateLower[i] == m.patternLower[j] {
+ j++
+ }
+ }
+ if j != len(m.patternLower) {
+ return false
+ }
+
+ // The input passes the simple test against pattern, so it is time to classify its characters.
+ // Character roles are used below to find the last segment.
+ m.roles = RuneRoles(candidate, m.rolesBuf[:])
+
+ return true
+}
+
+func (m *Matcher) computeScore(candidate string, candidateLower []byte) int {
+ pattLen, candLen := len(m.pattern), len(candidate)
+
+ for j := 0; j <= len(m.pattern); j++ {
+ m.scores[0][j][0] = minScore << 1
+ m.scores[0][j][1] = minScore << 1
+ }
+ m.scores[0][0][0] = score(0, 0) // Start with 0.
+
+ segmentsLeft, lastSegStart := 1, 0
+ for i := 0; i < candLen; i++ {
+ if m.roles[i] == RSep {
+ segmentsLeft++
+ lastSegStart = i + 1
+ }
+ }
+
+ // A per-character bonus for a consecutive match.
+ consecutiveBonus := 2
+ wordIdx := 0 // Word count within segment.
+ for i := 1; i <= candLen; i++ {
+
+ role := m.roles[i-1]
+ isHead := role == RHead
+
+ if isHead {
+ wordIdx++
+ } else if role == RSep && segmentsLeft > 1 {
+ wordIdx = 0
+ segmentsLeft--
+ }
+
+ var skipPenalty int
+ if i == 1 || (i-1) == lastSegStart {
+ // Skipping the start of first or last segment.
+ skipPenalty++
+ }
+
+ for j := 0; j <= pattLen; j++ {
+ // By default, we don't have a match. Fill in the skip data.
+ m.scores[i][j][1] = minScore << 1
+
+ // Compute the skip score.
+ k := 0
+ if m.scores[i-1][j][0].val() < m.scores[i-1][j][1].val() {
+ k = 1
+ }
+
+ skipScore := m.scores[i-1][j][k].val()
+ // Do not penalize missing characters after the last matched segment.
+ if j != pattLen {
+ skipScore -= skipPenalty
+ }
+ m.scores[i][j][0] = score(skipScore, k)
+
+ if j == 0 || candidateLower[i-1] != m.patternLower[j-1] {
+ // Not a match.
+ continue
+ }
+ pRole := m.patternRoles[j-1]
+
+ if role == RTail && pRole == RHead {
+ if j > 1 {
+ // Not a match: a head in the pattern matches a tail character in the candidate.
+ continue
+ }
+ // Special treatment for the first character of the pattern. We allow
+ // matches in the middle of a word if they are long enough, at least
+ // min(3, pattern.length) characters.
+ if !bytes.HasPrefix(candidateLower[i-1:], m.patternShort) {
+ continue
+ }
+ }
+
+ // Compute the char score.
+ var charScore int
+ // Bonus 1: the char is in the candidate's last segment.
+ if segmentsLeft <= 1 {
+ charScore++
+ }
+ // Bonus 2: Case match or a Head in the pattern aligns with one in the word.
+ // Single-case patterns lack segmentation signals and we assume any character
+ // can be a head of a segment.
+ if candidate[i-1] == m.pattern[j-1] || role == RHead && (!m.caseSensitive || pRole == RHead) {
+ charScore++
+ }
+
+ // Penalty 1: pattern char is Head, candidate char is Tail.
+ if role == RTail && pRole == RHead {
+ charScore--
+ }
+ // Penalty 2: first pattern character matched in the middle of a word.
+ if j == 1 && role == RTail {
+ charScore -= 4
+ }
+
+ // Third dimension encodes whether there is a gap between the previous match and the current
+ // one.
+ for k := 0; k < 2; k++ {
+ sc := m.scores[i-1][j-1][k].val() + charScore
+
+ isConsecutive := k == 1 || i-1 == 0 || i-1 == lastSegStart
+ if isConsecutive {
+ // Bonus 3: a consecutive match. First character match also gets a bonus to
+ // ensure prefix final match score normalizes to 1.0.
+ // Logically, this is a part of charScore, but we have to compute it here because it
+ // only applies for consecutive matches (k == 1).
+ sc += consecutiveBonus
+ }
+ if k == 0 {
+ // Penalty 3: Matching inside a segment (and previous char wasn't matched). Penalize for the lack
+ // of alignment.
+ if role == RTail || role == RUCTail {
+ sc -= 3
+ }
+ }
+
+ if sc > m.scores[i][j][1].val() {
+ m.scores[i][j][1] = score(sc, k)
+ }
+ }
+ }
+ }
+
+ result := m.scores[len(candidate)][len(m.pattern)][m.bestK(len(candidate), len(m.pattern))].val()
+
+ return result
+}
+
+// ScoreTable returns the score table computed for the provided candidate. Used only for debugging.
+func (m *Matcher) ScoreTable(candidate string) string {
+ var buf bytes.Buffer
+
+ var line1, line2, separator bytes.Buffer
+ line1.WriteString("\t")
+ line2.WriteString("\t")
+ for j := 0; j < len(m.pattern); j++ {
+ line1.WriteString(fmt.Sprintf("%c\t\t", m.pattern[j]))
+ separator.WriteString("----------------")
+ }
+
+ buf.WriteString(line1.String())
+ buf.WriteString("\n")
+ buf.WriteString(separator.String())
+ buf.WriteString("\n")
+
+ for i := 1; i <= len(candidate); i++ {
+ line1.Reset()
+ line2.Reset()
+
+ line1.WriteString(fmt.Sprintf("%c\t", candidate[i-1]))
+ line2.WriteString("\t")
+
+ for j := 1; j <= len(m.pattern); j++ {
+ line1.WriteString(fmt.Sprintf("M%6d(%c)\t", m.scores[i][j][0].val(), dir(m.scores[i][j][0].prevK())))
+ line2.WriteString(fmt.Sprintf("H%6d(%c)\t", m.scores[i][j][1].val(), dir(m.scores[i][j][1].prevK())))
+ }
+ buf.WriteString(line1.String())
+ buf.WriteString("\n")
+ buf.WriteString(line2.String())
+ buf.WriteString("\n")
+ buf.WriteString(separator.String())
+ buf.WriteString("\n")
+ }
+
+ return buf.String()
+}
+
+func dir(prevK int) rune {
+ if prevK == 0 {
+ return 'M'
+ }
+ return 'H'
+}
+
+func (m *Matcher) poorMatch() bool {
+ if len(m.pattern) < 2 {
+ return false
+ }
+
+ i, j := m.lastCandidateLen, len(m.pattern)
+ k := m.bestK(i, j)
+
+ var counter, len int
+ for i > 0 {
+ take := (k == 1)
+ k = m.scores[i][j][k].prevK()
+ if take {
+ len++
+ if k == 0 && len < 3 && m.roles[i-1] == RTail {
+ // Short match in the middle of a word
+ counter++
+ if counter > 1 {
+ return true
+ }
+ }
+ j--
+ } else {
+ len = 0
+ }
+ i--
+ }
+ return false
+}
diff --git a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
index b13ce33a39..2c4527f243 100644
--- a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
+++ b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
@@ -1,27 +1,14 @@
// Package packagesinternal exposes internal-only fields from go/packages.
package packagesinternal
-import "time"
-
-// Fields must match go list;
-type Module struct {
- Path string // module path
- Version string // module version
- Versions []string // available module versions (with -versions)
- Replace *Module // replaced by this module
- Time *time.Time // time version was created
- Update *Module // available update, if any (with -u)
- Main bool // is this the main module?
- Indirect bool // is this module only an indirect dependency of main module?
- Dir string // directory holding files for this module, if any
- GoMod string // path to go.mod file used when loading this module, if any
- GoVersion string // go version used in module
- Error *ModuleError // error loading module
-}
-type ModuleError struct {
- Err string // the error itself
-}
+import (
+ "golang.org/x/tools/internal/gocommand"
+)
var GetForTest = func(p interface{}) string { return "" }
-var GetModule = func(p interface{}) *Module { return nil }
+var GetGoCmdRunner = func(config interface{}) *gocommand.Runner { return nil }
+
+var SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {}
+
+var TypecheckCgo int
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go
new file mode 100644
index 0000000000..a5bb408e2f
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/types.go
@@ -0,0 +1,28 @@
+// Copyright 2020 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"
+ "reflect"
+ "unsafe"
+)
+
+func SetUsesCgo(conf *types.Config) bool {
+ v := reflect.ValueOf(conf).Elem()
+
+ f := v.FieldByName("go115UsesCgo")
+ if !f.IsValid() {
+ f = v.FieldByName("UsesCgo")
+ if !f.IsValid() {
+ return false
+ }
+ }
+
+ addr := unsafe.Pointer(f.UnsafeAddr())
+ *(*bool)(addr) = true
+
+ return true
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 50cf85855e..c815f5214c 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1,10 +1,10 @@
# cloud.google.com/go v0.45.0
## explicit
cloud.google.com/go/compute/metadata
-# gitea.com/jolheiser/gitea-vet v0.1.0
+# code.gitea.io/gitea-vet v0.2.1
## explicit
-gitea.com/jolheiser/gitea-vet
-gitea.com/jolheiser/gitea-vet/checks
+code.gitea.io/gitea-vet
+code.gitea.io/gitea-vet/checks
# gitea.com/lunny/levelqueue v0.3.0
## explicit
gitea.com/lunny/levelqueue
@@ -769,10 +769,10 @@ golang.org/x/crypto/ssh
golang.org/x/crypto/ssh/agent
golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
golang.org/x/crypto/ssh/knownhosts
-# golang.org/x/mod v0.2.0
+# golang.org/x/mod v0.3.0
golang.org/x/mod/module
golang.org/x/mod/semver
-# golang.org/x/net v0.0.0-20200602114024-627f9648deb9
+# golang.org/x/net v0.0.0-20200625001655-4c5254603344
## explicit
golang.org/x/net/context
golang.org/x/net/context/ctxhttp
@@ -823,7 +823,7 @@ golang.org/x/text/width
# golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1
## explicit
golang.org/x/time/rate
-# golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224
+# golang.org/x/tools v0.0.0-20200814230902-9882f1d1823d
## explicit
golang.org/x/tools/cover
golang.org/x/tools/go/analysis
@@ -840,11 +840,18 @@ golang.org/x/tools/go/loader
golang.org/x/tools/go/packages
golang.org/x/tools/go/types/objectpath
golang.org/x/tools/imports
+golang.org/x/tools/internal/analysisinternal
+golang.org/x/tools/internal/event
+golang.org/x/tools/internal/event/core
+golang.org/x/tools/internal/event/keys
+golang.org/x/tools/internal/event/label
golang.org/x/tools/internal/fastwalk
golang.org/x/tools/internal/gocommand
golang.org/x/tools/internal/gopathwalk
golang.org/x/tools/internal/imports
+golang.org/x/tools/internal/lsp/fuzzy
golang.org/x/tools/internal/packagesinternal
+golang.org/x/tools/internal/typesinternal
# golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
golang.org/x/xerrors
golang.org/x/xerrors/internal