]> Cypherpunks repositories - gostls13.git/commitdiff
go/parser: stop ParseFile after ten errors.
authorMichael Matloob <matloob@google.com>
Thu, 14 Feb 2013 19:26:21 +0000 (11:26 -0800)
committerRobert Griesemer <gri@golang.org>
Thu, 14 Feb 2013 19:26:21 +0000 (11:26 -0800)
There wil be a panic if more than ten errors are encountered. ParseFile
will recover and return the ErrorList.

Fixes #3943.

R=golang-dev, gri
CC=golang-dev
https://golang.org/cl/7307085

src/pkg/go/parser/error_test.go
src/pkg/go/parser/interface.go
src/pkg/go/parser/parser.go

index 8d06d1c843ad747c44629e26d4dc26151d16b19a..b5d9a39cf3b9224df24ef8e1b97477bc79830c3c 100644 (file)
@@ -145,6 +145,7 @@ func checkErrors(t *testing.T, filename string, input interface{}) {
                t.Error(err)
                return
        }
+       found.RemoveMultiples()
 
        // we are expecting the following errors
        // (collect these after parsing a file so that it is found in the file set)
index fac513e557c0a9074198eb9f3324cb128816be7b..a732e75fd1847e088f5237b8a2f23ffe385e54f4 100644 (file)
@@ -52,12 +52,13 @@ func readSource(filename string, src interface{}) ([]byte, error) {
 type Mode uint
 
 const (
-       PackageClauseOnly Mode = 1 << iota // parsing stops after package clause
-       ImportsOnly                        // parsing stops after import declarations
-       ParseComments                      // parse comments and add them to AST
-       Trace                              // print a trace of parsed productions
-       DeclarationErrors                  // report declaration errors
-       SpuriousErrors                     // report all (not just the first) errors per line
+       PackageClauseOnly Mode             = 1 << iota // parsing stops after package clause
+       ImportsOnly                                    // parsing stops after import declarations
+       ParseComments                                  // parse comments and add them to AST
+       Trace                                          // print a trace of parsed productions
+       DeclarationErrors                              // report declaration errors
+       SpuriousErrors                                 // same as AllErrors, for backward-compatibility
+       AllErrors         = SpuriousErrors             // report all (not just the first 10) errors per file
 )
 
 // ParseFile parses the source code of a single Go source file and returns
@@ -79,35 +80,39 @@ const (
 // representing the fragments of erroneous source code). Multiple errors
 // are returned via a scanner.ErrorList which is sorted by file position.
 //
-func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) (*ast.File, error) {
+func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) (f *ast.File, err error) {
        // get source
        text, err := readSource(filename, src)
        if err != nil {
                return nil, err
        }
 
-       // parse source
        var p parser
-       p.init(fset, filename, text, mode)
-       f := p.parseFile()
-       if f == nil {
-               // source is not a valid Go source file - satisfy
-               // ParseFile API and return a valid (but) empty
-               // *ast.File
-               f = &ast.File{
-                       Name:  new(ast.Ident),
-                       Scope: ast.NewScope(nil),
+       defer func() {
+               if e := recover(); e != nil {
+                       _ = e.(bailout) // re-panics if it's not a bailout
+               }
+
+               // set result values
+               if f == nil {
+                       // source is not a valid Go source file - satisfy
+                       // ParseFile API and return a valid (but) empty
+                       // *ast.File
+                       f = &ast.File{
+                               Name:  new(ast.Ident),
+                               Scope: ast.NewScope(nil),
+                       }
                }
-       }
 
-       // sort errors
-       if p.mode&SpuriousErrors == 0 {
-               p.errors.RemoveMultiples()
-       } else {
                p.errors.Sort()
-       }
+               err = p.errors.Err()
+       }()
 
-       return f, p.errors.Err()
+       // parse source
+       p.init(fset, filename, text, mode)
+       f = p.parseFile()
+
+       return
 }
 
 // ParseDir calls ParseFile for the files in the directory specified by path and
index 959af387200912d801a0e41f3bc07993b83d7716..e816ca326272d54bb4eab749103a671e07ee1fc3 100644 (file)
@@ -340,7 +340,13 @@ func (p *parser) next() {
        }
 }
 
+// A bailout panic is raised to indicate early termination.
+type bailout struct{}
+
 func (p *parser) error(pos token.Pos, msg string) {
+       if p.mode&SpuriousErrors == 0 && p.errors.Len() >= 10 {
+               panic(bailout{})
+       }
        p.errors.Add(p.file.Position(pos), msg)
 }