Skip to content

Commit

Permalink
modfile: fix Cleanup clobbering Line reference
Browse files Browse the repository at this point in the history
Fixes golang/go#45130

Change-Id: I2dccba5e958911177f10a5104a182f86ff8378d9
Reviewed-on: https://go-review.googlesource.com/c/mod/+/303234
Reviewed-by: Michael Matloob <matloob@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
  • Loading branch information
jameshartig authored and matloob committed Jul 25, 2024
1 parent b56a28f commit d1f873e
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 3 deletions.
7 changes: 4 additions & 3 deletions modfile/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,16 +226,17 @@ func (x *FileSyntax) Cleanup() {
continue
}
if ww == 1 && len(stmt.RParen.Comments.Before) == 0 {
// Collapse block into single line.
line := &Line{
// Collapse block into single line but keep the Line reference used by the
// parsed File structure.
*stmt.Line[0] = Line{
Comments: Comments{
Before: commentsAdd(stmt.Before, stmt.Line[0].Before),
Suffix: commentsAdd(stmt.Line[0].Suffix, stmt.Suffix),
After: commentsAdd(stmt.Line[0].After, stmt.After),
},
Token: stringsAdd(stmt.Token, stmt.Line[0].Token),
}
x.Stmt[w] = line
x.Stmt[w] = stmt.Line[0]
w++
continue
}
Expand Down
131 changes: 131 additions & 0 deletions modfile/read_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -603,3 +603,134 @@ comments before "// k"
})
}
}

func TestCleanup(t *testing.T) {
for _, test := range []struct {
desc string
want string
input []Expr
}{
{
desc: "simple_lines",
want: `line: module a
line: require b v1.0.0
`,
input: []Expr{
&Line{
Token: []string{"module", "a"},
},
&Line{
Token: []string{"require", "b", "v1.0.0"},
},
&Line{
Token: nil,
},
},
}, {
desc: "line_block",
want: `line: module a
block: require
blockline: b v1.0.0
blockline: c v1.0.0
`,
input: []Expr{
&Line{
Token: []string{"module", "a"},
},
&LineBlock{
Token: []string{"require"},
Line: []*Line{
{
Token: []string{"b", "v1.0.0"},
InBlock: true,
},
{
Token: nil,
InBlock: true,
},
{
Token: []string{"c", "v1.0.0"},
InBlock: true,
},
},
},
},
}, {
desc: "collapse",
want: `line: module a
line: require b v1.0.0
`,
input: []Expr{
&Line{
Token: []string{"module", "a"},
},
&LineBlock{
Token: []string{"require"},
Line: []*Line{
{
Token: []string{"b", "v1.0.0"},
InBlock: true,
},
{
Token: nil,
InBlock: true,
},
},
},
},
},
} {
t.Run(test.desc, func(t *testing.T) {
syntax := &FileSyntax{
Stmt: test.input,
}
syntax.Cleanup()

buf := &bytes.Buffer{}
for _, stmt := range syntax.Stmt {
switch stmt := stmt.(type) {
case *Line:
fmt.Fprintf(buf, "line: %v\n", strings.Join(stmt.Token, " "))
case *LineBlock:
fmt.Fprintf(buf, "block: %v\n", strings.Join(stmt.Token, " "))
for _, line := range stmt.Line {
fmt.Fprintf(buf, "blockline: %v\n", strings.Join(line.Token, " "))
}
}
}

got := strings.TrimSpace(buf.String())
want := strings.TrimSpace(test.want)
if got != want {
t.Errorf("got:\n%s\nwant:\n%s", got, want)
}
})
}
}

// Issue 45130: File.Cleanup breaks references so future edits do nothing
func TestCleanupMaintainsRefs(t *testing.T) {
lineB := &Line{
Token: []string{"b", "v1.0.0"},
InBlock: true,
}
syntax := &FileSyntax{
Stmt: []Expr{
&LineBlock{
Token: []string{"require"},
Line: []*Line{
lineB,
{
Token: nil,
InBlock: true,
},
},
},
},
}
syntax.Cleanup()

if syntax.Stmt[0] != lineB {
t.Errorf("got:\n%v\nwant:\n%v", syntax.Stmt[0], lineB)
}
}

0 comments on commit d1f873e

Please sign in to comment.