From 93e3d5dc5f2af317c874fd61cbd354409ea9fd33 Mon Sep 17 00:00:00 2001 From: Mateusz Poliwczak Date: Thu, 1 May 2025 12:20:45 +0000 Subject: [PATCH] go/parser: use non-adjusted position while parsing CommentGroups 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 Reviewed-by: Carlos Amedee Auto-Submit: Alan Donovan LUCI-TryBot-Result: Go LUCI --- src/go/parser/parser.go | 17 +++++++++++------ src/go/parser/parser_test.go | 37 ++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/go/parser/parser.go b/src/go/parser/parser.go index c31b65bb53..38ee0de3bb 100644 --- a/src/go/parser/parser.go +++ b/src/go/parser/parser.go @@ -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 diff --git a/src/go/parser/parser_test.go b/src/go/parser/parser_test.go index 714a6e0237..2516cedc88 100644 --- a/src/go/parser/parser_test.go +++ b/src/go/parser/parser_test.go @@ -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()) + } +} -- 2.51.0