@@ -335,13 +335,22 @@ && isAssistedFactoryType(requestKey.type().xprocessing().getTypeElement())) {
335335 requestKey ,
336336 bindings .stream ()
337337 .map (
338- binding ->
339- bindingNodeFactory .forContributionBindings (
340- getOwningComponentPath (requestKey , binding ),
341- binding ,
342- multibindingDeclarations ,
343- optionalBindingDeclarations ,
344- subcomponentDeclarations ))
338+ binding -> {
339+ Optional <BindingNode > bindingNodeOwnedByAncestor =
340+ getBindingNodeOwnedByAncestor (requestKey , binding );
341+ // If a binding is owned by an ancestor we use the corresponding BindingNode
342+ // instance directly rather than creating a new instance to avoid accidentally
343+ // including additional multi/optional/subcomponent declarations that don't
344+ // exist in the ancestor's BindingNode instance.
345+ return bindingNodeOwnedByAncestor .isPresent ()
346+ ? bindingNodeOwnedByAncestor .get ()
347+ : bindingNodeFactory .forContributionBindings (
348+ componentPath ,
349+ binding ,
350+ multibindingDeclarations ,
351+ optionalBindingDeclarations ,
352+ subcomponentDeclarations );
353+ })
345354 .collect (toImmutableSet ()));
346355 }
347356
@@ -443,38 +452,32 @@ private ContributionBinding createDelegateBinding(DelegateDeclaration delegateDe
443452 }
444453
445454 /**
446- * Returns the component that should contain the framework field for {@code binding}.
447- *
448- * <p>If {@code binding} is either not bound in an ancestor component or depends transitively on
449- * bindings in this component, returns this component.
450- *
451- * <p>Otherwise, resolves {@code request} in this component's parent in order to resolve any
452- * multibinding contributions in the parent, and returns the parent-resolved {@link
453- * ResolvedBindings#owningComponent(ContributionBinding)}.
455+ * Returns a {@link BindingNode} for the given binding that is owned by an ancestor component,
456+ * if one exists. Otherwise returns {@link Optional#empty()}.
454457 */
455- private ComponentPath getOwningComponentPath (Key requestKey , ContributionBinding binding ) {
456- if (isResolvedInParent (requestKey , binding ) && !requiresResolution (binding )) {
457- ResolvedBindings parentResolvedBindings =
458- parentResolver .get ().resolvedContributionBindings .get (requestKey );
459- return parentResolvedBindings .forBinding (binding ).componentPath ();
460- } else {
461- return componentPath ;
458+ private Optional <BindingNode > getBindingNodeOwnedByAncestor (
459+ Key requestKey , ContributionBinding binding ) {
460+ if (canBeResolvedInParent (requestKey , binding )) {
461+ // Resolve in the parent to make sure we have the most recent multi/optional contributions.
462+ parentResolver .get ().resolve (requestKey );
463+ if (!requiresResolution (binding )) {
464+ return Optional .of (getPreviouslyResolvedBindings (requestKey ).get ().forBinding (binding ));
465+ }
462466 }
467+ return Optional .empty ();
463468 }
464469
465- /**
466- * Returns {@code true} if {@code binding} is owned by an ancestor. If so, {@linkplain #resolve
467- * resolves} the {@link Key} in this component's parent. Don't resolve directly in the owning
468- * component in case it depends on multibindings in any of its descendants.
469- */
470- private boolean isResolvedInParent (Key requestKey , ContributionBinding binding ) {
471- Optional <Resolver > owningResolver = getOwningResolver (binding );
472- if (owningResolver .isPresent () && !owningResolver .get ().equals (this )) {
473- parentResolver .get ().resolve (requestKey );
474- return true ;
475- } else {
470+ private boolean canBeResolvedInParent (Key requestKey , ContributionBinding binding ) {
471+ if (parentResolver .isEmpty ()) {
476472 return false ;
477473 }
474+ Optional <Resolver > owningResolver = getOwningResolver (binding );
475+ return (owningResolver .isPresent () && !owningResolver .get ().equals (this ))
476+ || (!Keys .isComponentOrCreator (requestKey )
477+ // TODO(b/305748522): Allow caching for assisted injection bindings.
478+ && binding .kind () != BindingKind .ASSISTED_INJECTION
479+ && getPreviouslyResolvedBindings (requestKey ).isPresent ()
480+ && getPreviouslyResolvedBindings (requestKey ).get ().bindings ().contains (binding ));
478481 }
479482
480483 private Optional <Resolver > getOwningResolver (ContributionBinding binding ) {
@@ -647,36 +650,6 @@ void resolve(Key key) {
647650 return ;
648651 }
649652
650- /*
651- * If the binding was previously resolved in an ancestor component, then we may be able to
652- * avoid resolving it here and just depend on the ancestor component resolution.
653- *
654- * 1. If it depends transitively on multibinding contributions or optional bindings with
655- * bindings from this subcomponent, then we have to resolve it in this subcomponent so
656- * that it sees the local bindings.
657- *
658- * 2. If there are any explicit bindings in this component, they may conflict with those in
659- * the ancestor component, so resolve them here so that conflicts can be caught.
660- */
661- if (getPreviouslyResolvedBindings (key ).isPresent () && !Keys .isComponentOrCreator (key )) {
662- /* Resolve in the parent in case there are multibinding contributions or conflicts in some
663- * component between this one and the previously-resolved one. */
664- parentResolver .get ().resolve (key );
665- ResolvedBindings previouslyResolvedBindings = getPreviouslyResolvedBindings (key ).get ();
666- // TODO(b/305748522): Allow caching for assisted injection bindings.
667- boolean isAssistedInjectionBinding =
668- previouslyResolvedBindings .bindings ().stream ()
669- .anyMatch (binding -> binding .kind () == BindingKind .ASSISTED_INJECTION );
670- if (!isAssistedInjectionBinding
671- && !requiresResolution (key )
672- && !hasLocalExplicitBindings (key )) {
673- /* Cache the inherited parent component's bindings in case resolving at the parent found
674- * bindings in some component between this one and the previously-resolved one. */
675- resolvedContributionBindings .put (key , previouslyResolvedBindings );
676- return ;
677- }
678- }
679-
680653 cycleStack .push (key );
681654 try {
682655 ResolvedBindings bindings = lookUpBindings (key );
@@ -713,10 +686,6 @@ private ResolvedBindings getResolvedMembersInjectionBindings(Key key) {
713686 return resolvedMembersInjectionBindings .get (key );
714687 }
715688
716- private boolean requiresResolution (Key key ) {
717- return new LegacyRequiresResolutionChecker ().requiresResolution (key );
718- }
719-
720689 private boolean requiresResolution (Binding binding ) {
721690 return new LegacyRequiresResolutionChecker ().requiresResolution (binding );
722691 }
0 commit comments