/** * Called after top level methods (and other items) have been moved from entries to * ruleInstanceList. Task now is to scan ruleInstanceList looking for MethodEntry objects with * dependent (related, extracted) methods. Move these from the entries list to the correct place * in the ruleInstanceList list. * * @param entries Remaining (unarranged) items, including all dependent (extracted) methods. * @param ruleInstance Rule containing parents (callers) of potentially related methods */ public static void rearrangeRelatedItems( List<ClassContentsEntry> entries, RuleInstance ruleInstance, RelatedMethodsSettings rms) { List<RangeEntry> parentEntries = new ArrayList<RangeEntry>(ruleInstance.getMatches()); for (RangeEntry o : parentEntries) { if (o instanceof RelatableEntry) { MethodEntry me = (MethodEntry) o; if (me.isGetter()) { if (me.myKeptWithProperty) { if (me.getMatchedRule() != null && me.getMatchedRule().getMatches() != null) { // prevent the getter from appearing under a rule it matches; it will be placed under // the property me.getMatchedRule().getMatches().remove(me); } } for (MethodEntry theSetter : me.myCorrespondingGetterSetters) { final RuleInstance theRule = theSetter.getMatchedRule(); LOG.debug( "rearrangeRelatedItems: for getter method " + me + ", corresponding setter is " + theSetter); if (theRule != null && theRule.getMatches() != null) { LOG.debug( "remove entry " + theSetter.myEnd + " from matched rule" + theRule + "; matches = " + ((java.util.List) theRule.getMatches()) == null ? "null" : ""); theRule.getMatches().remove(theSetter); } } } if (me.myCalledMethods.size() > 0) { List<MethodEntry> parents = new LinkedList<MethodEntry>(); parents.add(me); moveRelatedItems( entries, parents, rms, ((PsiMethod) me.myEnd).getName(), ((PsiMethod) me.myEnd).getName() + "()", 1); if (LOG.isDebugEnabled()) { // dump sorted children recursively me.dumpChild(0); } me.assignComments(rms); } } } }
/** * Move methods related to this one underneath it (beginning at the index specified.) Do so in * depth-first or breadth-first order, as configured. At each level, do alphabetical, original * order, or call order sorting. * * @param entries list of global (all rule) unmatched items including dependent methods * @param parents contains a list of items to be handled; order is depth or breadth-first. */ private static void moveRelatedItems( List<ClassContentsEntry> entries, List<MethodEntry> parents, RelatedMethodsSettings rms, String topLevelMethodName, String allMethodNames, int level) { allMethodNames = buildAllMethodNamesString(allMethodNames, parents); /** First, identify all dependent methods. Move them to parents in the specified order. */ List<MethodEntry> children = ((MethodEntry) parents.get(parents.size() - 1)).sortedMethods; // if (rms.isDepthFirstOrdering()) // { switch (rms.getOrdering()) { case RelatedMethodsSettings.RETAIN_ORIGINAL_ORDER: { /** * iterate through entries looking for those that are called by method(s) in the set of * parent methods. Add these to the list of children in order seen in entries. */ ListIterator li = entries.listIterator(); while (li.hasNext()) { Object o = li.next(); if (o instanceof RelatableEntry) { MethodEntry me = (MethodEntry) o; for (MethodEntry entry : parents) { if (me.myCalledByMethods.contains(entry)) { children.add(me); li.remove(); break; } } } } } break; case RelatedMethodsSettings.ALPHABETICAL_ORDER: { /** * iterate through entries looking for those that are called by method(s) in the set of * parent methods. Add these to the list of children alphabetically. */ ListIterator li = entries.listIterator(); while (li.hasNext()) { Object o = li.next(); if (o instanceof RelatableEntry) { MethodEntry me = (MethodEntry) o; for (MethodEntry entry : parents) { if (me.myCalledByMethods.contains(entry)) { me.insertAlphabetically(children); li.remove(); break; } } } } } break; case RelatedMethodsSettings.INVOCATION_ORDER: /** * iterate through calling methods, looking for remaining unmatched methods (in 'entries' * list). Add these to the list of children in order of invocation. */ for (MethodEntry me : parents) { for (MethodEntry child : me.myCalledMethods) { if (entries.contains(child)) { children.add(child); entries.remove(child); } } } break; } /** * now children contains all the children of the parents for this level, and all these children * have been removed from "entries". Move these to the rearranged list. Then: If depth-first, * recurse setting the parent list to each of the children in turn. If breadth first, recurse * setting the parent list to all of the children. */ if (children.size() > 0) { if (rms.isDepthFirstOrdering()) { for (MethodEntry entry : children) { if (entry.myCalledMethods.size() == 0) { continue; } List<MethodEntry> parent = new LinkedList<MethodEntry>(); parent.add(entry); moveRelatedItems( entries, parent, rms, topLevelMethodName, allMethodNames + "." + ((PsiMethod) entry.myEnd).getName() + "()", level + 1); } } else { moveRelatedItems( entries, children, rms, topLevelMethodName, allMethodNames + ".Depth " + level, level + 1); } } }