]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/syntax: more tolerant parsing of import declarations
authorRobert Griesemer <gri@golang.org>
Wed, 31 Aug 2022 19:14:58 +0000 (12:14 -0700)
committerGopher Robot <gobot@golang.org>
Fri, 2 Sep 2022 02:09:04 +0000 (02:09 +0000)
Change-Id: I114548640d51bf69833259578609901fa1602510
Reviewed-on: https://go-review.googlesource.com/c/go/+/427156
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>

src/cmd/compile/internal/syntax/parser.go
src/cmd/compile/internal/types2/testdata/fixedbugs/issue43190.go

index e2298852b8bd2e5d8dbc8e440f00c0fc9b8297c9..b956028404d121ffbdd646cc2715b6263589fb25 100644 (file)
@@ -401,15 +401,20 @@ func (p *parser) fileOrNil() *File {
                return nil
        }
 
-       // { ImportDecl ";" }
-       for p.got(_Import) {
-               f.DeclList = p.appendGroup(f.DeclList, p.importDecl)
-               p.want(_Semi)
-       }
-
-       // { TopLevelDecl ";" }
+       // Accept import declarations anywhere for error tolerance, but complain.
+       // { ( ImportDecl | TopLevelDecl ) ";" }
+       prev := _Import
        for p.tok != _EOF {
+               if p.tok == _Import && prev != _Import {
+                       p.syntaxError("imports must appear before other declarations")
+               }
+               prev = p.tok
+
                switch p.tok {
+               case _Import:
+                       p.next()
+                       f.DeclList = p.appendGroup(f.DeclList, p.importDecl)
+
                case _Const:
                        p.next()
                        f.DeclList = p.appendGroup(f.DeclList, p.constDecl)
@@ -435,7 +440,7 @@ func (p *parser) fileOrNil() *File {
                        } else {
                                p.syntaxError("non-declaration statement outside function body")
                        }
-                       p.advance(_Const, _Type, _Var, _Func)
+                       p.advance(_Import, _Const, _Type, _Var, _Func)
                        continue
                }
 
@@ -445,7 +450,7 @@ func (p *parser) fileOrNil() *File {
 
                if p.tok != _EOF && !p.got(_Semi) {
                        p.syntaxError("after top level declaration")
-                       p.advance(_Const, _Type, _Var, _Func)
+                       p.advance(_Import, _Const, _Type, _Var, _Func)
                }
        }
        // p.tok == _EOF
@@ -543,7 +548,7 @@ func (p *parser) importDecl(group *Group) Decl {
                return d
        }
        if !d.Path.Bad && d.Path.Kind != StringLit {
-               p.syntaxError("import path must be a string")
+               p.syntaxErrorAt(d.Path.Pos(), "import path must be a string")
                d.Path.Bad = true
        }
        // d.Path.Bad || d.Path.Kind == StringLit
index ae42719ad75c5eb0e7f01aaacdbd9c581a3802f3..37b781ce9c4e55cc0284d97fc3533a8fcdf56807 100644 (file)
@@ -7,8 +7,12 @@ package p
 import ; // ERROR missing import path
 import
 var /* ERROR missing import path */ _ int
-import .; // ERROR missing import path
+import .; //  ERROR missing import path
+import 'x' // ERROR import path must be a string
+var _ int
+import /* ERROR imports must appear before other declarations */ _ "math"
 
+// Don't repeat previous error for each immediately following import ...
 import ()
 import (.) // ERROR missing import path
 import (
@@ -16,4 +20,8 @@ import (
        .
 ) // ERROR missing import path
 
-var _ = fmt.Println // avoid imported but not used error
+// ... but remind with error again if we start a new import section after
+// other declarations
+var _ = fmt.Println
+import /* ERROR imports must appear before other declarations */ _ "math"
+import _ "math"