Commit 2cd96806 authored by Michael Matloob's avatar Michael Matloob Committed by Robert Griesemer

go/parser: stop ParseFile after ten errors.

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
parent 208c8309
...@@ -145,6 +145,7 @@ func checkErrors(t *testing.T, filename string, input interface{}) { ...@@ -145,6 +145,7 @@ func checkErrors(t *testing.T, filename string, input interface{}) {
t.Error(err) t.Error(err)
return return
} }
found.RemoveMultiples()
// we are expecting the following errors // we are expecting the following errors
// (collect these after parsing a file so that it is found in the file set) // (collect these after parsing a file so that it is found in the file set)
......
...@@ -52,12 +52,13 @@ func readSource(filename string, src interface{}) ([]byte, error) { ...@@ -52,12 +52,13 @@ func readSource(filename string, src interface{}) ([]byte, error) {
type Mode uint type Mode uint
const ( const (
PackageClauseOnly Mode = 1 << iota // parsing stops after package clause PackageClauseOnly Mode = 1 << iota // parsing stops after package clause
ImportsOnly // parsing stops after import declarations ImportsOnly // parsing stops after import declarations
ParseComments // parse comments and add them to AST ParseComments // parse comments and add them to AST
Trace // print a trace of parsed productions Trace // print a trace of parsed productions
DeclarationErrors // report declaration errors DeclarationErrors // report declaration errors
SpuriousErrors // report all (not just the first) errors per line 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 // ParseFile parses the source code of a single Go source file and returns
...@@ -79,35 +80,39 @@ const ( ...@@ -79,35 +80,39 @@ const (
// representing the fragments of erroneous source code). Multiple errors // 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 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 // get source
text, err := readSource(filename, src) text, err := readSource(filename, src)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// parse source
var p parser var p parser
p.init(fset, filename, text, mode) defer func() {
f := p.parseFile() if e := recover(); e != nil {
if f == nil { _ = e.(bailout) // re-panics if it's not a bailout
// source is not a valid Go source file - satisfy }
// ParseFile API and return a valid (but) empty
// *ast.File // set result values
f = &ast.File{ if f == nil {
Name: new(ast.Ident), // source is not a valid Go source file - satisfy
Scope: ast.NewScope(nil), // 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() 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 // ParseDir calls ParseFile for the files in the directory specified by path and
......
...@@ -340,7 +340,13 @@ func (p *parser) next() { ...@@ -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) { 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) p.errors.Add(p.file.Position(pos), msg)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment