diff options
author | Robert Griesemer <gri@golang.org> | 2015-02-23 23:51:05 -0800 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2015-02-24 21:34:05 +0000 |
commit | 5ce9fde8b64a07a7cbfbe43c9451e2d1d536c972 (patch) | |
tree | 235647f24d466e347f4f5b0b88cdd6589d74c447 /src/go/parser/parser_test.go | |
parent | c651fdc0cf2ba7986ce0a0a23b4dbb44b6ecdae3 (diff) | |
download | go-5ce9fde8b64a07a7cbfbe43c9451e2d1d536c972.tar.gz go-5ce9fde8b64a07a7cbfbe43c9451e2d1d536c972.zip |
go/ast, go/parser: correct End() position for *ast.EmptyStmt
- added a new field ast.EmptyStmt.Implicit to indicate explicit
or implicit semicolon
- fix ast.EmptyStmt.End() accordingly
- adjusted parser and added test case
Fixes #9979.
Change-Id: I72b0983b3a0cabea085598e1bf6c8df629776b57
Reviewed-on: https://go-review.googlesource.com/5720
Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/go/parser/parser_test.go')
-rw-r--r-- | src/go/parser/parser_test.go | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/go/parser/parser_test.go b/src/go/parser/parser_test.go index 51ce1a9337..4b960d9e57 100644 --- a/src/go/parser/parser_test.go +++ b/src/go/parser/parser_test.go @@ -445,3 +445,50 @@ type T struct { t.Error("not expected to find T.f3") } } + +// TestIssue9979 verifies that empty statements are contained within their enclosing blocks. +func TestIssue9979(t *testing.T) { + for _, src := range []string{ + "package p; func f() {;}", + "package p; func f() {L:}", + "package p; func f() {L:;}", + "package p; func f() {L:\n}", + "package p; func f() {L:\n;}", + "package p; func f() { ; }", + "package p; func f() { L: }", + "package p; func f() { L: ; }", + "package p; func f() { L: \n}", + "package p; func f() { L: \n; }", + } { + fset := token.NewFileSet() + f, err := ParseFile(fset, "", src, 0) + if err != nil { + t.Fatal(err) + } + + var pos, end token.Pos + ast.Inspect(f, func(x ast.Node) bool { + switch s := x.(type) { + case *ast.BlockStmt: + pos, end = s.Pos()+1, s.End()-1 // exclude "{", "}" + case *ast.LabeledStmt: + pos, end = s.Pos()+2, s.End() // exclude "L:" + case *ast.EmptyStmt: + // check containment + if s.Pos() < pos || s.End() > end { + t.Errorf("%s: %T[%d, %d] not inside [%d, %d]", src, s, s.Pos(), s.End(), pos, end) + } + // check semicolon + offs := fset.Position(s.Pos()).Offset + if ch := src[offs]; ch != ';' != s.Implicit { + want := "want ';'" + if s.Implicit { + want = "but ';' is implicit" + } + t.Errorf("%s: found %q at offset %d; %s", src, ch, offs, want) + } + } + return true + }) + } +} |