func (p *printer) file(src *ast.File) { p.setComment(src.Doc) p.print(src.Pos(), token.PACKAGE, blank) p.expr(src.Name) p.declList(src.Decls) p.print(newline) }
// fileExports removes unexported declarations from src in place. // func (r *reader) fileExports(src *ast.File) { j := 0 for _, d := range src.Decls { if r.filterDecl(d) { src.Decls[j] = d j++ } } src.Decls = src.Decls[0:j] }
// readFile adds the AST for a source file to the reader. // func (r *reader) readFile(src *ast.File) { // add package documentation if src.Doc != nil { r.readDoc(src.Doc) src.Doc = nil // doc consumed - remove from AST } // add all declarations for _, decl := range src.Decls { switch d := decl.(type) { case *ast.GenDecl: switch d.Tok { case token.IMPORT: // imports are handled individually for _, spec := range d.Specs { if s, ok := spec.(*ast.ImportSpec); ok { if import_, err := strconv.Unquote(s.Path.Value); err == nil { r.imports[import_] = 1 } } } case token.CONST, token.VAR: // constants and variables are always handled as a group r.readValue(d) case token.TYPE: // types are handled individually if len(d.Specs) == 1 && !d.Lparen.IsValid() { // common case: single declaration w/o parentheses // (if a single declaration is parenthesized, // create a new fake declaration below, so that // go/doc type declarations always appear w/o // parentheses) if s, ok := d.Specs[0].(*ast.TypeSpec); ok { r.readType(d, s) } break } for _, spec := range d.Specs { if s, ok := spec.(*ast.TypeSpec); ok { // use an individual (possibly fake) declaration // for each type; this also ensures that each type // gets to (re-)use the declaration documentation // if there's none associated with the spec itself fake := &ast.GenDecl{ Doc: d.Doc, // don't use the existing TokPos because it // will lead to the wrong selection range for // the fake declaration if there are more // than one type in the group (this affects // src/cmd/godoc/godoc.go's posLink_urlFunc) TokPos: s.Pos(), Tok: token.TYPE, Specs: []ast.Spec{s}, } r.readType(fake, s) } } } case *ast.FuncDecl: r.readFunc(d) } } // collect MARKER(...): annotations r.readNotes(src.Comments) src.Comments = nil // consumed unassociated comments - remove from AST }