public static Declaration getRefinedDeclaration(Declaration declaration) { // Reproduces the algorithm used to build the type hierarchy // first walk up the superclass hierarchy if (declaration.isClassOrInterfaceMember() && declaration.isShared()) { TypeDeclaration dec = (TypeDeclaration) declaration.getContainer(); List<Type> signature = getSignature(declaration); Declaration refined = declaration.getRefinedDeclaration(); while (dec != null) { Type extended = dec.getExtendedType(); if (extended != null) { TypeDeclaration superDec = extended.getDeclaration(); Declaration superMemberDec = superDec.getDirectMember(declaration.getName(), signature, false); if (superMemberDec != null) { Declaration superRefined = superMemberDec.getRefinedDeclaration(); if (superRefined != null && refined != null && !isAbstraction(superMemberDec) && superRefined.equals(refined)) { return superMemberDec; } } dec = superDec; } else { dec = null; } } // now look at the very top of the hierarchy, even if it is an interface Declaration refinedDeclaration = refined; if (refinedDeclaration != null && !declaration.equals(refinedDeclaration)) { List<Declaration> directlyInheritedMembers = getInterveningRefinements( declaration.getName(), signature, refinedDeclaration, (TypeDeclaration) declaration.getContainer(), (TypeDeclaration) refinedDeclaration.getContainer()); directlyInheritedMembers.remove(refinedDeclaration); // TODO: do something for the case of // multiple intervening interfaces? if (directlyInheritedMembers.size() == 1) { // exactly one intervening interface return directlyInheritedMembers.get(0); } else { // no intervening interfaces return refinedDeclaration; } } } return null; }
/** * See #547 - a generic actual method that has different names in its type parameters as the one * it's refining, can receive the type arguments of the parent instead. */ static void addParentMethodTypeParameters(final Function m, final GenerateJsVisitor gen) { List<TypeParameter> tps = m.getTypeParameters(); if (m.isActual() && tps != null && !tps.isEmpty()) { // This gives us the root declaration Function sm = (Function) m.getRefinedDeclaration(); for (int i = 0; i < tps.size(); i++) { boolean end = false; end |= copyMissingTypeParameters(m, sm, i, true, gen); // We still need to find intermediate declarations if (m.isClassOrInterfaceMember()) { final Set<Declaration> decs = new HashSet<Declaration>(); decs.add(sm); decs.add(m); // This gives us the containing type TypeDeclaration cont = ModelUtil.getContainingClassOrInterface(m); for (TypeDeclaration sup : cont.getSupertypeDeclarations()) { Declaration d = sup.getDirectMember(m.getName(), null, false); if (d instanceof Function && !decs.contains(d)) { decs.add(d); end |= copyMissingTypeParameters(m, (Function) d, i, false, gen); } } for (Type sup : cont.getSatisfiedTypes()) { Declaration d = sup.getDeclaration().getDirectMember(m.getName(), null, false); if (d instanceof Function && !decs.contains(d)) { decs.add(d); end |= copyMissingTypeParameters(m, (Function) d, i, false, gen); } } } if (end) { gen.endLine(true); } } } }