github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/refactor/satisfy/find14.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 // +build !go1.5 6 7 // Package satisfy inspects the type-checked ASTs of Go packages and 8 // reports the set of discovered type constraints of the form (lhs, rhs 9 // Type) where lhs is a non-trivial interface, rhs satisfies this 10 // interface, and this fact is necessary for the package to be 11 // well-typed. 12 // 13 // THIS PACKAGE IS EXPERIMENTAL AND MAY CHANGE AT ANY TIME. 14 // 15 // It is provided only for the gorename tool. Ideally this 16 // functionality will become part of the type-checker in due course, 17 // since it is computing it anyway, and it is robust for ill-typed 18 // inputs, which this package is not. 19 // 20 package satisfy // import "golang.org/x/tools/refactor/satisfy" 21 22 // NOTES: 23 // 24 // We don't care about numeric conversions, so we don't descend into 25 // types or constant expressions. This is unsound because 26 // constant expressions can contain arbitrary statements, e.g. 27 // const x = len([1]func(){func() { 28 // ... 29 // }}) 30 // 31 // TODO(adonovan): make this robust against ill-typed input. 32 // Or move it into the type-checker. 33 // 34 // Assignability conversions are possible in the following places: 35 // - in assignments y = x, y := x, var y = x. 36 // - from call argument types to formal parameter types 37 // - in append and delete calls 38 // - from return operands to result parameter types 39 // - in composite literal T{k:v}, from k and v to T's field/element/key type 40 // - in map[key] from key to the map's key type 41 // - in comparisons x==y and switch x { case y: }. 42 // - in explicit conversions T(x) 43 // - in sends ch <- x, from x to the channel element type 44 // - in type assertions x.(T) and switch x.(type) { case T: } 45 // 46 // The results of this pass provide information equivalent to the 47 // ssa.MakeInterface and ssa.ChangeInterface instructions. 48 49 import ( 50 "fmt" 51 "go/ast" 52 "go/token" 53 54 "golang.org/x/tools/go/ast/astutil" 55 "golang.org/x/tools/go/types" 56 "golang.org/x/tools/go/types/typeutil" 57 ) 58 59 // A Constraint records the fact that the RHS type does and must 60 // satisify the LHS type, which is an interface. 61 // The names are suggestive of an assignment statement LHS = RHS. 62 type Constraint struct { 63 LHS, RHS types.Type 64 } 65 66 // A Finder inspects the type-checked ASTs of Go packages and 67 // accumulates the set of type constraints (x, y) such that x is 68 // assignable to y, y is an interface, and both x and y have methods. 69 // 70 // In other words, it returns the subset of the "implements" relation 71 // that is checked during compilation of a package. Refactoring tools 72 // will need to preserve at least this part of the relation to ensure 73 // continued compilation. 74 // 75 type Finder struct { 76 Result map[Constraint]bool 77 msetcache typeutil.MethodSetCache 78 79 // per-Find state 80 info *types.Info 81 sig *types.Signature 82 } 83 84 // Find inspects a single package, populating Result with its pairs of 85 // constrained types. 86 // 87 // The result is non-canonical and thus may contain duplicates (but this 88 // tends to preserves names of interface types better). 89 // 90 // The package must be free of type errors, and 91 // info.{Defs,Uses,Selections,Types} must have been populated by the 92 // type-checker. 93 // 94 func (f *Finder) Find(info *types.Info, files []*ast.File) { 95 if f.Result == nil { 96 f.Result = make(map[Constraint]bool) 97 } 98 99 f.info = info 100 for _, file := range files { 101 for _, d := range file.Decls { 102 switch d := d.(type) { 103 case *ast.GenDecl: 104 if d.Tok == token.VAR { // ignore consts 105 for _, spec := range d.Specs { 106 f.valueSpec(spec.(*ast.ValueSpec)) 107 } 108 } 109 110 case *ast.FuncDecl: 111 if d.Body != nil { 112 f.sig = f.info.Defs[d.Name].Type().(*types.Signature) 113 f.stmt(d.Body) 114 f.sig = nil 115 } 116 } 117 } 118 } 119 f.info = nil 120 } 121 122 var ( 123 tInvalid = types.Typ[types.Invalid] 124 tUntypedBool = types.Typ[types.UntypedBool] 125 tUntypedNil = types.Typ[types.UntypedNil] 126 ) 127 128 // exprN visits an expression in a multi-value context. 129 func (f *Finder) exprN(e ast.Expr) types.Type { 130 typ := f.info.Types[e].Type.(*types.Tuple) 131 switch e := e.(type) { 132 case *ast.ParenExpr: 133 return f.exprN(e.X) 134 135 case *ast.CallExpr: 136 // x, err := f(args) 137 sig := f.expr(e.Fun).Underlying().(*types.Signature) 138 f.call(sig, e.Args) 139 140 case *ast.IndexExpr: 141 // y, ok := x[i] 142 x := f.expr(e.X) 143 f.assign(f.expr(e.Index), x.Underlying().(*types.Map).Key()) 144 145 case *ast.TypeAssertExpr: 146 // y, ok := x.(T) 147 f.typeAssert(f.expr(e.X), typ.At(0).Type()) 148 149 case *ast.UnaryExpr: // must be receive <- 150 // y, ok := <-x 151 f.expr(e.X) 152 153 default: 154 panic(e) 155 } 156 return typ 157 } 158 159 func (f *Finder) call(sig *types.Signature, args []ast.Expr) { 160 if len(args) == 0 { 161 return 162 } 163 164 // Ellipsis call? e.g. f(x, y, z...) 165 if _, ok := args[len(args)-1].(*ast.Ellipsis); ok { 166 for i, arg := range args { 167 // The final arg is a slice, and so is the final param. 168 f.assign(sig.Params().At(i).Type(), f.expr(arg)) 169 } 170 return 171 } 172 173 var argtypes []types.Type 174 175 // Gather the effective actual parameter types. 176 if tuple, ok := f.info.Types[args[0]].Type.(*types.Tuple); ok { 177 // f(g()) call where g has multiple results? 178 f.expr(args[0]) 179 // unpack the tuple 180 for i := 0; i < tuple.Len(); i++ { 181 argtypes = append(argtypes, tuple.At(i).Type()) 182 } 183 } else { 184 for _, arg := range args { 185 argtypes = append(argtypes, f.expr(arg)) 186 } 187 } 188 189 // Assign the actuals to the formals. 190 if !sig.Variadic() { 191 for i, argtype := range argtypes { 192 f.assign(sig.Params().At(i).Type(), argtype) 193 } 194 } else { 195 // The first n-1 parameters are assigned normally. 196 nnormals := sig.Params().Len() - 1 197 for i, argtype := range argtypes[:nnormals] { 198 f.assign(sig.Params().At(i).Type(), argtype) 199 } 200 // Remaining args are assigned to elements of varargs slice. 201 tElem := sig.Params().At(nnormals).Type().(*types.Slice).Elem() 202 for i := nnormals; i < len(argtypes); i++ { 203 f.assign(tElem, argtypes[i]) 204 } 205 } 206 } 207 208 func (f *Finder) builtin(obj *types.Builtin, sig *types.Signature, args []ast.Expr, T types.Type) types.Type { 209 switch obj.Name() { 210 case "make", "new": 211 // skip the type operand 212 for _, arg := range args[1:] { 213 f.expr(arg) 214 } 215 216 case "append": 217 s := f.expr(args[0]) 218 if _, ok := args[len(args)-1].(*ast.Ellipsis); ok && len(args) == 2 { 219 // append(x, y...) including append([]byte, "foo"...) 220 f.expr(args[1]) 221 } else { 222 // append(x, y, z) 223 tElem := s.Underlying().(*types.Slice).Elem() 224 for _, arg := range args[1:] { 225 f.assign(tElem, f.expr(arg)) 226 } 227 } 228 229 case "delete": 230 m := f.expr(args[0]) 231 k := f.expr(args[1]) 232 f.assign(m.Underlying().(*types.Map).Key(), k) 233 234 default: 235 // ordinary call 236 f.call(sig, args) 237 } 238 239 return T 240 } 241 242 func (f *Finder) extract(tuple types.Type, i int) types.Type { 243 if tuple, ok := tuple.(*types.Tuple); ok && i < tuple.Len() { 244 return tuple.At(i).Type() 245 } 246 return tInvalid 247 } 248 249 func (f *Finder) valueSpec(spec *ast.ValueSpec) { 250 var T types.Type 251 if spec.Type != nil { 252 T = f.info.Types[spec.Type].Type 253 } 254 switch len(spec.Values) { 255 case len(spec.Names): // e.g. var x, y = f(), g() 256 for _, value := range spec.Values { 257 v := f.expr(value) 258 if T != nil { 259 f.assign(T, v) 260 } 261 } 262 263 case 1: // e.g. var x, y = f() 264 tuple := f.exprN(spec.Values[0]) 265 for i := range spec.Names { 266 if T != nil { 267 f.assign(T, f.extract(tuple, i)) 268 } 269 } 270 } 271 } 272 273 // assign records pairs of distinct types that are related by 274 // assignability, where the left-hand side is an interface and both 275 // sides have methods. 276 // 277 // It should be called for all assignability checks, type assertions, 278 // explicit conversions and comparisons between two types, unless the 279 // types are uninteresting (e.g. lhs is a concrete type, or the empty 280 // interface; rhs has no methods). 281 // 282 func (f *Finder) assign(lhs, rhs types.Type) { 283 if types.Identical(lhs, rhs) { 284 return 285 } 286 if !isInterface(lhs) { 287 return 288 } 289 290 if f.msetcache.MethodSet(lhs).Len() == 0 { 291 return 292 } 293 if f.msetcache.MethodSet(rhs).Len() == 0 { 294 return 295 } 296 // record the pair 297 f.Result[Constraint{lhs, rhs}] = true 298 } 299 300 // typeAssert must be called for each type assertion x.(T) where x has 301 // interface type I. 302 func (f *Finder) typeAssert(I, T types.Type) { 303 // Type assertions are slightly subtle, because they are allowed 304 // to be "impossible", e.g. 305 // 306 // var x interface{f()} 307 // _ = x.(interface{f()int}) // legal 308 // 309 // (In hindsight, the language spec should probably not have 310 // allowed this, but it's too late to fix now.) 311 // 312 // This means that a type assert from I to T isn't exactly a 313 // constraint that T is assignable to I, but for a refactoring 314 // tool it is a conditional constraint that, if T is assignable 315 // to I before a refactoring, it should remain so after. 316 317 if types.AssignableTo(T, I) { 318 f.assign(I, T) 319 } 320 } 321 322 // compare must be called for each comparison x==y. 323 func (f *Finder) compare(x, y types.Type) { 324 if types.AssignableTo(x, y) { 325 f.assign(y, x) 326 } else if types.AssignableTo(y, x) { 327 f.assign(x, y) 328 } 329 } 330 331 // expr visits a true expression (not a type or defining ident) 332 // and returns its type. 333 func (f *Finder) expr(e ast.Expr) types.Type { 334 tv := f.info.Types[e] 335 if tv.Value != nil { 336 return tv.Type // prune the descent for constants 337 } 338 339 // tv.Type may be nil for an ast.Ident. 340 341 switch e := e.(type) { 342 case *ast.BadExpr, *ast.BasicLit: 343 // no-op 344 345 case *ast.Ident: 346 // (referring idents only) 347 if obj, ok := f.info.Uses[e]; ok { 348 return obj.Type() 349 } 350 if e.Name == "_" { // e.g. "for _ = range x" 351 return tInvalid 352 } 353 panic("undefined ident: " + e.Name) 354 355 case *ast.Ellipsis: 356 if e.Elt != nil { 357 f.expr(e.Elt) 358 } 359 360 case *ast.FuncLit: 361 saved := f.sig 362 f.sig = tv.Type.(*types.Signature) 363 f.stmt(e.Body) 364 f.sig = saved 365 366 case *ast.CompositeLit: 367 switch T := deref(tv.Type).Underlying().(type) { 368 case *types.Struct: 369 for i, elem := range e.Elts { 370 if kv, ok := elem.(*ast.KeyValueExpr); ok { 371 f.assign(f.info.Uses[kv.Key.(*ast.Ident)].Type(), f.expr(kv.Value)) 372 } else { 373 f.assign(T.Field(i).Type(), f.expr(elem)) 374 } 375 } 376 377 case *types.Map: 378 for _, elem := range e.Elts { 379 elem := elem.(*ast.KeyValueExpr) 380 f.assign(T.Key(), f.expr(elem.Key)) 381 f.assign(T.Elem(), f.expr(elem.Value)) 382 } 383 384 case *types.Array, *types.Slice: 385 tElem := T.(interface { 386 Elem() types.Type 387 }).Elem() 388 for _, elem := range e.Elts { 389 if kv, ok := elem.(*ast.KeyValueExpr); ok { 390 // ignore the key 391 f.assign(tElem, f.expr(kv.Value)) 392 } else { 393 f.assign(tElem, f.expr(elem)) 394 } 395 } 396 397 default: 398 panic("unexpected composite literal type: " + tv.Type.String()) 399 } 400 401 case *ast.ParenExpr: 402 f.expr(e.X) 403 404 case *ast.SelectorExpr: 405 if _, ok := f.info.Selections[e]; ok { 406 f.expr(e.X) // selection 407 } else { 408 return f.info.Uses[e.Sel].Type() // qualified identifier 409 } 410 411 case *ast.IndexExpr: 412 x := f.expr(e.X) 413 i := f.expr(e.Index) 414 if ux, ok := x.Underlying().(*types.Map); ok { 415 f.assign(ux.Key(), i) 416 } 417 418 case *ast.SliceExpr: 419 f.expr(e.X) 420 if e.Low != nil { 421 f.expr(e.Low) 422 } 423 if e.High != nil { 424 f.expr(e.High) 425 } 426 if e.Max != nil { 427 f.expr(e.Max) 428 } 429 430 case *ast.TypeAssertExpr: 431 x := f.expr(e.X) 432 f.typeAssert(x, f.info.Types[e.Type].Type) 433 434 case *ast.CallExpr: 435 if tvFun := f.info.Types[e.Fun]; tvFun.IsType() { 436 // conversion 437 arg0 := f.expr(e.Args[0]) 438 f.assign(tvFun.Type, arg0) 439 } else { 440 // function call 441 if id, ok := unparen(e.Fun).(*ast.Ident); ok { 442 if obj, ok := f.info.Uses[id].(*types.Builtin); ok { 443 sig := f.info.Types[id].Type.(*types.Signature) 444 return f.builtin(obj, sig, e.Args, tv.Type) 445 } 446 } 447 // ordinary call 448 f.call(f.expr(e.Fun).Underlying().(*types.Signature), e.Args) 449 } 450 451 case *ast.StarExpr: 452 f.expr(e.X) 453 454 case *ast.UnaryExpr: 455 f.expr(e.X) 456 457 case *ast.BinaryExpr: 458 x := f.expr(e.X) 459 y := f.expr(e.Y) 460 if e.Op == token.EQL || e.Op == token.NEQ { 461 f.compare(x, y) 462 } 463 464 case *ast.KeyValueExpr: 465 f.expr(e.Key) 466 f.expr(e.Value) 467 468 case *ast.ArrayType, 469 *ast.StructType, 470 *ast.FuncType, 471 *ast.InterfaceType, 472 *ast.MapType, 473 *ast.ChanType: 474 panic(e) 475 } 476 477 if tv.Type == nil { 478 panic(fmt.Sprintf("no type for %T", e)) 479 } 480 481 return tv.Type 482 } 483 484 func (f *Finder) stmt(s ast.Stmt) { 485 switch s := s.(type) { 486 case *ast.BadStmt, 487 *ast.EmptyStmt, 488 *ast.BranchStmt: 489 // no-op 490 491 case *ast.DeclStmt: 492 d := s.Decl.(*ast.GenDecl) 493 if d.Tok == token.VAR { // ignore consts 494 for _, spec := range d.Specs { 495 f.valueSpec(spec.(*ast.ValueSpec)) 496 } 497 } 498 499 case *ast.LabeledStmt: 500 f.stmt(s.Stmt) 501 502 case *ast.ExprStmt: 503 f.expr(s.X) 504 505 case *ast.SendStmt: 506 ch := f.expr(s.Chan) 507 val := f.expr(s.Value) 508 f.assign(ch.Underlying().(*types.Chan).Elem(), val) 509 510 case *ast.IncDecStmt: 511 f.expr(s.X) 512 513 case *ast.AssignStmt: 514 switch s.Tok { 515 case token.ASSIGN, token.DEFINE: 516 // y := x or y = x 517 var rhsTuple types.Type 518 if len(s.Lhs) != len(s.Rhs) { 519 rhsTuple = f.exprN(s.Rhs[0]) 520 } 521 for i := range s.Lhs { 522 var lhs, rhs types.Type 523 if rhsTuple == nil { 524 rhs = f.expr(s.Rhs[i]) // 1:1 assignment 525 } else { 526 rhs = f.extract(rhsTuple, i) // n:1 assignment 527 } 528 529 if id, ok := s.Lhs[i].(*ast.Ident); ok { 530 if id.Name != "_" { 531 if obj, ok := f.info.Defs[id]; ok { 532 lhs = obj.Type() // definition 533 } 534 } 535 } 536 if lhs == nil { 537 lhs = f.expr(s.Lhs[i]) // assignment 538 } 539 f.assign(lhs, rhs) 540 } 541 542 default: 543 // y op= x 544 f.expr(s.Lhs[0]) 545 f.expr(s.Rhs[0]) 546 } 547 548 case *ast.GoStmt: 549 f.expr(s.Call) 550 551 case *ast.DeferStmt: 552 f.expr(s.Call) 553 554 case *ast.ReturnStmt: 555 formals := f.sig.Results() 556 switch len(s.Results) { 557 case formals.Len(): // 1:1 558 for i, result := range s.Results { 559 f.assign(formals.At(i).Type(), f.expr(result)) 560 } 561 562 case 1: // n:1 563 tuple := f.exprN(s.Results[0]) 564 for i := 0; i < formals.Len(); i++ { 565 f.assign(formals.At(i).Type(), f.extract(tuple, i)) 566 } 567 } 568 569 case *ast.SelectStmt: 570 f.stmt(s.Body) 571 572 case *ast.BlockStmt: 573 for _, s := range s.List { 574 f.stmt(s) 575 } 576 577 case *ast.IfStmt: 578 if s.Init != nil { 579 f.stmt(s.Init) 580 } 581 f.expr(s.Cond) 582 f.stmt(s.Body) 583 if s.Else != nil { 584 f.stmt(s.Else) 585 } 586 587 case *ast.SwitchStmt: 588 if s.Init != nil { 589 f.stmt(s.Init) 590 } 591 var tag types.Type = tUntypedBool 592 if s.Tag != nil { 593 tag = f.expr(s.Tag) 594 } 595 for _, cc := range s.Body.List { 596 cc := cc.(*ast.CaseClause) 597 for _, cond := range cc.List { 598 f.compare(tag, f.info.Types[cond].Type) 599 } 600 for _, s := range cc.Body { 601 f.stmt(s) 602 } 603 } 604 605 case *ast.TypeSwitchStmt: 606 if s.Init != nil { 607 f.stmt(s.Init) 608 } 609 var I types.Type 610 switch ass := s.Assign.(type) { 611 case *ast.ExprStmt: // x.(type) 612 I = f.expr(unparen(ass.X).(*ast.TypeAssertExpr).X) 613 case *ast.AssignStmt: // y := x.(type) 614 I = f.expr(unparen(ass.Rhs[0]).(*ast.TypeAssertExpr).X) 615 } 616 for _, cc := range s.Body.List { 617 cc := cc.(*ast.CaseClause) 618 for _, cond := range cc.List { 619 tCase := f.info.Types[cond].Type 620 if tCase != tUntypedNil { 621 f.typeAssert(I, tCase) 622 } 623 } 624 for _, s := range cc.Body { 625 f.stmt(s) 626 } 627 } 628 629 case *ast.CommClause: 630 if s.Comm != nil { 631 f.stmt(s.Comm) 632 } 633 for _, s := range s.Body { 634 f.stmt(s) 635 } 636 637 case *ast.ForStmt: 638 if s.Init != nil { 639 f.stmt(s.Init) 640 } 641 if s.Cond != nil { 642 f.expr(s.Cond) 643 } 644 if s.Post != nil { 645 f.stmt(s.Post) 646 } 647 f.stmt(s.Body) 648 649 case *ast.RangeStmt: 650 x := f.expr(s.X) 651 // No conversions are involved when Tok==DEFINE. 652 if s.Tok == token.ASSIGN { 653 if s.Key != nil { 654 k := f.expr(s.Key) 655 var xelem types.Type 656 // keys of array, *array, slice, string aren't interesting 657 switch ux := x.Underlying().(type) { 658 case *types.Chan: 659 xelem = ux.Elem() 660 case *types.Map: 661 xelem = ux.Key() 662 } 663 if xelem != nil { 664 f.assign(xelem, k) 665 } 666 } 667 if s.Value != nil { 668 val := f.expr(s.Value) 669 var xelem types.Type 670 // values of strings aren't interesting 671 switch ux := x.Underlying().(type) { 672 case *types.Array: 673 xelem = ux.Elem() 674 case *types.Chan: 675 xelem = ux.Elem() 676 case *types.Map: 677 xelem = ux.Elem() 678 case *types.Pointer: // *array 679 xelem = deref(ux).(*types.Array).Elem() 680 case *types.Slice: 681 xelem = ux.Elem() 682 } 683 if xelem != nil { 684 f.assign(xelem, val) 685 } 686 } 687 } 688 f.stmt(s.Body) 689 690 default: 691 panic(s) 692 } 693 } 694 695 // -- Plundered from golang.org/x/tools/go/ssa ----------------- 696 697 // deref returns a pointer's element type; otherwise it returns typ. 698 func deref(typ types.Type) types.Type { 699 if p, ok := typ.Underlying().(*types.Pointer); ok { 700 return p.Elem() 701 } 702 return typ 703 } 704 705 func unparen(e ast.Expr) ast.Expr { return astutil.Unparen(e) } 706 707 func isInterface(T types.Type) bool { return types.IsInterface(T) }