mirror of
https://github.com/golang/go
synced 2024-11-22 07:14:40 -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\
|
gotype.go\
|
||||||
|
|
||||||
include ../../Make.cmd
|
include ../../Make.cmd
|
||||||
|
|
||||||
|
test:
|
||||||
|
gotest
|
||||||
|
@ -55,3 +55,5 @@ To verify the output of a pipe:
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
package documentation
|
package documentation
|
||||||
|
|
||||||
|
// BUG(gri): At the moment, only single-file scope analysis is performed.
|
||||||
|
@ -30,11 +30,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
var (
|
var exitCode = 0
|
||||||
fset = token.NewFileSet()
|
|
||||||
exitCode = 0
|
|
||||||
parserMode = parser.DeclarationErrors
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func usage() {
|
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) {
|
func report(err os.Error) {
|
||||||
scanner.PrintError(os.Stderr, err)
|
scanner.PrintError(os.Stderr, err)
|
||||||
exitCode = 2
|
exitCode = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// parseFile returns the AST for the given file.
|
// parse returns the AST for the Go source src.
|
||||||
// The result
|
// The filename is for error reporting only.
|
||||||
func parseFile(filename string) *ast.File {
|
// 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 {
|
if *verbose {
|
||||||
fmt.Println(filename)
|
fmt.Println(filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get source
|
|
||||||
src, err := ioutil.ReadFile(filename)
|
|
||||||
if err != nil {
|
|
||||||
report(err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ignore files with different package name
|
// ignore files with different package name
|
||||||
if *pkgName != "" {
|
if *pkgName != "" {
|
||||||
file, err := parser.ParseFile(fset, filename, src, parser.PackageClauseOnly)
|
file, err := parser.ParseFile(fset, filename, src, parser.PackageClauseOnly)
|
||||||
@ -89,7 +71,11 @@ func parseFile(filename string) *ast.File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parse entire 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 {
|
if err != nil {
|
||||||
report(err)
|
report(err)
|
||||||
return nil
|
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
|
func parseFiles(fset *token.FileSet, filenames []string) (files map[string]*ast.File) {
|
||||||
pkgName := ""
|
files = make(map[string]*ast.File)
|
||||||
for _, filename := range filenames {
|
for _, filename := range filenames {
|
||||||
file := parseFile(filename)
|
src, err := ioutil.ReadFile(filename)
|
||||||
if file == nil {
|
if err != nil {
|
||||||
continue // ignore file
|
report(err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
// package names must match
|
if file := parse(fset, filename, src); file != nil {
|
||||||
// TODO(gri): this check should be moved into a
|
if files[filename] != nil {
|
||||||
// function making the package below
|
report(os.ErrorString(fmt.Sprintf("%q: duplicate file", filename)))
|
||||||
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)))
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
files[filename] = file
|
||||||
}
|
}
|
||||||
files = append(files, file)
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
// TODO(gri): make a ast.Package and analyze it
|
|
||||||
_ = files
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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() {
|
func main() {
|
||||||
processFlags()
|
flag.Usage = usage
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
if flag.NArg() == 0 {
|
if flag.NArg() == 0 {
|
||||||
processPackage([]string{os.Stdin.Name()})
|
processPackage(parseStdin(token.NewFileSet()))
|
||||||
} else {
|
} else {
|
||||||
processFiles(flag.Args(), true)
|
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/ebnflint\
|
||||||
../cmd/godoc\
|
../cmd/godoc\
|
||||||
../cmd/gofmt\
|
../cmd/gofmt\
|
||||||
../cmd/gotype\
|
|
||||||
../cmd/govet\
|
../cmd/govet\
|
||||||
../cmd/goyacc\
|
../cmd/goyacc\
|
||||||
../cmd/hgpatch\
|
../cmd/hgpatch\
|
||||||
|
Loading…
Reference in New Issue
Block a user