]> Cypherpunks repositories - gostls13.git/commitdiff
go/parser: return partial result from ParseExpr in case of error
authorRobert Griesemer <gri@golang.org>
Tue, 17 Sep 2019 23:32:11 +0000 (16:32 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 18 Sep 2019 04:47:40 +0000 (04:47 +0000)
Remove redundant code and improve documentation in the process.

Fixes #34211.

Change-Id: I9a6d1467f1a2c98a163f41f9df147fc6500c6fad
Reviewed-on: https://go-review.googlesource.com/c/go/+/196077
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/go/parser/interface.go
src/go/parser/parser_test.go

index 0c3f824c98d0149887a8f17790fe47cad03bc4c5..500c98d49669ca97c590726ba2fb885a4b0e4400 100644 (file)
@@ -75,7 +75,7 @@ const (
 // indicates the specific failure. If the source was read but syntax
 // errors were found, the result is a partial AST (with ast.Bad* nodes
 // representing the fragments of erroneous source code). Multiple errors
-// are returned via a scanner.ErrorList which is sorted by file position.
+// are returned via a scanner.ErrorList which is sorted by source position.
 //
 func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) (f *ast.File, err error) {
        if fset == nil {
@@ -173,6 +173,12 @@ func ParseDir(fset *token.FileSet, path string, filter func(os.FileInfo) bool, m
 // be a valid Go (type or value) expression. Specifically, fset must not
 // be nil.
 //
+// If the source couldn't be read, the returned AST is nil and the error
+// indicates the specific failure. If the source was read but syntax
+// errors were found, the result is a partial AST (with ast.Bad* nodes
+// representing the fragments of erroneous source code). Multiple errors
+// are returned via a scanner.ErrorList which is sorted by source position.
+//
 func ParseExprFrom(fset *token.FileSet, filename string, src interface{}, mode Mode) (expr ast.Expr, err error) {
        if fset == nil {
                panic("parser.ParseExprFrom: no token.FileSet provided (fset == nil)")
@@ -204,7 +210,7 @@ func ParseExprFrom(fset *token.FileSet, filename string, src interface{}, mode M
        // in case of an erroneous x.
        p.openScope()
        p.pkgScope = p.topScope
-       e := p.parseRhsOrType()
+       expr = p.parseRhsOrType()
        p.closeScope()
        assert(p.topScope == nil, "unbalanced scopes")
 
@@ -215,18 +221,17 @@ func ParseExprFrom(fset *token.FileSet, filename string, src interface{}, mode M
        }
        p.expect(token.EOF)
 
-       if p.errors.Len() > 0 {
-               p.errors.Sort()
-               return nil, p.errors.Err()
-       }
-
-       return e, nil
+       return
 }
 
 // ParseExpr is a convenience function for obtaining the AST of an expression x.
 // The position information recorded in the AST is undefined. The filename used
 // in error messages is the empty string.
 //
+// If syntax errors were found, the result is a partial AST (with ast.Bad* nodes
+// representing the fragments of erroneous source code). Multiple errors are
+// returned via a scanner.ErrorList which is sorted by source position.
+//
 func ParseExpr(x string) (ast.Expr, error) {
        return ParseExprFrom(token.NewFileSet(), "", []byte(x), 0)
 }
index 18c05bce203a2efc97902970b2c929a8fef74505..25a374eeefccb5d840e0898cc215e14c92cbe152 100644 (file)
@@ -108,9 +108,16 @@ func TestParseExpr(t *testing.T) {
 
        // an invalid expression
        src = "a + *"
-       if _, err := ParseExpr(src); err == nil {
+       x, err = ParseExpr(src)
+       if err == nil {
                t.Errorf("ParseExpr(%q): got no error", src)
        }
+       if x == nil {
+               t.Errorf("ParseExpr(%q): got no (partial) result", src)
+       }
+       if _, ok := x.(*ast.BinaryExpr); !ok {
+               t.Errorf("ParseExpr(%q): got %T, want *ast.BinaryExpr", src, x)
+       }
 
        // a valid expression followed by extra tokens is invalid
        src = "a[i] := x"