Begin to use the self-compiled Dagger within the :writing parts of the processor
This is meant to be a baby step, just adding the entry points of injected types. There's still plenty more that should be done to remove a lot of the manual DI.
RELNOTES=Dagger itself now uses more Dagger
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=226503266
diff --git a/java/dagger/internal/codegen/BUILD b/java/dagger/internal/codegen/BUILD
index c0944db..cb6cd2d 100644
--- a/java/dagger/internal/codegen/BUILD
+++ b/java/dagger/internal/codegen/BUILD
@@ -292,6 +292,9 @@
"OptionalBindingExpression.java",
"OptionalFactories.java",
"OptionalFactoryInstanceCreationExpression.java",
+ "ParentComponent.java",
+ "PerComponentImplementation.java",
+ "PerGeneratedFile.java",
"PrivateMethodBindingExpression.java",
"ProducerCreationExpression.java",
"ProducerEntryPointView.java",
@@ -310,6 +313,7 @@
"SubcomponentBuilderProviderCreationExpression.java",
"SubcomponentNames.java",
"SwitchingProviders.java",
+ "TopLevel.java",
"UnwrappedMapKeyGenerator.java",
],
plugins = CODEGEN_PLUGINS,
@@ -336,6 +340,8 @@
"ComponentImplementationFactory.java",
"ComponentProcessingStep.java",
"ComponentProcessor.java",
+ "ConfigureCreatorImplementationModule.java",
+ "CurrentImplementationSubcomponent.java",
"InjectBindingRegistryImpl.java",
"InjectBindingRegistryModule.java",
"InjectProcessingStep.java",
@@ -346,6 +352,7 @@
"SourceFileGeneratorsModule.java",
"SpiModule.java",
"SystemComponentsModule.java",
+ "TopLevelImplementationComponent.java",
"Validation.java",
],
plugins = CODEGEN_PLUGINS,
diff --git a/java/dagger/internal/codegen/ComponentBindingExpressions.java b/java/dagger/internal/codegen/ComponentBindingExpressions.java
index f715ca4..4161943 100644
--- a/java/dagger/internal/codegen/ComponentBindingExpressions.java
+++ b/java/dagger/internal/codegen/ComponentBindingExpressions.java
@@ -45,10 +45,12 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
+import javax.inject.Inject;
import javax.inject.Provider;
import javax.lang.model.type.TypeMirror;
/** A central repository of code expressions used to access any binding available to a component. */
+@PerComponentImplementation
final class ComponentBindingExpressions {
// TODO(dpb,ronshapiro): refactor this and ComponentRequirementExpressions into a
// HierarchicalComponentMap<K, V>, or perhaps this use a flattened ImmutableMap, built from its
@@ -68,28 +70,8 @@
private final ModifiableBindingExpressions modifiableBindingExpressions;
private final Map<BindingRequest, BindingExpression> expressions = new HashMap<>();
- ComponentBindingExpressions(
- BindingGraph graph,
- ComponentImplementation componentImplementation,
- ComponentRequirementExpressions componentRequirementExpressions,
- OptionalFactories optionalFactories,
- DaggerTypes types,
- DaggerElements elements,
- CompilerOptions compilerOptions) {
- this(
- Optional.empty(),
- graph,
- componentImplementation,
- componentRequirementExpressions,
- new StaticSwitchingProviders(componentImplementation, types),
- optionalFactories,
- types,
- elements,
- compilerOptions);
- }
-
- private ComponentBindingExpressions(
- Optional<ComponentBindingExpressions> parent,
+ @Inject ComponentBindingExpressions(
+ @ParentComponent Optional<ComponentBindingExpressions> parent,
BindingGraph graph,
ComponentImplementation componentImplementation,
ComponentRequirementExpressions componentRequirementExpressions,
@@ -121,25 +103,6 @@
types);
}
- /**
- * Returns a new object representing the bindings available from a child component of this one.
- */
- ComponentBindingExpressions forChildComponent(
- BindingGraph childGraph,
- ComponentImplementation childComponentImplementation,
- ComponentRequirementExpressions childComponentRequirementExpressions) {
- return new ComponentBindingExpressions(
- Optional.of(this),
- childGraph,
- childComponentImplementation,
- childComponentRequirementExpressions,
- staticSwitchingProviders,
- optionalFactories,
- types,
- elements,
- compilerOptions);
- }
-
/* Returns the {@link ModifiableBindingExpressions} for this component. */
ModifiableBindingExpressions modifiableBindingExpressions() {
return modifiableBindingExpressions;
diff --git a/java/dagger/internal/codegen/ComponentImplementationFactory.java b/java/dagger/internal/codegen/ComponentImplementationFactory.java
index 4706231..972a0cd 100644
--- a/java/dagger/internal/codegen/ComponentImplementationFactory.java
+++ b/java/dagger/internal/codegen/ComponentImplementationFactory.java
@@ -18,6 +18,7 @@
import static com.google.auto.common.MoreElements.getLocalAndInheritedMethods;
import static com.google.auto.common.MoreTypes.asDeclared;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.squareup.javapoet.MethodSpec.constructorBuilder;
import static com.squareup.javapoet.MethodSpec.methodBuilder;
@@ -79,24 +80,18 @@
private static final String CANCELLATION_LISTENER_METHOD_NAME = "onProducerFutureCancelled";
- private final DaggerTypes types;
- private final DaggerElements elements;
private final KeyFactory keyFactory;
private final CompilerOptions compilerOptions;
- private final BindingGraphFactory bindingGraphFactory;
+ private final TopLevelImplementationComponent.Builder topLevelImplementationComponentBuilder;
@Inject
ComponentImplementationFactory(
- DaggerTypes types,
- DaggerElements elements,
KeyFactory keyFactory,
CompilerOptions compilerOptions,
- BindingGraphFactory bindingGraphFactory) {
- this.types = types;
- this.elements = elements;
+ TopLevelImplementationComponent.Builder topLevelImplementationComponentBuilder) {
this.keyFactory = keyFactory;
this.compilerOptions = compilerOptions;
- this.bindingGraphFactory = bindingGraphFactory;
+ this.topLevelImplementationComponentBuilder = topLevelImplementationComponentBuilder;
}
/**
@@ -108,45 +103,28 @@
ComponentImplementation createComponentImplementation(BindingGraph bindingGraph) {
ComponentImplementation componentImplementation =
topLevelImplementation(componentName(bindingGraph.componentTypeElement()), bindingGraph);
- OptionalFactories optionalFactories = new OptionalFactories(componentImplementation);
- Optional<ComponentCreatorImplementation> componentCreatorImplementation =
- ComponentCreatorImplementation.create(
- componentImplementation, bindingGraph, elements, types);
- componentImplementation.setCreatorImplementation(componentCreatorImplementation);
- ComponentRequirementExpressions componentRequirementExpressions =
- new ComponentRequirementExpressions(
- bindingGraph, componentImplementation, types, elements, compilerOptions);
- ComponentBindingExpressions bindingExpressions =
- new ComponentBindingExpressions(
- bindingGraph,
- componentImplementation,
- componentRequirementExpressions,
- optionalFactories,
- types,
- elements,
- compilerOptions);
+ // TODO(dpb): explore using optional bindings for the "parent" bindings
+ CurrentImplementationSubcomponent currentImplementationSubcomponent =
+ topLevelImplementationComponentBuilder
+ .topLevelComponent(componentImplementation)
+ .build()
+ .currentImplementationSubcomponentBuilder()
+ .componentImplementation(componentImplementation)
+ .bindingGraph(bindingGraph)
+ .parentBuilder(Optional.empty())
+ .parentBindingExpressions(Optional.empty())
+ .parentRequirementExpressions(Optional.empty())
+ .build();
+
if (componentImplementation.isAbstract()) {
checkState(
compilerOptions.aheadOfTimeSubcomponents(),
"Calling 'componentImplementation()' on %s when not generating ahead-of-time "
+ "subcomponents.",
bindingGraph.componentTypeElement());
- return new SubcomponentImplementationBuilder(
- Optional.empty(), /* parent */
- bindingGraph,
- componentImplementation,
- optionalFactories,
- bindingExpressions,
- componentRequirementExpressions)
- .build();
+ return currentImplementationSubcomponent.subcomponentBuilder().build();
} else {
- return new RootComponentImplementationBuilder(
- bindingGraph,
- componentImplementation,
- optionalFactories,
- bindingExpressions,
- componentRequirementExpressions)
- .build();
+ return currentImplementationSubcomponent.rootComponentBuilder().build();
}
}
@@ -162,27 +140,21 @@
graph.componentDescriptor().kind().isTopLevel() ? FINAL : ABSTRACT);
}
- private abstract class ComponentImplementationBuilder {
- final BindingGraph graph;
- final ComponentBindingExpressions bindingExpressions;
- final ComponentRequirementExpressions componentRequirementExpressions;
- final ComponentImplementation componentImplementation;
- final OptionalFactories optionalFactories;
+ abstract static class ComponentImplementationBuilder {
+ // TODO(ronshapiro): replace this with composition instead of inheritance so we don't have
+ // non-final fields
+ @Inject BindingGraph graph;
+ @Inject ComponentBindingExpressions bindingExpressions;
+ @Inject ComponentRequirementExpressions componentRequirementExpressions;
+ @Inject ComponentImplementation componentImplementation;
+ @Inject BindingGraphFactory bindingGraphFactory;
+ @Inject DaggerTypes types;
+ @Inject DaggerElements elements;
+ @Inject CompilerOptions compilerOptions;
+ @Inject ComponentImplementationFactory componentImplementationFactory;
+ @Inject TopLevelImplementationComponent topLevelImplementationComponent;
boolean done;
- ComponentImplementationBuilder(
- BindingGraph graph,
- ComponentImplementation componentImplementation,
- OptionalFactories optionalFactories,
- ComponentBindingExpressions bindingExpressions,
- ComponentRequirementExpressions componentRequirementExpressions) {
- this.graph = graph;
- this.componentImplementation = componentImplementation;
- this.optionalFactories = optionalFactories;
- this.bindingExpressions = bindingExpressions;
- this.componentRequirementExpressions = componentRequirementExpressions;
- }
-
/**
* Returns a {@link ComponentImplementation} for this component. This is only intended to be
* called once (and will throw on successive invocations). If the component must be regenerated,
@@ -417,7 +389,7 @@
// implementation object for the base implementation of the child by truncating the binding
// graph at the child.
BindingGraph truncatedBindingGraph = bindingGraphFactory.create(child);
- return createComponentImplementation(truncatedBindingGraph);
+ return componentImplementationFactory.createComponentImplementation(truncatedBindingGraph);
}
final ComponentImplementation buildChildImplementation(BindingGraph childGraph) {
@@ -425,22 +397,16 @@
compilerOptions.aheadOfTimeSubcomponents()
? abstractInnerSubcomponent(childGraph.componentDescriptor())
: concreteSubcomponent(childGraph.componentDescriptor());
- Optional<ComponentCreatorImplementation> childCreatorImplementation =
- ComponentCreatorImplementation.create(childImplementation, childGraph, elements, types);
- childImplementation.setCreatorImplementation(childCreatorImplementation);
- ComponentRequirementExpressions childComponentRequirementExpressions =
- componentRequirementExpressions.forChildComponent(childGraph, childImplementation);
- ComponentBindingExpressions childBindingExpressions =
- bindingExpressions.forChildComponent(
- childGraph, childImplementation, childComponentRequirementExpressions);
- return new SubcomponentImplementationBuilder(
- Optional.of(this),
- childGraph,
- childImplementation,
- optionalFactories,
- childBindingExpressions,
- childComponentRequirementExpressions)
- .build();
+ return topLevelImplementationComponent
+ .currentImplementationSubcomponentBuilder()
+ .componentImplementation(childImplementation)
+ .bindingGraph(childGraph)
+ .parentBuilder(Optional.of(this))
+ .parentBindingExpressions(Optional.of(bindingExpressions))
+ .parentRequirementExpressions(Optional.of(componentRequirementExpressions))
+ .build()
+ .subcomponentBuilder()
+ .build();
}
/** Creates an inner abstract subcomponent implementation. */
@@ -603,21 +569,14 @@
}
/** Builds a root component implementation. */
- private final class RootComponentImplementationBuilder extends ComponentImplementationBuilder {
+ // TODO(ronshapiro): rename this as TopLevelComponentImplementationBuilder, since it may not
+ // always be a root component
+ static final class RootComponentImplementationBuilder extends ComponentImplementationBuilder {
private final ClassName componentCreatorName;
- RootComponentImplementationBuilder(
- BindingGraph graph,
- ComponentImplementation componentImplementation,
- OptionalFactories optionalFactories,
- ComponentBindingExpressions bindingExpressions,
- ComponentRequirementExpressions componentRequirementExpressions) {
- super(
- graph,
- componentImplementation,
- optionalFactories,
- bindingExpressions,
- componentRequirementExpressions);
+ @Inject
+ RootComponentImplementationBuilder(ComponentImplementation componentImplementation) {
+ checkArgument(!componentImplementation.superclassImplementation().isPresent());
this.componentCreatorName = componentImplementation.creatorImplementation().get().name();
}
@@ -673,22 +632,12 @@
* implementation that extends an abstract base implementation. Otherwise it represents a private,
* inner, concrete, final implementation of a subcomponent which extends a user defined type.
*/
- private final class SubcomponentImplementationBuilder extends ComponentImplementationBuilder {
+ static final class SubcomponentImplementationBuilder extends ComponentImplementationBuilder {
final Optional<ComponentImplementationBuilder> parent;
+ @Inject
SubcomponentImplementationBuilder(
- Optional<ComponentImplementationBuilder> parent,
- BindingGraph graph,
- ComponentImplementation componentImplementation,
- OptionalFactories optionalFactories,
- ComponentBindingExpressions bindingExpressions,
- ComponentRequirementExpressions componentRequirementExpressions) {
- super(
- graph,
- componentImplementation,
- optionalFactories,
- bindingExpressions,
- componentRequirementExpressions);
+ @ParentComponent Optional<ComponentImplementationBuilder> parent) {
this.parent = parent;
}
diff --git a/java/dagger/internal/codegen/ComponentProcessor.java b/java/dagger/internal/codegen/ComponentProcessor.java
index 28e5af7..28be5ff 100644
--- a/java/dagger/internal/codegen/ComponentProcessor.java
+++ b/java/dagger/internal/codegen/ComponentProcessor.java
@@ -124,7 +124,8 @@
ProcessingStepsModule.class,
SourceFileGeneratorsModule.class,
SpiModule.class,
- SystemComponentsModule.class
+ SystemComponentsModule.class,
+ TopLevelImplementationComponent.InstallationModule.class,
})
interface ProcessorComponent {
void inject(ComponentProcessor processor);
diff --git a/java/dagger/internal/codegen/ComponentRequirementExpressions.java b/java/dagger/internal/codegen/ComponentRequirementExpressions.java
index ccf328e..fdd7a55 100644
--- a/java/dagger/internal/codegen/ComponentRequirementExpressions.java
+++ b/java/dagger/internal/codegen/ComponentRequirementExpressions.java
@@ -39,11 +39,13 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
+import javax.inject.Inject;
/**
* A central repository of expressions used to access any {@link ComponentRequirement} available to
* a component.
*/
+@PerComponentImplementation
final class ComponentRequirementExpressions {
// TODO(dpb,ronshapiro): refactor this and ComponentBindingExpressions into a
@@ -55,44 +57,21 @@
componentRequirementExpressions = new HashMap<>();
private final BindingGraph graph;
private final ComponentImplementation componentImplementation;
- private final DaggerTypes types;
- private final DaggerElements elements;
private final CompilerOptions compilerOptions;
- private ComponentRequirementExpressions(
- Optional<ComponentRequirementExpressions> parent,
+ // TODO(ronshapiro): give ComponentImplementation a graph() method
+ @Inject
+ ComponentRequirementExpressions(
+ @ParentComponent Optional<ComponentRequirementExpressions> parent,
BindingGraph graph,
ComponentImplementation componentImplementation,
- DaggerTypes types,
- DaggerElements elements,
CompilerOptions compilerOptions) {
this.parent = parent;
this.graph = graph;
this.componentImplementation = componentImplementation;
- this.types = types;
- this.elements = elements;
this.compilerOptions = compilerOptions;
}
- // TODO(ronshapiro): give ComponentImplementation a graph() method
- ComponentRequirementExpressions(
- BindingGraph graph,
- ComponentImplementation componentImplementation,
- DaggerTypes types,
- DaggerElements elements,
- CompilerOptions compilerOptions) {
- this(Optional.empty(), graph, componentImplementation, types, elements, compilerOptions);
- }
-
- /**
- * Returns a new object representing the expressions available from a child component of this one.
- */
- ComponentRequirementExpressions forChildComponent(
- BindingGraph graph, ComponentImplementation componentImplementation) {
- return new ComponentRequirementExpressions(
- Optional.of(this), graph, componentImplementation, types, elements, compilerOptions);
- }
-
/**
* Returns an expression for the {@code componentRequirement} to be used when implementing a
* component method. This may add a field or method to the component in order to reference the
diff --git a/java/dagger/internal/codegen/ConfigureCreatorImplementationModule.java b/java/dagger/internal/codegen/ConfigureCreatorImplementationModule.java
new file mode 100644
index 0000000..c996788
--- /dev/null
+++ b/java/dagger/internal/codegen/ConfigureCreatorImplementationModule.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 The Dagger Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dagger.internal.codegen;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import dagger.Module;
+import dagger.Provides;
+import java.lang.annotation.Retention;
+import java.util.Optional;
+import javax.inject.Qualifier;
+
+/**
+ * Breaks the initialization cycle between {@link ComponentImplementation} and it's optional {@link
+ * ComponentCreatorImplementation}, which itself needs a {@link ComponentImplementation}.
+ *
+ * <p>This module takes the component implementation that is bound elsewhere with the {@link
+ * Unconfigured} qualifier, creates the creator implementation and calls {@link
+ * ComponentImplementation#setCreatorImplementation(Optional)}.
+ */
+@Module
+interface ConfigureCreatorImplementationModule {
+ @Provides
+ @PerComponentImplementation
+ static Optional<ComponentCreatorImplementation> creatorImplementation(
+ @Unconfigured ComponentImplementation componentImplementation,
+ BindingGraph bindingGraph,
+ DaggerTypes types,
+ DaggerElements elements) {
+ return ComponentCreatorImplementation.create(
+ componentImplementation, bindingGraph, elements, types);
+ }
+
+ @Provides
+ @PerComponentImplementation
+ static ComponentImplementation componentImplementation(
+ @Unconfigured ComponentImplementation componentImplementation,
+ Optional<ComponentCreatorImplementation> componentCreatorImplementation) {
+ componentImplementation.setCreatorImplementation(componentCreatorImplementation);
+ return componentImplementation;
+ }
+
+ /**
+ * Designates that the {@link ComponentImplementation} is not yet configured with its creator
+ * implementation.
+ */
+ @Retention(RUNTIME)
+ @Qualifier
+ @interface Unconfigured {}
+}
diff --git a/java/dagger/internal/codegen/CurrentImplementationSubcomponent.java b/java/dagger/internal/codegen/CurrentImplementationSubcomponent.java
new file mode 100644
index 0000000..ffae26c
--- /dev/null
+++ b/java/dagger/internal/codegen/CurrentImplementationSubcomponent.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 The Dagger Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dagger.internal.codegen;
+
+import dagger.BindsInstance;
+import dagger.Subcomponent;
+import dagger.internal.codegen.ComponentImplementationFactory.ComponentImplementationBuilder;
+import dagger.internal.codegen.ComponentImplementationFactory.RootComponentImplementationBuilder;
+import dagger.internal.codegen.ComponentImplementationFactory.SubcomponentImplementationBuilder;
+import dagger.internal.codegen.ConfigureCreatorImplementationModule.Unconfigured;
+import java.util.Optional;
+
+/**
+ * A subcomponent that injects all objects that are responsible for creating a single {@link
+ * ComponentImplementation} instance. Each child {@link ComponentImplementation} will have its own
+ * instance of {@link CurrentImplementationSubcomponent}.
+ */
+@Subcomponent(modules = ConfigureCreatorImplementationModule.class)
+@PerComponentImplementation
+interface CurrentImplementationSubcomponent {
+ RootComponentImplementationBuilder rootComponentBuilder();
+
+ SubcomponentImplementationBuilder subcomponentBuilder();
+
+ @Subcomponent.Builder
+ interface Builder {
+ @BindsInstance
+ Builder componentImplementation(@Unconfigured ComponentImplementation componentImplementation);
+
+ @BindsInstance
+ Builder bindingGraph(BindingGraph bindingGraph);
+
+ @BindsInstance
+ Builder parentBuilder(@ParentComponent Optional<ComponentImplementationBuilder> parentBuilder);
+
+ @BindsInstance
+ Builder parentBindingExpressions(
+ @ParentComponent Optional<ComponentBindingExpressions> parentBindingExpressions);
+
+ @BindsInstance
+ Builder parentRequirementExpressions(
+ @ParentComponent Optional<ComponentRequirementExpressions> parentRequirementExpressions);
+
+ CurrentImplementationSubcomponent build();
+ }
+}
diff --git a/java/dagger/internal/codegen/OptionalFactories.java b/java/dagger/internal/codegen/OptionalFactories.java
index 9987e1e..f4c1460 100644
--- a/java/dagger/internal/codegen/OptionalFactories.java
+++ b/java/dagger/internal/codegen/OptionalFactories.java
@@ -64,14 +64,16 @@
import java.util.Optional;
import java.util.TreeMap;
import java.util.concurrent.Executor;
+import javax.inject.Inject;
import javax.inject.Provider;
/** The nested class and static methods required by the component to implement optional bindings. */
// TODO(dpb): Name members simply if a component uses only one of Guava or JDK Optional.
+@PerGeneratedFile
final class OptionalFactories {
private final ComponentImplementation componentImplementation;
- OptionalFactories(ComponentImplementation componentImplementation) {
+ @Inject OptionalFactories(@TopLevel ComponentImplementation componentImplementation) {
this.componentImplementation = componentImplementation;
}
diff --git a/java/dagger/internal/codegen/ParentComponent.java b/java/dagger/internal/codegen/ParentComponent.java
new file mode 100644
index 0000000..2d2b583
--- /dev/null
+++ b/java/dagger/internal/codegen/ParentComponent.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2018 The Dagger Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dagger.internal.codegen;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import javax.inject.Qualifier;
+
+/**
+ * A {@link Qualifier} for bindings that are associated with a component implementation's
+ * parent component.
+ */
+@Retention(RUNTIME)
+@Qualifier
+@interface ParentComponent {}
diff --git a/java/dagger/internal/codegen/PerComponentImplementation.java b/java/dagger/internal/codegen/PerComponentImplementation.java
new file mode 100644
index 0000000..5d4ba18
--- /dev/null
+++ b/java/dagger/internal/codegen/PerComponentImplementation.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2018 The Dagger Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dagger.internal.codegen;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import javax.inject.Scope;
+
+/** A {@link Scope} that encompasses a single component implementation. */
+@Retention(RUNTIME)
+@Scope
+@interface PerComponentImplementation {}
diff --git a/java/dagger/internal/codegen/PerGeneratedFile.java b/java/dagger/internal/codegen/PerGeneratedFile.java
new file mode 100644
index 0000000..c30e67a
--- /dev/null
+++ b/java/dagger/internal/codegen/PerGeneratedFile.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2018 The Dagger Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dagger.internal.codegen;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import javax.inject.Scope;
+
+/**
+ * A {@link Scope} that encompasses a top-level component implementation and any of its inner
+ * descendant component implementations in the same generated file.
+ */
+@Retention(RUNTIME)
+@Scope
+@interface PerGeneratedFile {}
diff --git a/java/dagger/internal/codegen/StaticSwitchingProviders.java b/java/dagger/internal/codegen/StaticSwitchingProviders.java
index ecc5a58..2eec431 100644
--- a/java/dagger/internal/codegen/StaticSwitchingProviders.java
+++ b/java/dagger/internal/codegen/StaticSwitchingProviders.java
@@ -36,6 +36,7 @@
import dagger.internal.codegen.FrameworkFieldInitializer.FrameworkInstanceCreationExpression;
import dagger.model.Key;
import java.util.stream.Stream;
+import javax.inject.Inject;
import javax.inject.Provider;
import javax.lang.model.type.TypeMirror;
@@ -47,11 +48,14 @@
* in the root component. Ideally, each component would get its own {@code SwitchingProvider}, but
* since the subcomponents are inner classes they cannot contain static classes.
*/
+@PerGeneratedFile
final class StaticSwitchingProviders extends SwitchingProviders {
private final DaggerTypes types;
private final ClassName owningComponent;
- StaticSwitchingProviders(ComponentImplementation componentImplementation, DaggerTypes types) {
+ @Inject
+ StaticSwitchingProviders(
+ @TopLevel ComponentImplementation componentImplementation, DaggerTypes types) {
super(componentImplementation, types);
this.types = types;
this.owningComponent = componentImplementation.name();
diff --git a/java/dagger/internal/codegen/TopLevel.java b/java/dagger/internal/codegen/TopLevel.java
new file mode 100644
index 0000000..4f456f2
--- /dev/null
+++ b/java/dagger/internal/codegen/TopLevel.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 The Dagger Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dagger.internal.codegen;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import javax.inject.Qualifier;
+
+/**
+ * A {@link Qualifier} for bindings that are associated with the top level component implementation.
+ */
+@Retention(RUNTIME)
+@Qualifier
+@interface TopLevel {}
diff --git a/java/dagger/internal/codegen/TopLevelImplementationComponent.java b/java/dagger/internal/codegen/TopLevelImplementationComponent.java
new file mode 100644
index 0000000..306c05d
--- /dev/null
+++ b/java/dagger/internal/codegen/TopLevelImplementationComponent.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2018 The Dagger Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dagger.internal.codegen;
+
+import dagger.BindsInstance;
+import dagger.Module;
+import dagger.Subcomponent;
+
+/**
+ * A shared subcomponent for a top-level {@link ComponentImplementation} and any nested child
+ * implementations.
+ */
+@PerGeneratedFile
+@Subcomponent
+interface TopLevelImplementationComponent {
+ CurrentImplementationSubcomponent.Builder currentImplementationSubcomponentBuilder();
+
+ @Subcomponent.Builder
+ interface Builder {
+ @BindsInstance
+ Builder topLevelComponent(@TopLevel ComponentImplementation topLevelImplementation);
+ TopLevelImplementationComponent build();
+ }
+
+ @Module(subcomponents = TopLevelImplementationComponent.class)
+ interface InstallationModule {}
+}