Commit cde06f54 authored by Robert Griesemer's avatar Robert Griesemer

go/ast: adjustments to filter function

CL 4938041 made some incorrect changes to the filter
function which caused a different doc/codelab/wiki/index.html
file to be generated.

Added FilterFileExports and FilterPackageExports function.
Same as the existing FileExpors/PackageExports functions
but using shared code. The old functions will be removed
in the next CL.

R=r, rsc
CC=golang-dev
https://golang.org/cl/4932048
parent b99d7229
......@@ -135,7 +135,7 @@ func declExports(decl Decl) bool {
// 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.
// The File.Comments list is not changed.
//
// FileExports returns true if there is an exported declaration; it returns
// false otherwise.
......@@ -224,7 +224,9 @@ func filterFieldList(fields *FieldList, filter Filter) (removedFields bool) {
keepField = len(f.Names) > 0
}
if keepField {
filterType(f.Type, filter)
if filter == exportFilter {
filterType(f.Type, filter)
}
list[j] = f
j++
}
......@@ -286,15 +288,19 @@ func filterSpec(spec Spec, f Filter) bool {
case *ValueSpec:
s.Names = filterIdentList(s.Names, f)
if len(s.Names) > 0 {
filterType(s.Type, f)
if f == exportFilter {
filterType(s.Type, f)
}
return true
}
case *TypeSpec:
if f(s.Name.Name) {
filterType(s.Type, f)
if f == exportFilter {
filterType(s.Type, f)
}
return true
}
if f != IsExported {
if f != exportFilter {
// For general filtering (not just exports),
// filter type even if name is not filtered
// out.
......@@ -330,7 +336,9 @@ func FilterDecl(decl Decl, f Filter) bool {
d.Specs = filterSpecList(d.Specs, f)
return len(d.Specs) > 0
case *FuncDecl:
d.Body = nil // strip body
if f == exportFilter {
d.Body = nil // strip body
}
return f(d.Name.Name)
}
return false
......@@ -339,16 +347,13 @@ func FilterDecl(decl Decl, f Filter) bool {
// FilterFile trims the AST for a Go file in place by removing all
// names from top-level declarations (including struct field and
// interface method names, but not from parameter lists) that don't
// pass through the filter f. Function bodies are set to nil.
// If the declaration is empty afterwards, the declaration is
// removed from the AST. The File.comments list is not changed.
// pass through the filter f. If the declaration is empty afterwards,
// the declaration is removed from the AST. The File.Comments list
// is not changed.
//
// FilterFile returns true if there are any top-level declarations
// left after filtering; it returns false otherwise.
//
// To trim an AST such that only exported nodes remain, call
// FilterFile with IsExported as filter function.
//
func FilterFile(src *File, f Filter) bool {
j := 0
for _, d := range src.Decls {
......@@ -361,20 +366,17 @@ func FilterFile(src *File, f Filter) bool {
return j > 0
}
// FilterPackage trims the AST for a Go package in place by removing all
// names from top-level declarations (including struct field and
// FilterPackage trims the AST for a Go package in place by removing
// all names from top-level declarations (including struct field and
// interface method names, but not from parameter lists) that don't
// pass through the filter f. Function bodies are set to nil.
// If the declaration is empty afterwards, the declaration is
// removed from the AST. The pkg.Files list is not changed, so
// that file names and top-level package comments don't get lost.
// pass through the filter f. If the declaration is empty afterwards,
// the declaration is removed from the AST. The pkg.Files list is not
// changed, so that file names and top-level package comments don't get
// lost.
//
// FilterPackage returns true if there are any top-level declarations
// left after filtering; it returns false otherwise.
//
// To trim an AST such that only exported nodes remain, call
// FilterPackage with IsExported as filter function.
//
func FilterPackage(pkg *Package, f Filter) bool {
hasDecls := false
for _, src := range pkg.Files {
......@@ -385,6 +387,38 @@ 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
......
......@@ -26,7 +26,7 @@ import (
// 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 = 10
const maxFiles = 10000
type visitor struct {
t *testing.T
......@@ -72,7 +72,7 @@ func (v *visitor) VisitFile(path string, f *os.FileInfo) {
}
b1 := ast.FileExports(f1)
b2 := ast.FilterFile(f2, ast.IsExported)
b2 := ast.FilterFileExports(f2)
if b1 != b2 {
v.t.Errorf("filtering failed (a): %s", path)
return
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment