diff --git a/src/pkg/go/parser/parser.go b/src/pkg/go/parser/parser.go index 77bcc448273..7c5843f3637 100644 --- a/src/pkg/go/parser/parser.go +++ b/src/pkg/go/parser/parser.go @@ -1339,13 +1339,18 @@ func (p *parser) parseIfStmt() *ast.IfStmt { { prevLev := p.exprLev p.exprLev = -1 - s = p.parseSimpleStmt(false) if p.tok == token.SEMICOLON { p.next() x = p.parseExpr() } else { - x = p.makeExpr(s) - s = nil + s = p.parseSimpleStmt(false) + if p.tok == token.SEMICOLON { + p.next() + x = p.parseExpr() + } else { + x = p.makeExpr(s) + s = nil + } } p.exprLev = prevLev } @@ -1447,7 +1452,9 @@ func (p *parser) parseSwitchStmt() ast.Stmt { if p.tok != token.LBRACE { prevLev := p.exprLev p.exprLev = -1 - s2 = p.parseSimpleStmt(false) + if p.tok != token.SEMICOLON { + s2 = p.parseSimpleStmt(false) + } if p.tok == token.SEMICOLON { p.next() s1 = s2 @@ -1580,7 +1587,6 @@ func (p *parser) parseForStmt() ast.Stmt { if p.tok != token.LBRACE { prevLev := p.exprLev p.exprLev = -1 - if p.tok != token.SEMICOLON { s2 = p.parseSimpleStmt(false) } @@ -1596,7 +1602,6 @@ func (p *parser) parseForStmt() ast.Stmt { s3 = p.parseSimpleStmt(false) } } - p.exprLev = prevLev } diff --git a/src/pkg/go/parser/parser_test.go b/src/pkg/go/parser/parser_test.go index 71238702038..38535627a75 100644 --- a/src/pkg/go/parser/parser_test.go +++ b/src/pkg/go/parser/parser_test.go @@ -19,6 +19,8 @@ var illegalInputs = []interface{}{ []byte(nil), "foo!", `package p; func f() { if /* should have condition */ {} };`, + `package p; func f() { if ; /* should have condition */ {} };`, + `package p; func f() { if f(); /* should have condition */ {} };`, } @@ -33,21 +35,23 @@ func TestParseIllegalInputs(t *testing.T) { var validPrograms = []interface{}{ - "package main\n", - `package main;`, - `package main; import "fmt"; func main() { fmt.Println("Hello, World!") };`, - `package main; func main() { if f(T{}) {} };`, - `package main; func main() { _ = (<-chan int)(x) };`, - `package main; func main() { _ = (<-chan <-chan int)(x) };`, - `package main; func f(func() func() func());`, - `package main; func f(...T);`, - `package main; func f(float, ...int);`, - `package main; func f(x int, a ...int) { f(0, a...); f(1, a...,) };`, - `package main; type T []int; var a []bool; func f() { if a[T{42}[0]] {} };`, - `package main; type T []int; func g(int) bool { return true }; func f() { if g(T{42}[0]) {} };`, - `package main; type T []int; func f() { for _ = range []int{T{42}[0]} {} };`, - `package main; var a = T{{1, 2}, {3, 4}}`, - `package main; func f() { select { case <- c: case c <- d: case c <- <- d: case <-c <- d: } };`, + "package p\n", + `package p;`, + `package p; import "fmt"; func f() { fmt.Println("Hello, World!") };`, + `package p; func f() { if f(T{}) {} };`, + `package p; func f() { _ = (<-chan int)(x) };`, + `package p; func f() { _ = (<-chan <-chan int)(x) };`, + `package p; func f(func() func() func());`, + `package p; func f(...T);`, + `package p; func f(float, ...int);`, + `package p; func f(x int, a ...int) { f(0, a...); f(1, a...,) };`, + `package p; type T []int; var a []bool; func f() { if a[T{42}[0]] {} };`, + `package p; type T []int; func g(int) bool { return true }; func f() { if g(T{42}[0]) {} };`, + `package p; type T []int; func f() { for _ = range []int{T{42}[0]} {} };`, + `package p; var a = T{{1, 2}, {3, 4}}`, + `package p; func f() { select { case <- c: case c <- d: case c <- <- d: case <-c <- d: } };`, + `package p; func f() { if ; true {} };`, + `package p; func f() { switch ; {} };`, } diff --git a/src/pkg/go/printer/testdata/statements.golden b/src/pkg/go/printer/testdata/statements.golden index 98bc0319ffb..2900602699f 100644 --- a/src/pkg/go/printer/testdata/statements.golden +++ b/src/pkg/go/printer/testdata/statements.golden @@ -12,10 +12,16 @@ func use(x interface{}) {} func _() { if true { } + if true { + } // no semicolon printed if expr { } if expr { + } // no semicolon printed + if expr { } // no parens printed + if expr { + } // no semicolon and parens printed if x := expr; true { use(x) } @@ -29,10 +35,16 @@ func _() { func _() { switch { } + switch { + } // no semicolon printed switch expr { } switch expr { + } // no semicolon printed + switch expr { } // no parens printed + switch expr { + } // no semicolon and parens printed switch x := expr; { default: use( diff --git a/src/pkg/go/printer/testdata/statements.input b/src/pkg/go/printer/testdata/statements.input index c8df052a3a2..21e61efc4f8 100644 --- a/src/pkg/go/printer/testdata/statements.input +++ b/src/pkg/go/printer/testdata/statements.input @@ -11,9 +11,12 @@ func use(x interface{}) {} // Formatting of if-statement headers. func _() { if true {} + if; true {} // no semicolon printed if expr{} + if;expr{} // no semicolon printed if (expr){} // no parens printed - if x:=expr; true { + if;((expr)){} // no semicolon and parens printed + if x:=expr;true{ use(x)} if x:=expr; expr {use(x)} } @@ -22,8 +25,11 @@ func _() { // Formatting of switch-statement headers. func _() { switch {} + switch;{} // no semicolon printed switch expr {} + switch;expr{} // no semicolon printed switch (expr) {} // no parens printed + switch;((expr)){} // no semicolon and parens printed switch x := expr; { default:use( x) } @@ -112,7 +118,7 @@ func _() { if (((x))) {} if ([]T{}) {} if (([]T{})) {} - if (((([]T{})))) {} + if ; (((([]T{})))) {} for (x) {} for (((x))) {} @@ -123,21 +129,21 @@ func _() { switch (x) {} switch (((x))) {} switch ([]T{}) {} - switch (((([]T{})))) {} + switch ; (((([]T{})))) {} for _ = range ((([]T{T{42}}))) {} // leave parentheses - composite literals start with a type name if (T{}) {} if ((T{})) {} - if ((((T{})))) {} + if ; ((((T{})))) {} for (T{}) {} for ((T{})) {} for ; ((((T{})))) ; {} switch (T{}) {} - switch ((((T{})))) {} + switch ; ((((T{})))) {} for _ = range (((T1{T{42}}))) {}