Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
e656a184
Commit
e656a184
authored
Aug 23, 2011
by
Robert Griesemer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
go/ast cleanup: base File/PackageExports on FilterFile/FilterPackage code
R=r, rsc CC=golang-dev
https://golang.org/cl/4927046
parent
cde06f54
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
14 additions
and
267 deletions
+14
-267
src/pkg/go/ast/filter.go
src/pkg/go/ast/filter.go
+14
-176
src/pkg/go/parser/filter_test.go
src/pkg/go/parser/filter_test.go
+0
-91
No files found.
src/pkg/go/ast/filter.go
View file @
e656a184
...
...
@@ -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
...
...
src/pkg/go/parser/filter_test.go
deleted
100644 → 0
View file @
cde06f54
// 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
)
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment