mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
go.tools/cmd/vet: update to new go/types package
Now that it's in the same repository as the go/types package we can delete the mechanism to build it without type checking. Add a make rule to install it where the go tool can find it. Why doesn't "go install" take a -o flag? R=gri CC=gobot, golang-dev https://golang.org/cl/9526043
This commit is contained in:
parent
113d6d30b1
commit
08cc526448
@ -4,11 +4,11 @@
|
||||
|
||||
# Assumes go/types is installed
|
||||
test testshort:
|
||||
go build -tags 'vet_test gotypes'
|
||||
go build
|
||||
$(GOROOT)/test/errchk ./vet -printfuncs='Warn:1,Warnf:1' test_*.go test_*.s
|
||||
|
||||
test_notypes:
|
||||
go build -tags 'vet_test'
|
||||
# Only those tests that do not depend on types.
|
||||
# Excluded: test_print.go
|
||||
$(GOROOT)/test/errchk ./vet -printfuncs='Warn:1,Warnf:1' test_asm.go test_assign.go test_atomic.go test_buildtag.go test_buildtag_bad.go test_deadcode.go test_method.go test_rangeloop.go test_structtag.go test_taglit.go test_*.s
|
||||
# Install command where the go tool can find it.
|
||||
install:
|
||||
go build -o _vet
|
||||
cp _vet $(GOROOT)/pkg/tool/$(GOOS)_$(GOARCH)/vet
|
||||
rm -f _vet
|
||||
|
@ -20,6 +20,9 @@ import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.google.com/p/go.tools/go/exact"
|
||||
"code.google.com/p/go.tools/go/types"
|
||||
)
|
||||
|
||||
var verbose = flag.Bool("v", false, "verbose")
|
||||
@ -41,6 +44,8 @@ var report = map[string]*bool{
|
||||
"unreachable": flag.Bool("unreachable", false, "check for unreachable code"),
|
||||
}
|
||||
|
||||
// TODO: Need a flag to set build tags when parsing the package.
|
||||
|
||||
// vet tells whether to report errors for the named check, a flag name.
|
||||
func vet(name string) bool {
|
||||
return *report["all"] || *report[name]
|
||||
@ -136,7 +141,7 @@ func main() {
|
||||
}
|
||||
return
|
||||
}
|
||||
doPackage(flag.Args())
|
||||
doPackage(".", flag.Args())
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
|
||||
@ -168,23 +173,24 @@ func doPackageDir(directory string) {
|
||||
names = append(names, pkg.TestGoFiles...) // These are also in the "foo" package.
|
||||
names = append(names, pkg.SFiles...)
|
||||
prefixDirectory(directory, names)
|
||||
doPackage(names)
|
||||
doPackage(directory, names)
|
||||
// Is there also a "foo_test" package? If so, do that one as well.
|
||||
if len(pkg.XTestGoFiles) > 0 {
|
||||
names = pkg.XTestGoFiles
|
||||
prefixDirectory(directory, names)
|
||||
doPackage(names)
|
||||
doPackage(directory, names)
|
||||
}
|
||||
}
|
||||
|
||||
type Package struct {
|
||||
types map[ast.Expr]Type
|
||||
values map[ast.Expr]ExactValue
|
||||
path string
|
||||
types map[ast.Expr]types.Type
|
||||
values map[ast.Expr]exact.Value
|
||||
files []*File
|
||||
}
|
||||
|
||||
// doPackage analyzes the single package constructed from the named files.
|
||||
func doPackage(names []string) {
|
||||
func doPackage(directory string, names []string) {
|
||||
var files []*File
|
||||
var astFiles []*ast.File
|
||||
fs := token.NewFileSet()
|
||||
@ -214,6 +220,7 @@ func doPackage(names []string) {
|
||||
files = append(files, &File{fset: fs, content: data, name: name, file: parsedFile})
|
||||
}
|
||||
pkg := new(Package)
|
||||
pkg.path = directory
|
||||
pkg.files = files
|
||||
// Type check the package.
|
||||
err := pkg.check(fs, astFiles)
|
||||
|
@ -2,11 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build gotypes
|
||||
|
||||
// This file contains the pieces of the tool that require the go/types package.
|
||||
// To compile this file, you must first run
|
||||
// $ go get code.google.com/p/go.tools/go/types
|
||||
// This file contains the pieces of the tool that use typechecking from the go/types package.
|
||||
|
||||
package main
|
||||
|
||||
@ -18,22 +14,9 @@ import (
|
||||
"code.google.com/p/go.tools/go/types"
|
||||
)
|
||||
|
||||
// Type is equivalent to types.Type. Repeating it here allows us to avoid
|
||||
// having main depend on the go/types package.
|
||||
type Type interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
// ExactValue is equivalent to exact.Value. Repeating it here allows us to
|
||||
// avoid having main depend on the go/exact package.
|
||||
type ExactValue interface {
|
||||
Kind() exact.Kind
|
||||
String() string
|
||||
}
|
||||
|
||||
func (pkg *Package) check(fs *token.FileSet, astFiles []*ast.File) error {
|
||||
pkg.types = make(map[ast.Expr]Type)
|
||||
pkg.values = make(map[ast.Expr]ExactValue)
|
||||
pkg.types = make(map[ast.Expr]types.Type)
|
||||
pkg.values = make(map[ast.Expr]exact.Value)
|
||||
exprFn := func(x ast.Expr, typ types.Type, val exact.Value) {
|
||||
pkg.types[x] = typ
|
||||
if val != nil {
|
||||
@ -46,7 +29,7 @@ func (pkg *Package) check(fs *token.FileSet, astFiles []*ast.File) error {
|
||||
Expr: exprFn,
|
||||
Error: func(error) {},
|
||||
}
|
||||
_, err := context.Check(fs, astFiles)
|
||||
_, err := context.Check(pkg.path, fs, astFiles...)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -55,10 +38,11 @@ func (pkg *Package) check(fs *token.FileSet, astFiles []*ast.File) error {
|
||||
func (pkg *Package) isStruct(c *ast.CompositeLit) (bool, string) {
|
||||
// Check that the CompositeLit's type is a slice or array (which needs no tag), if possible.
|
||||
typ := pkg.types[c]
|
||||
// If it's a named type, pull out the underlying type.
|
||||
// If it's a named type, pull out the underlying type. If it's not, the Underlying
|
||||
// method returns the type itself.
|
||||
actual := typ
|
||||
if namedType, ok := typ.(*types.NamedType); ok {
|
||||
actual = namedType.Underlying
|
||||
if actual != nil {
|
||||
actual = actual.Underlying()
|
||||
}
|
||||
if actual == nil {
|
||||
// No type information available. Assume true, so we do the check.
|
||||
@ -82,7 +66,7 @@ func (f *File) matchArgType(t printfArgType, arg ast.Expr) bool {
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
switch basic.Kind {
|
||||
switch basic.Kind() {
|
||||
case types.Bool:
|
||||
return t&argBool != 0
|
||||
case types.Int, types.Int8, types.Int16, types.Int32, types.Int64:
|
||||
@ -136,7 +120,7 @@ func (f *File) numArgsInSignature(call *ast.CallExpr) int {
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
return len(sig.Params)
|
||||
return sig.Params().Len()
|
||||
}
|
||||
|
||||
// isErrorMethodCall reports whether the call is of a method with signature
|
||||
@ -168,16 +152,16 @@ func (f *File) isErrorMethodCall(call *ast.CallExpr) bool {
|
||||
return false
|
||||
}
|
||||
// There must be no arguments. Already verified by type checking, but be thorough.
|
||||
if len(sig.Params) > 0 {
|
||||
if sig.Params().Len() > 0 {
|
||||
return false
|
||||
}
|
||||
// Finally the real questions.
|
||||
// There must be one result.
|
||||
if len(sig.Results) != 1 {
|
||||
if sig.Results().Len() != 1 {
|
||||
return false
|
||||
}
|
||||
// It must have return type "string" from the universe.
|
||||
result := sig.Results[0].Type
|
||||
result := sig.Results().At(0).Type()
|
||||
if types.IsIdentical(result, types.Typ[types.String]) {
|
||||
return true
|
||||
}
|
||||
|
@ -1,50 +0,0 @@
|
||||
// Copyright 2010 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 !gotypes
|
||||
|
||||
// This file contains stubs for the pieces of the tool that require the go/types package,
|
||||
// to be used if go/types is not available.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/token"
|
||||
)
|
||||
|
||||
// Type is equivalent to go/types.Type. Repeating it here allows us to avoid
|
||||
// having main depend on the go/types package.
|
||||
type Type interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
// ExactValue is a stub for exact.Value. Stubbing it here allows us to
|
||||
// avoid having main depend on the go/exact package.
|
||||
type ExactValue interface {
|
||||
}
|
||||
|
||||
func (pkg *Package) check(fs *token.FileSet, astFiles []*ast.File) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pkg *Package) isStruct(c *ast.CompositeLit) (bool, string) {
|
||||
return true, "" // Assume true, so we do the check.
|
||||
}
|
||||
|
||||
func (f *File) matchArgType(t printfArgType, arg ast.Expr) bool {
|
||||
return true // We can't tell without types.
|
||||
}
|
||||
|
||||
func (f *File) numArgsInSignature(call *ast.CallExpr) int {
|
||||
return 0 // We don't know.
|
||||
}
|
||||
|
||||
func (f *File) isErrorMethodCall(call *ast.CallExpr) bool {
|
||||
// Is it a selector expression? Otherwise it's a function call, not a method call.
|
||||
if _, ok := call.Fun.(*ast.SelectorExpr); !ok {
|
||||
return false
|
||||
}
|
||||
return true // Best guess we can make without types.
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user