mirror of
https://github.com/golang/go
synced 2024-11-22 01:34:41 -07:00
gotype: clean handling of stdin, added tests
- removed uses of global variables - minor cleanups R=r CC=golang-dev https://golang.org/cl/4277044
This commit is contained in:
parent
86e35a96a7
commit
c734b50b11
@ -9,3 +9,6 @@ GOFILES=\
|
||||
gotype.go\
|
||||
|
||||
include ../../Make.cmd
|
||||
|
||||
test:
|
||||
gotest
|
||||
|
@ -55,3 +55,5 @@ To verify the output of a pipe:
|
||||
|
||||
*/
|
||||
package documentation
|
||||
|
||||
// BUG(gri): At the moment, only single-file scope analysis is performed.
|
||||
|
@ -30,11 +30,7 @@ var (
|
||||
)
|
||||
|
||||
|
||||
var (
|
||||
fset = token.NewFileSet()
|
||||
exitCode = 0
|
||||
parserMode = parser.DeclarationErrors
|
||||
)
|
||||
var exitCode = 0
|
||||
|
||||
|
||||
func usage() {
|
||||
@ -44,35 +40,21 @@ func usage() {
|
||||
}
|
||||
|
||||
|
||||
func processFlags() {
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
if *printTrace {
|
||||
parserMode |= parser.Trace
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func report(err os.Error) {
|
||||
scanner.PrintError(os.Stderr, err)
|
||||
exitCode = 2
|
||||
}
|
||||
|
||||
|
||||
// parseFile returns the AST for the given file.
|
||||
// The result
|
||||
func parseFile(filename string) *ast.File {
|
||||
// parse returns the AST for the Go source src.
|
||||
// The filename is for error reporting only.
|
||||
// The result is nil if there were errors or if
|
||||
// the file does not belong to the -p package.
|
||||
func parse(fset *token.FileSet, filename string, src []byte) *ast.File {
|
||||
if *verbose {
|
||||
fmt.Println(filename)
|
||||
}
|
||||
|
||||
// get source
|
||||
src, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
report(err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ignore files with different package name
|
||||
if *pkgName != "" {
|
||||
file, err := parser.ParseFile(fset, filename, src, parser.PackageClauseOnly)
|
||||
@ -89,7 +71,11 @@ func parseFile(filename string) *ast.File {
|
||||
}
|
||||
|
||||
// parse entire file
|
||||
file, err := parser.ParseFile(fset, filename, src, parserMode)
|
||||
mode := parser.DeclarationErrors
|
||||
if *printTrace {
|
||||
mode |= parser.Trace
|
||||
}
|
||||
file, err := parser.ParseFile(fset, filename, src, mode)
|
||||
if err != nil {
|
||||
report(err)
|
||||
return nil
|
||||
@ -102,33 +88,38 @@ func parseFile(filename string) *ast.File {
|
||||
}
|
||||
|
||||
|
||||
// BUG(gri): At the moment, only single-file scope analysis is performed.
|
||||
func parseStdin(fset *token.FileSet) (files map[string]*ast.File) {
|
||||
files = make(map[string]*ast.File)
|
||||
src, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
report(err)
|
||||
return
|
||||
}
|
||||
const filename = "<standard input>"
|
||||
if file := parse(fset, filename, src); file != nil {
|
||||
files[filename] = file
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func processPackage(filenames []string) {
|
||||
var files []*ast.File
|
||||
pkgName := ""
|
||||
|
||||
func parseFiles(fset *token.FileSet, filenames []string) (files map[string]*ast.File) {
|
||||
files = make(map[string]*ast.File)
|
||||
for _, filename := range filenames {
|
||||
file := parseFile(filename)
|
||||
if file == nil {
|
||||
continue // ignore file
|
||||
src, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
report(err)
|
||||
continue
|
||||
}
|
||||
// package names must match
|
||||
// TODO(gri): this check should be moved into a
|
||||
// function making the package below
|
||||
if pkgName == "" {
|
||||
// first package file
|
||||
pkgName = file.Name.Name
|
||||
} else {
|
||||
if file.Name.Name != pkgName {
|
||||
report(os.NewError(fmt.Sprintf("file %q is in package %q not %q", filename, file.Name.Name, pkgName)))
|
||||
if file := parse(fset, filename, src); file != nil {
|
||||
if files[filename] != nil {
|
||||
report(os.ErrorString(fmt.Sprintf("%q: duplicate file", filename)))
|
||||
continue
|
||||
}
|
||||
files[filename] = file
|
||||
}
|
||||
files = append(files, file)
|
||||
}
|
||||
|
||||
// TODO(gri): make a ast.Package and analyze it
|
||||
_ = files
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -174,15 +165,31 @@ func processFiles(filenames []string, allFiles bool) {
|
||||
}
|
||||
}
|
||||
}
|
||||
processPackage(filenames[0:i])
|
||||
processPackage(parseFiles(token.NewFileSet(), filenames[0:i]))
|
||||
}
|
||||
|
||||
|
||||
func processPackage(files map[string]*ast.File) {
|
||||
// TODO(gri) Enable this code once we have ast.NewPackage.
|
||||
/*
|
||||
// make a package (resolve all identifiers)
|
||||
pkg, err := ast.NewPackage(files)
|
||||
if err != nil {
|
||||
report(err)
|
||||
return
|
||||
}
|
||||
// TODO(gri): typecheck package
|
||||
_ = pkg
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
func main() {
|
||||
processFlags()
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
if flag.NArg() == 0 {
|
||||
processPackage([]string{os.Stdin.Name()})
|
||||
processPackage(parseStdin(token.NewFileSet()))
|
||||
} else {
|
||||
processFiles(flag.Args(), true)
|
||||
}
|
||||
|
29
src/cmd/gotype/gotype_test.go
Normal file
29
src/cmd/gotype/gotype_test.go
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2011 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 main
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
||||
func testDir(t *testing.T, dir, pkg string) {
|
||||
*pkgName = pkg
|
||||
*recursive = false
|
||||
processDirectory(dir)
|
||||
if exitCode != 0 {
|
||||
t.Errorf("processing %d failed: exitCode = %d", dir, exitCode)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func Test(t *testing.T) {
|
||||
testDir(t, ".", "main")
|
||||
testDir(t, filepath.Join(runtime.GOROOT(), "src/pkg/go/ast"), "ast")
|
||||
testDir(t, filepath.Join(runtime.GOROOT(), "src/pkg/go/scanner"), "scanner")
|
||||
testDir(t, filepath.Join(runtime.GOROOT(), "src/pkg/go/parser"), "parser")
|
||||
}
|
@ -192,7 +192,6 @@ NOTEST=\
|
||||
../cmd/ebnflint\
|
||||
../cmd/godoc\
|
||||
../cmd/gofmt\
|
||||
../cmd/gotype\
|
||||
../cmd/govet\
|
||||
../cmd/goyacc\
|
||||
../cmd/hgpatch\
|
||||
|
Loading…
Reference in New Issue
Block a user