RelString returns the full name of this function, qualified by package name, receiver type, etc. The specific formatting rules are not guaranteed and may change. Examples: "math.IsNaN" // a package-level function "(*bytes.Buffer).Bytes" // a declared method or a wrapper "(*b
(from *Package)
| 465 | // that case, the strings are equal but the identifiers "f" are distinct.) |
| 466 | // |
| 467 | func (f *Function) RelString(from *Package) string { |
| 468 | // Anonymous? |
| 469 | if f.parent != nil { |
| 470 | // An anonymous function's Name() looks like "parentName$1", |
| 471 | // but its String() should include the type/package/etc. |
| 472 | parent := f.parent.RelString(from) |
| 473 | for i, anon := range f.parent.AnonFuncs { |
| 474 | if anon == f { |
| 475 | return fmt.Sprintf("%s$%d", parent, 1+i) |
| 476 | } |
| 477 | } |
| 478 | |
| 479 | return f.name // should never happen |
| 480 | } |
| 481 | |
| 482 | // Method (declared or wrapper)? |
| 483 | if recv := f.Signature.Recv(); recv != nil { |
| 484 | return f.relMethod(from, recv.Type()) |
| 485 | } |
| 486 | |
| 487 | // Thunk? |
| 488 | if f.wrapperRecvType != nil { |
| 489 | return f.relMethod(from, f.wrapperRecvType) |
| 490 | } |
| 491 | |
| 492 | // Bound? |
| 493 | if len(f.FreeVars) == 1 && strings.HasSuffix(f.name, "$bound") { |
| 494 | return f.relMethod(from, f.FreeVars[0].Type()) |
| 495 | } |
| 496 | |
| 497 | // Package-level function? |
| 498 | // Prefix with package name for cross-package references only. |
| 499 | if p := f.pkg(); p != nil && p != from { |
| 500 | return fmt.Sprintf("%s.%s", p.Path(), f.name) |
| 501 | } |
| 502 | |
| 503 | // Unknown. |
| 504 | return f.name |
| 505 | } |
| 506 | |
| 507 | func (f *Function) relMethod(from *Package, recv Type) string { |
| 508 | return fmt.Sprintf("(%s).%s", relType(recv, from), f.name) |