]> Cypherpunks repositories - gostls13.git/commitdiff
go/parser: use non-adjusted position while parsing CommentGroups
authorMateusz Poliwczak <mpoliwczak34@gmail.com>
Thu, 1 May 2025 12:20:45 +0000 (12:20 +0000)
committerGopher Robot <gobot@golang.org>
Mon, 5 May 2025 15:29:32 +0000 (08:29 -0700)
Line directives should not affect the way Comments get grouped
into CommentGroups.

Change-Id: I9aa4b558cb1333b32be692e8720291d0e6961cae
GitHub-Last-Rev: de867b27bff28983716ba9126329d75f456a2b5a
GitHub-Pull-Request: golang/go#69133
Reviewed-on: https://go-review.googlesource.com/c/go/+/609515
Reviewed-by: Alan Donovan <adonovan@google.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Auto-Submit: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/go/parser/parser.go
src/go/parser/parser_test.go

index c31b65bb53081e184701165425e980deea4b2d7d..38ee0de3bb386a861383affe4c36a9070d55cd9d 100644 (file)
@@ -161,11 +161,16 @@ func (p *parser) next0() {
        }
 }
 
+// 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++ {
@@ -187,8 +192,8 @@ func (p *parser) consumeComment() (comment *ast.Comment, endline int) {
 // 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)
@@ -225,11 +230,11 @@ func (p *parser) next() {
                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
@@ -242,7 +247,7 @@ func (p *parser) next() {
                        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
index 714a6e02375c0e12b113134c8ff961b7589bce28..2516cedc88d0addd3aa9bf24efc6b9e3bc3b7dd7 100644 (file)
@@ -9,6 +9,7 @@ import (
        "go/ast"
        "go/token"
        "io/fs"
+       "reflect"
        "strings"
        "testing"
 )
@@ -859,3 +860,39 @@ func TestEmptyFileHasValidStartEnd(t *testing.T) {
                }
        }
 }
+
+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())
+       }
+}