}
}
+// lineFor returns the line of pos, ignoring line directive adjustments.
+func (p *parser) lineFor(pos token.Pos) int {
+ return p.file.PositionFor(pos, false).Line
+}
+
// Consume a comment and return it and the line on which it ends.
func (p *parser) consumeComment() (comment *ast.Comment, endline int) {
// /*-style comments may end on a different line than where they start.
// Scan the comment for '\n' chars and adjust endline accordingly.
- endline = p.file.Line(p.pos)
+ endline = p.lineFor(p.pos)
if p.lit[1] == '*' {
// don't use range here - no need to decode Unicode code points
for i := 0; i < len(p.lit); i++ {
// empty lines terminate a comment group.
func (p *parser) consumeCommentGroup(n int) (comments *ast.CommentGroup, endline int) {
var list []*ast.Comment
- endline = p.file.Line(p.pos)
- for p.tok == token.COMMENT && p.file.Line(p.pos) <= endline+n {
+ endline = p.lineFor(p.pos)
+ for p.tok == token.COMMENT && p.lineFor(p.pos) <= endline+n {
var comment *ast.Comment
comment, endline = p.consumeComment()
list = append(list, comment)
var comment *ast.CommentGroup
var endline int
- if p.file.Line(p.pos) == p.file.Line(prev) {
+ if p.lineFor(p.pos) == p.lineFor(prev) {
// The comment is on same line as the previous token; it
// cannot be a lead comment but may be a line comment.
comment, endline = p.consumeCommentGroup(0)
- if p.file.Line(p.pos) != endline || p.tok == token.SEMICOLON || p.tok == token.EOF {
+ if p.lineFor(p.pos) != endline || p.tok == token.SEMICOLON || p.tok == token.EOF {
// The next token is on a different line, thus
// the last comment group is a line comment.
p.lineComment = comment
comment, endline = p.consumeCommentGroup(1)
}
- if endline+1 == p.file.Line(p.pos) {
+ if endline+1 == p.lineFor(p.pos) {
// The next token is following on the line immediately after the
// comment group, thus the last comment group is a lead comment.
p.leadComment = comment
"go/ast"
"go/token"
"io/fs"
+ "reflect"
"strings"
"testing"
)
}
}
}
+
+func TestCommentGroupWithLineDirective(t *testing.T) {
+ const src = `package main
+func test() {
+//line a:15:1
+ //
+}
+`
+ fset := token.NewFileSet()
+ f, err := ParseFile(fset, "test.go", src, ParseComments|SkipObjectResolution)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ wantCommentGroups := []*ast.CommentGroup{
+ {
+ List: []*ast.Comment{
+ {
+ Slash: token.Pos(28),
+ Text: "//line a:15:1",
+ },
+ {
+ Slash: token.Pos(43),
+ Text: "//",
+ },
+ },
+ },
+ }
+
+ if !reflect.DeepEqual(f.Comments, wantCommentGroups) {
+ var got, want strings.Builder
+ ast.Fprint(&got, fset, f.Comments, nil)
+ ast.Fprint(&want, fset, wantCommentGroups, nil)
+ t.Fatalf("unexpected f.Comments got:\n%v\nwant:\n%v", got.String(), want.String())
+ }
+}