Skip to content

Commit 378535e

Browse files
bcorsoDagger Team
authored andcommitted
Refactor ResolvedBindings and LegacyBindingGraph to include the ComponentPath.
Including the ComponentPath in ResolvedBindings avoids having to create new objects of type ResolvedBindingsWithPath to satisfy our Map key. In addition, passing the ComponentPath while creating LegacyBindingGraph avoids having to recreate it from scratch during BindingGraphConverter phase. RELNOTES=N/A PiperOrigin-RevId: 570137117
1 parent fd907cb commit 378535e

File tree

4 files changed

+62
-72
lines changed

4 files changed

+62
-72
lines changed

java/dagger/internal/codegen/binding/BindingGraphConverter.java

Lines changed: 24 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import static com.google.common.base.Verify.verify;
2020
import static dagger.internal.codegen.binding.BindingRequest.bindingRequest;
2121
import static dagger.internal.codegen.extension.DaggerGraphs.unreachableNodes;
22-
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList;
2322
import static dagger.internal.codegen.model.BindingKind.SUBCOMPONENT_CREATOR;
2423

2524
import androidx.room.compiler.processing.XMethodElement;
@@ -29,11 +28,9 @@
2928
import com.google.auto.value.extension.memoized.Memoized;
3029
import com.google.common.collect.ImmutableList;
3130
import com.google.common.collect.ImmutableSet;
32-
import com.google.common.collect.Iterables;
3331
import com.google.common.collect.Iterators;
3432
import com.google.common.graph.ImmutableNetwork;
3533
import com.google.common.graph.MutableNetwork;
36-
import com.google.common.graph.Network;
3734
import com.google.common.graph.NetworkBuilder;
3835
import dagger.internal.codegen.binding.BindingGraph.TopLevelBindingGraph;
3936
import dagger.internal.codegen.binding.ComponentDescriptor.ComponentMethodDescriptor;
@@ -70,7 +67,7 @@ final class BindingGraphConverter {
7067
*/
7168
BindingGraph convert(LegacyBindingGraph legacyBindingGraph, boolean isFullBindingGraph) {
7269
MutableNetwork<Node, Edge> network = asNetwork(legacyBindingGraph);
73-
ComponentNode rootNode = rootComponentNode(network);
70+
ComponentNode rootNode = legacyBindingGraph.componentNode();
7471

7572
// When bindings are copied down into child graphs because they transitively depend on local
7673
// multibindings or optional bindings, the parent-owned binding is still there. If that
@@ -92,47 +89,19 @@ private MutableNetwork<Node, Edge> asNetwork(LegacyBindingGraph graph) {
9289
return converter.network;
9390
}
9491

95-
// TODO(dpb): Example of BindingGraph logic applied to derived networks.
96-
private ComponentNode rootComponentNode(Network<Node, Edge> network) {
97-
return (ComponentNode)
98-
Iterables.find(
99-
network.nodes(),
100-
node -> node instanceof ComponentNode && node.componentPath().atRoot());
101-
}
102-
103-
/**
104-
* Used as a cache key to make sure resolved bindings are cached per component path.
105-
* This is required so that binding nodes are not reused across different branches of the
106-
* graph since the ResolvedBindings class only contains the component and not the path.
107-
*/
108-
@AutoValue
109-
abstract static class ResolvedBindingsWithPath {
110-
abstract ResolvedBindings resolvedBindings();
111-
abstract ComponentPath componentPath();
112-
113-
static ResolvedBindingsWithPath create(
114-
ResolvedBindings resolvedBindings, ComponentPath componentPath) {
115-
return new AutoValue_BindingGraphConverter_ResolvedBindingsWithPath(
116-
resolvedBindings, componentPath);
117-
}
118-
}
119-
12092
private final class Converter {
12193
/** The path from the root graph to the currently visited graph. */
12294
private final Deque<LegacyBindingGraph> bindingGraphPath = new ArrayDeque<>();
12395

124-
/** The {@link ComponentPath} for each component in {@link #bindingGraphPath}. */
125-
private final Deque<ComponentPath> componentPaths = new ArrayDeque<>();
126-
12796
private final MutableNetwork<Node, Edge> network =
12897
NetworkBuilder.directed().allowsParallelEdges(true).allowsSelfLoops(true).build();
12998
private final Set<BindingNode> bindings = new HashSet<>();
13099

131-
private final Map<ResolvedBindingsWithPath, ImmutableSet<BindingNode>> resolvedBindingsMap =
100+
private final Map<ResolvedBindings, ImmutableSet<BindingNode>> resolvedBindingsMap =
132101
new HashMap<>();
133102

134103
private void visitRootComponent(LegacyBindingGraph graph) {
135-
visitComponent(graph, null);
104+
visitComponent(graph);
136105
}
137106

138107
/**
@@ -145,30 +114,20 @@ private void visitRootComponent(LegacyBindingGraph graph) {
145114
* {@link #visitSubcomponentFactoryMethod(ComponentNode, ComponentNode, XMethodElement)}.
146115
* <li>For each entry point in the component, calls {@link #visitEntryPoint(ComponentNode,
147116
* DependencyRequest)}.
148-
* <li>For each child component, calls {@link #visitComponent(LegacyBindingGraph,
149-
* ComponentNode)}, updating the traversal state.
117+
* <li>For each child component, calls {@link #visitComponent(LegacyBindingGraph)},
118+
* updating the traversal state.
150119
* </ol>
151120
*
152121
* @param graph the currently visited graph
153122
*/
154-
private void visitComponent(LegacyBindingGraph graph, ComponentNode parentComponent) {
123+
private void visitComponent(LegacyBindingGraph graph) {
155124
bindingGraphPath.addLast(graph);
156-
ComponentPath graphPath =
157-
ComponentPath.create(
158-
bindingGraphPath.stream()
159-
.map(LegacyBindingGraph::componentDescriptor)
160-
.map(ComponentDescriptor::typeElement)
161-
.map(DaggerTypeElement::from)
162-
.collect(toImmutableList()));
163-
componentPaths.addLast(graphPath);
164-
ComponentNode currentComponent =
165-
ComponentNodeImpl.create(componentPath(), graph.componentDescriptor());
166-
167-
network.addNode(currentComponent);
125+
126+
network.addNode(graph.componentNode());
168127

169128
for (ComponentMethodDescriptor entryPointMethod :
170129
graph.componentDescriptor().entryPointMethods()) {
171-
visitEntryPoint(currentComponent, entryPointMethod.dependencyRequest().get());
130+
visitEntryPoint(graph.componentNode(), entryPointMethod.dependencyRequest().get());
172131
}
173132

174133
for (ResolvedBindings resolvedBindings : graph.resolvedBindings()) {
@@ -180,7 +139,7 @@ private void visitComponent(LegacyBindingGraph graph, ComponentNode parentCompon
180139
}
181140
}
182141
if (binding.kind().equals(SUBCOMPONENT_CREATOR)
183-
&& binding.componentPath().equals(currentComponent.componentPath())) {
142+
&& binding.componentPath().equals(graph.componentPath())) {
184143
network.addEdge(
185144
binding,
186145
subcomponentNode(binding.key().type().xprocessing(), graph),
@@ -191,22 +150,23 @@ private void visitComponent(LegacyBindingGraph graph, ComponentNode parentCompon
191150
}
192151

193152
if (bindingGraphPath.size() > 1) {
194-
LegacyBindingGraph parent = Iterators.get(bindingGraphPath.descendingIterator(), 1);
195-
parent
153+
LegacyBindingGraph parentGraph = Iterators.get(bindingGraphPath.descendingIterator(), 1);
154+
parentGraph
196155
.componentDescriptor()
197156
.getFactoryMethodForChildComponent(graph.componentDescriptor())
198157
.ifPresent(
199158
childFactoryMethod ->
200159
visitSubcomponentFactoryMethod(
201-
parentComponent, currentComponent, childFactoryMethod.methodElement()));
160+
parentGraph.componentNode(),
161+
graph.componentNode(),
162+
childFactoryMethod.methodElement()));
202163
}
203164

204165
for (LegacyBindingGraph child : graph.subgraphs()) {
205-
visitComponent(child, currentComponent);
166+
visitComponent(child);
206167
}
207168

208169
verify(bindingGraphPath.removeLast().equals(graph));
209-
verify(componentPaths.removeLast().equals(graphPath));
210170
}
211171

212172
/**
@@ -242,17 +202,17 @@ private void visitSubcomponentFactoryMethod(
242202
* component.
243203
*/
244204
private ComponentPath componentPath() {
245-
return componentPaths.getLast();
205+
return bindingGraphPath.getLast().componentPath();
246206
}
247207

248208
/**
249209
* Returns the subpath from the root component to the matching {@code ancestor} of the current
250210
* component.
251211
*/
252212
private ComponentPath pathFromRootToAncestor(XTypeElement ancestor) {
253-
for (ComponentPath componentPath : componentPaths) {
254-
if (componentPath.currentComponent().xprocessing().equals(ancestor)) {
255-
return componentPath;
213+
for (LegacyBindingGraph graph : bindingGraphPath) {
214+
if (graph.componentDescriptor().typeElement().equals(ancestor)) {
215+
return graph.componentPath();
256216
}
257217
}
258218
throw new IllegalArgumentException(
@@ -325,23 +285,18 @@ private ResolvedBindings resolvedDependencies(
325285
}
326286

327287
private ImmutableSet<BindingNode> bindingNodes(ResolvedBindings resolvedBindings) {
328-
ResolvedBindingsWithPath resolvedBindingsWithPath =
329-
ResolvedBindingsWithPath.create(resolvedBindings, componentPath());
330-
return resolvedBindingsMap.computeIfAbsent(
331-
resolvedBindingsWithPath, this::uncachedBindingNodes);
288+
return resolvedBindingsMap.computeIfAbsent(resolvedBindings, this::uncachedBindingNodes);
332289
}
333290

334-
private ImmutableSet<BindingNode> uncachedBindingNodes(
335-
ResolvedBindingsWithPath resolvedBindingsWithPath) {
291+
private ImmutableSet<BindingNode> uncachedBindingNodes(ResolvedBindings resolvedBindings) {
336292
ImmutableSet.Builder<BindingNode> bindingNodes = ImmutableSet.builder();
337-
resolvedBindingsWithPath.resolvedBindings()
293+
resolvedBindings
338294
.allBindings()
339295
.asMap()
340296
.forEach(
341297
(component, bindings) -> {
342298
for (Binding binding : bindings) {
343-
bindingNodes.add(
344-
bindingNode(resolvedBindingsWithPath.resolvedBindings(), binding, component));
299+
bindingNodes.add(bindingNode(resolvedBindings, binding, component));
345300
}
346301
});
347302
return bindingNodes.build();

java/dagger/internal/codegen/binding/BindingGraphFactory.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
import dagger.internal.codegen.base.OptionalType;
5252
import dagger.internal.codegen.compileroption.CompilerOptions;
5353
import dagger.internal.codegen.javapoet.TypeNames;
54+
import dagger.internal.codegen.model.ComponentPath;
55+
import dagger.internal.codegen.model.DaggerTypeElement;
5456
import dagger.internal.codegen.model.DependencyRequest;
5557
import dagger.internal.codegen.model.Key;
5658
import dagger.internal.codegen.model.Scope;
@@ -190,8 +192,14 @@ private LegacyBindingGraph createLegacyBindingGraph(
190192
optionalsBuilder.addAll(moduleDescriptor.optionalDeclarations());
191193
}
192194

195+
DaggerTypeElement component = DaggerTypeElement.from(componentDescriptor.typeElement());
196+
ComponentPath componentPath =
197+
parentResolver.isPresent()
198+
? parentResolver.get().componentPath.childPath(component)
199+
: ComponentPath.create(ImmutableList.of(component));
193200
final Resolver requestResolver =
194201
new Resolver(
202+
componentPath,
195203
parentResolver,
196204
componentDescriptor,
197205
indexBindingDeclarationsByKey(explicitBindingsBuilder.build()),
@@ -237,6 +245,7 @@ private LegacyBindingGraph createLegacyBindingGraph(
237245
}
238246

239247
return new LegacyBindingGraph(
248+
componentPath,
240249
componentDescriptor,
241250
ImmutableMap.copyOf(requestResolver.getResolvedContributionBindings()),
242251
ImmutableMap.copyOf(requestResolver.getResolvedMembersInjectionBindings()),
@@ -300,6 +309,7 @@ public void clearCache() {
300309
}
301310

302311
private final class Resolver {
312+
final ComponentPath componentPath;
303313
final Optional<Resolver> parentResolver;
304314
final ComponentDescriptor componentDescriptor;
305315
final ImmutableSetMultimap<Key, ContributionBinding> explicitBindings;
@@ -318,13 +328,15 @@ private final class Resolver {
318328
final Queue<ComponentDescriptor> subcomponentsToResolve = new ArrayDeque<>();
319329

320330
Resolver(
331+
ComponentPath componentPath,
321332
Optional<Resolver> parentResolver,
322333
ComponentDescriptor componentDescriptor,
323334
ImmutableSetMultimap<Key, ContributionBinding> explicitBindings,
324335
ImmutableSetMultimap<Key, MultibindingDeclaration> multibindingDeclarations,
325336
ImmutableSetMultimap<Key, SubcomponentDeclaration> subcomponentDeclarations,
326337
ImmutableSetMultimap<Key, DelegateDeclaration> delegateDeclarations,
327338
ImmutableSetMultimap<Key, OptionalBindingDeclaration> optionalBindingDeclarations) {
339+
this.componentPath = componentPath;
328340
this.parentResolver = parentResolver;
329341
this.componentDescriptor = checkNotNull(componentDescriptor);
330342
this.explicitBindings = checkNotNull(explicitBindings);
@@ -428,6 +440,7 @@ && isAssistedFactoryType(requestKey.type().xprocessing().getTypeElement())) {
428440
}
429441

430442
return ResolvedBindings.forContributionBindings(
443+
componentPath,
431444
requestKey,
432445
Multimaps.index(bindings, binding -> getOwningComponent(requestKey, binding)),
433446
multibindingDeclarations,
@@ -466,8 +479,8 @@ ResolvedBindings lookUpMembersInjectionBinding(Key requestKey) {
466479
injectBindingRegistry.getOrFindMembersInjectionBinding(requestKey);
467480
return binding.isPresent()
468481
? ResolvedBindings.forMembersInjectionBinding(
469-
requestKey, componentDescriptor, binding.get())
470-
: ResolvedBindings.noBindings(requestKey);
482+
componentPath, requestKey, componentDescriptor, binding.get())
483+
: ResolvedBindings.noBindings(componentPath, requestKey);
471484
}
472485

473486
/**

java/dagger/internal/codegen/binding/LegacyBindingGraph.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import com.google.common.collect.Iterables;
2323
import com.google.common.collect.Maps;
2424
import com.google.common.collect.Multimaps;
25+
import dagger.internal.codegen.model.BindingGraph.ComponentNode;
26+
import dagger.internal.codegen.model.ComponentPath;
2527
import dagger.internal.codegen.model.Key;
2628
import dagger.internal.codegen.model.RequestKind;
2729
import java.util.Collection;
@@ -30,22 +32,33 @@
3032
// TODO(bcorso): Remove the LegacyBindingGraph after we've migrated to the new BindingGraph.
3133
/** The canonical representation of a full-resolved graph. */
3234
final class LegacyBindingGraph {
35+
private final ComponentNode componentNode;
3336
private final ComponentDescriptor componentDescriptor;
3437
private final ImmutableMap<Key, ResolvedBindings> contributionBindings;
3538
private final ImmutableMap<Key, ResolvedBindings> membersInjectionBindings;
3639
private final ImmutableList<LegacyBindingGraph> subgraphs;
3740

3841
LegacyBindingGraph(
42+
ComponentPath componentPath,
3943
ComponentDescriptor componentDescriptor,
4044
ImmutableMap<Key, ResolvedBindings> contributionBindings,
4145
ImmutableMap<Key, ResolvedBindings> membersInjectionBindings,
4246
ImmutableList<LegacyBindingGraph> subgraphs) {
47+
this.componentNode = ComponentNodeImpl.create(componentPath, componentDescriptor);
4348
this.componentDescriptor = componentDescriptor;
4449
this.contributionBindings = contributionBindings;
4550
this.membersInjectionBindings = membersInjectionBindings;
4651
this.subgraphs = checkForDuplicates(subgraphs);
4752
}
4853

54+
ComponentNode componentNode() {
55+
return componentNode;
56+
}
57+
58+
ComponentPath componentPath() {
59+
return componentNode.componentPath();
60+
}
61+
4962
ComponentDescriptor componentDescriptor() {
5063
return componentDescriptor;
5164
}

java/dagger/internal/codegen/binding/ResolvedBindings.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.google.common.collect.ImmutableSet;
2828
import com.google.common.collect.ImmutableSetMultimap;
2929
import com.google.common.collect.Multimap;
30+
import dagger.internal.codegen.model.ComponentPath;
3031
import dagger.internal.codegen.model.Key;
3132

3233
/**
@@ -40,6 +41,9 @@
4041
*/
4142
@AutoValue
4243
abstract class ResolvedBindings {
44+
/** The component path for the resolved bindings. */
45+
abstract ComponentPath componentPath();
46+
4347
/** The binding key for which the {@link #bindings()} have been resolved. */
4448
abstract Key key();
4549

@@ -127,12 +131,14 @@ final XTypeElement owningComponent(ContributionBinding binding) {
127131

128132
/** Creates a {@link ResolvedBindings} for contribution bindings. */
129133
static ResolvedBindings forContributionBindings(
134+
ComponentPath componentPath,
130135
Key key,
131136
Multimap<XTypeElement, ContributionBinding> contributionBindings,
132137
Iterable<MultibindingDeclaration> multibindings,
133138
Iterable<SubcomponentDeclaration> subcomponentDeclarations,
134139
Iterable<OptionalBindingDeclaration> optionalBindingDeclarations) {
135140
return new AutoValue_ResolvedBindings(
141+
componentPath,
136142
key,
137143
ImmutableSetMultimap.copyOf(contributionBindings),
138144
ImmutableMap.of(),
@@ -145,10 +151,12 @@ static ResolvedBindings forContributionBindings(
145151
* Creates a {@link ResolvedBindings} for members injection bindings.
146152
*/
147153
static ResolvedBindings forMembersInjectionBinding(
154+
ComponentPath componentPath,
148155
Key key,
149156
ComponentDescriptor owningComponent,
150157
MembersInjectionBinding ownedMembersInjectionBinding) {
151158
return new AutoValue_ResolvedBindings(
159+
componentPath,
152160
key,
153161
ImmutableSetMultimap.of(),
154162
ImmutableMap.of(owningComponent.typeElement(), ownedMembersInjectionBinding),
@@ -160,8 +168,9 @@ static ResolvedBindings forMembersInjectionBinding(
160168
/**
161169
* Creates a {@link ResolvedBindings} appropriate for when there are no bindings for the key.
162170
*/
163-
static ResolvedBindings noBindings(Key key) {
171+
static ResolvedBindings noBindings(ComponentPath componentPath, Key key) {
164172
return new AutoValue_ResolvedBindings(
173+
componentPath,
165174
key,
166175
ImmutableSetMultimap.of(),
167176
ImmutableMap.of(),

0 commit comments

Comments
 (0)