]> Cypherpunks repositories - gostls13.git/commitdiff
go/parser: always introduce an ast.Object when declaring an identifier
authorRobert Griesemer <gri@golang.org>
Mon, 9 May 2011 21:48:05 +0000 (14:48 -0700)
committerRobert Griesemer <gri@golang.org>
Mon, 9 May 2011 21:48:05 +0000 (14:48 -0700)
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

src/pkg/go/parser/parser.go

index afa9ae517b6f0ce2bf1f51e60a7d6c460227639c..6329cc918eb905f38650278c10694c598e8a9204 100644 (file)
@@ -134,11 +134,12 @@ func (p *parser) closeLabelScope() {
 func (p *parser) declare(decl interface{}, scope *ast.Scope, kind ast.ObjKind, idents ...*ast.Ident) {
        for _, ident := range idents {
                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 != "_" {
-                       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 {
                                prevDecl := ""
                                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))
                        }
-                       ident.Obj = obj
                }
        }
 }
@@ -159,17 +159,17 @@ func (p *parser) shortVarDecl(idents []*ast.Ident) {
        n := 0 // number of new variables
        for _, ident := range idents {
                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 != "_" {
-                       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
-                       alt := p.topScope.Insert(obj)
-                       if alt == nil {
+                       if alt := p.topScope.Insert(obj); alt != nil {
+                               ident.Obj = alt // redeclaration
+                       } else {
                                n++ // new declaration
-                               alt = obj
                        }
-                       ident.Obj = alt
                }
        }
        if n == 0 && p.mode&DeclarationErrors != 0 {