aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/go/parser/parser_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/go/parser/parser_test.go')
-rw-r--r--libgo/go/go/parser/parser_test.go106
1 files changed, 95 insertions, 11 deletions
diff --git a/libgo/go/go/parser/parser_test.go b/libgo/go/go/parser/parser_test.go
index 85065fd..c7bb36d 100644
--- a/libgo/go/go/parser/parser_test.go
+++ b/libgo/go/go/parser/parser_test.go
@@ -14,8 +14,6 @@ import (
"testing"
)
-var fset = token.NewFileSet()
-
var validFiles = []string{
"parser.go",
"parser_test.go",
@@ -25,7 +23,7 @@ var validFiles = []string{
func TestParse(t *testing.T) {
for _, filename := range validFiles {
- _, err := ParseFile(fset, filename, nil, DeclarationErrors)
+ _, err := ParseFile(token.NewFileSet(), filename, nil, DeclarationErrors)
if err != nil {
t.Fatalf("ParseFile(%s): %v", filename, err)
}
@@ -46,7 +44,7 @@ func dirFilter(f os.FileInfo) bool { return nameFilter(f.Name()) }
func TestParseDir(t *testing.T) {
path := "."
- pkgs, err := ParseDir(fset, path, dirFilter, 0)
+ pkgs, err := ParseDir(token.NewFileSet(), path, dirFilter, 0)
if err != nil {
t.Fatalf("ParseDir(%s): %v", path, err)
}
@@ -131,7 +129,7 @@ func TestParseExpr(t *testing.T) {
}
func TestColonEqualsScope(t *testing.T) {
- f, err := ParseFile(fset, "", `package p; func f() { x, y, z := x, y, z }`, 0)
+ f, err := ParseFile(token.NewFileSet(), "", `package p; func f() { x, y, z := x, y, z }`, 0)
if err != nil {
t.Fatal(err)
}
@@ -153,7 +151,7 @@ func TestColonEqualsScope(t *testing.T) {
}
func TestVarScope(t *testing.T) {
- f, err := ParseFile(fset, "", `package p; func f() { var x, y, z = x, y, z }`, 0)
+ f, err := ParseFile(token.NewFileSet(), "", `package p; func f() { var x, y, z = x, y, z }`, 0)
if err != nil {
t.Fatal(err)
}
@@ -183,7 +181,7 @@ var x int
func f() { L: }
`
- f, err := ParseFile(fset, "", src, 0)
+ f, err := ParseFile(token.NewFileSet(), "", src, 0)
if err != nil {
t.Fatal(err)
}
@@ -221,7 +219,7 @@ func f() { L: }
}
func TestUnresolved(t *testing.T) {
- f, err := ParseFile(fset, "", `
+ f, err := ParseFile(token.NewFileSet(), "", `
package p
//
func f1a(int)
@@ -316,7 +314,7 @@ var imports = map[string]bool{
func TestImports(t *testing.T) {
for path, isValid := range imports {
src := fmt.Sprintf("package p; import %s", path)
- _, err := ParseFile(fset, "", src, 0)
+ _, err := ParseFile(token.NewFileSet(), "", src, 0)
switch {
case err != nil && isValid:
t.Errorf("ParseFile(%s): got %v; expected no error", src, err)
@@ -327,7 +325,7 @@ func TestImports(t *testing.T) {
}
func TestCommentGroups(t *testing.T) {
- f, err := ParseFile(fset, "", `
+ f, err := ParseFile(token.NewFileSet(), "", `
package p /* 1a */ /* 1b */ /* 1c */ // 1d
/* 2a
*/
@@ -421,7 +419,7 @@ func checkFieldComments(t *testing.T, file *ast.File, fieldname, lead, line stri
}
func TestLeadAndLineComments(t *testing.T) {
- f, err := ParseFile(fset, "", `
+ f, err := ParseFile(token.NewFileSet(), "", `
package p
type T struct {
/* F1 lead comment */
@@ -447,3 +445,89 @@ 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
+ })
+ }
+}
+
+// TestIncompleteSelection ensures that an incomplete selector
+// expression is parsed as a (blank) *ast.SelectorExpr, not a
+// *ast.BadExpr.
+func TestIncompleteSelection(t *testing.T) {
+ for _, src := range []string{
+ "package p; var _ = fmt.", // at EOF
+ "package p; var _ = fmt.\ntype X int", // not at EOF
+ } {
+ fset := token.NewFileSet()
+ f, err := ParseFile(fset, "", src, 0)
+ if err == nil {
+ t.Errorf("ParseFile(%s) succeeded unexpectedly", src)
+ continue
+ }
+
+ const wantErr = "expected selector or type assertion"
+ if !strings.Contains(err.Error(), wantErr) {
+ t.Errorf("ParseFile returned wrong error %q, want %q", err, wantErr)
+ }
+
+ var sel *ast.SelectorExpr
+ ast.Inspect(f, func(n ast.Node) bool {
+ if n, ok := n.(*ast.SelectorExpr); ok {
+ sel = n
+ }
+ return true
+ })
+ if sel == nil {
+ t.Error("found no *ast.SelectorExpr")
+ continue
+ }
+ const wantSel = "&{fmt _}"
+ if fmt.Sprint(sel) != wantSel {
+ t.Errorf("found selector %s, want %s", sel, wantSel)
+ continue
+ }
+ }
+}