/** * Removes a method overridden by the given method, if present. In order to remain backwards * compatible with prior Guice versions, this will *not* remove overridden methods if * 'alwaysRemove' is false and the overridden signature was annotated with a * com.google.inject.Inject. * * @param method The method used to determine what is overridden and should be removed. * @param alwaysRemove true if overridden methods should be removed even if they were * guice @Inject * @param injectableMethod if this method overrode any guice @Inject methods, {@link * InjectableMethod#overrodeGuiceInject} is set to true */ boolean removeIfOverriddenBy( Method method, boolean alwaysRemove, InjectableMethod injectableMethod) { if (position == Position.TOP) { // If we're at the top of the hierarchy, there's nothing to override. return false; } if (bySignature == null) { // We encountered a method in a subclass. Time to index the // methods in the parent class. bySignature = new HashMap<Signature, List<InjectableMethod>>(); for (InjectableMember member = injectableMembers.head; member != null; member = member.next) { if (!(member instanceof InjectableMethod)) continue; InjectableMethod im = (InjectableMethod) member; if (im.isFinal()) continue; List<InjectableMethod> methods = new ArrayList<InjectableMethod>(); methods.add(im); bySignature.put(new Signature(im.method), methods); } } lastMethod = method; Signature signature = lastSignature = new Signature(method); List<InjectableMethod> methods = bySignature.get(signature); boolean removed = false; if (methods != null) { for (Iterator<InjectableMethod> iterator = methods.iterator(); iterator.hasNext(); ) { InjectableMethod possiblyOverridden = iterator.next(); if (overrides(method, possiblyOverridden.method)) { boolean wasGuiceInject = !possiblyOverridden.jsr330 || possiblyOverridden.overrodeGuiceInject; if (injectableMethod != null) { injectableMethod.overrodeGuiceInject = wasGuiceInject; } // Only actually remove the methods if we want to force // remove or if the signature never specified @com.google.inject.Inject // somewhere. if (alwaysRemove || !wasGuiceInject) { removed = true; iterator.remove(); injectableMembers.remove(possiblyOverridden); } } } } return removed; }
/** * Adds the given method to the list of injection points. Keeps track of it in this index in * case it gets overridden. */ void add(InjectableMethod injectableMethod) { injectableMembers.add(injectableMethod); if (position == Position.BOTTOM || injectableMethod.isFinal()) { // This method can't be overridden, so there's no need to index it. return; } if (bySignature != null) { // Try to reuse the signature we created during removal Signature signature = injectableMethod.method == lastMethod ? lastSignature : new Signature(injectableMethod.method); List<InjectableMethod> methods = bySignature.get(signature); if (methods == null) { methods = new ArrayList<InjectableMethod>(); bySignature.put(signature, methods); } methods.add(injectableMethod); } }