go/parser: add a SkipObjectResolution mode to bypass object resolution

Parser object resolution is an auxiliary feature in which the parser
attempts to resolve identifiers to their declarations. In functionality,
it significantly overlaps with go/types and in fact cannot be correctly
computed at parse-time without type information (for example, it is
generally not possible to resolve k in the composite lit c{k: v}). Due
to these limitations, it is of limited utility and rarely used.

Now that object resolution is isolated as a post-processing pass, it is
trivial to offer a parser mode that skips it entirely. This CL adds that
mode.

Fixes #45104

Change-Id: I5a2c05437e298964ad2039e1ff98e63d6efbd1af
Reviewed-on: https://go-review.googlesource.com/c/go/+/306149
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Rob Findley 2021-03-29 16:03:51 -04:00 committed by Robert Findley
parent b91f8a4c0b
commit 02a2ff47ef
2 changed files with 17 additions and 10 deletions

View file

@ -49,13 +49,14 @@ func readSource(filename string, src interface{}) ([]byte, error) {
type Mode uint type Mode uint
const ( const (
PackageClauseOnly Mode = 1 << iota // stop parsing after package clause PackageClauseOnly Mode = 1 << iota // stop parsing after package clause
ImportsOnly // stop parsing after import declarations ImportsOnly // stop parsing 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 // same as AllErrors, for backward-compatibility SpuriousErrors // same as AllErrors, for backward-compatibility
AllErrors = SpuriousErrors // report all errors (not just the first 10 on different lines) SkipObjectResolution // don't resolve identifiers to objects - see ParseFile
AllErrors = SpuriousErrors // report all errors (not just the first 10 on different lines)
) )
// 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
@ -68,8 +69,12 @@ const (
// If src == nil, ParseFile parses the file specified by filename. // If src == nil, ParseFile parses the file specified by filename.
// //
// The mode parameter controls the amount of source text parsed and other // The mode parameter controls the amount of source text parsed and other
// optional parser functionality. Position information is recorded in the // optional parser functionality. If the SkipObjectResolution mode bit is set,
// file set fset, which must not be nil. // the object resolution phase of parsing will be skipped, causing File.Scope,
// File.Unresolved, and all Ident.Obj fields to be nil.
//
// Position information is recorded in the file set fset, which must not be
// nil.
// //
// If the source couldn't be read, the returned AST is nil and the error // 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 // indicates the specific failure. If the source was read but syntax

View file

@ -2636,7 +2636,9 @@ func (p *parser) parseFile() *ast.File {
if p.mode&DeclarationErrors != 0 { if p.mode&DeclarationErrors != 0 {
declErr = p.error declErr = p.error
} }
resolveFile(f, p.file, declErr) if p.mode&SkipObjectResolution == 0 {
resolveFile(f, p.file, declErr)
}
return f return f
} }