]> Cypherpunks repositories - gostls13.git/commitdiff
gotype: clean handling of stdin, added tests
authorRobert Griesemer <gri@golang.org>
Sat, 12 Mar 2011 00:15:33 +0000 (16:15 -0800)
committerRobert Griesemer <gri@golang.org>
Sat, 12 Mar 2011 00:15:33 +0000 (16:15 -0800)
- removed uses of global variables
- minor cleanups

R=r
CC=golang-dev
https://golang.org/cl/4277044

src/cmd/gotype/Makefile
src/cmd/gotype/doc.go
src/cmd/gotype/gotype.go
src/cmd/gotype/gotype_test.go [new file with mode: 0644]
src/pkg/Makefile

index ac9e3bef44f11fd7463b1044c5a5b8d571178370..929fc52de1e2986e174555ba6792bb92c94c6a9e 100644 (file)
@@ -9,3 +9,6 @@ GOFILES=\
        gotype.go\
 
 include ../../Make.cmd
+
+test:
+       gotest
index 1bd4b5f6cf7d76895a8280eaf67312db1f36ac9a..ec4eb7c2448b5c1f5a47d76153a964d6631294f9 100644 (file)
@@ -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.
index 435f1aa941d969ff42cc80fd4a18e0ec797afcec..0d57c18a65ac252dee187b3c452973bb7202bdee 100644 (file)
@@ -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)
        }
diff --git a/src/cmd/gotype/gotype_test.go b/src/cmd/gotype/gotype_test.go
new file mode 100644 (file)
index 0000000..ddd958c
--- /dev/null
@@ -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")
+}
index ccba63b6aa8c3539021be10516d3255cf5ba08ab..3edb1e60bd0e9846a7ab944dd0ae84a6e4ab0543 100644 (file)
@@ -192,7 +192,6 @@ NOTEST=\
        ../cmd/ebnflint\
        ../cmd/godoc\
        ../cmd/gofmt\
-       ../cmd/gotype\
        ../cmd/govet\
        ../cmd/goyacc\
        ../cmd/hgpatch\