// LookupFieldOrMethod looks up a field or method with given package and name // in T and returns the corresponding *Var or *Func, an index sequence, and a // bool indicating if there were any pointer indirections on the path to the // field or method. If addressable is set, T is the type of an addressable // variable (only matters for method lookups). T must not be nil. // // The last index entry is the field or method index in the (possibly embedded) // type where the entry was found, either: // // 1. the list of declared methods of a named type; or // 2. the list of all methods (method set) of an interface type; or // 3. the list of fields of a struct type. // // The earlier index entries are the indices of the embedded struct fields // traversed to get to the found entry, starting at depth 0. // // If no entry is found, a nil object is returned. In this case, the returned // index and indirect values have the following meaning: // // - If index != nil, the index sequence points to an ambiguous entry // (the same name appeared more than once at the same embedding level). // // - If indirect is set, a method with a pointer receiver type was found // but there was no pointer on the path from the actual receiver type to // the method's formal receiver base type, nor was the receiver addressable. func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) { … } // lookupFieldOrMethod is like LookupFieldOrMethod but with the additional foldCase parameter // (see Object.sameId for the meaning of foldCase). func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string, foldCase bool) (obj Object, index []int, indirect bool) { … } // lookupFieldOrMethodImpl is the implementation of lookupFieldOrMethod. // Notably, in contrast to lookupFieldOrMethod, it won't find struct fields // in base types of defined (*Named) pointer types T. For instance, given // the declaration: // // type T *struct{f int} // // lookupFieldOrMethodImpl won't find the field f in the defined (*Named) type T // (methods on T are not permitted in the first place). // // Thus, lookupFieldOrMethodImpl should only be called by lookupFieldOrMethod // and missingMethod (the latter doesn't care about struct fields). // // The resulting object may not be fully type-checked. func lookupFieldOrMethodImpl(T Type, addressable bool, pkg *Package, name string, foldCase bool) (obj Object, index []int, indirect bool) { … } type embeddedType … // consolidateMultiples collects multiple list entries with the same type // into a single entry marked as containing multiples. The result is the // consolidated list. func consolidateMultiples(list []embeddedType) []embeddedType { … } func lookupType(m map[Type]int, typ Type) (int, bool) { … } type instanceLookup … func (l *instanceLookup) lookup(inst *Named) *Named { … } func (l *instanceLookup) add(inst *Named) { … } // MissingMethod returns (nil, false) if V implements T, otherwise it // returns a missing method required by T and whether it is missing or // just has the wrong type: either a pointer receiver or wrong signature. // // For non-interface types V, or if static is set, V implements T if all // methods of T are present in V. Otherwise (V is an interface and static // is not set), MissingMethod only checks that methods of T which are also // present in V have matching types (e.g., for a type assertion x.(T) where // x is of interface type V). func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool) { … } // missingMethod is like MissingMethod but accepts a *Checker as receiver, // a comparator equivalent for type comparison, and a *string for error causes. // The receiver may be nil if missingMethod is invoked through an exported // API call (such as MissingMethod), i.e., when all methods have been type- // checked. // The underlying type of T must be an interface; T (rather than its under- // lying type) is used for better error messages (reported through *cause). // The comparator is used to compare signatures. // If a method is missing and cause is not nil, *cause describes the error. func (check *Checker) missingMethod(V, T Type, static bool, equivalent func(x, y Type) bool, cause *string) (method *Func, wrongType bool) { … } func isInterfacePtr(T Type) bool { … } // check may be nil. func (check *Checker) interfacePtrError(T Type) string { … } // funcString returns a string of the form name + signature for f. // check may be nil. func (check *Checker) funcString(f *Func, pkgInfo bool) string { … } // assertableTo reports whether a value of type V can be asserted to have type T. // The receiver may be nil if assertableTo is invoked through an exported API call // (such as AssertableTo), i.e., when all methods have been type-checked. // The underlying type of V must be an interface. // If the result is false and cause is not nil, *cause describes the error. // TODO(gri) replace calls to this function with calls to newAssertableTo. func (check *Checker) assertableTo(V, T Type, cause *string) bool { … } // newAssertableTo reports whether a value of type V can be asserted to have type T. // It also implements behavior for interfaces that currently are only permitted // in constraint position (we have not yet defined that behavior in the spec). // The underlying type of V must be an interface. // If the result is false and cause is not nil, *cause is set to the error cause. func (check *Checker) newAssertableTo(V, T Type, cause *string) bool { … } // deref dereferences typ if it is a *Pointer (but not a *Named type // with an underlying pointer type!) and returns its base and true. // Otherwise it returns (typ, false). func deref(typ Type) (Type, bool) { … } // derefStructPtr dereferences typ if it is a (named or unnamed) pointer to a // (named or unnamed) struct and returns its base. Otherwise it returns typ. func derefStructPtr(typ Type) Type { … } // concat returns the result of concatenating list and i. // The result does not share its underlying array with list. func concat(list []int, i int) []int { … } // fieldIndex returns the index for the field with matching package and name, or a value < 0. // See Object.sameId for the meaning of foldCase. func fieldIndex(fields []*Var, pkg *Package, name string, foldCase bool) int { … } // methodIndex returns the index of and method with matching package and name, or (-1, nil). // See Object.sameId for the meaning of foldCase. func methodIndex(methods []*Func, pkg *Package, name string, foldCase bool) (int, *Func) { … }