Skip to content

Commit 51f18f3

Browse files
committed
syntax: recover binary commands properly
I wasn't paying close enough attention to the code; the returned statement is the parent containing both branches, not just the right branch which is recovered. Teach the tests to spot when the result is empty or all recovered, which caught these mistakes.
1 parent c6175e6 commit 51f18f3

File tree

2 files changed

+17
-6
lines changed

2 files changed

+17
-6
lines changed

syntax/parser.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,10 +1721,11 @@ func (p *Parser) getStmt(readEnd, binCmd, fnBody bool) *Stmt {
17211721
b.Y = p.getStmt(false, true, false)
17221722
if b.Y == nil || p.err != nil {
17231723
if p.recoverError() {
1724-
return &Stmt{Position: recoveredPos}
1724+
b.Y = &Stmt{Position: recoveredPos}
1725+
} else {
1726+
p.followErr(b.OpPos, b.Op.String(), "a statement")
1727+
return nil
17251728
}
1726-
p.followErr(b.OpPos, b.Op.String(), "a statement")
1727-
return nil
17281729
}
17291730
s = &Stmt{Position: s.Position}
17301731
s.Cmd = b
@@ -1897,10 +1898,11 @@ func (p *Parser) gotStmtPipe(s *Stmt, binCmd bool) *Stmt {
18971898
p.got(_Newl)
18981899
if b.Y = p.gotStmtPipe(&Stmt{Position: p.pos}, true); b.Y == nil || p.err != nil {
18991900
if p.recoverError() {
1900-
return &Stmt{Position: recoveredPos}
1901+
b.Y = &Stmt{Position: recoveredPos}
1902+
} else {
1903+
p.followErr(b.OpPos, b.Op.String(), "a statement")
1904+
break
19011905
}
1902-
p.followErr(b.OpPos, b.Op.String(), "a statement")
1903-
break
19041906
}
19051907
s = &Stmt{Position: s.Position}
19061908
s.Cmd = b

syntax/parser_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2618,12 +2618,21 @@ func TestParseRecoverErrors(t *testing.T) {
26182618
printer := NewPrinter()
26192619
for _, tc := range tests {
26202620
t.Run("", func(t *testing.T) {
2621+
t.Logf("input: %s", tc.src)
26212622
r := strings.NewReader(tc.src)
26222623
f, err := parser.Parse(r, "")
26232624
if tc.wantErr {
26242625
qt.Assert(t, qt.Not(qt.IsNil(err)))
26252626
} else {
26262627
qt.Assert(t, qt.IsNil(err))
2628+
switch len(f.Stmts) {
2629+
case 0:
2630+
t.Fatalf("result has no statements")
2631+
case 1:
2632+
if f.Stmts[0].Pos().IsRecovered() {
2633+
t.Fatalf("result is only a recovered statement")
2634+
}
2635+
}
26272636
}
26282637
qt.Assert(t, qt.Equals(countRecoveredPositions(reflect.ValueOf(f)), tc.wantMissing))
26292638

0 commit comments

Comments
 (0)