github.com/kdevb0x/go@v0.0.0-20180115030120-39687051e9e7/src/go/doc/reader.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package doc
     6  
     7  import (
     8  	"go/ast"
     9  	"go/token"
    10  	"regexp"
    11  	"sort"
    12  	"strconv"
    13  )
    14  
    15  // ----------------------------------------------------------------------------
    16  // function/method sets
    17  //
    18  // Internally, we treat functions like methods and collect them in method sets.
    19  
    20  // A methodSet describes a set of methods. Entries where Decl == nil are conflict
    21  // entries (more than one method with the same name at the same embedding level).
    22  //
    23  type methodSet map[string]*Func
    24  
    25  // recvString returns a string representation of recv of the
    26  // form "T", "*T", or "BADRECV" (if not a proper receiver type).
    27  //
    28  func recvString(recv ast.Expr) string {
    29  	switch t := recv.(type) {
    30  	case *ast.Ident:
    31  		return t.Name
    32  	case *ast.StarExpr:
    33  		return "*" + recvString(t.X)
    34  	}
    35  	return "BADRECV"
    36  }
    37  
    38  // set creates the corresponding Func for f and adds it to mset.
    39  // If there are multiple f's with the same name, set keeps the first
    40  // one with documentation; conflicts are ignored.
    41  //
    42  func (mset methodSet) set(f *ast.FuncDecl) {
    43  	name := f.Name.Name
    44  	if g := mset[name]; g != nil && g.Doc != "" {
    45  		// A function with the same name has already been registered;
    46  		// since it has documentation, assume f is simply another
    47  		// implementation and ignore it. This does not happen if the
    48  		// caller is using go/build.ScanDir to determine the list of
    49  		// files implementing a package.
    50  		return
    51  	}
    52  	// function doesn't exist or has no documentation; use f
    53  	recv := ""
    54  	if f.Recv != nil {
    55  		var typ ast.Expr
    56  		// be careful in case of incorrect ASTs
    57  		if list := f.Recv.List; len(list) == 1 {
    58  			typ = list[0].Type
    59  		}
    60  		recv = recvString(typ)
    61  	}
    62  	mset[name] = &Func{
    63  		Doc:  f.Doc.Text(),
    64  		Name: name,
    65  		Decl: f,
    66  		Recv: recv,
    67  		Orig: recv,
    68  	}
    69  	f.Doc = nil // doc consumed - remove from AST
    70  }
    71  
    72  // add adds method m to the method set; m is ignored if the method set
    73  // already contains a method with the same name at the same or a higher
    74  // level than m.
    75  //
    76  func (mset methodSet) add(m *Func) {
    77  	old := mset[m.Name]
    78  	if old == nil || m.Level < old.Level {
    79  		mset[m.Name] = m
    80  		return
    81  	}
    82  	if old != nil && m.Level == old.Level {
    83  		// conflict - mark it using a method with nil Decl
    84  		mset[m.Name] = &Func{
    85  			Name:  m.Name,
    86  			Level: m.Level,
    87  		}
    88  	}
    89  }
    90  
    91  // ----------------------------------------------------------------------------
    92  // Named types
    93  
    94  // baseTypeName returns the name of the base type of x (or "")
    95  // and whether the type is imported or not.
    96  //
    97  func baseTypeName(x ast.Expr) (name string, imported bool) {
    98  	switch t := x.(type) {
    99  	case *ast.Ident:
   100  		return t.Name, false
   101  	case *ast.SelectorExpr:
   102  		if _, ok := t.X.(*ast.Ident); ok {
   103  			// only possible for qualified type names;
   104  			// assume type is imported
   105  			return t.Sel.Name, true
   106  		}
   107  	case *ast.StarExpr:
   108  		return baseTypeName(t.X)
   109  	}
   110  	return
   111  }
   112  
   113  // An embeddedSet describes a set of embedded types.
   114  type embeddedSet map[*namedType]bool
   115  
   116  // A namedType represents a named unqualified (package local, or possibly
   117  // predeclared) type. The namedType for a type name is always found via
   118  // reader.lookupType.
   119  //
   120  type namedType struct {
   121  	doc  string       // doc comment for type
   122  	name string       // type name
   123  	decl *ast.GenDecl // nil if declaration hasn't been seen yet
   124  
   125  	isEmbedded bool        // true if this type is embedded
   126  	isStruct   bool        // true if this type is a struct
   127  	embedded   embeddedSet // true if the embedded type is a pointer
   128  
   129  	// associated declarations
   130  	values  []*Value // consts and vars
   131  	funcs   methodSet
   132  	methods methodSet
   133  }
   134  
   135  // ----------------------------------------------------------------------------
   136  // AST reader
   137  
   138  // reader accumulates documentation for a single package.
   139  // It modifies the AST: Comments (declaration documentation)
   140  // that have been collected by the reader are set to nil
   141  // in the respective AST nodes so that they are not printed
   142  // twice (once when printing the documentation and once when
   143  // printing the corresponding AST node).
   144  //
   145  type reader struct {
   146  	mode Mode
   147  
   148  	// package properties
   149  	doc       string // package documentation, if any
   150  	filenames []string
   151  	notes     map[string][]*Note
   152  
   153  	// declarations
   154  	imports   map[string]int
   155  	hasDotImp bool     // if set, package contains a dot import
   156  	values    []*Value // consts and vars
   157  	order     int      // sort order of const and var declarations (when we can't use a name)
   158  	types     map[string]*namedType
   159  	funcs     methodSet
   160  
   161  	// support for package-local error type declarations
   162  	errorDecl bool                 // if set, type "error" was declared locally
   163  	fixlist   []*ast.InterfaceType // list of interfaces containing anonymous field "error"
   164  }
   165  
   166  func (r *reader) isVisible(name string) bool {
   167  	return r.mode&AllDecls != 0 || ast.IsExported(name)
   168  }
   169  
   170  // lookupType returns the base type with the given name.
   171  // If the base type has not been encountered yet, a new
   172  // type with the given name but no associated declaration
   173  // is added to the type map.
   174  //
   175  func (r *reader) lookupType(name string) *namedType {
   176  	if name == "" || name == "_" {
   177  		return nil // no type docs for anonymous types
   178  	}
   179  	if typ, found := r.types[name]; found {
   180  		return typ
   181  	}
   182  	// type not found - add one without declaration
   183  	typ := &namedType{
   184  		name:     name,
   185  		embedded: make(embeddedSet),
   186  		funcs:    make(methodSet),
   187  		methods:  make(methodSet),
   188  	}
   189  	r.types[name] = typ
   190  	return typ
   191  }
   192  
   193  // recordAnonymousField registers fieldType as the type of an
   194  // anonymous field in the parent type. If the field is imported
   195  // (qualified name) or the parent is nil, the field is ignored.
   196  // The function returns the field name.
   197  //
   198  func (r *reader) recordAnonymousField(parent *namedType, fieldType ast.Expr) (fname string) {
   199  	fname, imp := baseTypeName(fieldType)
   200  	if parent == nil || imp {
   201  		return
   202  	}
   203  	if ftype := r.lookupType(fname); ftype != nil {
   204  		ftype.isEmbedded = true
   205  		_, ptr := fieldType.(*ast.StarExpr)
   206  		parent.embedded[ftype] = ptr
   207  	}
   208  	return
   209  }
   210  
   211  func (r *reader) readDoc(comment *ast.CommentGroup) {
   212  	// By convention there should be only one package comment
   213  	// but collect all of them if there are more than one.
   214  	text := comment.Text()
   215  	if r.doc == "" {
   216  		r.doc = text
   217  		return
   218  	}
   219  	r.doc += "\n" + text
   220  }
   221  
   222  func (r *reader) remember(typ *ast.InterfaceType) {
   223  	r.fixlist = append(r.fixlist, typ)
   224  }
   225  
   226  func specNames(specs []ast.Spec) []string {
   227  	names := make([]string, 0, len(specs)) // reasonable estimate
   228  	for _, s := range specs {
   229  		// s guaranteed to be an *ast.ValueSpec by readValue
   230  		for _, ident := range s.(*ast.ValueSpec).Names {
   231  			names = append(names, ident.Name)
   232  		}
   233  	}
   234  	return names
   235  }
   236  
   237  // readValue processes a const or var declaration.
   238  //
   239  func (r *reader) readValue(decl *ast.GenDecl) {
   240  	// determine if decl should be associated with a type
   241  	// Heuristic: For each typed entry, determine the type name, if any.
   242  	//            If there is exactly one type name that is sufficiently
   243  	//            frequent, associate the decl with the respective type.
   244  	domName := ""
   245  	domFreq := 0
   246  	prev := ""
   247  	n := 0
   248  	for _, spec := range decl.Specs {
   249  		s, ok := spec.(*ast.ValueSpec)
   250  		if !ok {
   251  			continue // should not happen, but be conservative
   252  		}
   253  		name := ""
   254  		switch {
   255  		case s.Type != nil:
   256  			// a type is present; determine its name
   257  			if n, imp := baseTypeName(s.Type); !imp {
   258  				name = n
   259  			}
   260  		case decl.Tok == token.CONST && len(s.Values) == 0:
   261  			// no type or value is present but we have a constant declaration;
   262  			// use the previous type name (possibly the empty string)
   263  			name = prev
   264  		}
   265  		if name != "" {
   266  			// entry has a named type
   267  			if domName != "" && domName != name {
   268  				// more than one type name - do not associate
   269  				// with any type
   270  				domName = ""
   271  				break
   272  			}
   273  			domName = name
   274  			domFreq++
   275  		}
   276  		prev = name
   277  		n++
   278  	}
   279  
   280  	// nothing to do w/o a legal declaration
   281  	if n == 0 {
   282  		return
   283  	}
   284  
   285  	// determine values list with which to associate the Value for this decl
   286  	values := &r.values
   287  	const threshold = 0.75
   288  	if domName != "" && r.isVisible(domName) && domFreq >= int(float64(len(decl.Specs))*threshold) {
   289  		// typed entries are sufficiently frequent
   290  		if typ := r.lookupType(domName); typ != nil {
   291  			values = &typ.values // associate with that type
   292  		}
   293  	}
   294  
   295  	*values = append(*values, &Value{
   296  		Doc:   decl.Doc.Text(),
   297  		Names: specNames(decl.Specs),
   298  		Decl:  decl,
   299  		order: r.order,
   300  	})
   301  	decl.Doc = nil // doc consumed - remove from AST
   302  
   303  	// Note: It's important that the order used here is global because the cleanupTypes
   304  	// methods may move values associated with types back into the global list. If the
   305  	// order is list-specific, sorting is not deterministic because the same order value
   306  	// may appear multiple times (was bug, found when fixing #16153).
   307  	r.order++
   308  }
   309  
   310  // fields returns a struct's fields or an interface's methods.
   311  //
   312  func fields(typ ast.Expr) (list []*ast.Field, isStruct bool) {
   313  	var fields *ast.FieldList
   314  	switch t := typ.(type) {
   315  	case *ast.StructType:
   316  		fields = t.Fields
   317  		isStruct = true
   318  	case *ast.InterfaceType:
   319  		fields = t.Methods
   320  	}
   321  	if fields != nil {
   322  		list = fields.List
   323  	}
   324  	return
   325  }
   326  
   327  // readType processes a type declaration.
   328  //
   329  func (r *reader) readType(decl *ast.GenDecl, spec *ast.TypeSpec) {
   330  	typ := r.lookupType(spec.Name.Name)
   331  	if typ == nil {
   332  		return // no name or blank name - ignore the type
   333  	}
   334  
   335  	// A type should be added at most once, so typ.decl
   336  	// should be nil - if it is not, simply overwrite it.
   337  	typ.decl = decl
   338  
   339  	// compute documentation
   340  	doc := spec.Doc
   341  	spec.Doc = nil // doc consumed - remove from AST
   342  	if doc == nil {
   343  		// no doc associated with the spec, use the declaration doc, if any
   344  		doc = decl.Doc
   345  	}
   346  	decl.Doc = nil // doc consumed - remove from AST
   347  	typ.doc = doc.Text()
   348  
   349  	// record anonymous fields (they may contribute methods)
   350  	// (some fields may have been recorded already when filtering
   351  	// exports, but that's ok)
   352  	var list []*ast.Field
   353  	list, typ.isStruct = fields(spec.Type)
   354  	for _, field := range list {
   355  		if len(field.Names) == 0 {
   356  			r.recordAnonymousField(typ, field.Type)
   357  		}
   358  	}
   359  }
   360  
   361  // readFunc processes a func or method declaration.
   362  //
   363  func (r *reader) readFunc(fun *ast.FuncDecl) {
   364  	// strip function body
   365  	fun.Body = nil
   366  
   367  	// associate methods with the receiver type, if any
   368  	if fun.Recv != nil {
   369  		// method
   370  		if len(fun.Recv.List) == 0 {
   371  			// should not happen (incorrect AST); (See issue 17788)
   372  			// don't show this method
   373  			return
   374  		}
   375  		recvTypeName, imp := baseTypeName(fun.Recv.List[0].Type)
   376  		if imp {
   377  			// should not happen (incorrect AST);
   378  			// don't show this method
   379  			return
   380  		}
   381  		if typ := r.lookupType(recvTypeName); typ != nil {
   382  			typ.methods.set(fun)
   383  		}
   384  		// otherwise ignore the method
   385  		// TODO(gri): There may be exported methods of non-exported types
   386  		// that can be called because of exported values (consts, vars, or
   387  		// function results) of that type. Could determine if that is the
   388  		// case and then show those methods in an appropriate section.
   389  		return
   390  	}
   391  
   392  	// associate factory functions with the first visible result type, if any
   393  	if fun.Type.Results.NumFields() >= 1 {
   394  		res := fun.Type.Results.List[0]
   395  		if len(res.Names) <= 1 {
   396  			// exactly one (named or anonymous) result associated
   397  			// with the first type in result signature (there may
   398  			// be more than one result)
   399  			factoryType := res.Type
   400  			if t, ok := factoryType.(*ast.ArrayType); ok && t.Len == nil {
   401  				// We consider functions that return slices of type T (or
   402  				// pointers to T) as factory functions of T.
   403  				factoryType = t.Elt
   404  			}
   405  			if n, imp := baseTypeName(factoryType); !imp && r.isVisible(n) {
   406  				if typ := r.lookupType(n); typ != nil {
   407  					// associate function with typ
   408  					typ.funcs.set(fun)
   409  					return
   410  				}
   411  			}
   412  		}
   413  	}
   414  
   415  	// just an ordinary function
   416  	r.funcs.set(fun)
   417  }
   418  
   419  var (
   420  	noteMarker    = `([A-Z][A-Z]+)\(([^)]+)\):?`                    // MARKER(uid), MARKER at least 2 chars, uid at least 1 char
   421  	noteMarkerRx  = regexp.MustCompile(`^[ \t]*` + noteMarker)      // MARKER(uid) at text start
   422  	noteCommentRx = regexp.MustCompile(`^/[/*][ \t]*` + noteMarker) // MARKER(uid) at comment start
   423  )
   424  
   425  // readNote collects a single note from a sequence of comments.
   426  //
   427  func (r *reader) readNote(list []*ast.Comment) {
   428  	text := (&ast.CommentGroup{List: list}).Text()
   429  	if m := noteMarkerRx.FindStringSubmatchIndex(text); m != nil {
   430  		// The note body starts after the marker.
   431  		// We remove any formatting so that we don't
   432  		// get spurious line breaks/indentation when
   433  		// showing the TODO body.
   434  		body := clean(text[m[1]:], keepNL)
   435  		if body != "" {
   436  			marker := text[m[2]:m[3]]
   437  			r.notes[marker] = append(r.notes[marker], &Note{
   438  				Pos:  list[0].Pos(),
   439  				End:  list[len(list)-1].End(),
   440  				UID:  text[m[4]:m[5]],
   441  				Body: body,
   442  			})
   443  		}
   444  	}
   445  }
   446  
   447  // readNotes extracts notes from comments.
   448  // A note must start at the beginning of a comment with "MARKER(uid):"
   449  // and is followed by the note body (e.g., "// BUG(gri): fix this").
   450  // The note ends at the end of the comment group or at the start of
   451  // another note in the same comment group, whichever comes first.
   452  //
   453  func (r *reader) readNotes(comments []*ast.CommentGroup) {
   454  	for _, group := range comments {
   455  		i := -1 // comment index of most recent note start, valid if >= 0
   456  		list := group.List
   457  		for j, c := range list {
   458  			if noteCommentRx.MatchString(c.Text) {
   459  				if i >= 0 {
   460  					r.readNote(list[i:j])
   461  				}
   462  				i = j
   463  			}
   464  		}
   465  		if i >= 0 {
   466  			r.readNote(list[i:])
   467  		}
   468  	}
   469  }
   470  
   471  // readFile adds the AST for a source file to the reader.
   472  //
   473  func (r *reader) readFile(src *ast.File) {
   474  	// add package documentation
   475  	if src.Doc != nil {
   476  		r.readDoc(src.Doc)
   477  		src.Doc = nil // doc consumed - remove from AST
   478  	}
   479  
   480  	// add all declarations
   481  	for _, decl := range src.Decls {
   482  		switch d := decl.(type) {
   483  		case *ast.GenDecl:
   484  			switch d.Tok {
   485  			case token.IMPORT:
   486  				// imports are handled individually
   487  				for _, spec := range d.Specs {
   488  					if s, ok := spec.(*ast.ImportSpec); ok {
   489  						if import_, err := strconv.Unquote(s.Path.Value); err == nil {
   490  							r.imports[import_] = 1
   491  							if s.Name != nil && s.Name.Name == "." {
   492  								r.hasDotImp = true
   493  							}
   494  						}
   495  					}
   496  				}
   497  			case token.CONST, token.VAR:
   498  				// constants and variables are always handled as a group
   499  				r.readValue(d)
   500  			case token.TYPE:
   501  				// types are handled individually
   502  				if len(d.Specs) == 1 && !d.Lparen.IsValid() {
   503  					// common case: single declaration w/o parentheses
   504  					// (if a single declaration is parenthesized,
   505  					// create a new fake declaration below, so that
   506  					// go/doc type declarations always appear w/o
   507  					// parentheses)
   508  					if s, ok := d.Specs[0].(*ast.TypeSpec); ok {
   509  						r.readType(d, s)
   510  					}
   511  					break
   512  				}
   513  				for _, spec := range d.Specs {
   514  					if s, ok := spec.(*ast.TypeSpec); ok {
   515  						// use an individual (possibly fake) declaration
   516  						// for each type; this also ensures that each type
   517  						// gets to (re-)use the declaration documentation
   518  						// if there's none associated with the spec itself
   519  						fake := &ast.GenDecl{
   520  							Doc: d.Doc,
   521  							// don't use the existing TokPos because it
   522  							// will lead to the wrong selection range for
   523  							// the fake declaration if there are more
   524  							// than one type in the group (this affects
   525  							// src/cmd/godoc/godoc.go's posLink_urlFunc)
   526  							TokPos: s.Pos(),
   527  							Tok:    token.TYPE,
   528  							Specs:  []ast.Spec{s},
   529  						}
   530  						r.readType(fake, s)
   531  					}
   532  				}
   533  			}
   534  		case *ast.FuncDecl:
   535  			r.readFunc(d)
   536  		}
   537  	}
   538  
   539  	// collect MARKER(...): annotations
   540  	r.readNotes(src.Comments)
   541  	src.Comments = nil // consumed unassociated comments - remove from AST
   542  }
   543  
   544  func (r *reader) readPackage(pkg *ast.Package, mode Mode) {
   545  	// initialize reader
   546  	r.filenames = make([]string, len(pkg.Files))
   547  	r.imports = make(map[string]int)
   548  	r.mode = mode
   549  	r.types = make(map[string]*namedType)
   550  	r.funcs = make(methodSet)
   551  	r.notes = make(map[string][]*Note)
   552  
   553  	// sort package files before reading them so that the
   554  	// result does not depend on map iteration order
   555  	i := 0
   556  	for filename := range pkg.Files {
   557  		r.filenames[i] = filename
   558  		i++
   559  	}
   560  	sort.Strings(r.filenames)
   561  
   562  	// process files in sorted order
   563  	for _, filename := range r.filenames {
   564  		f := pkg.Files[filename]
   565  		if mode&AllDecls == 0 {
   566  			r.fileExports(f)
   567  		}
   568  		r.readFile(f)
   569  	}
   570  }
   571  
   572  // ----------------------------------------------------------------------------
   573  // Types
   574  
   575  func customizeRecv(f *Func, recvTypeName string, embeddedIsPtr bool, level int) *Func {
   576  	if f == nil || f.Decl == nil || f.Decl.Recv == nil || len(f.Decl.Recv.List) != 1 {
   577  		return f // shouldn't happen, but be safe
   578  	}
   579  
   580  	// copy existing receiver field and set new type
   581  	newField := *f.Decl.Recv.List[0]
   582  	origPos := newField.Type.Pos()
   583  	_, origRecvIsPtr := newField.Type.(*ast.StarExpr)
   584  	newIdent := &ast.Ident{NamePos: origPos, Name: recvTypeName}
   585  	var typ ast.Expr = newIdent
   586  	if !embeddedIsPtr && origRecvIsPtr {
   587  		newIdent.NamePos++ // '*' is one character
   588  		typ = &ast.StarExpr{Star: origPos, X: newIdent}
   589  	}
   590  	newField.Type = typ
   591  
   592  	// copy existing receiver field list and set new receiver field
   593  	newFieldList := *f.Decl.Recv
   594  	newFieldList.List = []*ast.Field{&newField}
   595  
   596  	// copy existing function declaration and set new receiver field list
   597  	newFuncDecl := *f.Decl
   598  	newFuncDecl.Recv = &newFieldList
   599  
   600  	// copy existing function documentation and set new declaration
   601  	newF := *f
   602  	newF.Decl = &newFuncDecl
   603  	newF.Recv = recvString(typ)
   604  	// the Orig field never changes
   605  	newF.Level = level
   606  
   607  	return &newF
   608  }
   609  
   610  // collectEmbeddedMethods collects the embedded methods of typ in mset.
   611  //
   612  func (r *reader) collectEmbeddedMethods(mset methodSet, typ *namedType, recvTypeName string, embeddedIsPtr bool, level int, visited embeddedSet) {
   613  	visited[typ] = true
   614  	for embedded, isPtr := range typ.embedded {
   615  		// Once an embedded type is embedded as a pointer type
   616  		// all embedded types in those types are treated like
   617  		// pointer types for the purpose of the receiver type
   618  		// computation; i.e., embeddedIsPtr is sticky for this
   619  		// embedding hierarchy.
   620  		thisEmbeddedIsPtr := embeddedIsPtr || isPtr
   621  		for _, m := range embedded.methods {
   622  			// only top-level methods are embedded
   623  			if m.Level == 0 {
   624  				mset.add(customizeRecv(m, recvTypeName, thisEmbeddedIsPtr, level))
   625  			}
   626  		}
   627  		if !visited[embedded] {
   628  			r.collectEmbeddedMethods(mset, embedded, recvTypeName, thisEmbeddedIsPtr, level+1, visited)
   629  		}
   630  	}
   631  	delete(visited, typ)
   632  }
   633  
   634  // computeMethodSets determines the actual method sets for each type encountered.
   635  //
   636  func (r *reader) computeMethodSets() {
   637  	for _, t := range r.types {
   638  		// collect embedded methods for t
   639  		if t.isStruct {
   640  			// struct
   641  			r.collectEmbeddedMethods(t.methods, t, t.name, false, 1, make(embeddedSet))
   642  		} else {
   643  			// interface
   644  			// TODO(gri) fix this
   645  		}
   646  	}
   647  
   648  	// if error was declared locally, don't treat it as exported field anymore
   649  	if r.errorDecl {
   650  		for _, ityp := range r.fixlist {
   651  			removeErrorField(ityp)
   652  		}
   653  	}
   654  }
   655  
   656  // cleanupTypes removes the association of functions and methods with
   657  // types that have no declaration. Instead, these functions and methods
   658  // are shown at the package level. It also removes types with missing
   659  // declarations or which are not visible.
   660  //
   661  func (r *reader) cleanupTypes() {
   662  	for _, t := range r.types {
   663  		visible := r.isVisible(t.name)
   664  		predeclared := predeclaredTypes[t.name]
   665  
   666  		if t.decl == nil && (predeclared || visible && (t.isEmbedded || r.hasDotImp)) {
   667  			// t.name is a predeclared type (and was not redeclared in this package),
   668  			// or it was embedded somewhere but its declaration is missing (because
   669  			// the AST is incomplete), or we have a dot-import (and all bets are off):
   670  			// move any associated values, funcs, and methods back to the top-level so
   671  			// that they are not lost.
   672  			// 1) move values
   673  			r.values = append(r.values, t.values...)
   674  			// 2) move factory functions
   675  			for name, f := range t.funcs {
   676  				// in a correct AST, package-level function names
   677  				// are all different - no need to check for conflicts
   678  				r.funcs[name] = f
   679  			}
   680  			// 3) move methods
   681  			if !predeclared {
   682  				for name, m := range t.methods {
   683  					// don't overwrite functions with the same name - drop them
   684  					if _, found := r.funcs[name]; !found {
   685  						r.funcs[name] = m
   686  					}
   687  				}
   688  			}
   689  		}
   690  		// remove types w/o declaration or which are not visible
   691  		if t.decl == nil || !visible {
   692  			delete(r.types, t.name)
   693  		}
   694  	}
   695  }
   696  
   697  // ----------------------------------------------------------------------------
   698  // Sorting
   699  
   700  type data struct {
   701  	n    int
   702  	swap func(i, j int)
   703  	less func(i, j int) bool
   704  }
   705  
   706  func (d *data) Len() int           { return d.n }
   707  func (d *data) Swap(i, j int)      { d.swap(i, j) }
   708  func (d *data) Less(i, j int) bool { return d.less(i, j) }
   709  
   710  // sortBy is a helper function for sorting
   711  func sortBy(less func(i, j int) bool, swap func(i, j int), n int) {
   712  	sort.Sort(&data{n, swap, less})
   713  }
   714  
   715  func sortedKeys(m map[string]int) []string {
   716  	list := make([]string, len(m))
   717  	i := 0
   718  	for key := range m {
   719  		list[i] = key
   720  		i++
   721  	}
   722  	sort.Strings(list)
   723  	return list
   724  }
   725  
   726  // sortingName returns the name to use when sorting d into place.
   727  //
   728  func sortingName(d *ast.GenDecl) string {
   729  	if len(d.Specs) == 1 {
   730  		if s, ok := d.Specs[0].(*ast.ValueSpec); ok {
   731  			return s.Names[0].Name
   732  		}
   733  	}
   734  	return ""
   735  }
   736  
   737  func sortedValues(m []*Value, tok token.Token) []*Value {
   738  	list := make([]*Value, len(m)) // big enough in any case
   739  	i := 0
   740  	for _, val := range m {
   741  		if val.Decl.Tok == tok {
   742  			list[i] = val
   743  			i++
   744  		}
   745  	}
   746  	list = list[0:i]
   747  
   748  	sortBy(
   749  		func(i, j int) bool {
   750  			if ni, nj := sortingName(list[i].Decl), sortingName(list[j].Decl); ni != nj {
   751  				return ni < nj
   752  			}
   753  			return list[i].order < list[j].order
   754  		},
   755  		func(i, j int) { list[i], list[j] = list[j], list[i] },
   756  		len(list),
   757  	)
   758  
   759  	return list
   760  }
   761  
   762  func sortedTypes(m map[string]*namedType, allMethods bool) []*Type {
   763  	list := make([]*Type, len(m))
   764  	i := 0
   765  	for _, t := range m {
   766  		list[i] = &Type{
   767  			Doc:     t.doc,
   768  			Name:    t.name,
   769  			Decl:    t.decl,
   770  			Consts:  sortedValues(t.values, token.CONST),
   771  			Vars:    sortedValues(t.values, token.VAR),
   772  			Funcs:   sortedFuncs(t.funcs, true),
   773  			Methods: sortedFuncs(t.methods, allMethods),
   774  		}
   775  		i++
   776  	}
   777  
   778  	sortBy(
   779  		func(i, j int) bool { return list[i].Name < list[j].Name },
   780  		func(i, j int) { list[i], list[j] = list[j], list[i] },
   781  		len(list),
   782  	)
   783  
   784  	return list
   785  }
   786  
   787  func removeStar(s string) string {
   788  	if len(s) > 0 && s[0] == '*' {
   789  		return s[1:]
   790  	}
   791  	return s
   792  }
   793  
   794  func sortedFuncs(m methodSet, allMethods bool) []*Func {
   795  	list := make([]*Func, len(m))
   796  	i := 0
   797  	for _, m := range m {
   798  		// determine which methods to include
   799  		switch {
   800  		case m.Decl == nil:
   801  			// exclude conflict entry
   802  		case allMethods, m.Level == 0, !ast.IsExported(removeStar(m.Orig)):
   803  			// forced inclusion, method not embedded, or method
   804  			// embedded but original receiver type not exported
   805  			list[i] = m
   806  			i++
   807  		}
   808  	}
   809  	list = list[0:i]
   810  	sortBy(
   811  		func(i, j int) bool { return list[i].Name < list[j].Name },
   812  		func(i, j int) { list[i], list[j] = list[j], list[i] },
   813  		len(list),
   814  	)
   815  	return list
   816  }
   817  
   818  // noteBodies returns a list of note body strings given a list of notes.
   819  // This is only used to populate the deprecated Package.Bugs field.
   820  //
   821  func noteBodies(notes []*Note) []string {
   822  	var list []string
   823  	for _, n := range notes {
   824  		list = append(list, n.Body)
   825  	}
   826  	return list
   827  }
   828  
   829  // ----------------------------------------------------------------------------
   830  // Predeclared identifiers
   831  
   832  // IsPredeclared reports whether s is a predeclared identifier.
   833  func IsPredeclared(s string) bool {
   834  	return predeclaredTypes[s] || predeclaredFuncs[s] || predeclaredConstants[s]
   835  }
   836  
   837  var predeclaredTypes = map[string]bool{
   838  	"bool":       true,
   839  	"byte":       true,
   840  	"complex64":  true,
   841  	"complex128": true,
   842  	"error":      true,
   843  	"float32":    true,
   844  	"float64":    true,
   845  	"int":        true,
   846  	"int8":       true,
   847  	"int16":      true,
   848  	"int32":      true,
   849  	"int64":      true,
   850  	"rune":       true,
   851  	"string":     true,
   852  	"uint":       true,
   853  	"uint8":      true,
   854  	"uint16":     true,
   855  	"uint32":     true,
   856  	"uint64":     true,
   857  	"uintptr":    true,
   858  }
   859  
   860  var predeclaredFuncs = map[string]bool{
   861  	"append":  true,
   862  	"cap":     true,
   863  	"close":   true,
   864  	"complex": true,
   865  	"copy":    true,
   866  	"delete":  true,
   867  	"imag":    true,
   868  	"len":     true,
   869  	"make":    true,
   870  	"new":     true,
   871  	"panic":   true,
   872  	"print":   true,
   873  	"println": true,
   874  	"real":    true,
   875  	"recover": true,
   876  }
   877  
   878  var predeclaredConstants = map[string]bool{
   879  	"false": true,
   880  	"iota":  true,
   881  	"nil":   true,
   882  	"true":  true,
   883  }