Skip to content

Commit 9c5d902

Browse files
wanyingd1996Dagger Team
authored andcommitted
Support prunable hilt entry points.
Added `@OnlyUsedBy(\*binding identifiers*\)` to be used on entry points that indicates an entry point should be pruned if no usage of it is found. An entry point is considered as unused if: 1. No corresponding binding identifier is found. A binding's default identifier is its enclosing class, user may also explicitly specify a identifier using `@BindingIdentifier` on the binding element. 1. The entry point is only being used by a binding that is unused, which will not present in the pruned graph. RELNOTES=Support prunable hilt entry points. PiperOrigin-RevId: 640960016
1 parent 79aeed8 commit 9c5d902

File tree

28 files changed

+1474
-19
lines changed

28 files changed

+1474
-19
lines changed

java/dagger/internal/codegen/binding/BindingGraph.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ public abstract class BindingGraph {
7474
public abstract static class TopLevelBindingGraph
7575
extends dagger.internal.codegen.model.BindingGraph {
7676
static TopLevelBindingGraph create(
77-
ImmutableNetwork<Node, Edge> network, boolean isFullBindingGraph) {
77+
ImmutableNetwork<Node, Edge> network,
78+
boolean isFullBindingGraph) {
7879
TopLevelBindingGraph topLevelBindingGraph =
7980
new AutoValue_BindingGraph_TopLevelBindingGraph(network, isFullBindingGraph);
8081

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ BindingGraph convert(LegacyBindingGraph legacyBindingGraph, boolean isFullBindin
7777
}
7878

7979
TopLevelBindingGraph topLevelBindingGraph =
80-
TopLevelBindingGraph.create(ImmutableNetwork.copyOf(network), isFullBindingGraph);
80+
TopLevelBindingGraph.create(
81+
ImmutableNetwork.copyOf(network),
82+
isFullBindingGraph);
8183
return BindingGraph.create(rootNode, topLevelBindingGraph);
8284
}
8385

@@ -122,8 +124,7 @@ private void visitComponent(LegacyBindingGraph graph) {
122124

123125
network.addNode(graph.componentNode());
124126

125-
for (ComponentMethodDescriptor entryPointMethod :
126-
graph.componentDescriptor().entryPointMethods()) {
127+
for (ComponentMethodDescriptor entryPointMethod : graph.entryPointMethods()) {
127128
addDependencyEdges(graph.componentNode(), entryPointMethod.dependencyRequest().get());
128129
}
129130

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

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import static dagger.internal.codegen.base.Util.reentrantComputeIfAbsent;
2323
import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.isAssistedFactoryType;
2424
import static dagger.internal.codegen.binding.SourceFiles.generatedMonitoringModuleName;
25+
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList;
2526
import static dagger.internal.codegen.model.BindingKind.ASSISTED_INJECTION;
2627
import static dagger.internal.codegen.model.BindingKind.DELEGATE;
2728
import static dagger.internal.codegen.model.BindingKind.INJECTION;
@@ -48,6 +49,7 @@
4849
import dagger.internal.codegen.base.Keys;
4950
import dagger.internal.codegen.base.MapType;
5051
import dagger.internal.codegen.base.OptionalType;
52+
import dagger.internal.codegen.binding.ComponentDescriptor.ComponentMethodDescriptor;
5153
import dagger.internal.codegen.compileroption.CompilerOptions;
5254
import dagger.internal.codegen.javapoet.TypeNames;
5355
import dagger.internal.codegen.model.BindingGraph.ComponentNode;
@@ -212,14 +214,7 @@ private LegacyBindingGraph createLegacyBindingGraph(
212214

213215
componentDescriptor.entryPointMethods().stream()
214216
.map(method -> method.dependencyRequest().get())
215-
.forEach(
216-
entryPoint -> {
217-
if (entryPoint.kind().equals(MEMBERS_INJECTION)) {
218-
requestResolver.resolveMembersInjection(entryPoint.key());
219-
} else {
220-
requestResolver.resolve(entryPoint.key());
221-
}
222-
});
217+
.forEach(entryPoint -> resolveEntryPointsHelper(entryPoint, requestResolver));
223218

224219
if (createFullBindingGraph) {
225220
// Resolve the keys for all bindings in all modules, stripping any multibinding contribution
@@ -249,6 +244,14 @@ private LegacyBindingGraph createLegacyBindingGraph(
249244
return new LegacyBindingGraph(requestResolver, subgraphs.build());
250245
}
251246

247+
private void resolveEntryPointsHelper(DependencyRequest entryPoint, Resolver requestResolver) {
248+
if (entryPoint.kind().equals(MEMBERS_INJECTION)) {
249+
requestResolver.resolveMembersInjection(entryPoint.key());
250+
} else {
251+
requestResolver.resolve(entryPoint.key());
252+
}
253+
}
254+
252255
/**
253256
* Returns all the modules that should be installed in the component. For production components
254257
* and production subcomponents that have a parent that is not a production component or
@@ -296,7 +299,7 @@ static final class LegacyBindingGraph {
296299
private final ImmutableList<LegacyBindingGraph> resolvedSubgraphs;
297300
private final ComponentNode componentNode;
298301

299-
LegacyBindingGraph(Resolver resolver, ImmutableList<LegacyBindingGraph> resolvedSubgraphs) {
302+
LegacyBindingGraph(Resolver resolver, ImmutableList<LegacyBindingGraph> resolvedSubgraphs) {
300303
this.resolver = resolver;
301304
this.resolvedSubgraphs = resolvedSubgraphs;
302305
this.componentNode =
@@ -318,6 +321,11 @@ ComponentDescriptor componentDescriptor() {
318321
return resolver.componentDescriptor;
319322
}
320323

324+
ImmutableList<ComponentMethodDescriptor> entryPointMethods() {
325+
return componentDescriptor().entryPointMethods().stream()
326+
.collect(toImmutableList());
327+
}
328+
321329
/**
322330
* Returns the {@link ResolvedBindings} in this graph or a parent graph that matches the given
323331
* request.

java/dagger/internal/codegen/writing/ComponentImplementation.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
import com.google.common.collect.ListMultimap;
6060
import com.google.common.collect.Lists;
6161
import com.google.common.collect.MultimapBuilder;
62-
import com.google.common.collect.Sets;
6362
import com.squareup.javapoet.ClassName;
6463
import com.squareup.javapoet.CodeBlock;
6564
import com.squareup.javapoet.FieldSpec;
@@ -97,7 +96,6 @@
9796
import java.util.List;
9897
import java.util.Map;
9998
import java.util.Optional;
100-
import java.util.Set;
10199
import javax.inject.Inject;
102100
import javax.inject.Provider;
103101
import javax.lang.model.element.Modifier;
@@ -886,14 +884,19 @@ private void addInterfaceMethods() {
886884
// Each component method may have been declared by several supertypes. We want to implement
887885
// only one method for each distinct signature.
888886
XType componentType = graph.componentTypeElement().getType();
889-
Set<MethodSignature> signatures = Sets.newHashSet();
887+
Map<MethodSignature, ComponentMethodDescriptor> methodDescriptors = new LinkedHashMap<>();
890888
for (ComponentMethodDescriptor method : graph.componentDescriptor().entryPointMethods()) {
891-
if (signatures.add(
892-
MethodSignature.forComponentMethod(method, componentType, processingEnv))) {
889+
MethodSignature signature =
890+
MethodSignature.forComponentMethod(method, componentType, processingEnv);
891+
if (!methodDescriptors.containsKey(signature)) {
892+
methodDescriptors.put(signature, method);
893+
}
894+
}
895+
896+
for (ComponentMethodDescriptor method : methodDescriptors.values()) {
893897
addMethod(
894898
COMPONENT_METHOD,
895899
componentRequestRepresentationsProvider.get().getComponentMethod(method));
896-
}
897900
}
898901
}
899902

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package test;
2+
3+
import dagger.internal.DaggerGenerated;
4+
import javax.annotation.processing.Generated;
5+
6+
@DaggerGenerated
7+
@Generated(
8+
value = "dagger.internal.codegen.ComponentProcessor",
9+
comments = "https://dagger.dev"
10+
)
11+
@SuppressWarnings({
12+
"unchecked",
13+
"rawtypes",
14+
"KotlinInternal",
15+
"KotlinInternalInJava",
16+
"cast",
17+
"deprecation"
18+
})
19+
final class DaggerMyComponent {
20+
private DaggerMyComponent() {
21+
}
22+
23+
public static Builder builder() {
24+
return new Builder();
25+
}
26+
27+
public static MyComponent create() {
28+
return new Builder().build();
29+
}
30+
31+
static final class Builder {
32+
private Builder() {
33+
}
34+
35+
public MyComponent build() {
36+
return new MyComponentImpl();
37+
}
38+
}
39+
40+
private static final class MyComponentImpl implements MyComponent {
41+
private final MyComponentImpl myComponentImpl = this;
42+
43+
private MyComponentImpl() {
44+
45+
46+
}
47+
48+
@Override
49+
public Bar getBar() {
50+
return new Bar();
51+
}
52+
53+
@Override
54+
public Foo getFoo() {
55+
return new Foo();
56+
}
57+
}
58+
}
59+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package test;
2+
3+
import dagger.internal.DaggerGenerated;
4+
import javax.annotation.processing.Generated;
5+
6+
@DaggerGenerated
7+
@Generated(
8+
value = "dagger.internal.codegen.ComponentProcessor",
9+
comments = "https://dagger.dev"
10+
)
11+
@SuppressWarnings({
12+
"unchecked",
13+
"rawtypes",
14+
"KotlinInternal",
15+
"KotlinInternalInJava",
16+
"cast",
17+
"deprecation"
18+
})
19+
final class DaggerMyComponent {
20+
private DaggerMyComponent() {
21+
}
22+
23+
public static Builder builder() {
24+
return new Builder();
25+
}
26+
27+
public static MyComponent create() {
28+
return new Builder().build();
29+
}
30+
31+
static final class Builder {
32+
private Builder() {
33+
}
34+
35+
public MyComponent build() {
36+
return new MyComponentImpl();
37+
}
38+
}
39+
40+
private static final class MyComponentImpl implements MyComponent {
41+
private final MyComponentImpl myComponentImpl = this;
42+
43+
private MyComponentImpl() {
44+
45+
46+
}
47+
48+
@Override
49+
public Bar getBar() {
50+
return new Bar();
51+
}
52+
53+
@Override
54+
public Foo getFoo() {
55+
return new Foo();
56+
}
57+
}
58+
}
59+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package test;
2+
3+
import dagger.internal.DaggerGenerated;
4+
import dagger.internal.Preconditions;
5+
import javax.annotation.processing.Generated;
6+
7+
@DaggerGenerated
8+
@Generated(
9+
value = "dagger.internal.codegen.ComponentProcessor",
10+
comments = "https://dagger.dev"
11+
)
12+
@SuppressWarnings({
13+
"unchecked",
14+
"rawtypes",
15+
"KotlinInternal",
16+
"KotlinInternalInJava",
17+
"cast",
18+
"deprecation"
19+
})
20+
final class DaggerMyComponent {
21+
private DaggerMyComponent() {
22+
}
23+
24+
public static Builder builder() {
25+
return new Builder();
26+
}
27+
28+
public static MyComponent create() {
29+
return new Builder().build();
30+
}
31+
32+
static final class Builder {
33+
private FooModule fooModule;
34+
35+
private Builder() {
36+
}
37+
38+
public Builder fooModule(FooModule fooModule) {
39+
this.fooModule = Preconditions.checkNotNull(fooModule);
40+
return this;
41+
}
42+
43+
public MyComponent build() {
44+
if (fooModule == null) {
45+
this.fooModule = new FooModule();
46+
}
47+
return new MyComponentImpl(fooModule);
48+
}
49+
}
50+
51+
private static final class MyComponentImpl implements MyComponent {
52+
private final FooModule fooModule;
53+
54+
private final MyComponentImpl myComponentImpl = this;
55+
56+
private MyComponentImpl(FooModule fooModuleParam) {
57+
this.fooModule = fooModuleParam;
58+
59+
}
60+
61+
@Override
62+
public Bar getBar() {
63+
throw new UnsupportedOperationException("This entry point is pruned because it has been marked as unused, please update @OnlyUsedBy to reflect its usage.");
64+
}
65+
66+
@Override
67+
public Foo getFoo() {
68+
return FooModule_ProvidesFooFactory.providesFoo(fooModule);
69+
}
70+
}
71+
}
72+

0 commit comments

Comments
 (0)