mirror of
https://github.com/golang/go
synced 2024-11-25 16:07:56 -07:00
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
This commit is contained in:
parent
aaec61555a
commit
989ef60509
@ -75,7 +75,6 @@ type Comment struct {
|
|||||||
//
|
//
|
||||||
type CommentGroup struct {
|
type CommentGroup struct {
|
||||||
List []*Comment
|
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.
|
// 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 {
|
type File struct {
|
||||||
Doc *CommentGroup // associated documentation; or nil
|
Doc *CommentGroup // associated documentation; or nil
|
||||||
token.Position // position of "package" keyword
|
token.Position // position of "package" keyword
|
||||||
Name *Ident // package name
|
Name *Ident // package name
|
||||||
Decls []Decl // top-level declarations
|
Decls []Decl // top-level declarations
|
||||||
Comments *CommentGroup // list of all comments in the source file
|
Comments []*CommentGroup // list of all comments in the source file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -107,8 +107,6 @@ func filterSpec(spec Spec) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
case *TypeSpec:
|
case *TypeSpec:
|
||||||
// TODO(gri) consider stripping forward declarations
|
|
||||||
// of structs, interfaces, functions, and methods
|
|
||||||
if s.Name.IsExported() {
|
if s.Name.IsExported() {
|
||||||
filterType(s.Type)
|
filterType(s.Type)
|
||||||
return true
|
return true
|
||||||
@ -136,9 +134,6 @@ func filterDecl(decl Decl) bool {
|
|||||||
d.Specs = filterSpecList(d.Specs)
|
d.Specs = filterSpecList(d.Specs)
|
||||||
return len(d.Specs) > 0
|
return len(d.Specs) > 0
|
||||||
case *FuncDecl:
|
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
|
d.Body = nil // strip body
|
||||||
return d.Name.IsExported()
|
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.
|
// 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
|
// TODO(gri) Should collect comments as well.
|
||||||
// list should be changed back into a []*CommentGroup,
|
|
||||||
// otherwise need to modify the existing linked list.
|
|
||||||
return &File{doc, noPos, NewIdent(pkg.Name), decls, nil}
|
return &File{doc, noPos, NewIdent(pkg.Name), decls, nil}
|
||||||
}
|
}
|
||||||
|
@ -64,11 +64,6 @@ func Walk(v Visitor, node interface{}) {
|
|||||||
for _, c := range n.List {
|
for _, c := range n.List {
|
||||||
Walk(v, c)
|
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:
|
case *Field:
|
||||||
walkCommentGroup(v, n.Doc)
|
walkCommentGroup(v, n.Doc)
|
||||||
@ -283,7 +278,9 @@ func Walk(v Visitor, node interface{}) {
|
|||||||
walkCommentGroup(v, n.Doc)
|
walkCommentGroup(v, n.Doc)
|
||||||
walkIdent(v, n.Name)
|
walkIdent(v, n.Name)
|
||||||
Walk(v, n.Decls)
|
Walk(v, n.Decls)
|
||||||
walkCommentGroup(v, n.Comments)
|
for _, g := range n.Comments {
|
||||||
|
Walk(v, g)
|
||||||
|
}
|
||||||
|
|
||||||
case *Package:
|
case *Package:
|
||||||
for _, f := range n.Files {
|
for _, f := range n.Files {
|
||||||
|
@ -272,7 +272,7 @@ func (doc *docReader) addFile(src *ast.File) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// collect BUG(...) comments
|
// collect BUG(...) comments
|
||||||
for c := src.Comments; c != nil; c = c.Next {
|
for _, c := range src.Comments {
|
||||||
text := c.List[0].Text
|
text := c.List[0].Text
|
||||||
cstr := string(text)
|
cstr := string(text)
|
||||||
if m := bug_markers.ExecuteString(cstr); len(m) > 0 {
|
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
|
// non-empty BUG comment; collect comment without BUG prefix
|
||||||
list := copyCommentList(c.List)
|
list := copyCommentList(c.List)
|
||||||
list[0].Text = text[m[1]:]
|
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
|
indent uint // indentation used for tracing output
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
comments *ast.CommentGroup // list of collected comments
|
comments vector.Vector // list of *CommentGroup
|
||||||
lastComment *ast.CommentGroup // last comment in the comments list
|
lastComment *ast.CommentGroup // last comment in the comments list
|
||||||
leadComment *ast.CommentGroup // the last lead comment
|
leadComment *ast.CommentGroup // the last lead comment
|
||||||
lineComment *ast.CommentGroup // the last line comment
|
lineComment *ast.CommentGroup // the last line comment
|
||||||
@ -183,12 +183,8 @@ func (p *parser) consumeCommentGroup() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add comment group to the comments list
|
// add comment group to the comments list
|
||||||
g := &ast.CommentGroup{group, nil}
|
g := &ast.CommentGroup{group}
|
||||||
if p.lastComment != nil {
|
p.comments.Push(g)
|
||||||
p.lastComment.Next = g
|
|
||||||
} else {
|
|
||||||
p.comments = g
|
|
||||||
}
|
|
||||||
p.lastComment = g
|
p.lastComment = g
|
||||||
|
|
||||||
return endline
|
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.
|
// Print a lead comment followed by a newline.
|
||||||
func (p *printer) leadComment(d *ast.CommentGroup) {
|
func (p *printer) leadComment(d *ast.CommentGroup) {
|
||||||
// Ignore the comment if we have comments interspersed (p.comment != nil).
|
// 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.commentList(d.List)
|
||||||
p.print(newline)
|
p.print(newline)
|
||||||
}
|
}
|
||||||
@ -100,7 +100,7 @@ func (p *printer) leadComment(d *ast.CommentGroup) {
|
|||||||
// the comment may be a //-style comment.
|
// the comment may be a //-style comment.
|
||||||
func (p *printer) lineComment(d *ast.CommentGroup) {
|
func (p *printer) lineComment(d *ast.CommentGroup) {
|
||||||
// Ignore the comment if we have comments interspersed (p.comment != nil).
|
// 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.print(vtab)
|
||||||
p.commentList(d.List)
|
p.commentList(d.List)
|
||||||
}
|
}
|
||||||
@ -152,8 +152,8 @@ const (
|
|||||||
// Remove this after transitioning to new semicolon syntax and
|
// Remove this after transitioning to new semicolon syntax and
|
||||||
// some reasonable grace period (12/11/09).
|
// some reasonable grace period (12/11/09).
|
||||||
func (p *printer) beforeComment(pos token.Position) token.Position {
|
func (p *printer) beforeComment(pos token.Position) token.Position {
|
||||||
if p.comment != nil {
|
if p.cindex < len(p.comments) {
|
||||||
p := p.comment.List[0].Position
|
p := p.comments[p.cindex].List[0].Position
|
||||||
if !pos.IsValid() || pos.Offset > p.Offset {
|
if !pos.IsValid() || pos.Offset > p.Offset {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
@ -852,7 +852,7 @@ func (p *printer) moveCommentsAfter(pos token.Position) {
|
|||||||
// Remove this after transitioning to new semicolon
|
// Remove this after transitioning to new semicolon
|
||||||
// syntax and some reasonable grace period (12/11/09).
|
// syntax and some reasonable grace period (12/11/09).
|
||||||
if p.commentBefore(pos) {
|
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
|
// HTML support
|
||||||
lastTaggedLine int // last line for which a line tag was written
|
lastTaggedLine int // last line for which a line tag was written
|
||||||
|
|
||||||
// The list of comments; or nil.
|
// The list of all source comments, in order of appearance.
|
||||||
comment *ast.CommentGroup
|
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
|
isFirst := true
|
||||||
needsLinebreak := false
|
needsLinebreak := false
|
||||||
var last *ast.Comment
|
var last *ast.Comment
|
||||||
for ; p.commentBefore(next); p.comment = p.comment.Next {
|
for ; p.commentBefore(next); p.cindex++ {
|
||||||
for _, c := range p.comment.List {
|
for _, c := range p.comments[p.cindex].List {
|
||||||
p.writeCommentPrefix(c.Pos(), next, isFirst, isKeyword)
|
p.writeCommentPrefix(c.Pos(), next, isFirst, isKeyword)
|
||||||
isFirst = false
|
isFirst = false
|
||||||
p.writeComment(c)
|
p.writeComment(c)
|
||||||
@ -792,7 +793,7 @@ func (p *printer) print(args ...) {
|
|||||||
// before the next position in the source code.
|
// before the next position in the source code.
|
||||||
//
|
//
|
||||||
func (p *printer) commentBefore(next token.Position) bool {
|
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:
|
case ast.Decl:
|
||||||
p.decl(n, atTop, ignoreMultiLine)
|
p.decl(n, atTop, ignoreMultiLine)
|
||||||
case *ast.File:
|
case *ast.File:
|
||||||
p.comment = n.Comments
|
p.comments = n.Comments
|
||||||
p.file(n)
|
p.file(n)
|
||||||
default:
|
default:
|
||||||
p.errors <- os.NewError(fmt.Sprintf("printer.Fprint: unsupported node type %T", n))
|
p.errors <- os.NewError(fmt.Sprintf("printer.Fprint: unsupported node type %T", n))
|
||||||
|
Loading…
Reference in New Issue
Block a user