// declInScope declares an object of a given kind and name in scope and sets the object's Decl and N fields. // It returns the newly allocated object. If an object with the same name already exists in scope, an error // is reported and the object is not inserted. // (Objects with _ name are always inserted into a scope without errors, but they cannot be found.) func (tc *typechecker) declInScope(scope *ast.Scope, kind ast.Kind, name *ast.Ident, decl interface{}, n int) *ast.Object { obj := ast.NewObj(kind, name.Name) obj.Decl = decl obj.N = n name.Obj = obj if alt := scope.Insert(obj); alt != obj { tc.Errorf(name.Pos(), "%s already declared at %s", name.Name, objPos(alt)) } return obj }
// find returns the object with the given name if visible in the current scope hierarchy. // If no such object is found, an error is reported and a bad object is returned instead. func (tc *typechecker) find(name *ast.Ident) (obj *ast.Object) { for s := tc.topScope; s != nil && obj == nil; s = s.Outer { obj = s.Lookup(name.Name) } if obj == nil { tc.Errorf(name.Pos(), "%s not declared", name.Name) obj = ast.NewObj(ast.Bad, name.Name) } name.Obj = obj return }
func (p *parser) declIdent(scope *ast.Scope, id *ast.Ident) { decl := scope.Declare(id.Obj) if p.checkDecl && decl != id.Obj { if decl.Kind == ast.Err { // declared object is a forward declaration - update it *decl = *id.Obj id.Obj = decl return } p.Error(id.Pos(), "'"+id.Name()+"' declared already at "+decl.Pos.String()) } }
// declInScope declares an object of a given kind and name in scope and sets the object's Decl and N fields. // It returns the newly allocated object. If an object with the same name already exists in scope, an error // is reported and the object is not inserted. func (tc *typechecker) declInScope(scope *ast.Scope, kind ast.ObjKind, name *ast.Ident, decl interface{}, n int) *ast.Object { obj := ast.NewObj(kind, name.Name) obj.Decl = decl //obj.N = n name.Obj = obj if name.Name != "_" { if alt := scope.Insert(obj); alt != nil { tc.Errorf(name.Pos(), "%s already declared at %s", name.Name, tc.fset.Position(alt.Pos()).String()) } } return obj }
// declare declares an object of the given kind and name (ident) in scope; // decl is the corresponding declaration in the AST. An error is reported // if the object was declared before. // // TODO(gri) This is very similar to the declare function in go/parser; it // is only used to associate methods with their respective receiver base types. // In a future version, it might be simpler and cleaner to do all the resolution // in the type-checking phase. It would simplify the parser, AST, and also // reduce some amount of code duplication. // func (check *checker) declare(scope *ast.Scope, kind ast.ObjKind, ident *ast.Ident, decl ast.Decl) { assert(ident.Obj == nil) // identifier already declared or resolved obj := ast.NewObj(kind, ident.Name) obj.Decl = decl ident.Obj = obj if ident.Name != "_" { if alt := scope.Insert(obj); alt != nil { prevDecl := "" if pos := alt.Pos(); pos.IsValid() { prevDecl = fmt.Sprintf("\n\tprevious declaration at %s", check.fset.Position(pos)) } check.errorf(ident.Pos(), fmt.Sprintf("%s redeclared in this block%s", ident.Name, prevDecl)) } } }
func SetIdentObject(ident *ast.Ident) *ast.Object { ident.Obj = &ast.Object{Name: ident.Name} return ident.Obj }