mirror of
https://github.com/golang/go
synced 2024-11-20 10:24:40 -07:00
go/parser: if and switch statements still can have empty init statements
This is a fix for the overly aggressive CL 4173075. Ran all tests. R=r, rsc CC=golang-dev https://golang.org/cl/4203041
This commit is contained in:
parent
0e7995c02f
commit
8e4e11506b
@ -1339,13 +1339,18 @@ func (p *parser) parseIfStmt() *ast.IfStmt {
|
|||||||
{
|
{
|
||||||
prevLev := p.exprLev
|
prevLev := p.exprLev
|
||||||
p.exprLev = -1
|
p.exprLev = -1
|
||||||
s = p.parseSimpleStmt(false)
|
|
||||||
if p.tok == token.SEMICOLON {
|
if p.tok == token.SEMICOLON {
|
||||||
p.next()
|
p.next()
|
||||||
x = p.parseExpr()
|
x = p.parseExpr()
|
||||||
} else {
|
} else {
|
||||||
x = p.makeExpr(s)
|
s = p.parseSimpleStmt(false)
|
||||||
s = nil
|
if p.tok == token.SEMICOLON {
|
||||||
|
p.next()
|
||||||
|
x = p.parseExpr()
|
||||||
|
} else {
|
||||||
|
x = p.makeExpr(s)
|
||||||
|
s = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p.exprLev = prevLev
|
p.exprLev = prevLev
|
||||||
}
|
}
|
||||||
@ -1447,7 +1452,9 @@ func (p *parser) parseSwitchStmt() ast.Stmt {
|
|||||||
if p.tok != token.LBRACE {
|
if p.tok != token.LBRACE {
|
||||||
prevLev := p.exprLev
|
prevLev := p.exprLev
|
||||||
p.exprLev = -1
|
p.exprLev = -1
|
||||||
s2 = p.parseSimpleStmt(false)
|
if p.tok != token.SEMICOLON {
|
||||||
|
s2 = p.parseSimpleStmt(false)
|
||||||
|
}
|
||||||
if p.tok == token.SEMICOLON {
|
if p.tok == token.SEMICOLON {
|
||||||
p.next()
|
p.next()
|
||||||
s1 = s2
|
s1 = s2
|
||||||
@ -1580,7 +1587,6 @@ func (p *parser) parseForStmt() ast.Stmt {
|
|||||||
if p.tok != token.LBRACE {
|
if p.tok != token.LBRACE {
|
||||||
prevLev := p.exprLev
|
prevLev := p.exprLev
|
||||||
p.exprLev = -1
|
p.exprLev = -1
|
||||||
|
|
||||||
if p.tok != token.SEMICOLON {
|
if p.tok != token.SEMICOLON {
|
||||||
s2 = p.parseSimpleStmt(false)
|
s2 = p.parseSimpleStmt(false)
|
||||||
}
|
}
|
||||||
@ -1596,7 +1602,6 @@ func (p *parser) parseForStmt() ast.Stmt {
|
|||||||
s3 = p.parseSimpleStmt(false)
|
s3 = p.parseSimpleStmt(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.exprLev = prevLev
|
p.exprLev = prevLev
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@ var illegalInputs = []interface{}{
|
|||||||
[]byte(nil),
|
[]byte(nil),
|
||||||
"foo!",
|
"foo!",
|
||||||
`package p; func f() { if /* should have condition */ {} };`,
|
`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{}{
|
var validPrograms = []interface{}{
|
||||||
"package main\n",
|
"package p\n",
|
||||||
`package main;`,
|
`package p;`,
|
||||||
`package main; import "fmt"; func main() { fmt.Println("Hello, World!") };`,
|
`package p; import "fmt"; func f() { fmt.Println("Hello, World!") };`,
|
||||||
`package main; func main() { if f(T{}) {} };`,
|
`package p; func f() { if f(T{}) {} };`,
|
||||||
`package main; func main() { _ = (<-chan int)(x) };`,
|
`package p; func f() { _ = (<-chan int)(x) };`,
|
||||||
`package main; func main() { _ = (<-chan <-chan int)(x) };`,
|
`package p; func f() { _ = (<-chan <-chan int)(x) };`,
|
||||||
`package main; func f(func() func() func());`,
|
`package p; func f(func() func() func());`,
|
||||||
`package main; func f(...T);`,
|
`package p; func f(...T);`,
|
||||||
`package main; func f(float, ...int);`,
|
`package p; func f(float, ...int);`,
|
||||||
`package main; func f(x int, a ...int) { f(0, a...); f(1, a...,) };`,
|
`package p; 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 p; 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 p; 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 p; type T []int; func f() { for _ = range []int{T{42}[0]} {} };`,
|
||||||
`package main; var a = T{{1, 2}, {3, 4}}`,
|
`package p; 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; 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 ; {} };`,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
12
src/pkg/go/printer/testdata/statements.golden
vendored
12
src/pkg/go/printer/testdata/statements.golden
vendored
@ -12,10 +12,16 @@ func use(x interface{}) {}
|
|||||||
func _() {
|
func _() {
|
||||||
if true {
|
if true {
|
||||||
}
|
}
|
||||||
|
if true {
|
||||||
|
} // no semicolon printed
|
||||||
if expr {
|
if expr {
|
||||||
}
|
}
|
||||||
if expr {
|
if expr {
|
||||||
|
} // no semicolon printed
|
||||||
|
if expr {
|
||||||
} // no parens printed
|
} // no parens printed
|
||||||
|
if expr {
|
||||||
|
} // no semicolon and parens printed
|
||||||
if x := expr; true {
|
if x := expr; true {
|
||||||
use(x)
|
use(x)
|
||||||
}
|
}
|
||||||
@ -29,10 +35,16 @@ func _() {
|
|||||||
func _() {
|
func _() {
|
||||||
switch {
|
switch {
|
||||||
}
|
}
|
||||||
|
switch {
|
||||||
|
} // no semicolon printed
|
||||||
switch expr {
|
switch expr {
|
||||||
}
|
}
|
||||||
switch expr {
|
switch expr {
|
||||||
|
} // no semicolon printed
|
||||||
|
switch expr {
|
||||||
} // no parens printed
|
} // no parens printed
|
||||||
|
switch expr {
|
||||||
|
} // no semicolon and parens printed
|
||||||
switch x := expr; {
|
switch x := expr; {
|
||||||
default:
|
default:
|
||||||
use(
|
use(
|
||||||
|
16
src/pkg/go/printer/testdata/statements.input
vendored
16
src/pkg/go/printer/testdata/statements.input
vendored
@ -11,9 +11,12 @@ func use(x interface{}) {}
|
|||||||
// Formatting of if-statement headers.
|
// Formatting of if-statement headers.
|
||||||
func _() {
|
func _() {
|
||||||
if true {}
|
if true {}
|
||||||
|
if; true {} // no semicolon printed
|
||||||
if expr{}
|
if expr{}
|
||||||
|
if;expr{} // no semicolon printed
|
||||||
if (expr){} // no parens printed
|
if (expr){} // no parens printed
|
||||||
if x:=expr; true {
|
if;((expr)){} // no semicolon and parens printed
|
||||||
|
if x:=expr;true{
|
||||||
use(x)}
|
use(x)}
|
||||||
if x:=expr; expr {use(x)}
|
if x:=expr; expr {use(x)}
|
||||||
}
|
}
|
||||||
@ -22,8 +25,11 @@ func _() {
|
|||||||
// Formatting of switch-statement headers.
|
// Formatting of switch-statement headers.
|
||||||
func _() {
|
func _() {
|
||||||
switch {}
|
switch {}
|
||||||
|
switch;{} // no semicolon printed
|
||||||
switch expr {}
|
switch expr {}
|
||||||
|
switch;expr{} // no semicolon printed
|
||||||
switch (expr) {} // no parens printed
|
switch (expr) {} // no parens printed
|
||||||
|
switch;((expr)){} // no semicolon and parens printed
|
||||||
switch x := expr; { default:use(
|
switch x := expr; { default:use(
|
||||||
x)
|
x)
|
||||||
}
|
}
|
||||||
@ -112,7 +118,7 @@ func _() {
|
|||||||
if (((x))) {}
|
if (((x))) {}
|
||||||
if ([]T{}) {}
|
if ([]T{}) {}
|
||||||
if (([]T{})) {}
|
if (([]T{})) {}
|
||||||
if (((([]T{})))) {}
|
if ; (((([]T{})))) {}
|
||||||
|
|
||||||
for (x) {}
|
for (x) {}
|
||||||
for (((x))) {}
|
for (((x))) {}
|
||||||
@ -123,21 +129,21 @@ func _() {
|
|||||||
switch (x) {}
|
switch (x) {}
|
||||||
switch (((x))) {}
|
switch (((x))) {}
|
||||||
switch ([]T{}) {}
|
switch ([]T{}) {}
|
||||||
switch (((([]T{})))) {}
|
switch ; (((([]T{})))) {}
|
||||||
|
|
||||||
for _ = range ((([]T{T{42}}))) {}
|
for _ = range ((([]T{T{42}}))) {}
|
||||||
|
|
||||||
// leave parentheses - composite literals start with a type name
|
// leave parentheses - composite literals start with a type name
|
||||||
if (T{}) {}
|
if (T{}) {}
|
||||||
if ((T{})) {}
|
if ((T{})) {}
|
||||||
if ((((T{})))) {}
|
if ; ((((T{})))) {}
|
||||||
|
|
||||||
for (T{}) {}
|
for (T{}) {}
|
||||||
for ((T{})) {}
|
for ((T{})) {}
|
||||||
for ; ((((T{})))) ; {}
|
for ; ((((T{})))) ; {}
|
||||||
|
|
||||||
switch (T{}) {}
|
switch (T{}) {}
|
||||||
switch ((((T{})))) {}
|
switch ; ((((T{})))) {}
|
||||||
|
|
||||||
for _ = range (((T1{T{42}}))) {}
|
for _ = range (((T1{T{42}}))) {}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user