Skip to content

Commit 37dd689

Browse files
author
Jay Conrod
committed
modfile: in SetRequireSeparateIndirect, convert lines to blocks
When reading go.mod, SetRequireSeparateIndirect will insert new requirements into the last uncommented direct-only or indirect-only block OR line. If the last such statement is a line, SetRequireSeparateIndirect converts it to a block before inserting new requirements. Cleanup will convert it back to a line later if no requirements are inserted. For golang/go#47733 Change-Id: Id8ee3b0ce2d005488ddb3d9a5349115bd93938e7 Reviewed-on: https://go-review.googlesource.com/c/mod/+/348576 Trust: Jay Conrod <[email protected]> Run-TryBot: Jay Conrod <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]> Reviewed-by: Michael Matloob <[email protected]>
1 parent 4be982b commit 37dd689

File tree

2 files changed

+82
-31
lines changed

2 files changed

+82
-31
lines changed

modfile/rule.go

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,9 +1087,8 @@ func (f *File) SetRequireSeparateIndirect(req []*Require) {
10871087
// We may insert new requirements into the last uncommented
10881088
// direct-only and indirect-only blocks. We may also move requirements
10891089
// to the opposite block if their indirect markings change.
1090-
lastDirectBlock, lastIndirectBlock *LineBlock
1091-
lastDirectBlockIndex = -1
1092-
lastIndirectBlockIndex = -1
1090+
lastDirectIndex = -1
1091+
lastIndirectIndex = -1
10931092

10941093
// If there are no direct-only or indirect-only blocks, a new block may
10951094
// be inserted after the last require line or block.
@@ -1111,6 +1110,13 @@ func (f *File) SetRequireSeparateIndirect(req []*Require) {
11111110
}
11121111
lastRequireIndex = i
11131112
requireLineOrBlockCount++
1113+
if !hasComments(stmt.Comments) {
1114+
if isIndirect(stmt) {
1115+
lastIndirectIndex = i
1116+
} else {
1117+
lastDirectIndex = i
1118+
}
1119+
}
11141120

11151121
case *LineBlock:
11161122
if len(stmt.Token) == 0 || stmt.Token[0] != "require" {
@@ -1132,46 +1138,67 @@ func (f *File) SetRequireSeparateIndirect(req []*Require) {
11321138
}
11331139
}
11341140
if allDirect {
1135-
lastDirectBlock = stmt
1136-
lastDirectBlockIndex = i
1141+
lastDirectIndex = i
11371142
}
11381143
if allIndirect {
1139-
lastIndirectBlock = stmt
1140-
lastIndirectBlockIndex = i
1144+
lastIndirectIndex = i
11411145
}
11421146
}
11431147
}
11441148

11451149
oneFlatUncommentedBlock := requireLineOrBlockCount == 1 &&
11461150
!hasComments(*f.Syntax.Stmt[lastRequireIndex].Comment())
11471151

1148-
// Create direct and indirect blocks if needed. It's okay if they're empty.
1149-
// Cleanup will remove them and convert one-line blocks to lines.
1150-
if lastDirectBlock == nil {
1151-
lastDirectBlock = &LineBlock{Token: []string{"require"}}
1152-
i := len(f.Syntax.Stmt)
1153-
if lastIndirectBlockIndex >= 0 {
1154-
i = lastIndirectBlockIndex
1155-
lastIndirectBlockIndex++
1156-
} else if lastRequireIndex >= 0 {
1157-
i = lastRequireIndex + 1
1158-
}
1152+
// Create direct and indirect blocks if needed. Convert lines into blocks
1153+
// if needed. If we end up with an empty block or a one-line block,
1154+
// Cleanup will delete it or convert it to a line later.
1155+
insertBlock := func(i int) *LineBlock {
1156+
block := &LineBlock{Token: []string{"require"}}
11591157
f.Syntax.Stmt = append(f.Syntax.Stmt, nil)
11601158
copy(f.Syntax.Stmt[i+1:], f.Syntax.Stmt[i:])
1161-
f.Syntax.Stmt[i] = lastDirectBlock
1162-
lastDirectBlockIndex = i
1159+
f.Syntax.Stmt[i] = block
1160+
return block
11631161
}
11641162

1165-
if lastIndirectBlock == nil {
1166-
lastIndirectBlock = &LineBlock{Token: []string{"require"}}
1167-
i := len(f.Syntax.Stmt)
1168-
if lastDirectBlockIndex >= 0 {
1169-
i = lastDirectBlockIndex + 1
1163+
ensureBlock := func(i int) *LineBlock {
1164+
switch stmt := f.Syntax.Stmt[i].(type) {
1165+
case *LineBlock:
1166+
return stmt
1167+
case *Line:
1168+
block := &LineBlock{
1169+
Token: []string{"require"},
1170+
Line: []*Line{stmt},
1171+
}
1172+
stmt.Token = stmt.Token[1:] // remove "require"
1173+
stmt.InBlock = true
1174+
f.Syntax.Stmt[i] = block
1175+
return block
1176+
default:
1177+
panic(fmt.Sprintf("unexpected statement: %v", stmt))
11701178
}
1171-
f.Syntax.Stmt = append(f.Syntax.Stmt, nil)
1172-
copy(f.Syntax.Stmt[i+1:], f.Syntax.Stmt[i:])
1173-
f.Syntax.Stmt[i] = lastIndirectBlock
1174-
lastIndirectBlockIndex = i
1179+
}
1180+
1181+
var lastDirectBlock *LineBlock
1182+
if lastDirectIndex < 0 {
1183+
if lastIndirectIndex >= 0 {
1184+
lastDirectIndex = lastIndirectIndex
1185+
lastIndirectIndex++
1186+
} else if lastRequireIndex >= 0 {
1187+
lastDirectIndex = lastRequireIndex + 1
1188+
} else {
1189+
lastDirectIndex = len(f.Syntax.Stmt)
1190+
}
1191+
lastDirectBlock = insertBlock(lastDirectIndex)
1192+
} else {
1193+
lastDirectBlock = ensureBlock(lastDirectIndex)
1194+
}
1195+
1196+
var lastIndirectBlock *LineBlock
1197+
if lastIndirectIndex < 0 {
1198+
lastIndirectIndex = lastDirectIndex + 1
1199+
lastIndirectBlock = insertBlock(lastIndirectIndex)
1200+
} else {
1201+
lastIndirectBlock = ensureBlock(lastIndirectIndex)
11751202
}
11761203

11771204
// Delete requirements we don't want anymore.

modfile/rule_test.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,28 @@ var setRequireSeparateIndirectTests = []struct {
339339
)
340340
`,
341341
},
342+
{
343+
`existing_line`,
344+
`module m
345+
require x.y/a v1.0.0
346+
require x.y/c v1.0.0 // indirect
347+
`,
348+
[]require{
349+
{"x.y/a", "v1.2.3", false},
350+
{"x.y/b", "v1.2.3", false},
351+
{"x.y/c", "v1.2.3", true},
352+
{"x.y/d", "v1.2.3", true},
353+
},
354+
`module m
355+
require (
356+
x.y/a v1.2.3
357+
x.y/b v1.2.3
358+
)
359+
require (
360+
x.y/c v1.2.3 // indirect
361+
x.y/d v1.2.3 // indirect
362+
)`,
363+
},
342364
{
343365
`existing_multi`,
344366
`module m
@@ -366,7 +388,10 @@ var setRequireSeparateIndirectTests = []struct {
366388
{"x.y/g", "v1.2.3", false},
367389
},
368390
`module m
369-
require x.y/a v1.2.3
391+
require (
392+
x.y/a v1.2.3
393+
x.y/h v1.2.3
394+
)
370395
require x.y/b v1.2.3 // indirect; demoted to indirect
371396
require x.y/c v1.2.3 // not v1.2.3!
372397
require x.y/d v1.2.3 // comment kept
@@ -376,7 +401,6 @@ var setRequireSeparateIndirectTests = []struct {
376401
require x.y/g v1.2.3
377402
require x.y/i v1.2.3 // indirect
378403
require x.y/j v1.2.3 // indirect
379-
require x.y/h v1.2.3
380404
`,
381405
},
382406
{

0 commit comments

Comments
 (0)