Commit 989ef605 authored by Robert Griesemer's avatar Robert Griesemer

go/ast: use a slice instead of a linked list for the list of comments

        (this will simplify some further changes)
removed several TODOs

R=rsc
CC=golang-dev
https://golang.org/cl/216059
parent aaec6155
......@@ -75,7 +75,6 @@ type Comment struct {
//
type CommentGroup struct {
List []*Comment
Next *CommentGroup // next comment group in source order
}
......@@ -695,12 +694,16 @@ func (d *FuncDecl) declNode() {}
// A File node represents a Go source file.
//
// The Comments list contains all comments in the source file in order of
// appearance, including the comments that are pointed to from other nodes
// via Doc and Comment fields.
//
type File struct {
Doc *CommentGroup // associated documentation; or nil
token.Position // position of "package" keyword
Name *Ident // package name
Decls []Decl // top-level declarations
Comments *CommentGroup // list of all comments in the source file
Doc *CommentGroup // associated documentation; or nil
token.Position // position of "package" keyword
Name *Ident // package name
Decls []Decl // top-level declarations
Comments []*CommentGroup // list of all comments in the source file
}
......
......@@ -107,8 +107,6 @@ func filterSpec(spec Spec) bool {
return true
}
case *TypeSpec:
// TODO(gri) consider stripping forward declarations
// of structs, interfaces, functions, and methods
if s.Name.IsExported() {
filterType(s.Type)
return true
......@@ -136,9 +134,6 @@ func filterDecl(decl Decl) bool {
d.Specs = filterSpecList(d.Specs)
return len(d.Specs) > 0
case *FuncDecl:
// TODO consider removing function declaration altogether if
// forward declaration (i.e., if d.Body == nil) because
// in that case the actual declaration will come later.
d.Body = nil // strip body
return d.Name.IsExported()
}
......@@ -230,7 +225,7 @@ func MergePackageFiles(pkg *Package) *File {
}
}
}
doc = &CommentGroup{list, nil}
doc = &CommentGroup{list}
}
// Collect declarations from all package files.
......@@ -246,8 +241,6 @@ func MergePackageFiles(pkg *Package) *File {
}
}
// TODO(gri) Should collect comments as well. For that the comment
// list should be changed back into a []*CommentGroup,
// otherwise need to modify the existing linked list.
// TODO(gri) Should collect comments as well.
return &File{doc, noPos, NewIdent(pkg.Name), decls, nil}
}
......@@ -64,11 +64,6 @@ func Walk(v Visitor, node interface{}) {
for _, c := range n.List {
Walk(v, c)
}
// TODO(gri): Keep comments in a list/vector instead
// of linking them via Next. Following next will lead
// to multiple visits and potentially n^2 behavior
// since Doc and Comments fields point into the global
// comments list.
case *Field:
walkCommentGroup(v, n.Doc)
......@@ -283,7 +278,9 @@ func Walk(v Visitor, node interface{}) {
walkCommentGroup(v, n.Doc)
walkIdent(v, n.Name)
Walk(v, n.Decls)
walkCommentGroup(v, n.Comments)
for _, g := range n.Comments {
Walk(v, g)
}
case *Package:
for _, f := range n.Files {
......
......@@ -272,7 +272,7 @@ func (doc *docReader) addFile(src *ast.File) {
}
// collect BUG(...) comments
for c := src.Comments; c != nil; c = c.Next {
for _, c := range src.Comments {
text := c.List[0].Text
cstr := string(text)
if m := bug_markers.ExecuteString(cstr); len(m) > 0 {
......@@ -281,7 +281,7 @@ func (doc *docReader) addFile(src *ast.File) {
// non-empty BUG comment; collect comment without BUG prefix
list := copyCommentList(c.List)
list[0].Text = text[m[1]:]
doc.bugs.Push(&ast.CommentGroup{list, nil})
doc.bugs.Push(&ast.CommentGroup{list})
}
}
}
......
......@@ -45,7 +45,7 @@ type parser struct {
indent uint // indentation used for tracing output
// Comments
comments *ast.CommentGroup // list of collected comments
comments vector.Vector // list of *CommentGroup
lastComment *ast.CommentGroup // last comment in the comments list
leadComment *ast.CommentGroup // the last lead comment
lineComment *ast.CommentGroup // the last line comment
......@@ -183,12 +183,8 @@ func (p *parser) consumeCommentGroup() int {
}
// add comment group to the comments list
g := &ast.CommentGroup{group, nil}
if p.lastComment != nil {
p.lastComment.Next = g
} else {
p.comments = g
}
g := &ast.CommentGroup{group}
p.comments.Push(g)
p.lastComment = g
return endline
......@@ -2095,5 +2091,11 @@ func (p *parser) parseFile() *ast.File {
}
}
return &ast.File{doc, pos, ident, decls, p.comments}
// convert comments list
comments := make([]*ast.CommentGroup, len(p.comments))
for i, x := range p.comments {
comments[i] = x.(*ast.CommentGroup)
}
return &ast.File{doc, pos, ident, decls, comments}
}
......@@ -88,7 +88,7 @@ func (p *printer) commentList(list []*ast.Comment) {
// Print a lead comment followed by a newline.
func (p *printer) leadComment(d *ast.CommentGroup) {
// Ignore the comment if we have comments interspersed (p.comment != nil).
if p.comment == nil && d != nil {
if p.comments == nil && d != nil {
p.commentList(d.List)
p.print(newline)
}
......@@ -100,7 +100,7 @@ func (p *printer) leadComment(d *ast.CommentGroup) {
// the comment may be a //-style comment.
func (p *printer) lineComment(d *ast.CommentGroup) {
// Ignore the comment if we have comments interspersed (p.comment != nil).
if p.comment == nil && d != nil {
if p.comments == nil && d != nil {
p.print(vtab)
p.commentList(d.List)
}
......@@ -152,8 +152,8 @@ const (
// Remove this after transitioning to new semicolon syntax and
// some reasonable grace period (12/11/09).
func (p *printer) beforeComment(pos token.Position) token.Position {
if p.comment != nil {
p := p.comment.List[0].Position
if p.cindex < len(p.comments) {
p := p.comments[p.cindex].List[0].Position
if !pos.IsValid() || pos.Offset > p.Offset {
return p
}
......@@ -852,7 +852,7 @@ func (p *printer) moveCommentsAfter(pos token.Position) {
// Remove this after transitioning to new semicolon
// syntax and some reasonable grace period (12/11/09).
if p.commentBefore(pos) {
p.comment.List[0].Position = pos
p.comments[p.cindex].List[0].Position = pos
}
}
......
......@@ -88,8 +88,9 @@ type printer struct {
// HTML support
lastTaggedLine int // last line for which a line tag was written
// The list of comments; or nil.
comment *ast.CommentGroup
// The list of all source comments, in order of appearance.
comments []*ast.CommentGroup // may be nil
cindex int // current comment index
}
......@@ -624,8 +625,8 @@ func (p *printer) intersperseComments(next token.Position, isKeyword bool) {
isFirst := true
needsLinebreak := false
var last *ast.Comment
for ; p.commentBefore(next); p.comment = p.comment.Next {
for _, c := range p.comment.List {
for ; p.commentBefore(next); p.cindex++ {
for _, c := range p.comments[p.cindex].List {
p.writeCommentPrefix(c.Pos(), next, isFirst, isKeyword)
isFirst = false
p.writeComment(c)
......@@ -792,7 +793,7 @@ func (p *printer) print(args ...) {
// before the next position in the source code.
//
func (p *printer) commentBefore(next token.Position) bool {
return p.comment != nil && p.comment.List[0].Pos().Offset < next.Offset
return p.cindex < len(p.comments) && p.comments[p.cindex].List[0].Pos().Offset < next.Offset
}
......@@ -981,7 +982,7 @@ func (cfg *Config) Fprint(output io.Writer, node interface{}) (int, os.Error) {
case ast.Decl:
p.decl(n, atTop, ignoreMultiLine)
case *ast.File:
p.comment = n.Comments
p.comments = n.Comments
p.file(n)
default:
p.errors <- os.NewError(fmt.Sprintf("printer.Fprint: unsupported node type %T", n))
......
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