github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/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 // pathString returns a string of the form a->b-> ... ->g for a path [a, b, ... g]. 41 // TODO(gri) remove once we don't need the old cycle detection (explicitly passed 42 // []*TypeName path) anymore 43 func pathString(path []*TypeName) string { 44 var s string 45 for i, p := range path { 46 if i > 0 { 47 s += "->" 48 } 49 s += p.Name() 50 } 51 return s 52 } 53 54 // objPathString returns a string of the form a->b-> ... ->g for a path [a, b, ... g]. 55 // TODO(gri) s/objPathString/pathString/ once we got rid of pathString above 56 func objPathString(path []Object) string { 57 var s string 58 for i, p := range path { 59 if i > 0 { 60 s += "->" 61 } 62 s += p.Name() 63 } 64 return s 65 } 66 67 // objDecl type-checks the declaration of obj in its respective (file) context. 68 // For the meaning of def, see Checker.definedType, in typexpr.go. 69 func (check *Checker) objDecl(obj Object, def *Named) { 70 if trace { 71 check.trace(obj.Pos(), "-- checking %s %s (objPath = %s)", obj.color(), obj, objPathString(check.objPath)) 72 check.indent++ 73 defer func() { 74 check.indent-- 75 check.trace(obj.Pos(), "=> %s", obj) 76 }() 77 } 78 79 // Checking the declaration of obj means inferring its type 80 // (and possibly its value, for constants). 81 // An object's type (and thus the object) may be in one of 82 // three states which are expressed by colors: 83 // 84 // - an object whose type is not yet known is painted white (initial color) 85 // - an object whose type is in the process of being inferred is painted grey 86 // - an object whose type is fully inferred is painted black 87 // 88 // During type inference, an object's color changes from white to grey 89 // to black (pre-declared objects are painted black from the start). 90 // A black object (i.e., its type) can only depend on (refer to) other black 91 // ones. White and grey objects may depend on white and black objects. 92 // A dependency on a grey object indicates a cycle which may or may not be 93 // valid. 94 // 95 // When objects turn grey, they are pushed on the object path (a stack); 96 // they are popped again when they turn black. Thus, if a grey object (a 97 // cycle) is encountered, it is on the object path, and all the objects 98 // it depends on are the remaining objects on that path. Color encoding 99 // is such that the color value of a grey object indicates the index of 100 // that object in the object path. 101 102 // During type-checking, white objects may be assigned a type without 103 // traversing through objDecl; e.g., when initializing constants and 104 // variables. Update the colors of those objects here (rather than 105 // everywhere where we set the type) to satisfy the color invariants. 106 if obj.color() == white && obj.Type() != nil { 107 obj.setColor(black) 108 return 109 } 110 111 switch obj.color() { 112 case white: 113 assert(obj.Type() == nil) 114 // All color values other than white and black are considered grey. 115 // Because black and white are < grey, all values >= grey are grey. 116 // Use those values to encode the object's index into the object path. 117 obj.setColor(grey + color(check.push(obj))) 118 defer func() { 119 check.pop().setColor(black) 120 }() 121 122 case black: 123 assert(obj.Type() != nil) 124 return 125 126 default: 127 // Color values other than white or black are considered grey. 128 fallthrough 129 130 case grey: 131 // We have a cycle. 132 // In the existing code, this is marked by a non-nil type 133 // for the object except for constants and variables whose 134 // type may be non-nil (known), or nil if it depends on the 135 // not-yet known initialization value. 136 // In the former case, set the type to Typ[Invalid] because 137 // we have an initialization cycle. The cycle error will be 138 // reported later, when determining initialization order. 139 // TODO(gri) Report cycle here and simplify initialization 140 // order code. 141 switch obj := obj.(type) { 142 case *Const: 143 if check.typeCycle(obj) || obj.typ == nil { 144 obj.typ = Typ[Invalid] 145 } 146 147 case *Var: 148 if check.typeCycle(obj) || obj.typ == nil { 149 obj.typ = Typ[Invalid] 150 } 151 152 case *TypeName: 153 if check.typeCycle(obj) { 154 // break cycle 155 // (without this, calling underlying() 156 // below may lead to an endless loop 157 // if we have a cycle for a defined 158 // (*Named) type) 159 obj.typ = Typ[Invalid] 160 } 161 162 case *Func: 163 if check.typeCycle(obj) { 164 // Don't set obj.typ to Typ[Invalid] here 165 // because plenty of code type-asserts that 166 // functions have a *Signature type. Grey 167 // functions have their type set to an empty 168 // signature which makes it impossible to 169 // initialize a variable with the function. 170 } 171 172 default: 173 unreachable() 174 } 175 assert(obj.Type() != nil) 176 return 177 } 178 179 d := check.objMap[obj] 180 if d == nil { 181 check.dump("%v: %s should have been declared", obj.Pos(), obj) 182 unreachable() 183 } 184 185 // save/restore current context and setup object context 186 defer func(ctxt context) { 187 check.context = ctxt 188 }(check.context) 189 check.context = context{ 190 scope: d.file, 191 } 192 193 // Const and var declarations must not have initialization 194 // cycles. We track them by remembering the current declaration 195 // in check.decl. Initialization expressions depending on other 196 // consts, vars, or functions, add dependencies to the current 197 // check.decl. 198 switch obj := obj.(type) { 199 case *Const: 200 check.decl = d // new package-level const decl 201 check.constDecl(obj, d.typ, d.init) 202 case *Var: 203 check.decl = d // new package-level var decl 204 check.varDecl(obj, d.lhs, d.typ, d.init) 205 case *TypeName: 206 // invalid recursive types are detected via path 207 check.typeDecl(obj, d.typ, def, d.alias) 208 case *Func: 209 // functions may be recursive - no need to track dependencies 210 check.funcDecl(obj, d) 211 default: 212 unreachable() 213 } 214 } 215 216 // indir is a sentinel type name that is pushed onto the object path 217 // to indicate an "indirection" in the dependency from one type name 218 // to the next. For instance, for "type p *p" the object path contains 219 // p followed by indir, indicating that there's an indirection *p. 220 // Indirections are used to break type cycles. 221 var indir = NewTypeName(token.NoPos, nil, "*", nil) 222 223 // typeCycle checks if the cycle starting with obj is valid and 224 // reports an error if it is not. 225 // TODO(gri) rename s/typeCycle/cycle/ once we don't need the other 226 // cycle method anymore. 227 func (check *Checker) typeCycle(obj Object) (isCycle bool) { 228 // The object map contains the package scope objects and the non-interface methods. 229 if debug { 230 info := check.objMap[obj] 231 inObjMap := info != nil && (info.fdecl == nil || info.fdecl.Recv == nil) // exclude methods 232 isPkgObj := obj.Parent() == check.pkg.scope 233 if isPkgObj != inObjMap { 234 check.dump("%v: inconsistent object map for %s (isPkgObj = %v, inObjMap = %v)", obj.Pos(), obj, isPkgObj, inObjMap) 235 unreachable() 236 } 237 } 238 239 // Given the number of constants and variables (nval) in the cycle 240 // and the cycle length (ncycle = number of named objects in the cycle), 241 // we distinguish between cycles involving only constants and variables 242 // (nval = ncycle), cycles involving types (and functions) only 243 // (nval == 0), and mixed cycles (nval != 0 && nval != ncycle). 244 // We ignore functions at the moment (taking them into account correctly 245 // is complicated and it doesn't improve error reporting significantly). 246 // 247 // A cycle must have at least one indirection and one type definition 248 // to be permitted: If there is no indirection, the size of the type 249 // cannot be computed (it's either infinite or 0); if there is no type 250 // definition, we have a sequence of alias type names which will expand 251 // ad infinitum. 252 var nval, ncycle int 253 var hasIndir, hasTDef bool 254 assert(obj.color() >= grey) 255 start := obj.color() - grey // index of obj in objPath 256 cycle := check.objPath[start:] 257 ncycle = len(cycle) // including indirections 258 for _, obj := range cycle { 259 switch obj := obj.(type) { 260 case *Const, *Var: 261 nval++ 262 case *TypeName: 263 if obj == indir { 264 ncycle-- // don't count (indirections are not objects) 265 hasIndir = true 266 } else { 267 // Determine if the type name is an alias or not. For 268 // package-level objects, use the object map which 269 // provides syntactic information (which doesn't rely 270 // on the order in which the objects are set up). For 271 // local objects, we can rely on the order, so use 272 // the object's predicate. 273 // TODO(gri) It would be less fragile to always access 274 // the syntactic information. We should consider storing 275 // this information explicitly in the object. 276 var alias bool 277 if d := check.objMap[obj]; d != nil { 278 alias = d.alias // package-level object 279 } else { 280 alias = obj.IsAlias() // function local object 281 } 282 if !alias { 283 hasTDef = true 284 } 285 } 286 case *Func: 287 // ignored for now 288 default: 289 unreachable() 290 } 291 } 292 293 if trace { 294 check.trace(obj.Pos(), "## cycle detected: objPath = %s->%s (len = %d)", objPathString(cycle), obj.Name(), ncycle) 295 check.trace(obj.Pos(), "## cycle contains: %d values, has indirection = %v, has type definition = %v", nval, hasIndir, hasTDef) 296 defer func() { 297 if isCycle { 298 check.trace(obj.Pos(), "=> error: cycle is invalid") 299 } 300 }() 301 } 302 303 // A cycle involving only constants and variables is invalid but we 304 // ignore them here because they are reported via the initialization 305 // cycle check. 306 if nval == ncycle { 307 return false 308 } 309 310 // A cycle involving only types (and possibly functions) must have at 311 // least one indirection and one type definition to be permitted: If 312 // there is no indirection, the size of the type cannot be computed 313 // (it's either infinite or 0); if there is no type definition, we 314 // have a sequence of alias type names which will expand ad infinitum. 315 if nval == 0 && hasIndir && hasTDef { 316 return false // cycle is permitted 317 } 318 319 // report cycle 320 check.errorf(obj.Pos(), "illegal cycle in declaration of %s", obj.Name()) 321 for _, obj := range cycle { 322 if obj == indir { 323 continue // don't print indir sentinels 324 } 325 check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented 326 } 327 check.errorf(obj.Pos(), "\t%s", obj.Name()) 328 329 return true 330 } 331 332 func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) { 333 assert(obj.typ == nil) 334 335 // use the correct value of iota 336 check.iota = obj.val 337 defer func() { check.iota = nil }() 338 339 // provide valid constant value under all circumstances 340 obj.val = constant.MakeUnknown() 341 342 // determine type, if any 343 if typ != nil { 344 t := check.typ(typ) 345 if !isConstType(t) { 346 // don't report an error if the type is an invalid C (defined) type 347 // (issue #22090) 348 if t.Underlying() != Typ[Invalid] { 349 check.errorf(typ.Pos(), "invalid constant type %s", t) 350 } 351 obj.typ = Typ[Invalid] 352 return 353 } 354 obj.typ = t 355 } 356 357 // check initialization 358 var x operand 359 if init != nil { 360 check.expr(&x, init) 361 } 362 check.initConst(obj, &x) 363 } 364 365 func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) { 366 assert(obj.typ == nil) 367 368 // determine type, if any 369 if typ != nil { 370 obj.typ = check.typ(typ) 371 // We cannot spread the type to all lhs variables if there 372 // are more than one since that would mark them as checked 373 // (see Checker.objDecl) and the assignment of init exprs, 374 // if any, would not be checked. 375 // 376 // TODO(gri) If we have no init expr, we should distribute 377 // a given type otherwise we need to re-evalate the type 378 // expr for each lhs variable, leading to duplicate work. 379 } 380 381 // check initialization 382 if init == nil { 383 if typ == nil { 384 // error reported before by arityMatch 385 obj.typ = Typ[Invalid] 386 } 387 return 388 } 389 390 if lhs == nil || len(lhs) == 1 { 391 assert(lhs == nil || lhs[0] == obj) 392 var x operand 393 check.expr(&x, init) 394 check.initVar(obj, &x, "variable declaration") 395 return 396 } 397 398 if debug { 399 // obj must be one of lhs 400 found := false 401 for _, lhs := range lhs { 402 if obj == lhs { 403 found = true 404 break 405 } 406 } 407 if !found { 408 panic("inconsistent lhs") 409 } 410 } 411 412 // We have multiple variables on the lhs and one init expr. 413 // Make sure all variables have been given the same type if 414 // one was specified, otherwise they assume the type of the 415 // init expression values (was issue #15755). 416 if typ != nil { 417 for _, lhs := range lhs { 418 lhs.typ = obj.typ 419 } 420 } 421 422 check.initVars(lhs, []ast.Expr{init}, token.NoPos) 423 } 424 425 // underlying returns the underlying type of typ; possibly by following 426 // forward chains of named types. Such chains only exist while named types 427 // are incomplete. 428 func underlying(typ Type) Type { 429 for { 430 n, _ := typ.(*Named) 431 if n == nil { 432 break 433 } 434 typ = n.underlying 435 } 436 return typ 437 } 438 439 func (n *Named) setUnderlying(typ Type) { 440 if n != nil { 441 n.underlying = typ 442 } 443 } 444 445 func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, alias bool) { 446 assert(obj.typ == nil) 447 448 if alias { 449 450 obj.typ = Typ[Invalid] 451 obj.typ = check.typ(typ) 452 453 } else { 454 455 named := &Named{obj: obj} 456 def.setUnderlying(named) 457 obj.typ = named // make sure recursive type declarations terminate 458 459 // determine underlying type of named 460 check.definedType(typ, named) 461 462 // The underlying type of named may be itself a named type that is 463 // incomplete: 464 // 465 // type ( 466 // A B 467 // B *C 468 // C A 469 // ) 470 // 471 // The type of C is the (named) type of A which is incomplete, 472 // and which has as its underlying type the named type B. 473 // Determine the (final, unnamed) underlying type by resolving 474 // any forward chain (they always end in an unnamed type). 475 named.underlying = underlying(named.underlying) 476 477 } 478 479 check.addMethodDecls(obj) 480 } 481 482 func (check *Checker) addMethodDecls(obj *TypeName) { 483 // get associated methods 484 // (Checker.collectObjects only collects methods with non-blank names; 485 // Checker.resolveBaseTypeName ensures that obj is not an alias name 486 // if it has attached methods.) 487 methods := check.methods[obj] 488 if methods == nil { 489 return 490 } 491 delete(check.methods, obj) 492 assert(!check.objMap[obj].alias) // don't use TypeName.IsAlias (requires fully set up object) 493 494 // use an objset to check for name conflicts 495 var mset objset 496 497 // spec: "If the base type is a struct type, the non-blank method 498 // and field names must be distinct." 499 base, _ := obj.typ.(*Named) // shouldn't fail but be conservative 500 if base != nil { 501 if t, _ := base.underlying.(*Struct); t != nil { 502 for _, fld := range t.fields { 503 if fld.name != "_" { 504 assert(mset.insert(fld) == nil) 505 } 506 } 507 } 508 509 // Checker.Files may be called multiple times; additional package files 510 // may add methods to already type-checked types. Add pre-existing methods 511 // so that we can detect redeclarations. 512 for _, m := range base.methods { 513 assert(m.name != "_") 514 assert(mset.insert(m) == nil) 515 } 516 } 517 518 // add valid methods 519 for _, m := range methods { 520 // spec: "For a base type, the non-blank names of methods bound 521 // to it must be unique." 522 assert(m.name != "_") 523 if alt := mset.insert(m); alt != nil { 524 switch alt.(type) { 525 case *Var: 526 check.errorf(m.pos, "field and method with the same name %s", m.name) 527 case *Func: 528 check.errorf(m.pos, "method %s already declared for %s", m.name, obj) 529 default: 530 unreachable() 531 } 532 check.reportAltDecl(alt) 533 continue 534 } 535 536 if base != nil { 537 base.methods = append(base.methods, m) 538 } 539 } 540 } 541 542 func (check *Checker) funcDecl(obj *Func, decl *declInfo) { 543 assert(obj.typ == nil) 544 545 // func declarations cannot use iota 546 assert(check.iota == nil) 547 548 sig := new(Signature) 549 obj.typ = sig // guard against cycles 550 fdecl := decl.fdecl 551 check.funcType(sig, fdecl.Recv, fdecl.Type) 552 if sig.recv == nil && obj.name == "init" && (sig.params.Len() > 0 || sig.results.Len() > 0) { 553 check.errorf(fdecl.Pos(), "func init must have no arguments and no return values") 554 // ok to continue 555 } 556 557 // function body must be type-checked after global declarations 558 // (functions implemented elsewhere have no body) 559 if !check.conf.IgnoreFuncBodies && fdecl.Body != nil { 560 check.later(func() { 561 check.funcBody(decl, obj.name, sig, fdecl.Body, nil) 562 }) 563 } 564 } 565 566 func (check *Checker) declStmt(decl ast.Decl) { 567 pkg := check.pkg 568 569 switch d := decl.(type) { 570 case *ast.BadDecl: 571 // ignore 572 573 case *ast.GenDecl: 574 var last *ast.ValueSpec // last ValueSpec with type or init exprs seen 575 for iota, spec := range d.Specs { 576 switch s := spec.(type) { 577 case *ast.ValueSpec: 578 switch d.Tok { 579 case token.CONST: 580 top := len(check.delayed) 581 582 // determine which init exprs to use 583 switch { 584 case s.Type != nil || len(s.Values) > 0: 585 last = s 586 case last == nil: 587 last = new(ast.ValueSpec) // make sure last exists 588 } 589 590 // declare all constants 591 lhs := make([]*Const, len(s.Names)) 592 for i, name := range s.Names { 593 obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota))) 594 lhs[i] = obj 595 596 var init ast.Expr 597 if i < len(last.Values) { 598 init = last.Values[i] 599 } 600 601 check.constDecl(obj, last.Type, init) 602 } 603 604 check.arityMatch(s, last) 605 606 // process function literals in init expressions before scope changes 607 check.processDelayed(top) 608 609 // spec: "The scope of a constant or variable identifier declared 610 // inside a function begins at the end of the ConstSpec or VarSpec 611 // (ShortVarDecl for short variable declarations) and ends at the 612 // end of the innermost containing block." 613 scopePos := s.End() 614 for i, name := range s.Names { 615 check.declare(check.scope, name, lhs[i], scopePos) 616 } 617 618 case token.VAR: 619 top := len(check.delayed) 620 621 lhs0 := make([]*Var, len(s.Names)) 622 for i, name := range s.Names { 623 lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil) 624 } 625 626 // initialize all variables 627 for i, obj := range lhs0 { 628 var lhs []*Var 629 var init ast.Expr 630 switch len(s.Values) { 631 case len(s.Names): 632 // lhs and rhs match 633 init = s.Values[i] 634 case 1: 635 // rhs is expected to be a multi-valued expression 636 lhs = lhs0 637 init = s.Values[0] 638 default: 639 if i < len(s.Values) { 640 init = s.Values[i] 641 } 642 } 643 check.varDecl(obj, lhs, s.Type, init) 644 if len(s.Values) == 1 { 645 // If we have a single lhs variable we are done either way. 646 // If we have a single rhs expression, it must be a multi- 647 // valued expression, in which case handling the first lhs 648 // variable will cause all lhs variables to have a type 649 // assigned, and we are done as well. 650 if debug { 651 for _, obj := range lhs0 { 652 assert(obj.typ != nil) 653 } 654 } 655 break 656 } 657 } 658 659 check.arityMatch(s, nil) 660 661 // process function literals in init expressions before scope changes 662 check.processDelayed(top) 663 664 // declare all variables 665 // (only at this point are the variable scopes (parents) set) 666 scopePos := s.End() // see constant declarations 667 for i, name := range s.Names { 668 // see constant declarations 669 check.declare(check.scope, name, lhs0[i], scopePos) 670 } 671 672 default: 673 check.invalidAST(s.Pos(), "invalid token %s", d.Tok) 674 } 675 676 case *ast.TypeSpec: 677 obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil) 678 // spec: "The scope of a type identifier declared inside a function 679 // begins at the identifier in the TypeSpec and ends at the end of 680 // the innermost containing block." 681 scopePos := s.Name.Pos() 682 check.declare(check.scope, s.Name, obj, scopePos) 683 // mark and unmark type before calling typeDecl; its type is still nil (see Checker.objDecl) 684 obj.setColor(grey + color(check.push(obj))) 685 check.typeDecl(obj, s.Type, nil, s.Assign.IsValid()) 686 check.pop().setColor(black) 687 default: 688 check.invalidAST(s.Pos(), "const, type, or var declaration expected") 689 } 690 } 691 692 default: 693 check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d) 694 } 695 }