]> Cypherpunks repositories - gostls13.git/commitdiff
go/parser: parse incomplete selection "fmt." as a blank selection "fmt._"
authorAlan Donovan <adonovan@google.com>
Wed, 20 May 2015 19:49:23 +0000 (15:49 -0400)
committerAlan Donovan <adonovan@google.com>
Wed, 20 May 2015 20:57:49 +0000 (20:57 +0000)
Formerly it would return a BadExpr.

This prevents partial syntax from being discarded, and makes the error
recovery logic more consistent with other places where an identifier
was expected but not found.

+ test

Change-Id: I223c0c0589e7ceb7207ae951b8f71b9275a1eb73
Reviewed-on: https://go-review.googlesource.com/10269
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/parser/interface.go
src/go/parser/parser.go
src/go/parser/parser_test.go

index 49103058b59785e04872f279cebe5a8dd946fd00..f3bc4b9cc811fd31aba7d6ca9ee0463c14e76341 100644 (file)
@@ -91,7 +91,10 @@ func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode)
        var p parser
        defer func() {
                if e := recover(); e != nil {
-                       _ = e.(bailout) // re-panics if it's not a bailout
+                       // resume same panic if it's not a bailout
+                       if _, ok := e.(bailout); !ok {
+                               panic(e)
+                       }
                }
 
                // set result values
index fb6ca76a77515604b9594217dbe8a1cb1dc3bbf6..18278ba4b7ba0ed6a13a779d51f8580bc85d111e 100644 (file)
@@ -1472,7 +1472,8 @@ L:
                                pos := p.pos
                                p.errorExpected(pos, "selector or type assertion")
                                p.next() // make progress
-                               x = &ast.BadExpr{From: pos, To: p.pos}
+                               sel := &ast.Ident{NamePos: pos, Name: "_"}
+                               x = &ast.SelectorExpr{X: x, Sel: sel}
                        }
                case token.LBRACK:
                        if lhs {
index 4b960d9e577faf84b200d6a35bd1e0cbc694f370..c7bb36d789d551543d02cf42a81edeaa5110cbd1 100644 (file)
@@ -492,3 +492,42 @@ func TestIssue9979(t *testing.T) {
                })
        }
 }
+
+// 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
+               }
+       }
+}