aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8.1/libgo/go/go/ast/filter.go
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.8.1/libgo/go/go/ast/filter.go')
-rw-r--r--gcc-4.8.1/libgo/go/go/ast/filter.go445
1 files changed, 0 insertions, 445 deletions
diff --git a/gcc-4.8.1/libgo/go/go/ast/filter.go b/gcc-4.8.1/libgo/go/go/ast/filter.go
deleted file mode 100644
index 4db5814cb..000000000
--- a/gcc-4.8.1/libgo/go/go/ast/filter.go
+++ /dev/null
@@ -1,445 +0,0 @@
-// Copyright 2009 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 ast
-
-import (
- "go/token"
- "sort"
-)
-
-// ----------------------------------------------------------------------------
-// Export filtering
-
-// 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
-// and their associated information (such as type, initial value, or function
-// body) are removed. Non-exported fields and methods of exported types are
-// stripped. The File.Comments list is not changed.
-//
-// FileExports returns true if there are exported declarations;
-// it returns false otherwise.
-//
-func FileExports(src *File) bool {
- return filterFile(src, exportFilter, true)
-}
-
-// 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 are exported declarations;
-// it returns false otherwise.
-//
-func PackageExports(pkg *Package) bool {
- return filterPackage(pkg, exportFilter, true)
-}
-
-// ----------------------------------------------------------------------------
-// General filtering
-
-type Filter func(string) bool
-
-func filterIdentList(list []*Ident, f Filter) []*Ident {
- j := 0
- for _, x := range list {
- if f(x.Name) {
- list[j] = x
- j++
- }
- }
- return list[0:j]
-}
-
-// fieldName assumes that x is the type of an anonymous field and
-// returns the corresponding field name. If x is not an acceptable
-// anonymous field, the result is nil.
-//
-func fieldName(x Expr) *Ident {
- switch t := x.(type) {
- case *Ident:
- return t
- case *SelectorExpr:
- if _, ok := t.X.(*Ident); ok {
- return t.Sel
- }
- case *StarExpr:
- return fieldName(t.X)
- }
- return nil
-}
-
-func filterFieldList(fields *FieldList, filter Filter, export bool) (removedFields bool) {
- if fields == nil {
- return false
- }
- list := fields.List
- j := 0
- for _, f := range list {
- keepField := false
- if len(f.Names) == 0 {
- // anonymous field
- name := fieldName(f.Type)
- keepField = name != nil && filter(name.Name)
- } else {
- n := len(f.Names)
- f.Names = filterIdentList(f.Names, filter)
- if len(f.Names) < n {
- removedFields = true
- }
- keepField = len(f.Names) > 0
- }
- if keepField {
- if export {
- filterType(f.Type, filter, export)
- }
- list[j] = f
- j++
- }
- }
- if j < len(list) {
- removedFields = true
- }
- fields.List = list[0:j]
- return
-}
-
-func filterParamList(fields *FieldList, filter Filter, export bool) bool {
- if fields == nil {
- return false
- }
- var b bool
- for _, f := range fields.List {
- if filterType(f.Type, filter, export) {
- b = true
- }
- }
- return b
-}
-
-func filterType(typ Expr, f Filter, export bool) bool {
- switch t := typ.(type) {
- case *Ident:
- return f(t.Name)
- case *ParenExpr:
- return filterType(t.X, f, export)
- case *ArrayType:
- return filterType(t.Elt, f, export)
- case *StructType:
- if filterFieldList(t.Fields, f, export) {
- t.Incomplete = true
- }
- return len(t.Fields.List) > 0
- case *FuncType:
- b1 := filterParamList(t.Params, f, export)
- b2 := filterParamList(t.Results, f, export)
- return b1 || b2
- case *InterfaceType:
- if filterFieldList(t.Methods, f, export) {
- t.Incomplete = true
- }
- return len(t.Methods.List) > 0
- case *MapType:
- b1 := filterType(t.Key, f, export)
- b2 := filterType(t.Value, f, export)
- return b1 || b2
- case *ChanType:
- return filterType(t.Value, f, export)
- }
- return false
-}
-
-func filterSpec(spec Spec, f Filter, export bool) bool {
- switch s := spec.(type) {
- case *ValueSpec:
- s.Names = filterIdentList(s.Names, f)
- if len(s.Names) > 0 {
- if export {
- filterType(s.Type, f, export)
- }
- return true
- }
- case *TypeSpec:
- if f(s.Name.Name) {
- if export {
- filterType(s.Type, f, export)
- }
- return true
- }
- if !export {
- // For general filtering (not just exports),
- // filter type even if name is not filtered
- // out.
- // If the type contains filtered elements,
- // keep the declaration.
- return filterType(s.Type, f, export)
- }
- }
- return false
-}
-
-func filterSpecList(list []Spec, f Filter, export bool) []Spec {
- j := 0
- for _, s := range list {
- if filterSpec(s, f, export) {
- list[j] = s
- j++
- }
- }
- return list[0:j]
-}
-
-// FilterDecl trims the AST for a Go declaration in place by removing
-// all names (including struct field and interface method names, but
-// not from parameter lists) that don't pass through the filter f.
-//
-// FilterDecl returns true if there are any declared names left after
-// filtering; it returns false otherwise.
-//
-func FilterDecl(decl Decl, f Filter) bool {
- return filterDecl(decl, f, false)
-}
-
-func filterDecl(decl Decl, f Filter, export bool) bool {
- switch d := decl.(type) {
- case *GenDecl:
- d.Specs = filterSpecList(d.Specs, f, export)
- return len(d.Specs) > 0
- case *FuncDecl:
- return f(d.Name.Name)
- }
- return false
-}
-
-// 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. 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.
-//
-func FilterFile(src *File, f Filter) bool {
- return filterFile(src, f, false)
-}
-
-func filterFile(src *File, f Filter, export bool) bool {
- j := 0
- for _, d := range src.Decls {
- if filterDecl(d, f, export) {
- src.Decls[j] = d
- j++
- }
- }
- src.Decls = src.Decls[0:j]
- 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
-// interface method names, but not from parameter lists) that don't
-// 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.
-//
-func FilterPackage(pkg *Package, f Filter) bool {
- return filterPackage(pkg, f, false)
-}
-
-func filterPackage(pkg *Package, f Filter, export bool) bool {
- hasDecls := false
- for _, src := range pkg.Files {
- if filterFile(src, f, export) {
- hasDecls = true
- }
- }
- return hasDecls
-}
-
-// ----------------------------------------------------------------------------
-// Merging of package files
-
-// The MergeMode flags control the behavior of MergePackageFiles.
-type MergeMode uint
-
-const (
- // If set, duplicate function declarations are excluded.
- FilterFuncDuplicates MergeMode = 1 << iota
- // If set, comments that are not associated with a specific
- // AST node (as Doc or Comment) are excluded.
- FilterUnassociatedComments
- // If set, duplicate import declarations are excluded.
- FilterImportDuplicates
-)
-
-// separator is an empty //-style comment that is interspersed between
-// different comment groups when they are concatenated into a single group
-//
-var separator = &Comment{noPos, "//"}
-
-// MergePackageFiles creates a file AST by merging the ASTs of the
-// files belonging to a package. The mode flags control merging behavior.
-//
-func MergePackageFiles(pkg *Package, mode MergeMode) *File {
- // Count the number of package docs, comments and declarations across
- // all package files. Also, compute sorted list of filenames, so that
- // subsequent iterations can always iterate in the same order.
- ndocs := 0
- ncomments := 0
- ndecls := 0
- filenames := make([]string, len(pkg.Files))
- i := 0
- for filename, f := range pkg.Files {
- filenames[i] = filename
- i++
- if f.Doc != nil {
- ndocs += len(f.Doc.List) + 1 // +1 for separator
- }
- ncomments += len(f.Comments)
- ndecls += len(f.Decls)
- }
- sort.Strings(filenames)
-
- // Collect package comments from all package files into a single
- // CommentGroup - the collected package documentation. In general
- // there should be only one file with a package comment; but it's
- // better to collect extra comments than drop them on the floor.
- var doc *CommentGroup
- var pos token.Pos
- if ndocs > 0 {
- list := make([]*Comment, ndocs-1) // -1: no separator before first group
- i := 0
- for _, filename := range filenames {
- f := pkg.Files[filename]
- if f.Doc != nil {
- if i > 0 {
- // not the first group - add separator
- list[i] = separator
- i++
- }
- for _, c := range f.Doc.List {
- list[i] = c
- i++
- }
- if f.Package > pos {
- // Keep the maximum package clause position as
- // position for the package clause of the merged
- // files.
- pos = f.Package
- }
- }
- }
- doc = &CommentGroup{list}
- }
-
- // Collect declarations from all package files.
- var decls []Decl
- if ndecls > 0 {
- decls = make([]Decl, ndecls)
- funcs := make(map[string]int) // map of global function name -> decls index
- i := 0 // current index
- n := 0 // number of filtered entries
- for _, filename := range filenames {
- f := pkg.Files[filename]
- for _, d := range f.Decls {
- if mode&FilterFuncDuplicates != 0 {
- // A language entity may be declared multiple
- // times in different package files; only at
- // build time declarations must be unique.
- // For now, exclude multiple declarations of
- // functions - keep the one with documentation.
- //
- // TODO(gri): Expand this filtering to other
- // entities (const, type, vars) if
- // multiple declarations are common.
- if f, isFun := d.(*FuncDecl); isFun {
- name := f.Name.Name
- if j, exists := funcs[name]; exists {
- // function declared already
- if decls[j] != nil && decls[j].(*FuncDecl).Doc == nil {
- // existing declaration has no documentation;
- // ignore the existing declaration
- decls[j] = nil
- } else {
- // ignore the new declaration
- d = nil
- }
- n++ // filtered an entry
- } else {
- funcs[name] = i
- }
- }
- }
- decls[i] = d
- i++
- }
- }
-
- // Eliminate nil entries from the decls list if entries were
- // filtered. We do this using a 2nd pass in order to not disturb
- // the original declaration order in the source (otherwise, this
- // would also invalidate the monotonically increasing position
- // info within a single file).
- if n > 0 {
- i = 0
- for _, d := range decls {
- if d != nil {
- decls[i] = d
- i++
- }
- }
- decls = decls[0:i]
- }
- }
-
- // Collect import specs from all package files.
- var imports []*ImportSpec
- if mode&FilterImportDuplicates != 0 {
- seen := make(map[string]bool)
- for _, filename := range filenames {
- f := pkg.Files[filename]
- for _, imp := range f.Imports {
- if path := imp.Path.Value; !seen[path] {
- // TODO: consider handling cases where:
- // - 2 imports exist with the same import path but
- // have different local names (one should probably
- // keep both of them)
- // - 2 imports exist but only one has a comment
- // - 2 imports exist and they both have (possibly
- // different) comments
- imports = append(imports, imp)
- seen[path] = true
- }
- }
- }
- } else {
- for _, f := range pkg.Files {
- imports = append(imports, f.Imports...)
- }
- }
-
- // Collect comments from all package files.
- var comments []*CommentGroup
- if mode&FilterUnassociatedComments == 0 {
- comments = make([]*CommentGroup, ncomments)
- i := 0
- for _, f := range pkg.Files {
- i += copy(comments[i:], f.Comments)
- }
- }
-
- // TODO(gri) need to compute unresolved identifiers!
- return &File{doc, pos, NewIdent(pkg.Name), decls, pkg.Scope, imports, nil, comments}
-}