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{}) {
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)
......
......@@ -57,7 +57,8 @@ const (
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
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,17 +80,20 @@ 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()
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
......@@ -100,14 +104,15 @@ func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode)
}
}
// 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
......
......@@ -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)
}
......
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