From 02a2ff47ef6004a59e4d688c7c93198778c36bcf Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Mon, 29 Mar 2021 16:03:51 -0400 Subject: [PATCH] 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 Run-TryBot: Robert Findley TryBot-Result: Go Bot Reviewed-by: Robert Griesemer --- src/go/parser/interface.go | 23 ++++++++++++++--------- src/go/parser/parser.go | 4 +++- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/go/parser/interface.go b/src/go/parser/interface.go index dcc5fa6616..85486d2f4b 100644 --- a/src/go/parser/interface.go +++ b/src/go/parser/interface.go @@ -49,13 +49,14 @@ func readSource(filename string, src interface{}) ([]byte, error) { type Mode uint const ( - PackageClauseOnly Mode = 1 << iota // stop parsing after package clause - ImportsOnly // stop parsing 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 errors (not just the first 10 on different lines) + PackageClauseOnly Mode = 1 << iota // stop parsing after package clause + ImportsOnly // stop parsing 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 + 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 @@ -68,8 +69,12 @@ const ( // If src == nil, ParseFile parses the file specified by filename. // // The mode parameter controls the amount of source text parsed and other -// optional parser functionality. Position information is recorded in the -// file set fset, which must not be nil. +// optional parser functionality. If the SkipObjectResolution mode bit is set, +// 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 // indicates the specific failure. If the source was read but syntax diff --git a/src/go/parser/parser.go b/src/go/parser/parser.go index aff5838780..cddaef350e 100644 --- a/src/go/parser/parser.go +++ b/src/go/parser/parser.go @@ -2636,7 +2636,9 @@ func (p *parser) parseFile() *ast.File { if p.mode&DeclarationErrors != 0 { declErr = p.error } - resolveFile(f, p.file, declErr) + if p.mode&SkipObjectResolution == 0 { + resolveFile(f, p.file, declErr) + } return f }