Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1020)

Unified Diff: src/cmd/vet/main.go

Issue 7393052: code review 7393052: cmd/vet: restructure to be package-driven (Closed)
Patch Set: diff -r 91778e3920ae https://code.google.com/p/go Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/cmd/vet/method.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/cmd/vet/main.go
===================================================================
--- a/src/cmd/vet/main.go
+++ b/src/cmd/vet/main.go
@@ -11,10 +11,11 @@
"flag"
"fmt"
"go/ast"
+ "go/build"
"go/parser"
"go/printer"
"go/token"
- "io"
+ "go/types"
"io/ioutil"
"os"
"path/filepath"
@@ -54,6 +55,8 @@
// Usage is a replacement usage function for the flags package.
func Usage() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
+ fmt.Fprintf(os.Stderr, "\tvet [flags] directory...\n")
+ fmt.Fprintf(os.Stderr, "\tvet [flags] files... # Must be a single package\n")
flag.PrintDefaults()
os.Exit(2)
}
@@ -62,6 +65,7 @@
// The parse tree walkers are all methods of this type.
type File struct {
fset *token.FileSet
+ name string
file *ast.File
b bytes.Buffer // for use by methods
}
@@ -102,56 +106,104 @@
}
if flag.NArg() == 0 {
- doFile("stdin", os.Stdin)
- } else {
- for _, name := range flag.Args() {
- // Is it a directory?
- if fi, err := os.Stat(name); err == nil && fi.IsDir() {
- walkDir(name)
- } else {
- doFile(name, nil)
- }
+ Usage()
+ }
+ dirs := false
+ files := false
+ for _, name := range flag.Args() {
+ // Is it a directory?
+ fi, err := os.Stat(name)
+ if err != nil {
+ warnf("error walking tree: %s", err)
+ continue
+ }
+ if fi.IsDir() {
+ dirs = true
+ } else {
+ files = true
}
}
+ if dirs && files {
+ Usage()
+ }
+ if dirs {
+ for _, name := range flag.Args() {
+ walkDir(name)
+ }
+ return
+ }
+ doPackage(flag.Args())
os.Exit(exitCode)
}
-// doFile analyzes one file. If the reader is nil, the source code is read from the
-// named file.
-func doFile(name string, reader io.Reader) {
- if reader == nil {
+// doPackageDir analyzes the single package found in the directory, if there is one.
+func doPackageDir(directory string) {
+ pkg, err := build.Default.ImportDir(directory, 0)
+ if err != nil {
+ // If it's just that there are no go source files, that's fine.
+ if _, nogo := err.(*build.NoGoError); nogo {
+ return
+ }
+ // Non-fatal: we are doing a recursive walk and there may be other directories.
+ warnf("cannot process directory %s: %s", directory, err)
+ return
+ }
+ names := append(pkg.GoFiles, pkg.CgoFiles...)
+ // Prefix file names with directory names.
+ if directory != "." {
+ for i, name := range names {
+ names[i] = filepath.Join(directory, name)
+ }
+ }
+ doPackage(names)
+}
+
+// doPackage analyzes the single package constructed from the named files.
+func doPackage(names []string) {
+ var files []*File
+ var astFiles []*ast.File
+ fs := token.NewFileSet()
+ for _, name := range names {
f, err := os.Open(name)
if err != nil {
errorf("%s: %s", name, err)
- return
}
defer f.Close()
- reader = f
+ data, err := ioutil.ReadAll(f)
+ if err != nil {
+ errorf("%s: %s", name, err)
+ }
+ checkBuildTag(name, data)
+ parsedFile, err := parser.ParseFile(fs, name, bytes.NewReader(data), 0)
+ if err != nil {
+ errorf("%s: %s", name, err)
+ }
+ files = append(files, &File{fset: fs, name: name, file: parsedFile})
+ astFiles = append(astFiles, parsedFile)
}
- data, err := ioutil.ReadAll(reader)
+ context := types.Context{
+ // TODO: set up Expr, Ident.
+ }
+ // Type check the package.
+ pkg, err := context.Check(fs, astFiles)
if err != nil {
- errorf("%s: %s", name, err)
- return
+ warnf("%s", err)
}
- checkBuildTag(name, data)
- fs := token.NewFileSet()
- parsedFile, err := parser.ParseFile(fs, name, bytes.NewReader(data), 0)
- if err != nil {
- errorf("%s: %s", name, err)
- return
+ _ = pkg
+ for _, file := range files {
+ file.walkFile(file.name, file.file)
}
- file := &File{fset: fs, file: parsedFile}
- file.walkFile(name, parsedFile)
}
func visit(path string, f os.FileInfo, err error) error {
if err != nil {
errorf("walk error: %s", err)
+ }
+ // One package per directory. Ignore the files themselves.
+ if !f.IsDir() {
return nil
}
- if !f.IsDir() && strings.HasSuffix(path, ".go") {
- doFile(path, nil)
- }
+ doPackageDir(path)
return nil
}
@@ -160,11 +212,18 @@
filepath.Walk(root, visit)
}
-// error formats the error to standard error, adding program
-// identification and a newline
+// errorf formats the error to standard error, adding program
+// identification and a newline, and exits.
func errorf(format string, args ...interface{}) {
fmt.Fprintf(os.Stderr, "vet: "+format+"\n", args...)
- setExit(2)
+ os.Exit(2)
+}
+
+// warnf formats the error to standard error, adding program
+// identification and a newline, but does not exit.
+func warnf(format string, args ...interface{}) {
+ fmt.Fprintf(os.Stderr, "vet: "+format+"\n", args...)
+ setExit(1)
}
// Println is fmt.Println guarded by -v.
@@ -240,7 +299,7 @@
return f
}
-// walkCall walks an assignment statement
+// walkAssignStmt walks an assignment statement
func (f *File) walkAssignStmt(stmt *ast.AssignStmt) {
f.checkAtomicAssignment(stmt)
}
« no previous file with comments | « no previous file | src/cmd/vet/method.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b