]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: refactor import statement parsing
authorMatthew Dempsky <mdempsky@google.com>
Tue, 1 Dec 2015 20:15:25 +0000 (12:15 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Fri, 19 Feb 2016 22:54:15 +0000 (22:54 +0000)
Combine parser's import_stmt and import_here methods as a single new
importdcl method, and cleanup conditional logic slightly to make the
code easier to follow.

Also, eliminate importfile's unused line parameter, and get rid of all
of its duplicate type assertions.

Change-Id: Ic37ae8490afedc533f98ead9feef383e3599bc01
Reviewed-on: https://go-review.googlesource.com/19629
Reviewed-by: Robert Griesemer <gri@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/lex.go
src/cmd/compile/internal/gc/parser.go

index 8053aaffe9dc620d8ff3b9c5e2f0fed4214ff396..ebc6a5171ba4e535bcc8ccbbab1df8168c0351c7 100644 (file)
@@ -492,8 +492,6 @@ var debugstr string
 var Debug_checknil int
 var Debug_typeassert int
 
-var importmyname *Sym // my name for package
-
 var localpkg *Pkg // package being compiled
 
 var importpkg *Pkg // package being imported
index 8161cad568dd5e2cee10ae39f2c6369088726aa1..83f25a5e2ab8296d076ab24f25139de1615c2609 100644 (file)
@@ -687,21 +687,21 @@ func fakeimport() {
        cannedimports("fake.o", "$$\n")
 }
 
-// TODO(gri) line argument doesn't appear to be used
-func importfile(f *Val, line int) {
-       if _, ok := f.U.(string); !ok {
+func importfile(f *Val) {
+       path_, ok := f.U.(string)
+       if !ok {
                Yyerror("import statement not a string")
                fakeimport()
                return
        }
 
-       if len(f.U.(string)) == 0 {
+       if len(path_) == 0 {
                Yyerror("import path is empty")
                fakeimport()
                return
        }
 
-       if isbadimport(f.U.(string)) {
+       if isbadimport(path_) {
                fakeimport()
                return
        }
@@ -710,18 +710,16 @@ func importfile(f *Val, line int) {
        // but we reserve the import path "main" to identify
        // the main package, just as we reserve the import
        // path "math" to identify the standard math package.
-       if f.U.(string) == "main" {
+       if path_ == "main" {
                Yyerror("cannot import \"main\"")
                errorexit()
        }
 
-       if myimportpath != "" && f.U.(string) == myimportpath {
-               Yyerror("import %q while compiling that package (import cycle)", f.U.(string))
+       if myimportpath != "" && path_ == myimportpath {
+               Yyerror("import %q while compiling that package (import cycle)", path_)
                errorexit()
        }
 
-       path_ := f.U.(string)
-
        if mapped, ok := importMap[path_]; ok {
                path_ = mapped
        }
@@ -763,7 +761,7 @@ func importfile(f *Val, line int) {
 
        file, found := findpkg(path_)
        if !found {
-               Yyerror("can't find import: %q", f.U.(string))
+               Yyerror("can't find import: %q", path_)
                errorexit()
        }
 
@@ -788,7 +786,7 @@ func importfile(f *Val, line int) {
        var imp *obj.Biobuf
        imp, err = obj.Bopenr(file)
        if err != nil {
-               Yyerror("can't open import: %q: %v", f.U.(string), err)
+               Yyerror("can't open import: %q: %v", path_, err)
                errorexit()
        }
 
@@ -878,7 +876,7 @@ func importfile(f *Val, line int) {
                incannedimport = 0
 
        default:
-               Yyerror("no import in %q", f.U.(string))
+               Yyerror("no import in %q", path_)
        }
 }
 
index 7e521d1f7d95b95f3ce02d354d20cb67bfe2b8d3..60813839186111e9b2b5ebd3160c66182b089d99 100644 (file)
@@ -323,108 +323,92 @@ func (p *parser) import_() {
        p.want(LIMPORT)
        if p.got('(') {
                for p.tok != EOF && p.tok != ')' {
-                       p.import_stmt()
+                       p.importdcl()
                        if !p.osemi(')') {
                                break
                        }
                }
                p.want(')')
        } else {
-               p.import_stmt()
-       }
-}
-
-func (p *parser) import_stmt() {
-       if trace && Debug['x'] != 0 {
-               defer p.trace("import_stmt")()
-       }
-
-       line := int32(p.import_here())
-       if p.tok == LPACKAGE {
-               p.import_package()
-               p.import_there()
-
-               ipkg := importpkg
-               my := importmyname
-               importpkg = nil
-               importmyname = nil
-
-               if my == nil {
-                       my = Lookup(ipkg.Name)
-               }
-
-               pack := Nod(OPACK, nil, nil)
-               pack.Sym = my
-               pack.Name.Pkg = ipkg
-               pack.Lineno = line
-
-               if strings.HasPrefix(my.Name, ".") {
-                       importdot(ipkg, pack)
-                       return
-               }
-               if my.Name == "init" {
-                       lineno = line
-                       Yyerror("cannot import package as init - init must be a func")
-                       return
-               }
-               if my.Name == "_" {
-                       return
-               }
-               if my.Def != nil {
-                       lineno = line
-                       redeclare(my, "as imported package name")
-               }
-               my.Def = pack
-               my.Lastlineno = line
-               my.Block = 1 // at top level
-
-               return
-       }
-
-       p.import_there()
-       // When an invalid import path is passed to importfile,
-       // it calls Yyerror and then sets up a fake import with
-       // no package statement. This allows us to test more
-       // than one invalid import statement in a single file.
-       if nerrors == 0 {
-               Fatalf("phase error in import")
+               p.importdcl()
        }
 }
 
 // ImportSpec = [ "." | PackageName ] ImportPath .
 // ImportPath = string_lit .
-//
-// import_here switches the underlying lexed source to the export data
-// of the imported package.
-func (p *parser) import_here() int {
+func (p *parser) importdcl() {
        if trace && Debug['x'] != 0 {
-               defer p.trace("import_here")()
+               defer p.trace("importdcl")()
        }
 
-       importmyname = nil
+       var my *Sym
        switch p.tok {
        case LNAME, '@', '?':
                // import with given name
-               importmyname = p.sym()
+               my = p.sym()
 
        case '.':
                // import into my name space
-               importmyname = Lookup(".")
+               my = Lookup(".")
                p.next()
        }
 
-       var path Val
-       if p.tok == LLITERAL {
-               path = p.val
-               p.next()
-       } else {
+       if p.tok != LLITERAL {
                p.syntax_error("missing import path; require quoted string")
                p.advance(';', ')')
+               return
+       }
+
+       line := int32(parserline())
+       path := p.val
+       p.next()
+
+       importfile(&path)
+       if p.tok != LPACKAGE {
+               // When an invalid import path is passed to importfile,
+               // it calls Yyerror and then sets up a fake import with
+               // no package statement. This allows us to test more
+               // than one invalid import statement in a single file.
+               p.import_there()
+               if nerrors == 0 {
+                       Fatalf("phase error in import")
+               }
+               return
        }
+       p.import_package()
+       p.import_there()
+
+       ipkg := importpkg
+       importpkg = nil
+
+       if my == nil {
+               my = Lookup(ipkg.Name)
+       }
+
+       pack := Nod(OPACK, nil, nil)
+       pack.Sym = my
+       pack.Name.Pkg = ipkg
+       pack.Lineno = line
 
-       line := parserline()
-       importfile(&path, line)
-       return line
+       if strings.HasPrefix(my.Name, ".") {
+               importdot(ipkg, pack)
+               return
+       }
+       if my.Name == "init" {
+               lineno = line
+               Yyerror("cannot import package as init - init must be a func")
+               return
+       }
+       if my.Name == "_" {
+               return
+       }
+       if my.Def != nil {
+               lineno = line
+               redeclare(my, "as imported package name")
+       }
+       my.Def = pack
+       my.Lastlineno = line
+       my.Block = 1 // at top level
 }
 
 // import_package parses the header of an imported package as exported