mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/vet: update buildtag check for //go:build lines
Brings in golang.org/x/tools@2363391a and adjusts, adds cmd/vet tests accordingly. Part of //go:build change (#41184). See https://golang.org/design/draft-gobuild This brings in the new //go:build checks in cmd/vet. Change-Id: I8a9735cc014171691012b307ec30e94c81aadfe1 Reviewed-on: https://go-review.googlesource.com/c/go/+/240609 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Jay Conrod <jayconrod@google.com>
This commit is contained in:
parent
9fd6cc105d
commit
0625460f79
19 changed files with 589 additions and 94 deletions
|
|
@ -8,5 +8,5 @@ require (
|
||||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
|
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
|
||||||
golang.org/x/mod v0.4.1
|
golang.org/x/mod v0.4.1
|
||||||
golang.org/x/sys v0.0.0-20210218145245-beda7e5e158e // indirect
|
golang.org/x/sys v0.0.0-20210218145245-beda7e5e158e // indirect
|
||||||
golang.org/x/tools v0.0.0-20210107193943-4ed967dd8eff
|
golang.org/x/tools v0.1.1-0.20210220032852-2363391a5b2f
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
|
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
|
||||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
|
golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
|
||||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
|
@ -25,14 +24,15 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210218145245-beda7e5e158e h1:f5mksnk+hgXHnImpZoWj64ja99j9zV7YUgrVG95uFE4=
|
golang.org/x/sys v0.0.0-20210218145245-beda7e5e158e h1:f5mksnk+hgXHnImpZoWj64ja99j9zV7YUgrVG95uFE4=
|
||||||
golang.org/x/sys v0.0.0-20210218145245-beda7e5e158e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210218145245-beda7e5e158e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20210107193943-4ed967dd8eff h1:6EkB024TP1fu6cmQqeCNw685zYDVt5g8N1BXh755SQM=
|
golang.org/x/tools v0.1.1-0.20210220032852-2363391a5b2f h1:R8L2zr6nSvQoIIw/EiaPP6HfmxeiArf+Nh/CWTC60wQ=
|
||||||
golang.org/x/tools v0.0.0-20210107193943-4ed967dd8eff/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.1.1-0.20210220032852-2363391a5b2f/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||||
|
|
|
||||||
332
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go
generated
vendored
332
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go
generated
vendored
|
|
@ -2,14 +2,17 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.16
|
||||||
|
// +build go1.16
|
||||||
|
|
||||||
// Package buildtag defines an Analyzer that checks build tags.
|
// Package buildtag defines an Analyzer that checks build tags.
|
||||||
package buildtag
|
package buildtag
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
|
"go/build/constraint"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
|
"go/token"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
|
@ -52,118 +55,313 @@ func runBuildTag(pass *analysis.Pass) (interface{}, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkGoFile(pass *analysis.Pass, f *ast.File) {
|
func checkGoFile(pass *analysis.Pass, f *ast.File) {
|
||||||
pastCutoff := false
|
var check checker
|
||||||
|
check.init(pass)
|
||||||
|
defer check.finish()
|
||||||
|
|
||||||
for _, group := range f.Comments {
|
for _, group := range f.Comments {
|
||||||
// A +build comment is ignored after or adjoining the package declaration.
|
// A +build comment is ignored after or adjoining the package declaration.
|
||||||
if group.End()+1 >= f.Package {
|
if group.End()+1 >= f.Package {
|
||||||
pastCutoff = true
|
check.plusBuildOK = false
|
||||||
}
|
}
|
||||||
|
// A //go:build comment is ignored after the package declaration
|
||||||
// "+build" is ignored within or after a /*...*/ comment.
|
// (but adjoining it is OK, in contrast to +build comments).
|
||||||
if !strings.HasPrefix(group.List[0].Text, "//") {
|
if group.Pos() >= f.Package {
|
||||||
pastCutoff = true
|
check.goBuildOK = false
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check each line of a //-comment.
|
// Check each line of a //-comment.
|
||||||
for _, c := range group.List {
|
for _, c := range group.List {
|
||||||
if !strings.Contains(c.Text, "+build") {
|
// "+build" is ignored within or after a /*...*/ comment.
|
||||||
continue
|
if !strings.HasPrefix(c.Text, "//") {
|
||||||
}
|
check.plusBuildOK = false
|
||||||
if err := checkLine(c.Text, pastCutoff); err != nil {
|
|
||||||
pass.Reportf(c.Pos(), "%s", err)
|
|
||||||
}
|
}
|
||||||
|
check.comment(c.Slash, c.Text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkOtherFile(pass *analysis.Pass, filename string) error {
|
func checkOtherFile(pass *analysis.Pass, filename string) error {
|
||||||
|
var check checker
|
||||||
|
check.init(pass)
|
||||||
|
defer check.finish()
|
||||||
|
|
||||||
|
// We cannot use the Go parser, since this may not be a Go source file.
|
||||||
|
// Read the raw bytes instead.
|
||||||
content, tf, err := analysisutil.ReadFile(pass.Fset, filename)
|
content, tf, err := analysisutil.ReadFile(pass.Fset, filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// We must look at the raw lines, as build tags may appear in non-Go
|
check.file(token.Pos(tf.Base()), string(content))
|
||||||
// files such as assembly files.
|
return nil
|
||||||
lines := bytes.SplitAfter(content, nl)
|
}
|
||||||
|
|
||||||
|
type checker struct {
|
||||||
|
pass *analysis.Pass
|
||||||
|
plusBuildOK bool // "+build" lines still OK
|
||||||
|
goBuildOK bool // "go:build" lines still OK
|
||||||
|
crossCheck bool // cross-check go:build and +build lines when done reading file
|
||||||
|
inStar bool // currently in a /* */ comment
|
||||||
|
goBuildPos token.Pos // position of first go:build line found
|
||||||
|
plusBuildPos token.Pos // position of first "+build" line found
|
||||||
|
goBuild constraint.Expr // go:build constraint found
|
||||||
|
plusBuild constraint.Expr // AND of +build constraints found
|
||||||
|
}
|
||||||
|
|
||||||
|
func (check *checker) init(pass *analysis.Pass) {
|
||||||
|
check.pass = pass
|
||||||
|
check.goBuildOK = true
|
||||||
|
check.plusBuildOK = true
|
||||||
|
check.crossCheck = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (check *checker) file(pos token.Pos, text string) {
|
||||||
// Determine cutpoint where +build comments are no longer valid.
|
// Determine cutpoint where +build comments are no longer valid.
|
||||||
// They are valid in leading // comments in the file followed by
|
// They are valid in leading // comments in the file followed by
|
||||||
// a blank line.
|
// a blank line.
|
||||||
//
|
//
|
||||||
// This must be done as a separate pass because of the
|
// This must be done as a separate pass because of the
|
||||||
// requirement that the comment be followed by a blank line.
|
// requirement that the comment be followed by a blank line.
|
||||||
var cutoff int
|
var plusBuildCutoff int
|
||||||
for i, line := range lines {
|
fullText := text
|
||||||
line = bytes.TrimSpace(line)
|
for text != "" {
|
||||||
if !bytes.HasPrefix(line, slashSlash) {
|
i := strings.Index(text, "\n")
|
||||||
if len(line) > 0 {
|
if i < 0 {
|
||||||
break
|
i = len(text)
|
||||||
|
} else {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
offset := len(fullText) - len(text)
|
||||||
|
line := text[:i]
|
||||||
|
text = text[i:]
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if !strings.HasPrefix(line, "//") && line != "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if line == "" {
|
||||||
|
plusBuildCutoff = offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process each line.
|
||||||
|
// Must stop once we hit goBuildOK == false
|
||||||
|
text = fullText
|
||||||
|
check.inStar = false
|
||||||
|
for text != "" {
|
||||||
|
i := strings.Index(text, "\n")
|
||||||
|
if i < 0 {
|
||||||
|
i = len(text)
|
||||||
|
} else {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
offset := len(fullText) - len(text)
|
||||||
|
line := text[:i]
|
||||||
|
text = text[i:]
|
||||||
|
check.plusBuildOK = offset < plusBuildCutoff
|
||||||
|
|
||||||
|
if strings.HasPrefix(line, "//") {
|
||||||
|
check.comment(pos+token.Pos(offset), line)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep looking for the point at which //go:build comments
|
||||||
|
// stop being allowed. Skip over, cut out any /* */ comments.
|
||||||
|
for {
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if check.inStar {
|
||||||
|
i := strings.Index(line, "*/")
|
||||||
|
if i < 0 {
|
||||||
|
line = ""
|
||||||
|
break
|
||||||
|
}
|
||||||
|
line = line[i+len("*/"):]
|
||||||
|
check.inStar = false
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
cutoff = i
|
if strings.HasPrefix(line, "/*") {
|
||||||
|
check.inStar = true
|
||||||
|
line = line[len("/*"):]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if line != "" {
|
||||||
|
// Found non-comment non-blank line.
|
||||||
|
// Ends space for valid //go:build comments,
|
||||||
|
// but also ends the fraction of the file we can
|
||||||
|
// reliably parse. From this point on we might
|
||||||
|
// incorrectly flag "comments" inside multiline
|
||||||
|
// string constants or anything else (this might
|
||||||
|
// not even be a Go program). So stop.
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, line := range lines {
|
|
||||||
line = bytes.TrimSpace(line)
|
|
||||||
if !bytes.HasPrefix(line, slashSlash) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !bytes.Contains(line, []byte("+build")) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := checkLine(string(line), i >= cutoff); err != nil {
|
|
||||||
pass.Reportf(analysisutil.LineStart(tf, i+1), "%s", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkLine checks a line that starts with "//" and contains "+build".
|
func (check *checker) comment(pos token.Pos, text string) {
|
||||||
func checkLine(line string, pastCutoff bool) error {
|
if strings.HasPrefix(text, "//") {
|
||||||
line = strings.TrimPrefix(line, "//")
|
if strings.Contains(text, "+build") {
|
||||||
line = strings.TrimSpace(line)
|
check.plusBuildLine(pos, text)
|
||||||
|
}
|
||||||
|
if strings.Contains(text, "//go:build") {
|
||||||
|
check.goBuildLine(pos, text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(text, "/*") {
|
||||||
|
if i := strings.Index(text, "\n"); i >= 0 {
|
||||||
|
// multiline /* */ comment - process interior lines
|
||||||
|
check.inStar = true
|
||||||
|
i++
|
||||||
|
pos += token.Pos(i)
|
||||||
|
text = text[i:]
|
||||||
|
for text != "" {
|
||||||
|
i := strings.Index(text, "\n")
|
||||||
|
if i < 0 {
|
||||||
|
i = len(text)
|
||||||
|
} else {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
line := text[:i]
|
||||||
|
if strings.HasPrefix(line, "//") {
|
||||||
|
check.comment(pos, line)
|
||||||
|
}
|
||||||
|
pos += token.Pos(i)
|
||||||
|
text = text[i:]
|
||||||
|
}
|
||||||
|
check.inStar = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(line, "+build") {
|
func (check *checker) goBuildLine(pos token.Pos, line string) {
|
||||||
fields := strings.Fields(line)
|
if !constraint.IsGoBuild(line) {
|
||||||
if fields[0] != "+build" {
|
if !strings.HasPrefix(line, "//go:build") && constraint.IsGoBuild("//"+strings.TrimSpace(line[len("//"):])) {
|
||||||
// Comment is something like +buildasdf not +build.
|
check.pass.Reportf(pos, "malformed //go:build line (space between // and go:build)")
|
||||||
return fmt.Errorf("possible malformed +build comment")
|
|
||||||
}
|
|
||||||
if pastCutoff {
|
|
||||||
return fmt.Errorf("+build comment must appear before package clause and be followed by a blank line")
|
|
||||||
}
|
|
||||||
if err := checkArguments(fields); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !check.goBuildOK || check.inStar {
|
||||||
|
check.pass.Reportf(pos, "misplaced //go:build comment")
|
||||||
|
check.crossCheck = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if check.goBuildPos == token.NoPos {
|
||||||
|
check.goBuildPos = pos
|
||||||
} else {
|
} else {
|
||||||
// Comment with +build but not at beginning.
|
check.pass.Reportf(pos, "unexpected extra //go:build line")
|
||||||
if !pastCutoff {
|
check.crossCheck = false
|
||||||
return fmt.Errorf("possible malformed +build comment")
|
}
|
||||||
}
|
|
||||||
|
// testing hack: stop at // ERROR
|
||||||
|
if i := strings.Index(line, " // ERROR "); i >= 0 {
|
||||||
|
line = line[:i]
|
||||||
|
}
|
||||||
|
|
||||||
|
x, err := constraint.Parse(line)
|
||||||
|
if err != nil {
|
||||||
|
check.pass.Reportf(pos, "%v", err)
|
||||||
|
check.crossCheck = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if check.goBuild == nil {
|
||||||
|
check.goBuild = x
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkArguments(fields []string) error {
|
func (check *checker) plusBuildLine(pos token.Pos, line string) {
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if !constraint.IsPlusBuild(line) {
|
||||||
|
// Comment with +build but not at beginning.
|
||||||
|
// Only report early in file.
|
||||||
|
if check.plusBuildOK && !strings.HasPrefix(line, "// want") {
|
||||||
|
check.pass.Reportf(pos, "possible malformed +build comment")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !check.plusBuildOK { // inStar implies !plusBuildOK
|
||||||
|
check.pass.Reportf(pos, "misplaced +build comment")
|
||||||
|
check.crossCheck = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if check.plusBuildPos == token.NoPos {
|
||||||
|
check.plusBuildPos = pos
|
||||||
|
}
|
||||||
|
|
||||||
|
// testing hack: stop at // ERROR
|
||||||
|
if i := strings.Index(line, " // ERROR "); i >= 0 {
|
||||||
|
line = line[:i]
|
||||||
|
}
|
||||||
|
|
||||||
|
fields := strings.Fields(line[len("//"):])
|
||||||
|
// IsPlusBuildConstraint check above implies fields[0] == "+build"
|
||||||
for _, arg := range fields[1:] {
|
for _, arg := range fields[1:] {
|
||||||
for _, elem := range strings.Split(arg, ",") {
|
for _, elem := range strings.Split(arg, ",") {
|
||||||
if strings.HasPrefix(elem, "!!") {
|
if strings.HasPrefix(elem, "!!") {
|
||||||
return fmt.Errorf("invalid double negative in build constraint: %s", arg)
|
check.pass.Reportf(pos, "invalid double negative in build constraint: %s", arg)
|
||||||
|
check.crossCheck = false
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
elem = strings.TrimPrefix(elem, "!")
|
elem = strings.TrimPrefix(elem, "!")
|
||||||
for _, c := range elem {
|
for _, c := range elem {
|
||||||
if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
|
if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
|
||||||
return fmt.Errorf("invalid non-alphanumeric build constraint: %s", arg)
|
check.pass.Reportf(pos, "invalid non-alphanumeric build constraint: %s", arg)
|
||||||
|
check.crossCheck = false
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
if check.crossCheck {
|
||||||
|
y, err := constraint.Parse(line)
|
||||||
|
if err != nil {
|
||||||
|
// Should never happen - constraint.Parse never rejects a // +build line.
|
||||||
|
// Also, we just checked the syntax above.
|
||||||
|
// Even so, report.
|
||||||
|
check.pass.Reportf(pos, "%v", err)
|
||||||
|
check.crossCheck = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if check.plusBuild == nil {
|
||||||
|
check.plusBuild = y
|
||||||
|
} else {
|
||||||
|
check.plusBuild = &constraint.AndExpr{X: check.plusBuild, Y: y}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
func (check *checker) finish() {
|
||||||
nl = []byte("\n")
|
if !check.crossCheck || check.plusBuildPos == token.NoPos || check.goBuildPos == token.NoPos {
|
||||||
slashSlash = []byte("//")
|
return
|
||||||
)
|
}
|
||||||
|
|
||||||
|
// Have both //go:build and // +build,
|
||||||
|
// with no errors found (crossCheck still true).
|
||||||
|
// Check they match.
|
||||||
|
var want constraint.Expr
|
||||||
|
lines, err := constraint.PlusBuildLines(check.goBuild)
|
||||||
|
if err != nil {
|
||||||
|
check.pass.Reportf(check.goBuildPos, "%v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, line := range lines {
|
||||||
|
y, err := constraint.Parse(line)
|
||||||
|
if err != nil {
|
||||||
|
// Definitely should not happen, but not the user's fault.
|
||||||
|
// Do not report.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if want == nil {
|
||||||
|
want = y
|
||||||
|
} else {
|
||||||
|
want = &constraint.AndExpr{X: want, Y: y}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if want.String() != check.plusBuild.String() {
|
||||||
|
check.pass.Reportf(check.plusBuildPos, "+build lines do not match //go:build condition")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
174
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag_old.go
generated
vendored
Normal file
174
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag_old.go
generated
vendored
Normal file
|
|
@ -0,0 +1,174 @@
|
||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// TODO(rsc): Delete this file once Go 1.17 comes out and we can retire Go 1.15 support.
|
||||||
|
|
||||||
|
//go:build !go1.16
|
||||||
|
// +build !go1.16
|
||||||
|
|
||||||
|
// Package buildtag defines an Analyzer that checks build tags.
|
||||||
|
package buildtag
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"go/ast"
|
||||||
|
"go/parser"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
|
"golang.org/x/tools/go/analysis"
|
||||||
|
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Doc = "check that +build tags are well-formed and correctly located"
|
||||||
|
|
||||||
|
var Analyzer = &analysis.Analyzer{
|
||||||
|
Name: "buildtag",
|
||||||
|
Doc: Doc,
|
||||||
|
Run: runBuildTag,
|
||||||
|
}
|
||||||
|
|
||||||
|
func runBuildTag(pass *analysis.Pass) (interface{}, error) {
|
||||||
|
for _, f := range pass.Files {
|
||||||
|
checkGoFile(pass, f)
|
||||||
|
}
|
||||||
|
for _, name := range pass.OtherFiles {
|
||||||
|
if err := checkOtherFile(pass, name); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, name := range pass.IgnoredFiles {
|
||||||
|
if strings.HasSuffix(name, ".go") {
|
||||||
|
f, err := parser.ParseFile(pass.Fset, name, nil, parser.ParseComments)
|
||||||
|
if err != nil {
|
||||||
|
// Not valid Go source code - not our job to diagnose, so ignore.
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
checkGoFile(pass, f)
|
||||||
|
} else {
|
||||||
|
if err := checkOtherFile(pass, name); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkGoFile(pass *analysis.Pass, f *ast.File) {
|
||||||
|
pastCutoff := false
|
||||||
|
for _, group := range f.Comments {
|
||||||
|
// A +build comment is ignored after or adjoining the package declaration.
|
||||||
|
if group.End()+1 >= f.Package {
|
||||||
|
pastCutoff = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// "+build" is ignored within or after a /*...*/ comment.
|
||||||
|
if !strings.HasPrefix(group.List[0].Text, "//") {
|
||||||
|
pastCutoff = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check each line of a //-comment.
|
||||||
|
for _, c := range group.List {
|
||||||
|
if !strings.Contains(c.Text, "+build") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := checkLine(c.Text, pastCutoff); err != nil {
|
||||||
|
pass.Reportf(c.Pos(), "%s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkOtherFile(pass *analysis.Pass, filename string) error {
|
||||||
|
content, tf, err := analysisutil.ReadFile(pass.Fset, filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// We must look at the raw lines, as build tags may appear in non-Go
|
||||||
|
// files such as assembly files.
|
||||||
|
lines := bytes.SplitAfter(content, nl)
|
||||||
|
|
||||||
|
// Determine cutpoint where +build comments are no longer valid.
|
||||||
|
// They are valid in leading // comments in the file followed by
|
||||||
|
// a blank line.
|
||||||
|
//
|
||||||
|
// This must be done as a separate pass because of the
|
||||||
|
// requirement that the comment be followed by a blank line.
|
||||||
|
var cutoff int
|
||||||
|
for i, line := range lines {
|
||||||
|
line = bytes.TrimSpace(line)
|
||||||
|
if !bytes.HasPrefix(line, slashSlash) {
|
||||||
|
if len(line) > 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
cutoff = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, line := range lines {
|
||||||
|
line = bytes.TrimSpace(line)
|
||||||
|
if !bytes.HasPrefix(line, slashSlash) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !bytes.Contains(line, []byte("+build")) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := checkLine(string(line), i >= cutoff); err != nil {
|
||||||
|
pass.Reportf(analysisutil.LineStart(tf, i+1), "%s", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkLine checks a line that starts with "//" and contains "+build".
|
||||||
|
func checkLine(line string, pastCutoff bool) error {
|
||||||
|
line = strings.TrimPrefix(line, "//")
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
|
||||||
|
if strings.HasPrefix(line, "+build") {
|
||||||
|
fields := strings.Fields(line)
|
||||||
|
if fields[0] != "+build" {
|
||||||
|
// Comment is something like +buildasdf not +build.
|
||||||
|
return fmt.Errorf("possible malformed +build comment")
|
||||||
|
}
|
||||||
|
if pastCutoff {
|
||||||
|
return fmt.Errorf("+build comment must appear before package clause and be followed by a blank line")
|
||||||
|
}
|
||||||
|
if err := checkArguments(fields); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Comment with +build but not at beginning.
|
||||||
|
if !pastCutoff {
|
||||||
|
return fmt.Errorf("possible malformed +build comment")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkArguments(fields []string) error {
|
||||||
|
for _, arg := range fields[1:] {
|
||||||
|
for _, elem := range strings.Split(arg, ",") {
|
||||||
|
if strings.HasPrefix(elem, "!!") {
|
||||||
|
return fmt.Errorf("invalid double negative in build constraint: %s", arg)
|
||||||
|
}
|
||||||
|
elem = strings.TrimPrefix(elem, "!")
|
||||||
|
for _, c := range elem {
|
||||||
|
if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
|
||||||
|
return fmt.Errorf("invalid non-alphanumeric build constraint: %s", arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
nl = []byte("\n")
|
||||||
|
slashSlash = []byte("//")
|
||||||
|
)
|
||||||
67
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure/loopclosure.go
generated
vendored
67
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure/loopclosure.go
generated
vendored
|
|
@ -8,22 +8,14 @@ package loopclosure
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go/ast"
|
"go/ast"
|
||||||
|
"go/types"
|
||||||
|
|
||||||
"golang.org/x/tools/go/analysis"
|
"golang.org/x/tools/go/analysis"
|
||||||
"golang.org/x/tools/go/analysis/passes/inspect"
|
"golang.org/x/tools/go/analysis/passes/inspect"
|
||||||
"golang.org/x/tools/go/ast/inspector"
|
"golang.org/x/tools/go/ast/inspector"
|
||||||
|
"golang.org/x/tools/go/types/typeutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO(adonovan): also report an error for the following structure,
|
|
||||||
// which is often used to ensure that deferred calls do not accumulate
|
|
||||||
// in a loop:
|
|
||||||
//
|
|
||||||
// for i, x := range c {
|
|
||||||
// func() {
|
|
||||||
// ...reference to i or x...
|
|
||||||
// }()
|
|
||||||
// }
|
|
||||||
|
|
||||||
const Doc = `check references to loop variables from within nested functions
|
const Doc = `check references to loop variables from within nested functions
|
||||||
|
|
||||||
This analyzer checks for references to loop variables from within a
|
This analyzer checks for references to loop variables from within a
|
||||||
|
|
@ -95,16 +87,19 @@ func run(pass *analysis.Pass) (interface{}, error) {
|
||||||
if len(body.List) == 0 {
|
if len(body.List) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var last *ast.CallExpr
|
// The function invoked in the last return statement.
|
||||||
|
var fun ast.Expr
|
||||||
switch s := body.List[len(body.List)-1].(type) {
|
switch s := body.List[len(body.List)-1].(type) {
|
||||||
case *ast.GoStmt:
|
case *ast.GoStmt:
|
||||||
last = s.Call
|
fun = s.Call.Fun
|
||||||
case *ast.DeferStmt:
|
case *ast.DeferStmt:
|
||||||
last = s.Call
|
fun = s.Call.Fun
|
||||||
default:
|
case *ast.ExprStmt: // check for errgroup.Group.Go()
|
||||||
return
|
if call, ok := s.X.(*ast.CallExpr); ok {
|
||||||
|
fun = goInvokes(pass.TypesInfo, call)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lit, ok := last.Fun.(*ast.FuncLit)
|
lit, ok := fun.(*ast.FuncLit)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -128,3 +123,43 @@ func run(pass *analysis.Pass) (interface{}, error) {
|
||||||
})
|
})
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// goInvokes returns a function expression that would be called asynchronously
|
||||||
|
// (but not awaited) in another goroutine as a consequence of the call.
|
||||||
|
// For example, given the g.Go call below, it returns the function literal expression.
|
||||||
|
//
|
||||||
|
// import "sync/errgroup"
|
||||||
|
// var g errgroup.Group
|
||||||
|
// g.Go(func() error { ... })
|
||||||
|
//
|
||||||
|
// Currently only "golang.org/x/sync/errgroup.Group()" is considered.
|
||||||
|
func goInvokes(info *types.Info, call *ast.CallExpr) ast.Expr {
|
||||||
|
f := typeutil.StaticCallee(info, call)
|
||||||
|
// Note: Currently only supports: golang.org/x/sync/errgroup.Go.
|
||||||
|
if f == nil || f.Name() != "Go" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
recv := f.Type().(*types.Signature).Recv()
|
||||||
|
if recv == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
rtype, ok := recv.Type().(*types.Pointer)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
named, ok := rtype.Elem().(*types.Named)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if named.Obj().Name() != "Group" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
pkg := f.Pkg()
|
||||||
|
if pkg == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if pkg.Path() != "golang.org/x/sync/errgroup" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return call.Args[0]
|
||||||
|
}
|
||||||
|
|
|
||||||
2
src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go
generated
vendored
2
src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go
generated
vendored
|
|
@ -97,7 +97,7 @@ func Main(analyzers ...*analysis.Analyzer) {
|
||||||
|
|
||||||
Usage of %[1]s:
|
Usage of %[1]s:
|
||||||
%.16[1]s unit.cfg # execute analysis specified by config file
|
%.16[1]s unit.cfg # execute analysis specified by config file
|
||||||
%.16[1]s help # general help
|
%.16[1]s help # general help, including listing analyzers and flags
|
||||||
%.16[1]s help name # help on specific analyzer and its flags
|
%.16[1]s help name # help on specific analyzer and its flags
|
||||||
`, progname)
|
`, progname)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|
|
||||||
1
src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker112.go
generated
vendored
1
src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker112.go
generated
vendored
|
|
@ -2,6 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.12
|
||||||
// +build go1.12
|
// +build go1.12
|
||||||
|
|
||||||
package unitchecker
|
package unitchecker
|
||||||
|
|
|
||||||
2
src/cmd/vendor/modules.txt
vendored
2
src/cmd/vendor/modules.txt
vendored
|
|
@ -44,7 +44,7 @@ golang.org/x/mod/zip
|
||||||
golang.org/x/sys/internal/unsafeheader
|
golang.org/x/sys/internal/unsafeheader
|
||||||
golang.org/x/sys/unix
|
golang.org/x/sys/unix
|
||||||
golang.org/x/sys/windows
|
golang.org/x/sys/windows
|
||||||
# golang.org/x/tools v0.0.0-20210107193943-4ed967dd8eff
|
# golang.org/x/tools v0.1.1-0.20210220032852-2363391a5b2f
|
||||||
## explicit
|
## explicit
|
||||||
golang.org/x/tools/go/analysis
|
golang.org/x/tools/go/analysis
|
||||||
golang.org/x/tools/go/analysis/internal/analysisflags
|
golang.org/x/tools/go/analysis/internal/analysisflags
|
||||||
|
|
|
||||||
1
src/cmd/vet/testdata/asm/asm1.s
vendored
1
src/cmd/vet/testdata/asm/asm1.s
vendored
|
|
@ -2,6 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build amd64
|
||||||
// +build amd64
|
// +build amd64
|
||||||
|
|
||||||
TEXT ·arg1(SB),0,$0-2
|
TEXT ·arg1(SB),0,$0-2
|
||||||
|
|
|
||||||
6
src/cmd/vet/testdata/buildtag/buildtag.go
vendored
6
src/cmd/vet/testdata/buildtag/buildtag.go
vendored
|
|
@ -4,12 +4,14 @@
|
||||||
|
|
||||||
// This file contains tests for the buildtag checker.
|
// This file contains tests for the buildtag checker.
|
||||||
|
|
||||||
// +builder // ERROR "possible malformed \+build comment"
|
// ERRORNEXT "possible malformed [+]build comment"
|
||||||
|
// +builder
|
||||||
// +build !ignore
|
// +build !ignore
|
||||||
|
|
||||||
package testdata
|
package testdata
|
||||||
|
|
||||||
// +build toolate // ERROR "build comment must appear before package clause and be followed by a blank line$"
|
// ERRORNEXT "misplaced \+build comment"
|
||||||
|
// +build toolate
|
||||||
|
|
||||||
var _ = 3
|
var _ = 3
|
||||||
|
|
||||||
|
|
|
||||||
22
src/cmd/vet/testdata/buildtag/buildtag2.go
vendored
Normal file
22
src/cmd/vet/testdata/buildtag/buildtag2.go
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// This file contains tests for the buildtag checker.
|
||||||
|
|
||||||
|
// ERRORNEXT "possible malformed [+]build comment"
|
||||||
|
// +builder
|
||||||
|
// +build !ignore
|
||||||
|
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
// ERRORNEXT "misplaced \+build comment"
|
||||||
|
// +build toolate
|
||||||
|
// ERRORNEXT "misplaced //go:build comment"
|
||||||
|
//go:build toolate
|
||||||
|
|
||||||
|
var _ = 3
|
||||||
|
|
||||||
|
var _ = `
|
||||||
|
// +build notacomment
|
||||||
|
`
|
||||||
15
src/cmd/vet/testdata/buildtag/buildtag3.go
vendored
Normal file
15
src/cmd/vet/testdata/buildtag/buildtag3.go
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// This file contains tests for the buildtag checker.
|
||||||
|
|
||||||
|
//go:build good
|
||||||
|
// ERRORNEXT "[+]build lines do not match //go:build condition"
|
||||||
|
// +build bad
|
||||||
|
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
var _ = `
|
||||||
|
// +build notacomment
|
||||||
|
`
|
||||||
11
src/cmd/vet/testdata/buildtag/buildtag4.go
vendored
Normal file
11
src/cmd/vet/testdata/buildtag/buildtag4.go
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// This file contains tests for the buildtag checker.
|
||||||
|
|
||||||
|
//go:build !(bad || worse)
|
||||||
|
// +build !bad
|
||||||
|
// +build !worse
|
||||||
|
|
||||||
|
package testdata
|
||||||
11
src/cmd/vet/testdata/buildtag/buildtag5.go
vendored
Normal file
11
src/cmd/vet/testdata/buildtag/buildtag5.go
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// This file contains tests for the buildtag checker.
|
||||||
|
|
||||||
|
//go:build !(bad || worse)
|
||||||
|
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
// +build other // ERROR "misplaced \+build comment"
|
||||||
9
src/cmd/vet/testdata/buildtag/buildtag6.s
vendored
Normal file
9
src/cmd/vet/testdata/buildtag/buildtag6.s
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#include "go_asm.h"
|
||||||
|
|
||||||
|
// ok because we cannot parse assembly files.
|
||||||
|
// +build no
|
||||||
|
|
||||||
11
src/cmd/vet/testdata/buildtag/buildtag7.s
vendored
Normal file
11
src/cmd/vet/testdata/buildtag/buildtag7.s
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
#include "go_asm.h"
|
||||||
|
|
||||||
|
// ok because we cannot parse assembly files
|
||||||
|
// the assembler would complain if we did assemble this file.
|
||||||
|
//go:build no
|
||||||
1
src/cmd/vet/testdata/tagtest/file1.go
vendored
1
src/cmd/vet/testdata/tagtest/file1.go
vendored
|
|
@ -2,6 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build testtag
|
||||||
// +build testtag
|
// +build testtag
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
|
||||||
1
src/cmd/vet/testdata/tagtest/file2.go
vendored
1
src/cmd/vet/testdata/tagtest/file2.go
vendored
|
|
@ -2,6 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !testtag
|
||||||
// +build !testtag
|
// +build !testtag
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
|
||||||
|
|
@ -334,8 +334,8 @@ type wantedError struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errRx = regexp.MustCompile(`// (?:GC_)?ERROR (.*)`)
|
errRx = regexp.MustCompile(`// (?:GC_)?ERROR(NEXT)? (.*)`)
|
||||||
errAutoRx = regexp.MustCompile(`// (?:GC_)?ERRORAUTO (.*)`)
|
errAutoRx = regexp.MustCompile(`// (?:GC_)?ERRORAUTO(NEXT)? (.*)`)
|
||||||
errQuotesRx = regexp.MustCompile(`"([^"]*)"`)
|
errQuotesRx = regexp.MustCompile(`"([^"]*)"`)
|
||||||
lineRx = regexp.MustCompile(`LINE(([+-])([0-9]+))?`)
|
lineRx = regexp.MustCompile(`LINE(([+-])([0-9]+))?`)
|
||||||
)
|
)
|
||||||
|
|
@ -364,7 +364,10 @@ func wantedErrors(file, short string) (errs []wantedError) {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
all := m[1]
|
if m[1] == "NEXT" {
|
||||||
|
lineNum++
|
||||||
|
}
|
||||||
|
all := m[2]
|
||||||
mm := errQuotesRx.FindAllStringSubmatch(all, -1)
|
mm := errQuotesRx.FindAllStringSubmatch(all, -1)
|
||||||
if mm == nil {
|
if mm == nil {
|
||||||
log.Fatalf("%s:%d: invalid errchk line: %s", file, lineNum, line)
|
log.Fatalf("%s:%d: invalid errchk line: %s", file, lineNum, line)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue