github.com/gmemcc/yaegi@v0.12.1-0.20221128122509-aa99124c5d16/internal/cmd/extract/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(obj, _DuplicateDecl, "\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, _DuplicateDecl, "%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 func pathString(path []Object) string { 42 var s string 43 for i, p := range path { 44 if i > 0 { 45 s += "->" 46 } 47 s += p.Name() 48 } 49 return s 50 } 51 52 // objDecl type-checks the declaration of obj in its respective (file) context. 53 // For the meaning of def, see Checker.definedType, in typexpr.go. 54 func (check *Checker) objDecl(obj Object, def *Named) { 55 if trace { 56 check.trace(obj.Pos(), "-- checking %s (%s, objPath = %s)", obj, obj.color(), pathString(check.objPath)) 57 check.indent++ 58 defer func() { 59 check.indent-- 60 check.trace(obj.Pos(), "=> %s (%s)", obj, obj.color()) 61 }() 62 } 63 64 // Checking the declaration of obj means inferring its type 65 // (and possibly its value, for constants). 66 // An object's type (and thus the object) may be in one of 67 // three states which are expressed by colors: 68 // 69 // - an object whose type is not yet known is painted white (initial color) 70 // - an object whose type is in the process of being inferred is painted grey 71 // - an object whose type is fully inferred is painted black 72 // 73 // During type inference, an object's color changes from white to grey 74 // to black (pre-declared objects are painted black from the start). 75 // A black object (i.e., its type) can only depend on (refer to) other black 76 // ones. White and grey objects may depend on white and black objects. 77 // A dependency on a grey object indicates a cycle which may or may not be 78 // valid. 79 // 80 // When objects turn grey, they are pushed on the object path (a stack); 81 // they are popped again when they turn black. Thus, if a grey object (a 82 // cycle) is encountered, it is on the object path, and all the objects 83 // it depends on are the remaining objects on that path. Color encoding 84 // is such that the color value of a grey object indicates the index of 85 // that object in the object path. 86 87 // During type-checking, white objects may be assigned a type without 88 // traversing through objDecl; e.g., when initializing constants and 89 // variables. Update the colors of those objects here (rather than 90 // everywhere where we set the type) to satisfy the color invariants. 91 if obj.color() == white && obj.Type() != nil { 92 obj.setColor(black) 93 return 94 } 95 96 switch obj.color() { 97 case white: 98 assert(obj.Type() == nil) 99 // All color values other than white and black are considered grey. 100 // Because black and white are < grey, all values >= grey are grey. 101 // Use those values to encode the object's index into the object path. 102 obj.setColor(grey + color(check.push(obj))) 103 defer func() { 104 check.pop().setColor(black) 105 }() 106 107 case black: 108 assert(obj.Type() != nil) 109 return 110 111 default: 112 // Color values other than white or black are considered grey. 113 fallthrough 114 115 case grey: 116 // We have a cycle. 117 // In the existing code, this is marked by a non-nil type 118 // for the object except for constants and variables whose 119 // type may be non-nil (known), or nil if it depends on the 120 // not-yet known initialization value. 121 // In the former case, set the type to Typ[Invalid] because 122 // we have an initialization cycle. The cycle error will be 123 // reported later, when determining initialization order. 124 // TODO(gri) Report cycle here and simplify initialization 125 // order code. 126 switch obj := obj.(type) { 127 case *Const: 128 if check.cycle(obj) || obj.typ == nil { 129 obj.typ = Typ[Invalid] 130 } 131 132 case *Var: 133 if check.cycle(obj) || obj.typ == nil { 134 obj.typ = Typ[Invalid] 135 } 136 137 case *TypeName: 138 if check.cycle(obj) { 139 // break cycle 140 // (without this, calling underlying() 141 // below may lead to an endless loop 142 // if we have a cycle for a defined 143 // (*Named) type) 144 obj.typ = Typ[Invalid] 145 } 146 147 case *Func: 148 if check.cycle(obj) { 149 // Don't set obj.typ to Typ[Invalid] here 150 // because plenty of code type-asserts that 151 // functions have a *Signature type. Grey 152 // functions have their type set to an empty 153 // signature which makes it impossible to 154 // initialize a variable with the function. 155 } 156 157 default: 158 unreachable() 159 } 160 assert(obj.Type() != nil) 161 return 162 } 163 164 d := check.objMap[obj] 165 if d == nil { 166 check.dump("%v: %s should have been declared", obj.Pos(), obj) 167 unreachable() 168 } 169 170 // save/restore current context and setup object context 171 defer func(ctxt context) { 172 check.context = ctxt 173 }(check.context) 174 check.context = context{ 175 scope: d.file, 176 } 177 178 // Const and var declarations must not have initialization 179 // cycles. We track them by remembering the current declaration 180 // in check.decl. Initialization expressions depending on other 181 // consts, vars, or functions, add dependencies to the current 182 // check.decl. 183 switch obj := obj.(type) { 184 case *Const: 185 check.decl = d // new package-level const decl 186 check.constDecl(obj, d.typ, d.init, d.inherited) 187 case *Var: 188 check.decl = d // new package-level var decl 189 check.varDecl(obj, d.lhs, d.typ, d.init) 190 case *TypeName: 191 // invalid recursive types are detected via path 192 check.typeDecl(obj, d.typ, def, d.alias) 193 case *Func: 194 // functions may be recursive - no need to track dependencies 195 check.funcDecl(obj, d) 196 default: 197 unreachable() 198 } 199 } 200 201 // cycle checks if the cycle starting with obj is valid and 202 // reports an error if it is not. 203 func (check *Checker) cycle(obj Object) (isCycle bool) { 204 // The object map contains the package scope objects and the non-interface methods. 205 if debug { 206 info := check.objMap[obj] 207 inObjMap := info != nil && (info.fdecl == nil || info.fdecl.Recv == nil) // exclude methods 208 isPkgObj := obj.Parent() == check.pkg.scope 209 if isPkgObj != inObjMap { 210 check.dump("%v: inconsistent object map for %s (isPkgObj = %v, inObjMap = %v)", obj.Pos(), obj, isPkgObj, inObjMap) 211 unreachable() 212 } 213 } 214 215 // Count cycle objects. 216 assert(obj.color() >= grey) 217 start := obj.color() - grey // index of obj in objPath 218 cycle := check.objPath[start:] 219 nval := 0 // number of (constant or variable) values in the cycle 220 ndef := 0 // number of type definitions in the cycle 221 for _, obj := range cycle { 222 switch obj := obj.(type) { 223 case *Const, *Var: 224 nval++ 225 case *TypeName: 226 // Determine if the type name is an alias or not. For 227 // package-level objects, use the object map which 228 // provides syntactic information (which doesn't rely 229 // on the order in which the objects are set up). For 230 // local objects, we can rely on the order, so use 231 // the object's predicate. 232 // TODO(gri) It would be less fragile to always access 233 // the syntactic information. We should consider storing 234 // this information explicitly in the object. 235 var alias bool 236 if d := check.objMap[obj]; d != nil { 237 alias = d.alias // package-level object 238 } else { 239 alias = obj.IsAlias() // function local object 240 } 241 if !alias { 242 ndef++ 243 } 244 case *Func: 245 // ignored for now 246 default: 247 unreachable() 248 } 249 } 250 251 if trace { 252 check.trace(obj.Pos(), "## cycle detected: objPath = %s->%s (len = %d)", pathString(cycle), obj.Name(), len(cycle)) 253 check.trace(obj.Pos(), "## cycle contains: %d values, %d type definitions", nval, ndef) 254 defer func() { 255 if isCycle { 256 check.trace(obj.Pos(), "=> error: cycle is invalid") 257 } 258 }() 259 } 260 261 // A cycle involving only constants and variables is invalid but we 262 // ignore them here because they are reported via the initialization 263 // cycle check. 264 if nval == len(cycle) { 265 return false 266 } 267 268 // A cycle involving only types (and possibly functions) must have at least 269 // one type definition to be permitted: If there is no type definition, we 270 // have a sequence of alias type names which will expand ad infinitum. 271 if nval == 0 && ndef > 0 { 272 return false // cycle is permitted 273 } 274 275 check.cycleError(cycle) 276 277 return true 278 } 279 280 type typeInfo uint 281 282 // validType verifies that the given type does not "expand" infinitely 283 // producing a cycle in the type graph. Cycles are detected by marking 284 // defined types. 285 // (Cycles involving alias types, as in "type A = [10]A" are detected 286 // earlier, via the objDecl cycle detection mechanism.) 287 func (check *Checker) validType(typ Type, path []Object) typeInfo { 288 const ( 289 unknown typeInfo = iota 290 marked 291 valid 292 invalid 293 ) 294 295 switch t := typ.(type) { 296 case *Array: 297 return check.validType(t.elem, path) 298 299 case *Struct: 300 for _, f := range t.fields { 301 if check.validType(f.typ, path) == invalid { 302 return invalid 303 } 304 } 305 306 case *Interface: 307 for _, etyp := range t.embeddeds { 308 if check.validType(etyp, path) == invalid { 309 return invalid 310 } 311 } 312 313 case *Named: 314 // don't touch the type if it is from a different package or the Universe scope 315 // (doing so would lead to a race condition - was issue #35049) 316 if t.obj.pkg != check.pkg { 317 return valid 318 } 319 320 // don't report a 2nd error if we already know the type is invalid 321 // (e.g., if a cycle was detected earlier, via Checker.underlying). 322 if t.underlying == Typ[Invalid] { 323 t.info = invalid 324 return invalid 325 } 326 327 switch t.info { 328 case unknown: 329 t.info = marked 330 t.info = check.validType(t.orig, append(path, t.obj)) // only types of current package added to path 331 case marked: 332 // cycle detected 333 for i, tn := range path { 334 if t.obj.pkg != check.pkg { 335 panic("internal error: type cycle via package-external type") 336 } 337 if tn == t.obj { 338 check.cycleError(path[i:]) 339 t.info = invalid 340 t.underlying = Typ[Invalid] 341 return t.info 342 } 343 } 344 panic("internal error: cycle start not found") 345 } 346 return t.info 347 } 348 349 return valid 350 } 351 352 // cycleError reports a declaration cycle starting with 353 // the object in cycle that is "first" in the source. 354 func (check *Checker) cycleError(cycle []Object) { 355 // TODO(gri) Should we start with the last (rather than the first) object in the cycle 356 // since that is the earliest point in the source where we start seeing the 357 // cycle? That would be more consistent with other error messages. 358 i := firstInSrc(cycle) 359 obj := cycle[i] 360 check.errorf(obj, _InvalidDeclCycle, "illegal cycle in declaration of %s", obj.Name()) 361 for range cycle { 362 check.errorf(obj, _InvalidDeclCycle, "\t%s refers to", obj.Name()) // secondary error, \t indented 363 i++ 364 if i >= len(cycle) { 365 i = 0 366 } 367 obj = cycle[i] 368 } 369 check.errorf(obj, _InvalidDeclCycle, "\t%s", obj.Name()) 370 } 371 372 // firstInSrc reports the index of the object with the "smallest" 373 // source position in path. path must not be empty. 374 func firstInSrc(path []Object) int { 375 fst, pos := 0, path[0].Pos() 376 for i, t := range path[1:] { 377 if t.Pos() < pos { 378 fst, pos = i+1, t.Pos() 379 } 380 } 381 return fst 382 } 383 384 type ( 385 decl interface { 386 node() ast.Node 387 } 388 389 importDecl struct{ spec *ast.ImportSpec } 390 constDecl struct { 391 spec *ast.ValueSpec 392 iota int 393 typ ast.Expr 394 init []ast.Expr 395 inherited bool 396 } 397 varDecl struct{ spec *ast.ValueSpec } 398 typeDecl struct{ spec *ast.TypeSpec } 399 funcDecl struct{ decl *ast.FuncDecl } 400 ) 401 402 func (d importDecl) node() ast.Node { return d.spec } 403 func (d constDecl) node() ast.Node { return d.spec } 404 func (d varDecl) node() ast.Node { return d.spec } 405 func (d typeDecl) node() ast.Node { return d.spec } 406 func (d funcDecl) node() ast.Node { return d.decl } 407 408 func (check *Checker) walkDecls(decls []ast.Decl, f func(decl)) { 409 for _, d := range decls { 410 check.walkDecl(d, f) 411 } 412 } 413 414 func (check *Checker) walkDecl(d ast.Decl, f func(decl)) { 415 switch d := d.(type) { 416 case *ast.BadDecl: 417 // ignore 418 case *ast.GenDecl: 419 var last *ast.ValueSpec // last ValueSpec with type or init exprs seen 420 for iota, s := range d.Specs { 421 switch s := s.(type) { 422 case *ast.ImportSpec: 423 f(importDecl{s}) 424 case *ast.ValueSpec: 425 switch d.Tok { 426 case token.CONST: 427 // determine which initialization expressions to use 428 inherited := true 429 switch { 430 case s.Type != nil || len(s.Values) > 0: 431 last = s 432 inherited = false 433 case last == nil: 434 last = new(ast.ValueSpec) // make sure last exists 435 inherited = false 436 } 437 check.arityMatch(s, last) 438 f(constDecl{spec: s, iota: iota, typ: last.Type, init: last.Values, inherited: inherited}) 439 case token.VAR: 440 check.arityMatch(s, nil) 441 f(varDecl{s}) 442 default: 443 check.invalidAST(s, "invalid token %s", d.Tok) 444 } 445 case *ast.TypeSpec: 446 f(typeDecl{s}) 447 default: 448 check.invalidAST(s, "unknown ast.Spec node %T", s) 449 } 450 } 451 case *ast.FuncDecl: 452 f(funcDecl{d}) 453 default: 454 check.invalidAST(d, "unknown ast.Decl node %T", d) 455 } 456 } 457 458 func (check *Checker) constDecl(obj *Const, typ, init ast.Expr, inherited bool) { 459 assert(obj.typ == nil) 460 461 // use the correct value of iota 462 defer func(iota constant.Value, errpos positioner) { 463 check.iota = iota 464 check.errpos = errpos 465 }(check.iota, check.errpos) 466 check.iota = obj.val 467 check.errpos = nil 468 469 // provide valid constant value under all circumstances 470 obj.val = constant.MakeUnknown() 471 472 // determine type, if any 473 if typ != nil { 474 t := check.typ(typ) 475 if !isConstType(t) { 476 // don't report an error if the type is an invalid C (defined) type 477 // (issue #22090) 478 if t.Underlying() != Typ[Invalid] { 479 check.errorf(typ, _InvalidConstType, "invalid constant type %s", t) 480 } 481 obj.typ = Typ[Invalid] 482 return 483 } 484 obj.typ = t 485 } 486 487 // check initialization 488 var x operand 489 if init != nil { 490 if inherited { 491 // The initialization expression is inherited from a previous 492 // constant declaration, and (error) positions refer to that 493 // expression and not the current constant declaration. Use 494 // the constant identifier position for any errors during 495 // init expression evaluation since that is all we have 496 // (see issues #42991, #42992). 497 check.errpos = atPos(obj.pos) 498 } 499 check.expr(&x, init) 500 } 501 check.initConst(obj, &x) 502 } 503 504 func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) { 505 assert(obj.typ == nil) 506 507 // determine type, if any 508 if typ != nil { 509 obj.typ = check.typ(typ) 510 // We cannot spread the type to all lhs variables if there 511 // are more than one since that would mark them as checked 512 // (see Checker.objDecl) and the assignment of init exprs, 513 // if any, would not be checked. 514 // 515 // TODO(gri) If we have no init expr, we should distribute 516 // a given type otherwise we need to re-evalate the type 517 // expr for each lhs variable, leading to duplicate work. 518 } 519 520 // check initialization 521 if init == nil { 522 if typ == nil { 523 // error reported before by arityMatch 524 obj.typ = Typ[Invalid] 525 } 526 return 527 } 528 529 if lhs == nil || len(lhs) == 1 { 530 assert(lhs == nil || lhs[0] == obj) 531 var x operand 532 check.expr(&x, init) 533 check.initVar(obj, &x, "variable declaration") 534 return 535 } 536 537 if debug { 538 // obj must be one of lhs 539 found := false 540 for _, lhs := range lhs { 541 if obj == lhs { 542 found = true 543 break 544 } 545 } 546 if !found { 547 panic("inconsistent lhs") 548 } 549 } 550 551 // We have multiple variables on the lhs and one init expr. 552 // Make sure all variables have been given the same type if 553 // one was specified, otherwise they assume the type of the 554 // init expression values (was issue #15755). 555 if typ != nil { 556 for _, lhs := range lhs { 557 lhs.typ = obj.typ 558 } 559 } 560 561 check.initVars(lhs, []ast.Expr{init}, token.NoPos) 562 } 563 564 // underlying returns the underlying type of typ; possibly by following 565 // forward chains of named types. Such chains only exist while named types 566 // are incomplete. If an underlying type is found, resolve the chain by 567 // setting the underlying type for each defined type in the chain before 568 // returning it. 569 // 570 // If no underlying type is found, a cycle error is reported and Typ[Invalid] 571 // is used as underlying type for each defined type in the chain and returned 572 // as result. 573 func (check *Checker) underlying(typ Type) Type { 574 // If typ is not a defined type, its underlying type is itself. 575 n0, _ := typ.(*Named) 576 if n0 == nil { 577 return typ // nothing to do 578 } 579 580 // If the underlying type of a defined type is not a defined 581 // type, then that is the desired underlying type. 582 typ = n0.underlying 583 n, _ := typ.(*Named) 584 if n == nil { 585 return typ // common case 586 } 587 588 // Otherwise, follow the forward chain. 589 seen := map[*Named]int{n0: 0} 590 path := []Object{n0.obj} 591 for { 592 typ = n.underlying 593 n1, _ := typ.(*Named) 594 if n1 == nil { 595 break // end of chain 596 } 597 598 seen[n] = len(seen) 599 path = append(path, n.obj) 600 n = n1 601 602 if i, ok := seen[n]; ok { 603 // cycle 604 check.cycleError(path[i:]) 605 typ = Typ[Invalid] 606 break 607 } 608 } 609 610 for n := range seen { 611 // We should never have to update the underlying type of an imported type; 612 // those underlying types should have been resolved during the import. 613 // Also, doing so would lead to a race condition (was issue #31749). 614 if n.obj.pkg != check.pkg { 615 panic("internal error: imported type with unresolved underlying type") 616 } 617 n.underlying = typ 618 } 619 620 return typ 621 } 622 623 func (n *Named) setUnderlying(typ Type) { 624 if n != nil { 625 n.underlying = typ 626 } 627 } 628 629 func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, alias bool) { 630 assert(obj.typ == nil) 631 632 check.later(func() { 633 check.validType(obj.typ, nil) 634 }) 635 636 if alias { 637 638 obj.typ = Typ[Invalid] 639 obj.typ = check.typ(typ) 640 641 } else { 642 643 named := &Named{obj: obj} 644 def.setUnderlying(named) 645 obj.typ = named // make sure recursive type declarations terminate 646 647 // determine underlying type of named 648 named.orig = check.definedType(typ, named) 649 650 // The underlying type of named may be itself a named type that is 651 // incomplete: 652 // 653 // type ( 654 // A B 655 // B *C 656 // C A 657 // ) 658 // 659 // The type of C is the (named) type of A which is incomplete, 660 // and which has as its underlying type the named type B. 661 // Determine the (final, unnamed) underlying type by resolving 662 // any forward chain. 663 named.underlying = check.underlying(named) 664 665 } 666 667 check.addMethodDecls(obj) 668 } 669 670 func (check *Checker) addMethodDecls(obj *TypeName) { 671 // get associated methods 672 // (Checker.collectObjects only collects methods with non-blank names; 673 // Checker.resolveBaseTypeName ensures that obj is not an alias name 674 // if it has attached methods.) 675 methods := check.methods[obj] 676 if methods == nil { 677 return 678 } 679 delete(check.methods, obj) 680 assert(!check.objMap[obj].alias) // don't use TypeName.IsAlias (requires fully set up object) 681 682 // use an objset to check for name conflicts 683 var mset objset 684 685 // spec: "If the base type is a struct type, the non-blank method 686 // and field names must be distinct." 687 base, _ := obj.typ.(*Named) // shouldn't fail but be conservative 688 if base != nil { 689 if t, _ := base.underlying.(*Struct); t != nil { 690 for _, fld := range t.fields { 691 if fld.name != "_" { 692 assert(mset.insert(fld) == nil) 693 } 694 } 695 } 696 697 // Checker.Files may be called multiple times; additional package files 698 // may add methods to already type-checked types. Add pre-existing methods 699 // so that we can detect redeclarations. 700 for _, m := range base.methods { 701 assert(m.name != "_") 702 assert(mset.insert(m) == nil) 703 } 704 } 705 706 // add valid methods 707 for _, m := range methods { 708 // spec: "For a base type, the non-blank names of methods bound 709 // to it must be unique." 710 assert(m.name != "_") 711 if alt := mset.insert(m); alt != nil { 712 switch alt.(type) { 713 case *Var: 714 check.errorf(m, _DuplicateFieldAndMethod, "field and method with the same name %s", m.name) 715 case *Func: 716 check.errorf(m, _DuplicateMethod, "method %s already declared for %s", m.name, obj) 717 default: 718 unreachable() 719 } 720 check.reportAltDecl(alt) 721 continue 722 } 723 724 if base != nil { 725 base.methods = append(base.methods, m) 726 } 727 } 728 } 729 730 func (check *Checker) funcDecl(obj *Func, decl *declInfo) { 731 assert(obj.typ == nil) 732 733 // func declarations cannot use iota 734 assert(check.iota == nil) 735 736 sig := new(Signature) 737 obj.typ = sig // guard against cycles 738 fdecl := decl.fdecl 739 check.funcType(sig, fdecl.Recv, fdecl.Type) 740 if sig.recv == nil && obj.name == "init" && (sig.params.Len() > 0 || sig.results.Len() > 0) { 741 check.errorf(fdecl, _InvalidInitSig, "func init must have no arguments and no return values") 742 // ok to continue 743 } 744 745 // function body must be type-checked after global declarations 746 // (functions implemented elsewhere have no body) 747 if !check.conf.IgnoreFuncBodies && fdecl.Body != nil { 748 check.later(func() { 749 check.funcBody(decl, obj.name, sig, fdecl.Body, nil) 750 }) 751 } 752 } 753 754 func (check *Checker) declStmt(d ast.Decl) { 755 pkg := check.pkg 756 757 check.walkDecl(d, func(d decl) { 758 switch d := d.(type) { 759 case constDecl: 760 top := len(check.delayed) 761 762 // declare all constants 763 lhs := make([]*Const, len(d.spec.Names)) 764 for i, name := range d.spec.Names { 765 obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(d.iota))) 766 lhs[i] = obj 767 768 var init ast.Expr 769 if i < len(d.init) { 770 init = d.init[i] 771 } 772 773 check.constDecl(obj, d.typ, init, d.inherited) 774 } 775 776 // process function literals in init expressions before scope changes 777 check.processDelayed(top) 778 779 // spec: "The scope of a constant or variable identifier declared 780 // inside a function begins at the end of the ConstSpec or VarSpec 781 // (ShortVarDecl for short variable declarations) and ends at the 782 // end of the innermost containing block." 783 scopePos := d.spec.End() 784 for i, name := range d.spec.Names { 785 check.declare(check.scope, name, lhs[i], scopePos) 786 } 787 788 case varDecl: 789 top := len(check.delayed) 790 791 lhs0 := make([]*Var, len(d.spec.Names)) 792 for i, name := range d.spec.Names { 793 lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil) 794 } 795 796 // initialize all variables 797 for i, obj := range lhs0 { 798 var lhs []*Var 799 var init ast.Expr 800 switch len(d.spec.Values) { 801 case len(d.spec.Names): 802 // lhs and rhs match 803 init = d.spec.Values[i] 804 case 1: 805 // rhs is expected to be a multi-valued expression 806 lhs = lhs0 807 init = d.spec.Values[0] 808 default: 809 if i < len(d.spec.Values) { 810 init = d.spec.Values[i] 811 } 812 } 813 check.varDecl(obj, lhs, d.spec.Type, init) 814 if len(d.spec.Values) == 1 { 815 // If we have a single lhs variable we are done either way. 816 // If we have a single rhs expression, it must be a multi- 817 // valued expression, in which case handling the first lhs 818 // variable will cause all lhs variables to have a type 819 // assigned, and we are done as well. 820 if debug { 821 for _, obj := range lhs0 { 822 assert(obj.typ != nil) 823 } 824 } 825 break 826 } 827 } 828 829 // process function literals in init expressions before scope changes 830 check.processDelayed(top) 831 832 // declare all variables 833 // (only at this point are the variable scopes (parents) set) 834 scopePos := d.spec.End() // see constant declarations 835 for i, name := range d.spec.Names { 836 // see constant declarations 837 check.declare(check.scope, name, lhs0[i], scopePos) 838 } 839 840 case typeDecl: 841 obj := NewTypeName(d.spec.Name.Pos(), pkg, d.spec.Name.Name, nil) 842 // spec: "The scope of a type identifier declared inside a function 843 // begins at the identifier in the TypeSpec and ends at the end of 844 // the innermost containing block." 845 scopePos := d.spec.Name.Pos() 846 check.declare(check.scope, d.spec.Name, obj, scopePos) 847 // mark and unmark type before calling typeDecl; its type is still nil (see Checker.objDecl) 848 obj.setColor(grey + color(check.push(obj))) 849 check.typeDecl(obj, d.spec.Type, nil, d.spec.Assign.IsValid()) 850 check.pop().setColor(black) 851 default: 852 check.invalidAST(d.node(), "unknown ast.Decl node %T", d.node()) 853 } 854 }) 855 }