mirror of
https://github.com/golang/go
synced 2024-10-02 10:18:33 -06:00
go/parser: always introduce an ast.Object when declaring an identifier
When traversing parameter lists (e.g. for type checking), we want the invariant that all identifers have associated objects (even _ idents), so that we can associate a type with each object. R=rsc CC=golang-dev https://golang.org/cl/4490042
This commit is contained in:
parent
45ea58746b
commit
447db23c4a
@ -134,11 +134,12 @@ func (p *parser) closeLabelScope() {
|
|||||||
func (p *parser) declare(decl interface{}, scope *ast.Scope, kind ast.ObjKind, idents ...*ast.Ident) {
|
func (p *parser) declare(decl interface{}, scope *ast.Scope, kind ast.ObjKind, idents ...*ast.Ident) {
|
||||||
for _, ident := range idents {
|
for _, ident := range idents {
|
||||||
assert(ident.Obj == nil, "identifier already declared or resolved")
|
assert(ident.Obj == nil, "identifier already declared or resolved")
|
||||||
|
obj := ast.NewObj(kind, ident.Name)
|
||||||
|
// remember the corresponding declaration for redeclaration
|
||||||
|
// errors and global variable resolution/typechecking phase
|
||||||
|
obj.Decl = decl
|
||||||
|
ident.Obj = obj
|
||||||
if ident.Name != "_" {
|
if ident.Name != "_" {
|
||||||
obj := ast.NewObj(kind, ident.Name)
|
|
||||||
// remember the corresponding declaration for redeclaration
|
|
||||||
// errors and global variable resolution/typechecking phase
|
|
||||||
obj.Decl = decl
|
|
||||||
if alt := scope.Insert(obj); alt != nil && p.mode&DeclarationErrors != 0 {
|
if alt := scope.Insert(obj); alt != nil && p.mode&DeclarationErrors != 0 {
|
||||||
prevDecl := ""
|
prevDecl := ""
|
||||||
if pos := alt.Pos(); pos.IsValid() {
|
if pos := alt.Pos(); pos.IsValid() {
|
||||||
@ -146,7 +147,6 @@ func (p *parser) declare(decl interface{}, scope *ast.Scope, kind ast.ObjKind, i
|
|||||||
}
|
}
|
||||||
p.error(ident.Pos(), fmt.Sprintf("%s redeclared in this block%s", ident.Name, prevDecl))
|
p.error(ident.Pos(), fmt.Sprintf("%s redeclared in this block%s", ident.Name, prevDecl))
|
||||||
}
|
}
|
||||||
ident.Obj = obj
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,17 +159,17 @@ func (p *parser) shortVarDecl(idents []*ast.Ident) {
|
|||||||
n := 0 // number of new variables
|
n := 0 // number of new variables
|
||||||
for _, ident := range idents {
|
for _, ident := range idents {
|
||||||
assert(ident.Obj == nil, "identifier already declared or resolved")
|
assert(ident.Obj == nil, "identifier already declared or resolved")
|
||||||
|
obj := ast.NewObj(ast.Var, ident.Name)
|
||||||
|
// short var declarations cannot have redeclaration errors
|
||||||
|
// and are not global => no need to remember the respective
|
||||||
|
// declaration
|
||||||
|
ident.Obj = obj
|
||||||
if ident.Name != "_" {
|
if ident.Name != "_" {
|
||||||
obj := ast.NewObj(ast.Var, ident.Name)
|
if alt := p.topScope.Insert(obj); alt != nil {
|
||||||
// short var declarations cannot have redeclaration errors
|
ident.Obj = alt // redeclaration
|
||||||
// and are not global => no need to remember the respective
|
} else {
|
||||||
// declaration
|
|
||||||
alt := p.topScope.Insert(obj)
|
|
||||||
if alt == nil {
|
|
||||||
n++ // new declaration
|
n++ // new declaration
|
||||||
alt = obj
|
|
||||||
}
|
}
|
||||||
ident.Obj = alt
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if n == 0 && p.mode&DeclarationErrors != 0 {
|
if n == 0 && p.mode&DeclarationErrors != 0 {
|
||||||
|
Loading…
Reference in New Issue
Block a user