String memberName) {
// TODO (jwren) create a public version of this method which doesn't require the initial chain
// to be provided, then provided tests for this functionality in InheritanceManagerTest
chain.add(currentType);
ClassElement classElt = currentType.getElement();
InterfaceType supertype = classElt.getSupertype();
// Base case- reached Object
if (supertype == null) {
// Looked up the chain all the way to Object, return null.
// This should never happen.
return;
}
// If we are done, return the chain
// We are not done if this is the first recursive call on this method.
if (chain.size() != 1) {
// We are done however if the member is in this classElt
if (lookupMemberInClass(classElt, memberName) != null) {
return;
}
}
// Otherwise, determine the next type (up the inheritance graph) to search for our member, start
// with the mixins, followed by the superclass, and finally the interfaces:
// Mixins- note that mixins call lookupMemberInClass, not lookupMember
InterfaceType[] mixins = classElt.getMixins();
for (int i = mixins.length - 1; i >= 0; i--) {
ClassElement mixinElement = mixins[i].getElement();
if (mixinElement != null) {
ExecutableElement elt = lookupMemberInClass(mixinElement, memberName);
if (elt != null) {
// this is equivalent (but faster than) calling this method recursively
// (return computeInheritancePath(chain, mixins[i], memberName);)
chain.add(mixins[i]);
return;
}
}
}
// Superclass
ClassElement superclassElt = supertype.getElement();
if (lookupMember(superclassElt, memberName) != null) {
computeInheritancePath(chain, supertype, memberName);
return;
}