mirror of https://github.com/golang/go.git
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
This commit is contained in:
parent
208c83096a
commit
2cd96806f4
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue