github.com/panjjo/go@v0.0.0-20161104043856-d62b31386338/src/go/types/decl.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package types 6 7 import ( 8 "go/ast" 9 "go/constant" 10 "go/token" 11 ) 12 13 func (check *Checker) reportAltDecl(obj Object) { 14 if pos := obj.Pos(); pos.IsValid() { 15 // We use "other" rather than "previous" here because 16 // the first declaration seen may not be textually 17 // earlier in the source. 18 check.errorf(pos, "\tother declaration of %s", obj.Name()) // secondary error, \t indented 19 } 20 } 21 22 func (check *Checker) declare(scope *Scope, id *ast.Ident, obj Object, pos token.Pos) { 23 // spec: "The blank identifier, represented by the underscore 24 // character _, may be used in a declaration like any other 25 // identifier but the declaration does not introduce a new 26 // binding." 27 if obj.Name() != "_" { 28 if alt := scope.Insert(obj); alt != nil { 29 check.errorf(obj.Pos(), "%s redeclared in this block", obj.Name()) 30 check.reportAltDecl(alt) 31 return 32 } 33 obj.setScopePos(pos) 34 } 35 if id != nil { 36 check.recordDef(id, obj) 37 } 38 } 39 40 // objDecl type-checks the declaration of obj in its respective (file) context. 41 // See check.typ for the details on def and path. 42 func (check *Checker) objDecl(obj Object, def *Named, path []*TypeName) { 43 if obj.Type() != nil { 44 return // already checked - nothing to do 45 } 46 47 if trace { 48 check.trace(obj.Pos(), "-- declaring %s", obj.Name()) 49 check.indent++ 50 defer func() { 51 check.indent-- 52 check.trace(obj.Pos(), "=> %s", obj) 53 }() 54 } 55 56 d := check.objMap[obj] 57 if d == nil { 58 check.dump("%s: %s should have been declared", obj.Pos(), obj.Name()) 59 unreachable() 60 } 61 62 // save/restore current context and setup object context 63 defer func(ctxt context) { 64 check.context = ctxt 65 }(check.context) 66 check.context = context{ 67 scope: d.file, 68 } 69 70 // Const and var declarations must not have initialization 71 // cycles. We track them by remembering the current declaration 72 // in check.decl. Initialization expressions depending on other 73 // consts, vars, or functions, add dependencies to the current 74 // check.decl. 75 switch obj := obj.(type) { 76 case *Const: 77 check.decl = d // new package-level const decl 78 check.constDecl(obj, d.typ, d.init) 79 case *Var: 80 check.decl = d // new package-level var decl 81 check.varDecl(obj, d.lhs, d.typ, d.init) 82 case *TypeName: 83 // invalid recursive types are detected via path 84 check.typeDecl(obj, d.typ, def, path) 85 case *Func: 86 // functions may be recursive - no need to track dependencies 87 check.funcDecl(obj, d) 88 case *Alias: 89 // aliases cannot be recursive - no need to track dependencies 90 check.aliasDecl(obj, d) 91 default: 92 unreachable() 93 } 94 } 95 96 func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) { 97 assert(obj.typ == nil) 98 99 if obj.visited { 100 obj.typ = Typ[Invalid] 101 return 102 } 103 obj.visited = true 104 105 // use the correct value of iota 106 assert(check.iota == nil) 107 check.iota = obj.val 108 defer func() { check.iota = nil }() 109 110 // provide valid constant value under all circumstances 111 obj.val = constant.MakeUnknown() 112 113 // determine type, if any 114 if typ != nil { 115 t := check.typ(typ) 116 if !isConstType(t) { 117 check.errorf(typ.Pos(), "invalid constant type %s", t) 118 obj.typ = Typ[Invalid] 119 return 120 } 121 obj.typ = t 122 } 123 124 // check initialization 125 var x operand 126 if init != nil { 127 check.expr(&x, init) 128 } 129 check.initConst(obj, &x) 130 } 131 132 func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) { 133 assert(obj.typ == nil) 134 135 if obj.visited { 136 obj.typ = Typ[Invalid] 137 return 138 } 139 obj.visited = true 140 141 // var declarations cannot use iota 142 assert(check.iota == nil) 143 144 // determine type, if any 145 if typ != nil { 146 obj.typ = check.typ(typ) 147 // We cannot spread the type to all lhs variables if there 148 // are more than one since that would mark them as checked 149 // (see Checker.objDecl) and the assignment of init exprs, 150 // if any, would not be checked. 151 // 152 // TODO(gri) If we have no init expr, we should distribute 153 // a given type otherwise we need to re-evalate the type 154 // expr for each lhs variable, leading to duplicate work. 155 } 156 157 // check initialization 158 if init == nil { 159 if typ == nil { 160 // error reported before by arityMatch 161 obj.typ = Typ[Invalid] 162 } 163 return 164 } 165 166 if lhs == nil || len(lhs) == 1 { 167 assert(lhs == nil || lhs[0] == obj) 168 var x operand 169 check.expr(&x, init) 170 check.initVar(obj, &x, "variable declaration") 171 return 172 } 173 174 if debug { 175 // obj must be one of lhs 176 found := false 177 for _, lhs := range lhs { 178 if obj == lhs { 179 found = true 180 break 181 } 182 } 183 if !found { 184 panic("inconsistent lhs") 185 } 186 } 187 188 // We have multiple variables on the lhs and one init expr. 189 // Make sure all variables have been given the same type if 190 // one was specified, otherwise they assume the type of the 191 // init expression values (was issue #15755). 192 if typ != nil { 193 for _, lhs := range lhs { 194 lhs.typ = obj.typ 195 } 196 } 197 198 check.initVars(lhs, []ast.Expr{init}, token.NoPos) 199 } 200 201 // underlying returns the underlying type of typ; possibly by following 202 // forward chains of named types. Such chains only exist while named types 203 // are incomplete. 204 func underlying(typ Type) Type { 205 for { 206 n, _ := typ.(*Named) 207 if n == nil { 208 break 209 } 210 typ = n.underlying 211 } 212 return typ 213 } 214 215 func (n *Named) setUnderlying(typ Type) { 216 if n != nil { 217 n.underlying = typ 218 } 219 } 220 221 func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, path []*TypeName) { 222 assert(obj.typ == nil) 223 224 // type declarations cannot use iota 225 assert(check.iota == nil) 226 227 named := &Named{obj: obj} 228 def.setUnderlying(named) 229 obj.typ = named // make sure recursive type declarations terminate 230 231 // determine underlying type of named 232 check.typExpr(typ, named, append(path, obj)) 233 234 // The underlying type of named may be itself a named type that is 235 // incomplete: 236 // 237 // type ( 238 // A B 239 // B *C 240 // C A 241 // ) 242 // 243 // The type of C is the (named) type of A which is incomplete, 244 // and which has as its underlying type the named type B. 245 // Determine the (final, unnamed) underlying type by resolving 246 // any forward chain (they always end in an unnamed type). 247 named.underlying = underlying(named.underlying) 248 249 // check and add associated methods 250 // TODO(gri) It's easy to create pathological cases where the 251 // current approach is incorrect: In general we need to know 252 // and add all methods _before_ type-checking the type. 253 // See https://play.golang.org/p/WMpE0q2wK8 254 check.addMethodDecls(obj) 255 } 256 257 func (check *Checker) addMethodDecls(obj *TypeName) { 258 // get associated methods 259 methods := check.methods[obj.name] 260 if len(methods) == 0 { 261 return // no methods 262 } 263 delete(check.methods, obj.name) 264 265 // use an objset to check for name conflicts 266 var mset objset 267 268 // spec: "If the base type is a struct type, the non-blank method 269 // and field names must be distinct." 270 base := obj.typ.(*Named) 271 if t, _ := base.underlying.(*Struct); t != nil { 272 for _, fld := range t.fields { 273 if fld.name != "_" { 274 assert(mset.insert(fld) == nil) 275 } 276 } 277 } 278 279 // Checker.Files may be called multiple times; additional package files 280 // may add methods to already type-checked types. Add pre-existing methods 281 // so that we can detect redeclarations. 282 for _, m := range base.methods { 283 assert(m.name != "_") 284 assert(mset.insert(m) == nil) 285 } 286 287 // type-check methods 288 for _, m := range methods { 289 // spec: "For a base type, the non-blank names of methods bound 290 // to it must be unique." 291 if m.name != "_" { 292 if alt := mset.insert(m); alt != nil { 293 switch alt.(type) { 294 case *Var: 295 check.errorf(m.pos, "field and method with the same name %s", m.name) 296 case *Func: 297 check.errorf(m.pos, "method %s already declared for %s", m.name, base) 298 default: 299 unreachable() 300 } 301 check.reportAltDecl(alt) 302 continue 303 } 304 } 305 check.objDecl(m, nil, nil) 306 // methods with blank _ names cannot be found - don't keep them 307 if m.name != "_" { 308 base.methods = append(base.methods, m) 309 } 310 } 311 } 312 313 func (check *Checker) funcDecl(obj *Func, decl *declInfo) { 314 assert(obj.typ == nil) 315 316 // func declarations cannot use iota 317 assert(check.iota == nil) 318 319 sig := new(Signature) 320 obj.typ = sig // guard against cycles 321 fdecl := decl.fdecl 322 check.funcType(sig, fdecl.Recv, fdecl.Type) 323 if sig.recv == nil && obj.name == "init" && (sig.params.Len() > 0 || sig.results.Len() > 0) { 324 check.errorf(fdecl.Pos(), "func init must have no arguments and no return values") 325 // ok to continue 326 } 327 328 // function body must be type-checked after global declarations 329 // (functions implemented elsewhere have no body) 330 if !check.conf.IgnoreFuncBodies && fdecl.Body != nil { 331 check.later(obj.name, decl, sig, fdecl.Body) 332 } 333 } 334 335 // original returns the original Object if obj is an Alias; 336 // otherwise it returns obj. The result is never an Alias, 337 // but it may be nil. 338 func original(obj Object) Object { 339 // an alias stands for the original object; use that one instead 340 if alias, _ := obj.(*Alias); alias != nil { 341 obj = alias.orig 342 // aliases always refer to non-alias originals 343 if _, ok := obj.(*Alias); ok { 344 panic("original is an alias") 345 } 346 } 347 return obj 348 } 349 350 func (check *Checker) aliasDecl(obj *Alias, decl *declInfo) { 351 assert(obj.typ == nil) 352 353 // alias declarations cannot use iota 354 assert(check.iota == nil) 355 356 // assume alias is invalid to start with 357 obj.typ = Typ[Invalid] 358 359 // rhs must be package-qualified identifer pkg.sel (see also call.go: checker.selector) 360 // TODO(gri) factor this code out and share with checker.selector 361 rhs := decl.init 362 var pkg *Package 363 var sel *ast.Ident 364 if sexpr, ok := rhs.(*ast.SelectorExpr); ok { 365 if ident, ok := sexpr.X.(*ast.Ident); ok { 366 _, obj := check.scope.LookupParent(ident.Name, check.pos) 367 if pname, _ := obj.(*PkgName); pname != nil { 368 assert(pname.pkg == check.pkg) 369 check.recordUse(ident, pname) 370 pname.used = true 371 pkg = pname.imported 372 sel = sexpr.Sel 373 } 374 } 375 } 376 if pkg == nil { 377 check.errorf(rhs.Pos(), "invalid alias: %v is not a package-qualified identifier", rhs) 378 return 379 } 380 381 // qualified identifier must denote an exported object 382 orig := pkg.scope.Lookup(sel.Name) 383 if orig == nil || !orig.Exported() { 384 if !pkg.fake { 385 check.errorf(rhs.Pos(), "%s is not exported by package %s", sel.Name, pkg.name) 386 } 387 return 388 } 389 check.recordUse(sel, orig) 390 orig = original(orig) 391 392 // avoid further errors if the imported object is an alias that's broken 393 if orig == nil { 394 return 395 } 396 397 // An alias declaration must not refer to package unsafe. 398 if orig.Pkg() == Unsafe { 399 check.errorf(rhs.Pos(), "invalid alias: %s refers to package unsafe (%v)", obj.Name(), orig) 400 return 401 } 402 403 // The original must be of the same kind as the alias declaration. 404 var why string 405 switch obj.kind { 406 case token.CONST: 407 if _, ok := orig.(*Const); !ok { 408 why = "constant" 409 } 410 case token.TYPE: 411 if _, ok := orig.(*TypeName); !ok { 412 why = "type" 413 } 414 case token.VAR: 415 if _, ok := orig.(*Var); !ok { 416 why = "variable" 417 } 418 case token.FUNC: 419 if _, ok := orig.(*Func); !ok { 420 why = "function" 421 } 422 default: 423 unreachable() 424 } 425 if why != "" { 426 check.errorf(rhs.Pos(), "invalid alias: %v is not a %s", orig, why) 427 return 428 } 429 430 // alias is valid 431 obj.typ = orig.Type() 432 obj.orig = orig 433 } 434 435 func (check *Checker) declStmt(decl ast.Decl) { 436 pkg := check.pkg 437 438 switch d := decl.(type) { 439 case *ast.BadDecl: 440 // ignore 441 442 case *ast.GenDecl: 443 var last *ast.ValueSpec // last ValueSpec with type or init exprs seen 444 for iota, spec := range d.Specs { 445 switch s := spec.(type) { 446 case *ast.ValueSpec: 447 switch d.Tok { 448 case token.CONST: 449 // determine which init exprs to use 450 switch { 451 case s.Type != nil || len(s.Values) > 0: 452 last = s 453 case last == nil: 454 last = new(ast.ValueSpec) // make sure last exists 455 } 456 457 // declare all constants 458 lhs := make([]*Const, len(s.Names)) 459 for i, name := range s.Names { 460 obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota))) 461 lhs[i] = obj 462 463 var init ast.Expr 464 if i < len(last.Values) { 465 init = last.Values[i] 466 } 467 468 check.constDecl(obj, last.Type, init) 469 } 470 471 check.arityMatch(s, last) 472 473 // spec: "The scope of a constant or variable identifier declared 474 // inside a function begins at the end of the ConstSpec or VarSpec 475 // (ShortVarDecl for short variable declarations) and ends at the 476 // end of the innermost containing block." 477 scopePos := s.End() 478 for i, name := range s.Names { 479 check.declare(check.scope, name, lhs[i], scopePos) 480 } 481 482 case token.VAR: 483 lhs0 := make([]*Var, len(s.Names)) 484 for i, name := range s.Names { 485 lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil) 486 } 487 488 // initialize all variables 489 for i, obj := range lhs0 { 490 var lhs []*Var 491 var init ast.Expr 492 switch len(s.Values) { 493 case len(s.Names): 494 // lhs and rhs match 495 init = s.Values[i] 496 case 1: 497 // rhs is expected to be a multi-valued expression 498 lhs = lhs0 499 init = s.Values[0] 500 default: 501 if i < len(s.Values) { 502 init = s.Values[i] 503 } 504 } 505 check.varDecl(obj, lhs, s.Type, init) 506 if len(s.Values) == 1 { 507 // If we have a single lhs variable we are done either way. 508 // If we have a single rhs expression, it must be a multi- 509 // valued expression, in which case handling the first lhs 510 // variable will cause all lhs variables to have a type 511 // assigned, and we are done as well. 512 if debug { 513 for _, obj := range lhs0 { 514 assert(obj.typ != nil) 515 } 516 } 517 break 518 } 519 } 520 521 check.arityMatch(s, nil) 522 523 // declare all variables 524 // (only at this point are the variable scopes (parents) set) 525 scopePos := s.End() // see constant declarations 526 for i, name := range s.Names { 527 // see constant declarations 528 check.declare(check.scope, name, lhs0[i], scopePos) 529 } 530 531 default: 532 check.invalidAST(s.Pos(), "invalid token %s", d.Tok) 533 } 534 535 case *ast.TypeSpec: 536 obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil) 537 // spec: "The scope of a type identifier declared inside a function 538 // begins at the identifier in the TypeSpec and ends at the end of 539 // the innermost containing block." 540 scopePos := s.Name.Pos() 541 check.declare(check.scope, s.Name, obj, scopePos) 542 check.typeDecl(obj, s.Type, nil, nil) 543 544 default: 545 check.invalidAST(s.Pos(), "const, type, or var declaration expected") 546 } 547 } 548 549 default: 550 check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d) 551 } 552 }