github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/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, d.alias) 85 case *Func: 86 // functions may be recursive - no need to track dependencies 87 check.funcDecl(obj, d) 88 default: 89 unreachable() 90 } 91 } 92 93 func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) { 94 assert(obj.typ == nil) 95 96 if obj.visited { 97 obj.typ = Typ[Invalid] 98 return 99 } 100 obj.visited = true 101 102 // use the correct value of iota 103 assert(check.iota == nil) 104 check.iota = obj.val 105 defer func() { check.iota = nil }() 106 107 // provide valid constant value under all circumstances 108 obj.val = constant.MakeUnknown() 109 110 // determine type, if any 111 if typ != nil { 112 t := check.typ(typ) 113 if !isConstType(t) { 114 check.errorf(typ.Pos(), "invalid constant type %s", t) 115 obj.typ = Typ[Invalid] 116 return 117 } 118 obj.typ = t 119 } 120 121 // check initialization 122 var x operand 123 if init != nil { 124 check.expr(&x, init) 125 } 126 check.initConst(obj, &x) 127 } 128 129 func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) { 130 assert(obj.typ == nil) 131 132 if obj.visited { 133 obj.typ = Typ[Invalid] 134 return 135 } 136 obj.visited = true 137 138 // var declarations cannot use iota 139 assert(check.iota == nil) 140 141 // determine type, if any 142 if typ != nil { 143 obj.typ = check.typ(typ) 144 // We cannot spread the type to all lhs variables if there 145 // are more than one since that would mark them as checked 146 // (see Checker.objDecl) and the assignment of init exprs, 147 // if any, would not be checked. 148 // 149 // TODO(gri) If we have no init expr, we should distribute 150 // a given type otherwise we need to re-evalate the type 151 // expr for each lhs variable, leading to duplicate work. 152 } 153 154 // check initialization 155 if init == nil { 156 if typ == nil { 157 // error reported before by arityMatch 158 obj.typ = Typ[Invalid] 159 } 160 return 161 } 162 163 if lhs == nil || len(lhs) == 1 { 164 assert(lhs == nil || lhs[0] == obj) 165 var x operand 166 check.expr(&x, init) 167 check.initVar(obj, &x, "variable declaration") 168 return 169 } 170 171 if debug { 172 // obj must be one of lhs 173 found := false 174 for _, lhs := range lhs { 175 if obj == lhs { 176 found = true 177 break 178 } 179 } 180 if !found { 181 panic("inconsistent lhs") 182 } 183 } 184 185 // We have multiple variables on the lhs and one init expr. 186 // Make sure all variables have been given the same type if 187 // one was specified, otherwise they assume the type of the 188 // init expression values (was issue #15755). 189 if typ != nil { 190 for _, lhs := range lhs { 191 lhs.typ = obj.typ 192 } 193 } 194 195 check.initVars(lhs, []ast.Expr{init}, token.NoPos) 196 } 197 198 // underlying returns the underlying type of typ; possibly by following 199 // forward chains of named types. Such chains only exist while named types 200 // are incomplete. 201 func underlying(typ Type) Type { 202 for { 203 n, _ := typ.(*Named) 204 if n == nil { 205 break 206 } 207 typ = n.underlying 208 } 209 return typ 210 } 211 212 func (n *Named) setUnderlying(typ Type) { 213 if n != nil { 214 n.underlying = typ 215 } 216 } 217 218 func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, path []*TypeName, alias bool) { 219 assert(obj.typ == nil) 220 221 // type declarations cannot use iota 222 assert(check.iota == nil) 223 224 if alias { 225 226 obj.typ = Typ[Invalid] 227 obj.typ = check.typExpr(typ, nil, append(path, obj)) 228 229 } else { 230 231 named := &Named{obj: obj} 232 def.setUnderlying(named) 233 obj.typ = named // make sure recursive type declarations terminate 234 235 // determine underlying type of named 236 check.typExpr(typ, named, append(path, obj)) 237 238 // The underlying type of named may be itself a named type that is 239 // incomplete: 240 // 241 // type ( 242 // A B 243 // B *C 244 // C A 245 // ) 246 // 247 // The type of C is the (named) type of A which is incomplete, 248 // and which has as its underlying type the named type B. 249 // Determine the (final, unnamed) underlying type by resolving 250 // any forward chain (they always end in an unnamed type). 251 named.underlying = underlying(named.underlying) 252 253 } 254 255 // check and add associated methods 256 // TODO(gri) It's easy to create pathological cases where the 257 // current approach is incorrect: In general we need to know 258 // and add all methods _before_ type-checking the type. 259 // See https://play.golang.org/p/WMpE0q2wK8 260 check.addMethodDecls(obj) 261 } 262 263 func (check *Checker) addMethodDecls(obj *TypeName) { 264 // get associated methods 265 methods := check.methods[obj.name] 266 if len(methods) == 0 { 267 return // no methods 268 } 269 delete(check.methods, obj.name) 270 271 // use an objset to check for name conflicts 272 var mset objset 273 274 // spec: "If the base type is a struct type, the non-blank method 275 // and field names must be distinct." 276 base, _ := obj.typ.(*Named) // nil if receiver base type is type alias 277 if base != nil { 278 if t, _ := base.underlying.(*Struct); t != nil { 279 for _, fld := range t.fields { 280 if fld.name != "_" { 281 assert(mset.insert(fld) == nil) 282 } 283 } 284 } 285 286 // Checker.Files may be called multiple times; additional package files 287 // may add methods to already type-checked types. Add pre-existing methods 288 // so that we can detect redeclarations. 289 for _, m := range base.methods { 290 assert(m.name != "_") 291 assert(mset.insert(m) == nil) 292 } 293 } 294 295 // type-check methods 296 for _, m := range methods { 297 // spec: "For a base type, the non-blank names of methods bound 298 // to it must be unique." 299 if m.name != "_" { 300 if alt := mset.insert(m); alt != nil { 301 switch alt.(type) { 302 case *Var: 303 check.errorf(m.pos, "field and method with the same name %s", m.name) 304 case *Func: 305 check.errorf(m.pos, "method %s already declared for %s", m.name, obj) 306 default: 307 unreachable() 308 } 309 check.reportAltDecl(alt) 310 continue 311 } 312 } 313 314 // type-check 315 check.objDecl(m, nil, nil) 316 317 // methods with blank _ names cannot be found - don't keep them 318 if base != nil && m.name != "_" { 319 base.methods = append(base.methods, m) 320 } 321 } 322 } 323 324 func (check *Checker) funcDecl(obj *Func, decl *declInfo) { 325 assert(obj.typ == nil) 326 327 // func declarations cannot use iota 328 assert(check.iota == nil) 329 330 sig := new(Signature) 331 obj.typ = sig // guard against cycles 332 fdecl := decl.fdecl 333 check.funcType(sig, fdecl.Recv, fdecl.Type) 334 if sig.recv == nil && obj.name == "init" && (sig.params.Len() > 0 || sig.results.Len() > 0) { 335 check.errorf(fdecl.Pos(), "func init must have no arguments and no return values") 336 // ok to continue 337 } 338 339 // function body must be type-checked after global declarations 340 // (functions implemented elsewhere have no body) 341 if !check.conf.IgnoreFuncBodies && fdecl.Body != nil { 342 check.later(obj.name, decl, sig, fdecl.Body) 343 } 344 } 345 346 func (check *Checker) declStmt(decl ast.Decl) { 347 pkg := check.pkg 348 349 switch d := decl.(type) { 350 case *ast.BadDecl: 351 // ignore 352 353 case *ast.GenDecl: 354 var last *ast.ValueSpec // last ValueSpec with type or init exprs seen 355 for iota, spec := range d.Specs { 356 switch s := spec.(type) { 357 case *ast.ValueSpec: 358 switch d.Tok { 359 case token.CONST: 360 // determine which init exprs to use 361 switch { 362 case s.Type != nil || len(s.Values) > 0: 363 last = s 364 case last == nil: 365 last = new(ast.ValueSpec) // make sure last exists 366 } 367 368 // declare all constants 369 lhs := make([]*Const, len(s.Names)) 370 for i, name := range s.Names { 371 obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota))) 372 lhs[i] = obj 373 374 var init ast.Expr 375 if i < len(last.Values) { 376 init = last.Values[i] 377 } 378 379 check.constDecl(obj, last.Type, init) 380 } 381 382 check.arityMatch(s, last) 383 384 // spec: "The scope of a constant or variable identifier declared 385 // inside a function begins at the end of the ConstSpec or VarSpec 386 // (ShortVarDecl for short variable declarations) and ends at the 387 // end of the innermost containing block." 388 scopePos := s.End() 389 for i, name := range s.Names { 390 check.declare(check.scope, name, lhs[i], scopePos) 391 } 392 393 case token.VAR: 394 lhs0 := make([]*Var, len(s.Names)) 395 for i, name := range s.Names { 396 lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil) 397 } 398 399 // initialize all variables 400 for i, obj := range lhs0 { 401 var lhs []*Var 402 var init ast.Expr 403 switch len(s.Values) { 404 case len(s.Names): 405 // lhs and rhs match 406 init = s.Values[i] 407 case 1: 408 // rhs is expected to be a multi-valued expression 409 lhs = lhs0 410 init = s.Values[0] 411 default: 412 if i < len(s.Values) { 413 init = s.Values[i] 414 } 415 } 416 check.varDecl(obj, lhs, s.Type, init) 417 if len(s.Values) == 1 { 418 // If we have a single lhs variable we are done either way. 419 // If we have a single rhs expression, it must be a multi- 420 // valued expression, in which case handling the first lhs 421 // variable will cause all lhs variables to have a type 422 // assigned, and we are done as well. 423 if debug { 424 for _, obj := range lhs0 { 425 assert(obj.typ != nil) 426 } 427 } 428 break 429 } 430 } 431 432 check.arityMatch(s, nil) 433 434 // declare all variables 435 // (only at this point are the variable scopes (parents) set) 436 scopePos := s.End() // see constant declarations 437 for i, name := range s.Names { 438 // see constant declarations 439 check.declare(check.scope, name, lhs0[i], scopePos) 440 } 441 442 default: 443 check.invalidAST(s.Pos(), "invalid token %s", d.Tok) 444 } 445 446 case *ast.TypeSpec: 447 obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil) 448 // spec: "The scope of a type identifier declared inside a function 449 // begins at the identifier in the TypeSpec and ends at the end of 450 // the innermost containing block." 451 scopePos := s.Name.Pos() 452 check.declare(check.scope, s.Name, obj, scopePos) 453 check.typeDecl(obj, s.Type, nil, nil, s.Assign.IsValid()) 454 455 default: 456 check.invalidAST(s.Pos(), "const, type, or var declaration expected") 457 } 458 } 459 460 default: 461 check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d) 462 } 463 }