]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/parser: parse import specs the same way as the syntax parser
authorRobert Griesemer <gri@golang.org>
Wed, 31 Aug 2022 18:26:43 +0000 (11:26 -0700)
committerGopher Robot <gobot@golang.org>
Fri, 2 Sep 2022 02:09:03 +0000 (02:09 +0000)
This results in better error recovery and allows us to use the
same tests for go/types and types2.

For #54511.

Change-Id: Ic11a9dafb8c62e0cb952b3924d55a28b438241c6
Reviewed-on: https://go-review.googlesource.com/c/go/+/427154
Run-TryBot: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@google.com>
src/go/parser/parser.go
src/go/types/resolver.go
src/go/types/testdata/fixedbugs/issue43190.go

index cc3c0480949ebc2f2a02f6db25b77dcdc76d1d2e..fcd6a4adcc9570b6852ec66d0a348e6cfb8c7775 100644 (file)
@@ -2425,11 +2425,11 @@ func (p *parser) parseImportSpec(doc *ast.CommentGroup, _ token.Pos, _ token.Tok
 
        var ident *ast.Ident
        switch p.tok {
+       case token.IDENT:
+               ident = p.parseIdent()
        case token.PERIOD:
                ident = &ast.Ident{NamePos: p.pos, Name: "."}
                p.next()
-       case token.IDENT:
-               ident = p.parseIdent()
        }
 
        pos := p.pos
@@ -2437,8 +2437,15 @@ func (p *parser) parseImportSpec(doc *ast.CommentGroup, _ token.Pos, _ token.Tok
        if p.tok == token.STRING {
                path = p.lit
                p.next()
+       } else if p.tok.IsLiteral() {
+               p.error(pos, "import path must be a string")
+               p.next()
        } else {
-               p.expect(token.STRING) // use expect() error handling
+               p.error(pos, "missing import path")
+               // don't advance if we're at a semicolon or closing parenthesis
+               if p.tok != token.SEMICOLON && p.tok != token.RPAREN {
+                       p.next()
+               }
        }
        p.expectSemi() // call before accessing p.linecomment
 
index 09fb7b45ad370724f8e1df71b18ea2e078ff237b..c4a973a5b9df711bd8690f3ff42831285d6930e2 100644 (file)
@@ -254,6 +254,9 @@ func (check *Checker) collectObjects() {
                        switch d := d.(type) {
                        case importDecl:
                                // import package
+                               if d.spec.Path.Value == "" {
+                                       return // error reported by parser
+                               }
                                path, err := validatedImportPath(d.spec.Path.Value)
                                if err != nil {
                                        check.errorf(d.spec.Path, _BadImportPath, "invalid import path (%s)", err)
index 96acb3a2e32a30a9e5482dcfb711c5f045afc85c..3a36a1eef5287d6b70ff6c4974ff770a42a2b40f 100644 (file)
@@ -2,21 +2,23 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Most of the errors below are actually produced by the parser, but we check
+// The errors below are produced by the parser, but we check
 // them here for consistency with the types2 tests.
 
 package p
 
-import ; /* ERROR invalid import path */ /* ERROR expected 'STRING' */
-import // ERROR expected ';'
-var _ int
-import /* ERROR expected declaration */ .;
+import ; // ERROR missing import path
+import ';' // ERROR import path must be a string
+// TODO(gri) The parser should accept mixing imports with other
+//           top-level declarations for better error recovery.
+// var _ int
+import . ; //  ERROR missing import path
 
 import ()
-import (.)
+import (.) // ERROR missing import path
 import (
        "fmt"
        .
-)
+) // ERROR missing import path
 
-var _ = fmt /* ERROR "undeclared name" */ .Println
+var _ = fmt.Println