]> Cypherpunks repositories - gostls13.git/commitdiff
go/parser: if and switch statements still can have empty init statements
authorRobert Griesemer <gri@golang.org>
Wed, 23 Feb 2011 04:10:09 +0000 (20:10 -0800)
committerRobert Griesemer <gri@golang.org>
Wed, 23 Feb 2011 04:10:09 +0000 (20:10 -0800)
This is a fix for the overly aggressive CL 4173075.
Ran all tests.

R=r, rsc
CC=golang-dev
https://golang.org/cl/4203041

src/pkg/go/parser/parser.go
src/pkg/go/parser/parser_test.go
src/pkg/go/printer/testdata/statements.golden
src/pkg/go/printer/testdata/statements.input

index 77bcc448273704ede7047ec1478c97c8f6469ff5..7c5843f36371a19b23b476edf985bc13f666a633 100644 (file)
@@ -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
        }
 
index 71238702038ebe77fcc83fd7566a4ce8a8f2a2d4..38535627a75ec76029993c986f53e25b04a82c00 100644 (file)
@@ -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 ; {} };`,
 }
 
 
index 98bc0319ffb22e5f119fc3db25afbef9f1b4b4e2..2900602699ffbd0450b6cb100fb8059e59708974 100644 (file)
@@ -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(
index c8df052a3a27ac507af0c862456a96c49cbede75..21e61efc4f8f308d38bde6d6eb60f8fd59212217 100644 (file)
@@ -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}}))) {}