]> Cypherpunks repositories - gostls13.git/commitdiff
go/ast cleanup: base File/PackageExports on FilterFile/FilterPackage code
authorRobert Griesemer <gri@golang.org>
Tue, 23 Aug 2011 23:03:42 +0000 (16:03 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 23 Aug 2011 23:03:42 +0000 (16:03 -0700)
R=r, rsc
CC=golang-dev
https://golang.org/cl/4927046

src/pkg/go/ast/filter.go
src/pkg/go/parser/filter_test.go [deleted file]

index 6d00d11970e58a8555f1b3b04a30d65d25ca73c3..1bd8990f835a20e01ee616b15e7f3db2665147d4 100644 (file)
@@ -9,164 +9,34 @@ import "go/token"
 // ----------------------------------------------------------------------------
 // Export filtering
 
-func identListExports(list []*Ident) []*Ident {
-       j := 0
-       for _, x := range list {
-               if x.IsExported() {
-                       list[j] = x
-                       j++
-               }
-       }
-       return list[0:j]
-}
-
-func fieldListExports(fields *FieldList) (removedFields bool) {
-       if fields == nil {
-               return
-       }
-       list := fields.List
-       j := 0
-       for _, f := range list {
-               exported := false
-               if len(f.Names) == 0 {
-                       // anonymous field
-                       // (Note that a non-exported anonymous field
-                       // may still refer to a type with exported
-                       // fields, so this is not absolutely correct.
-                       // However, this cannot be done w/o complete
-                       // type information.)
-                       name := fieldName(f.Type)
-                       exported = name != nil && name.IsExported()
-               } else {
-                       n := len(f.Names)
-                       f.Names = identListExports(f.Names)
-                       if len(f.Names) < n {
-                               removedFields = true
-                       }
-                       exported = len(f.Names) > 0
-               }
-               if exported {
-                       typeExports(f.Type)
-                       list[j] = f
-                       j++
-               }
-       }
-       if j < len(list) {
-               removedFields = true
-       }
-       fields.List = list[0:j]
-       return
-}
-
-func paramListExports(fields *FieldList) {
-       if fields == nil {
-               return
-       }
-       for _, f := range fields.List {
-               typeExports(f.Type)
-       }
-}
-
-func typeExports(typ Expr) {
-       switch t := typ.(type) {
-       case *ArrayType:
-               typeExports(t.Elt)
-       case *StructType:
-               if fieldListExports(t.Fields) {
-                       t.Incomplete = true
-               }
-       case *FuncType:
-               paramListExports(t.Params)
-               paramListExports(t.Results)
-       case *InterfaceType:
-               if fieldListExports(t.Methods) {
-                       t.Incomplete = true
-               }
-       case *MapType:
-               typeExports(t.Key)
-               typeExports(t.Value)
-       case *ChanType:
-               typeExports(t.Value)
-       }
-}
-
-func specExports(spec Spec) bool {
-       switch s := spec.(type) {
-       case *ValueSpec:
-               s.Names = identListExports(s.Names)
-               if len(s.Names) > 0 {
-                       typeExports(s.Type)
-                       return true
-               }
-       case *TypeSpec:
-               if s.Name.IsExported() {
-                       typeExports(s.Type)
-                       return true
-               }
-       }
-       return false
-}
-
-func specListExports(list []Spec) []Spec {
-       j := 0
-       for _, s := range list {
-               if specExports(s) {
-                       list[j] = s
-                       j++
-               }
-       }
-       return list[0:j]
-}
-
-func declExports(decl Decl) bool {
-       switch d := decl.(type) {
-       case *GenDecl:
-               d.Specs = specListExports(d.Specs)
-               return len(d.Specs) > 0
-       case *FuncDecl:
-               d.Body = nil // strip body
-               return d.Name.IsExported()
-       }
-       return false
+// exportFilter is a special filter function to extract exported nodes.
+func exportFilter(name string) bool {
+       return IsExported(name)
 }
 
-// FileExports trims the AST for a Go source file in place such that only
-// exported nodes remain: all top-level identifiers which are not exported
+// FileExports trims the AST for a Go source file in place such that
+// only exported nodes remain: all top-level identifiers which are not exported
 // and their associated information (such as type, initial value, or function
 // body) are removed. Non-exported fields and methods of exported types are
 // stripped, and the function bodies of exported functions are set to nil.
 // The File.Comments list is not changed.
 //
-// FileExports returns true if there is an exported declaration; it returns
-// false otherwise.
+// FileExports returns true if there are exported declarationa;
+// it returns false otherwise.
 //
 func FileExports(src *File) bool {
-       j := 0
-       for _, d := range src.Decls {
-               if declExports(d) {
-                       src.Decls[j] = d
-                       j++
-               }
-       }
-       src.Decls = src.Decls[0:j]
-       return j > 0
+       return FilterFile(src, exportFilter)
 }
 
-// PackageExports trims the AST for a Go package in place such that only
-// exported nodes remain. The pkg.Files list is not changed, so that file
-// names and top-level package comments don't get lost.
+// PackageExports trims the AST for a Go package in place such that
+// only exported nodes remain. The pkg.Files list is not changed, so that
+// file names and top-level package comments don't get lost.
 //
-// PackageExports returns true if there is an exported declaration; it
-// returns false otherwise.
+// PackageExports returns true if there are exported declarations;
+// it returns false otherwise.
 //
 func PackageExports(pkg *Package) bool {
-       hasExports := false
-       for _, f := range pkg.Files {
-               if FileExports(f) {
-                       hasExports = true
-               }
-       }
-       return hasExports
+       return FilterPackage(pkg, exportFilter)
 }
 
 // ----------------------------------------------------------------------------
@@ -387,38 +257,6 @@ func FilterPackage(pkg *Package, f Filter) bool {
        return hasDecls
 }
 
-// exportFilter is a special filter function to extract exported nodes.
-func exportFilter(name string) bool {
-       return IsExported(name)
-}
-
-// TODO(gri): Remove the FileExports and PackageExports (above).
-
-// FilterFileExports trims the AST for a Go source file in place such that
-// only exported nodes remain: all top-level identifiers which are not exported
-// and their associated information (such as type, initial value, or function
-// body) are removed. Non-exported fields and methods of exported types are
-// stripped, and the function bodies of exported functions are set to nil.
-// The File.Comments list is not changed.
-//
-// FilterFileExports returns true if there are exported declarationa;
-// it returns false otherwise.
-//
-func FilterFileExports(src *File) bool {
-       return FilterFile(src, exportFilter)
-}
-
-// FilterPackageExports trims the AST for a Go package in place such that
-// only exported nodes remain. The pkg.Files list is not changed, so that
-// file names and top-level package comments don't get lost.
-//
-// FilterPackageExports returns true if there are exported declarations;
-// it returns false otherwise.
-//
-func FilterPackageExports(pkg *Package) bool {
-       return FilterPackage(pkg, exportFilter)
-}
-
 // ----------------------------------------------------------------------------
 // Merging of package files
 
diff --git a/src/pkg/go/parser/filter_test.go b/src/pkg/go/parser/filter_test.go
deleted file mode 100644 (file)
index 856a1c0..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-// 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.
-
-// A test that ensures that ast.FileExports(file) and
-// ast.FilterFile(file, ast.IsExported) produce the
-// same trimmed AST given the same input file for all
-// files under runtime.GOROOT().
-//
-// The test is here because it requires parsing, and the
-// parser imports AST already (avoid import cycle).
-
-package parser
-
-import (
-       "bytes"
-       "go/ast"
-       "go/printer"
-       "go/token"
-       "os"
-       "path/filepath"
-       "runtime"
-       "strings"
-       "testing"
-)
-
-// For a short test run, limit the number of files to a few.
-// Set to a large value to test all files under GOROOT.
-const maxFiles = 10000
-
-type visitor struct {
-       t *testing.T
-       n int
-}
-
-func (v *visitor) VisitDir(path string, f *os.FileInfo) bool {
-       return true
-}
-
-func str(f *ast.File, fset *token.FileSet) string {
-       var buf bytes.Buffer
-       printer.Fprint(&buf, fset, f)
-       return buf.String()
-}
-
-func (v *visitor) VisitFile(path string, f *os.FileInfo) {
-       // exclude files that clearly don't make it
-       if !f.IsRegular() || len(f.Name) > 0 && f.Name[0] == '.' || !strings.HasSuffix(f.Name, ".go") {
-               return
-       }
-
-       // should we stop early for quick test runs?
-       if v.n <= 0 {
-               return
-       }
-       v.n--
-
-       fset := token.NewFileSet()
-
-       // get two ASTs f1, f2 of identical structure;
-       // parsing twice is easiest
-       f1, err := ParseFile(fset, path, nil, ParseComments)
-       if err != nil {
-               v.t.Logf("parse error (1): %s", err)
-               return
-       }
-
-       f2, err := ParseFile(fset, path, nil, ParseComments)
-       if err != nil {
-               v.t.Logf("parse error (2): %s", err)
-               return
-       }
-
-       b1 := ast.FileExports(f1)
-       b2 := ast.FilterFileExports(f2)
-       if b1 != b2 {
-               v.t.Errorf("filtering failed (a): %s", path)
-               return
-       }
-
-       s1 := str(f1, fset)
-       s2 := str(f2, fset)
-       if s1 != s2 {
-               v.t.Errorf("filtering failed (b): %s", path)
-               return
-       }
-}
-
-func TestFilter(t *testing.T) {
-       filepath.Walk(runtime.GOROOT(), &visitor{t, maxFiles}, nil)
-}