mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: refactor import statement parsing
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>
This commit is contained in:
parent
d930d69fd9
commit
113c4d2581
3 changed files with 70 additions and 90 deletions
|
|
@ -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 := parserline()
|
||||
importfile(&path, line)
|
||||
return line
|
||||
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
|
||||
|
||||
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue