]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: add test typechecking std lib
authorRobert Griesemer <gri@golang.org>
Tue, 5 Mar 2013 19:42:43 +0000 (11:42 -0800)
committerRobert Griesemer <gri@golang.org>
Tue, 5 Mar 2013 19:42:43 +0000 (11:42 -0800)
- run time is limited if -short is set
- also added missing TODO to unrelated file return.go

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

src/pkg/go/types/return.go
src/pkg/go/types/stdlib_test.go [new file with mode: 0644]

index 5806fb25da3ffabb2be58771ed82c9a8c2a87d73..8644d28c91b840aad50d68e83ebd714e6ebbd53d 100644 (file)
@@ -81,7 +81,6 @@ func (check *checker) isTerminating(s ast.Stmt, label string) bool {
                if s.Cond == nil && !hasBreak(s.Body, label, true) {
                        return true
                }
-
        }
 
        return false
@@ -106,6 +105,10 @@ func (check *checker) isTerminatingSwitch(body *ast.BlockStmt, label string) boo
        return hasDefault
 }
 
+// TODO(gri) For nested breakable statements, the current implementation of hasBreak
+//          will traverse the same subtree repeatedly, once for each label. Replace
+//           with a single-pass label/break matching phase.
+
 // hasBreak reports if s is or contains a break statement
 // referring to the label-ed statement or implicit-ly the
 // closest outer breakable statement.
diff --git a/src/pkg/go/types/stdlib_test.go b/src/pkg/go/types/stdlib_test.go
new file mode 100644 (file)
index 0000000..8b26411
--- /dev/null
@@ -0,0 +1,133 @@
+// Copyright 2013 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.
+
+// This file tests types.Check by using it to
+// typecheck the standard library.
+
+package types
+
+import (
+       "flag"
+       "fmt"
+       "go/ast"
+       "go/build"
+       "go/parser"
+       "go/scanner"
+       "go/token"
+       "io/ioutil"
+       "path/filepath"
+       "runtime"
+       "testing"
+       "time"
+)
+
+var verbose = flag.Bool("types.v", false, "verbose mode")
+
+var (
+       pkgCount int // number of packages processed
+       start    = time.Now()
+)
+
+func TestStdlib(t *testing.T) {
+       walkDirs(t, filepath.Join(runtime.GOROOT(), "src/pkg"))
+       if *verbose {
+               fmt.Println(pkgCount, "packages typechecked in", time.Since(start))
+       }
+}
+
+// Package paths of excluded packages.
+var excluded = map[string]bool{
+       "builtin": true,
+}
+
+// typecheck typechecks the given package files.
+func typecheck(t *testing.T, filenames []string) {
+       fset := token.NewFileSet()
+
+       // parse package files
+       var files []*ast.File
+       for _, filename := range filenames {
+               file, err := parser.ParseFile(fset, filename, nil, parser.DeclarationErrors|parser.AllErrors)
+               if err != nil {
+                       // the parser error may be a list of individual errors; report them all
+                       if list, ok := err.(scanner.ErrorList); ok {
+                               for _, err := range list {
+                                       t.Error(err)
+                               }
+                               return
+                       }
+                       t.Error(err)
+                       return
+               }
+
+               if *verbose {
+                       if len(files) == 0 {
+                               fmt.Println("package", file.Name.Name)
+                       }
+                       fmt.Println("\t", filename)
+               }
+
+               files = append(files, file)
+       }
+
+       // typecheck package files
+       ctxt := Context{
+               Error: func(err error) { t.Error(err) },
+       }
+       ctxt.Check(fset, files)
+       pkgCount++
+}
+
+// pkgfiles returns the list of package files for the given directory.
+func pkgfiles(t *testing.T, dir string) []string {
+       ctxt := build.Default
+       ctxt.CgoEnabled = false
+       pkg, err := ctxt.ImportDir(dir, 0)
+       if err != nil {
+               if _, nogo := err.(*build.NoGoError); !nogo {
+                       t.Error(err)
+               }
+               return nil
+       }
+       if excluded[pkg.ImportPath] {
+               return nil
+       }
+       var filenames []string
+       for _, name := range pkg.GoFiles {
+               filenames = append(filenames, filepath.Join(pkg.Dir, name))
+       }
+       for _, name := range pkg.TestGoFiles {
+               filenames = append(filenames, filepath.Join(pkg.Dir, name))
+       }
+       return filenames
+}
+
+// Note: Could use filepath.Walk instead of walkDirs but that wouldn't
+//       necessarily be shorter or clearer after adding the code to
+//       terminate early for -short tests.
+
+func walkDirs(t *testing.T, dir string) {
+       // limit run time for short tests
+       if testing.Short() && time.Since(start) >= 750*time.Millisecond {
+               return
+       }
+
+       fis, err := ioutil.ReadDir(dir)
+       if err != nil {
+               t.Error(err)
+               return
+       }
+
+       // typecheck package in directory
+       if files := pkgfiles(t, dir); files != nil {
+               typecheck(t, files)
+       }
+
+       // traverse subdirectories, but don't walk into testdata
+       for _, fi := range fis {
+               if fi.IsDir() && fi.Name() != "testdata" {
+                       walkDirs(t, filepath.Join(dir, fi.Name()))
+               }
+       }
+}