diff options
Diffstat (limited to 'src/pkg/go')
| -rw-r--r-- | src/pkg/go/ast/ast.go | 2 | ||||
| -rw-r--r-- | src/pkg/go/ast/walk.go | 4 | ||||
| -rw-r--r-- | src/pkg/go/parser/interface.go | 4 | ||||
| -rw-r--r-- | src/pkg/go/parser/parser.go | 93 | ||||
| -rw-r--r-- | src/pkg/go/parser/parser_test.go | 35 | ||||
| -rw-r--r-- | src/pkg/go/printer/printer.go | 4 | ||||
| -rw-r--r-- | src/pkg/go/printer/printer_test.go | 6 | ||||
| -rw-r--r-- | src/pkg/go/printer/testdata/statements.golden | 10 | ||||
| -rw-r--r-- | src/pkg/go/printer/testdata/statements.input | 10 | ||||
| -rw-r--r-- | src/pkg/go/scanner/scanner.go | 11 | 
10 files changed, 106 insertions, 73 deletions
| diff --git a/src/pkg/go/ast/ast.go b/src/pkg/go/ast/ast.go index 2e8f0973f..abafb5663 100644 --- a/src/pkg/go/ast/ast.go +++ b/src/pkg/go/ast/ast.go @@ -597,7 +597,7 @@ type (  	IfStmt struct {  		If   token.Pos // position of "if" keyword  		Init Stmt      // initalization statement; or nil -		Cond Expr      // condition; or nil +		Cond Expr      // condition  		Body *BlockStmt  		Else Stmt // else branch; or nil  	} diff --git a/src/pkg/go/ast/walk.go b/src/pkg/go/ast/walk.go index a77f8ee5e..20c337c3b 100644 --- a/src/pkg/go/ast/walk.go +++ b/src/pkg/go/ast/walk.go @@ -227,9 +227,7 @@ func Walk(v Visitor, node Node) {  		if n.Init != nil {  			Walk(v, n.Init)  		} -		if n.Cond != nil { -			Walk(v, n.Cond) -		} +		Walk(v, n.Cond)  		Walk(v, n.Body)  		if n.Else != nil {  			Walk(v, n.Else) diff --git a/src/pkg/go/parser/interface.go b/src/pkg/go/parser/interface.go index 84d699a67..6f35b495e 100644 --- a/src/pkg/go/parser/interface.go +++ b/src/pkg/go/parser/interface.go @@ -14,7 +14,7 @@ import (  	"io"  	"io/ioutil"  	"os" -	pathutil "path" +	"path/filepath"  ) @@ -198,7 +198,7 @@ func ParseDir(fset *token.FileSet, path string, filter func(*os.FileInfo) bool,  	for i := 0; i < len(list); i++ {  		d := &list[i]  		if filter == nil || filter(d) { -			filenames[n] = pathutil.Join(path, d.Name) +			filenames[n] = filepath.Join(path, d.Name)  			n++  		}  	} diff --git a/src/pkg/go/parser/parser.go b/src/pkg/go/parser/parser.go index 2395b8158..7c5843f36 100644 --- a/src/pkg/go/parser/parser.go +++ b/src/pkg/go/parser/parser.go @@ -1327,44 +1327,34 @@ func (p *parser) makeExpr(s ast.Stmt) ast.Expr {  } -func (p *parser) parseControlClause(isForStmt bool) (s1, s2, s3 ast.Stmt) { -	if p.tok != token.LBRACE { +func (p *parser) parseIfStmt() *ast.IfStmt { +	if p.trace { +		defer un(trace(p, "IfStmt")) +	} + +	pos := p.expect(token.IF) + +	var s ast.Stmt +	var x ast.Expr +	{  		prevLev := p.exprLev  		p.exprLev = -1 - -		if p.tok != token.SEMICOLON { -			s1 = p.parseSimpleStmt(false) -		}  		if p.tok == token.SEMICOLON {  			p.next() -			if p.tok != token.LBRACE && p.tok != token.SEMICOLON { -				s2 = p.parseSimpleStmt(false) -			} -			if isForStmt { -				// for statements have a 3rd section -				p.expectSemi() -				if p.tok != token.LBRACE { -					s3 = p.parseSimpleStmt(false) -				} -			} +			x = p.parseExpr()  		} else { -			s1, s2 = nil, s1 +			s = p.parseSimpleStmt(false) +			if p.tok == token.SEMICOLON { +				p.next() +				x = p.parseExpr() +			} else { +				x = p.makeExpr(s) +				s = nil +			}  		} -  		p.exprLev = prevLev  	} -	return s1, s2, s3 -} - - -func (p *parser) parseIfStmt() *ast.IfStmt { -	if p.trace { -		defer un(trace(p, "IfStmt")) -	} - -	pos := p.expect(token.IF) -	s1, s2, _ := p.parseControlClause(false)  	body := p.parseBlockStmt()  	var else_ ast.Stmt  	if p.tok == token.ELSE { @@ -1374,7 +1364,7 @@ func (p *parser) parseIfStmt() *ast.IfStmt {  		p.expectSemi()  	} -	return &ast.IfStmt{pos, s1, p.makeExpr(s2), body, else_} +	return &ast.IfStmt{pos, s, x, body, else_}  } @@ -1457,7 +1447,24 @@ func (p *parser) parseSwitchStmt() ast.Stmt {  	}  	pos := p.expect(token.SWITCH) -	s1, s2, _ := p.parseControlClause(false) + +	var s1, s2 ast.Stmt +	if p.tok != token.LBRACE { +		prevLev := p.exprLev +		p.exprLev = -1 +		if p.tok != token.SEMICOLON { +			s2 = p.parseSimpleStmt(false) +		} +		if p.tok == token.SEMICOLON { +			p.next() +			s1 = s2 +			s2 = nil +			if p.tok != token.LBRACE { +				s2 = p.parseSimpleStmt(false) +			} +		} +		p.exprLev = prevLev +	}  	if isExprSwitch(s2) {  		lbrace := p.expect(token.LBRACE) @@ -1575,7 +1582,29 @@ func (p *parser) parseForStmt() ast.Stmt {  	}  	pos := p.expect(token.FOR) -	s1, s2, s3 := p.parseControlClause(true) + +	var s1, s2, s3 ast.Stmt +	if p.tok != token.LBRACE { +		prevLev := p.exprLev +		p.exprLev = -1 +		if p.tok != token.SEMICOLON { +			s2 = p.parseSimpleStmt(false) +		} +		if p.tok == token.SEMICOLON { +			p.next() +			s1 = s2 +			s2 = nil +			if p.tok != token.SEMICOLON { +				s2 = p.parseSimpleStmt(false) +			} +			p.expectSemi() +			if p.tok != token.LBRACE { +				s3 = p.parseSimpleStmt(false) +			} +		} +		p.exprLev = prevLev +	} +  	body := p.parseBlockStmt()  	p.expectSemi() diff --git a/src/pkg/go/parser/parser_test.go b/src/pkg/go/parser/parser_test.go index 5a7f05ca8..38535627a 100644 --- a/src/pkg/go/parser/parser_test.go +++ b/src/pkg/go/parser/parser_test.go @@ -18,6 +18,9 @@ var illegalInputs = []interface{}{  	3.14,  	[]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 */ {} };`,  } @@ -32,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/printer.go b/src/pkg/go/printer/printer.go index 48e2af1b7..90d9784ac 100644 --- a/src/pkg/go/printer/printer.go +++ b/src/pkg/go/printer/printer.go @@ -12,7 +12,7 @@ import (  	"go/token"  	"io"  	"os" -	"path" +	"path/filepath"  	"runtime"  	"tabwriter"  ) @@ -244,7 +244,7 @@ func (p *printer) writeItem(pos token.Position, data []byte) {  	}  	if debug {  		// do not update p.pos - use write0 -		_, filename := path.Split(pos.Filename) +		_, filename := filepath.Split(pos.Filename)  		p.write0([]byte(fmt.Sprintf("[%s:%d:%d]", filename, pos.Line, pos.Column)))  	}  	p.write(data) diff --git a/src/pkg/go/printer/printer_test.go b/src/pkg/go/printer/printer_test.go index 565075aa2..62b726913 100644 --- a/src/pkg/go/printer/printer_test.go +++ b/src/pkg/go/printer/printer_test.go @@ -11,7 +11,7 @@ import (  	"go/ast"  	"go/parser"  	"go/token" -	"path" +	"path/filepath"  	"testing"  ) @@ -129,8 +129,8 @@ var data = []entry{  func TestFiles(t *testing.T) {  	for _, e := range data { -		source := path.Join(dataDir, e.source) -		golden := path.Join(dataDir, e.golden) +		source := filepath.Join(dataDir, e.source) +		golden := filepath.Join(dataDir, e.golden)  		check(t, source, golden, e.mode)  		// TODO(gri) check that golden is idempotent  		//check(t, golden, golden, e.mode); diff --git a/src/pkg/go/printer/testdata/statements.golden b/src/pkg/go/printer/testdata/statements.golden index 5eceb7dd5..290060269 100644 --- a/src/pkg/go/printer/testdata/statements.golden +++ b/src/pkg/go/printer/testdata/statements.golden @@ -10,9 +10,9 @@ func use(x interface{})	{}  // Formatting of if-statement headers.  func _() { -	if { +	if true {  	} -	if { +	if true {  	}	// no semicolon printed  	if expr {  	} @@ -22,7 +22,7 @@ func _() {  	}	// no parens printed  	if expr {  	}	// no semicolon and parens printed -	if x := expr; { +	if x := expr; true {  		use(x)  	}  	if x := expr; expr { @@ -354,14 +354,14 @@ func _() {  func _() { -	if { +	if true {  		_ = 0  	}  	_ = 0	// the indentation here should not be affected by the long label name  AnOverlongLabel:  	_ = 0 -	if { +	if true {  		_ = 0  	}  	_ = 0 diff --git a/src/pkg/go/printer/testdata/statements.input b/src/pkg/go/printer/testdata/statements.input index 7819820ed..21e61efc4 100644 --- a/src/pkg/go/printer/testdata/statements.input +++ b/src/pkg/go/printer/testdata/statements.input @@ -10,13 +10,13 @@ func use(x interface{}) {}  // Formatting of if-statement headers.  func _() { -	if {} -	if;{}  // no semicolon printed +	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;{ +	if x:=expr;true{  	use(x)}  	if x:=expr; expr {use(x)}  } @@ -271,14 +271,14 @@ func _() {  func _() { -	if { +	if true {  		_ = 0  	}  	_ = 0  // the indentation here should not be affected by the long label name  AnOverlongLabel:  	_ = 0 -	if { +	if true {  		_ = 0  	}  	_ = 0 diff --git a/src/pkg/go/scanner/scanner.go b/src/pkg/go/scanner/scanner.go index 8c3205230..153707f59 100644 --- a/src/pkg/go/scanner/scanner.go +++ b/src/pkg/go/scanner/scanner.go @@ -8,7 +8,8 @@  //  //	var s Scanner  //	fset := token.NewFileSet()  // position information is relative to fset -//	s.Init(fset, filename, src, nil /* no error handler */, 0) +//      file := fset.AddFile(filename, fset.Base(), len(src))  // register file +//	s.Init(file, src, nil /* no error handler */, 0)  //	for {  //		pos, tok, lit := s.Scan()  //		if tok == token.EOF { @@ -22,7 +23,7 @@ package scanner  import (  	"bytes"  	"go/token" -	"path" +	"path/filepath"  	"strconv"  	"unicode"  	"utf8" @@ -117,7 +118,7 @@ func (S *Scanner) Init(file *token.File, src []byte, err ErrorHandler, mode uint  		panic("file size does not match src len")  	}  	S.file = file -	S.dir, _ = path.Split(file.Name()) +	S.dir, _ = filepath.Split(file.Name())  	S.src = src  	S.err = err  	S.mode = mode @@ -179,10 +180,10 @@ func (S *Scanner) interpretLineComment(text []byte) {  		if i := bytes.Index(text, []byte{':'}); i > 0 {  			if line, err := strconv.Atoi(string(text[i+1:])); err == nil && line > 0 {  				// valid //line filename:line comment; -				filename := path.Clean(string(text[len(prefix):i])) +				filename := filepath.Clean(string(text[len(prefix):i]))  				if filename[0] != '/' {  					// make filename relative to current directory -					filename = path.Join(S.dir, filename) +					filename = filepath.Join(S.dir, filename)  				}  				// update scanner position  				S.file.AddLineInfo(S.lineOffset, filename, line-1) // -1 since comment applies to next line | 
