From 60ebd65f1d64e2bbd90d09bcf356b535c4190fea Mon Sep 17 00:00:00 2001 From: gak Date: Wed, 17 Aug 2016 12:48:52 -0700 Subject: [PATCH 1/4] Add an import to fix a broken javadoc tag. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=130551749 --- compiler/src/main/java/dagger/internal/codegen/BindingGraph.java | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/src/main/java/dagger/internal/codegen/BindingGraph.java b/compiler/src/main/java/dagger/internal/codegen/BindingGraph.java index 533e2681fef..e184632b252 100644 --- a/compiler/src/main/java/dagger/internal/codegen/BindingGraph.java +++ b/compiler/src/main/java/dagger/internal/codegen/BindingGraph.java @@ -56,6 +56,7 @@ import com.google.common.collect.TreeTraverser; import dagger.Component; import dagger.Reusable; +import dagger.Subcomponent; import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor; import dagger.internal.codegen.Key.HasKey; import dagger.producers.Produced; From e71823b2fc26b1bbbca151c6df56c08bd7aeb8b0 Mon Sep 17 00:00:00 2001 From: gak Date: Wed, 17 Aug 2016 12:53:16 -0700 Subject: [PATCH 2/4] Remove a redundant modifier -- all enum constructors are private ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=130552186 --- compiler/src/main/java/dagger/internal/codegen/BindingType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/main/java/dagger/internal/codegen/BindingType.java b/compiler/src/main/java/dagger/internal/codegen/BindingType.java index a2a6dcdb8e3..7041101f99b 100644 --- a/compiler/src/main/java/dagger/internal/codegen/BindingType.java +++ b/compiler/src/main/java/dagger/internal/codegen/BindingType.java @@ -45,7 +45,7 @@ interface HasBindingType { private final Class frameworkClass; - private BindingType(Class frameworkClass) { + BindingType(Class frameworkClass) { this.frameworkClass = frameworkClass; } From 8449ca3c6a59947d6df3189d7a80443c8e963609 Mon Sep 17 00:00:00 2001 From: gak Date: Thu, 18 Aug 2016 19:59:29 -0700 Subject: [PATCH 3/4] "Framework class" meant 2 things. 1) Any type owned by the framework like Provider or Lazy or Produced. 2) One of the 3 types that is the baseline representation of a binding: Provider, Producer, MembersInjector. This CL migrates any class literal used to represent (2) to use BindingType instead. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=130712137 --- .../codegen/AbstractComponentWriter.java | 2 +- .../java/dagger/internal/codegen/Binding.java | 7 - .../dagger/internal/codegen/BindingType.java | 5 + .../internal/codegen/BindingTypeMapper.java | 100 +++++++++++ .../internal/codegen/ContributionBinding.java | 2 +- .../codegen/DependencyRequestMapper.java | 104 ------------ .../internal/codegen/FrameworkDependency.java | 17 +- .../codegen/BindingTypeMapperTest.java | 66 ++++++++ .../codegen/DependencyRequestMapperTest.java | 155 ------------------ 9 files changed, 183 insertions(+), 275 deletions(-) create mode 100644 compiler/src/main/java/dagger/internal/codegen/BindingTypeMapper.java delete mode 100644 compiler/src/main/java/dagger/internal/codegen/DependencyRequestMapper.java create mode 100644 compiler/src/test/java/dagger/internal/codegen/BindingTypeMapperTest.java delete mode 100644 compiler/src/test/java/dagger/internal/codegen/DependencyRequestMapperTest.java diff --git a/compiler/src/main/java/dagger/internal/codegen/AbstractComponentWriter.java b/compiler/src/main/java/dagger/internal/codegen/AbstractComponentWriter.java index 8778e424889..64b78268e4b 100644 --- a/compiler/src/main/java/dagger/internal/codegen/AbstractComponentWriter.java +++ b/compiler/src/main/java/dagger/internal/codegen/AbstractComponentWriter.java @@ -839,7 +839,7 @@ private Optional initializeContributionBinding(BindingKey bindingKey) case DELEGATE: CodeBlock delegatingCodeBlock = CodeBlock.of( "($T) $L", - binding.frameworkClass(), + binding.bindingType().frameworkClass(), getMemberSelect( Iterables.getOnlyElement(binding.dependencies()).bindingKey()) .getExpressionFor(name)); diff --git a/compiler/src/main/java/dagger/internal/codegen/Binding.java b/compiler/src/main/java/dagger/internal/codegen/Binding.java index 27e41297060..159745000d8 100644 --- a/compiler/src/main/java/dagger/internal/codegen/Binding.java +++ b/compiler/src/main/java/dagger/internal/codegen/Binding.java @@ -50,13 +50,6 @@ */ abstract class Binding extends BindingDeclaration implements HasBindingType { - /** - * Returns the framework class associated with this binding. - */ - Class frameworkClass() { - return bindingType().frameworkClass(); - } - /** The {@link Key} that is provided by this binding. */ @Override public abstract Key key(); diff --git a/compiler/src/main/java/dagger/internal/codegen/BindingType.java b/compiler/src/main/java/dagger/internal/codegen/BindingType.java index 7041101f99b..50220094dd0 100644 --- a/compiler/src/main/java/dagger/internal/codegen/BindingType.java +++ b/compiler/src/main/java/dagger/internal/codegen/BindingType.java @@ -19,6 +19,8 @@ import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; import dagger.MembersInjector; import dagger.producers.Producer; import javax.inject.Provider; @@ -37,6 +39,9 @@ enum BindingType { PRODUCTION(Producer.class), ; + static final ImmutableSet CONTRIBUTION_TYPES = + Sets.immutableEnumSet(PROVISION, PRODUCTION); + /** An object that is associated with a {@link BindingType}. */ interface HasBindingType { /** The binding type of this object. */ diff --git a/compiler/src/main/java/dagger/internal/codegen/BindingTypeMapper.java b/compiler/src/main/java/dagger/internal/codegen/BindingTypeMapper.java new file mode 100644 index 00000000000..e5c2bbdfed1 --- /dev/null +++ b/compiler/src/main/java/dagger/internal/codegen/BindingTypeMapper.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2014 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 com.google.common.collect.Iterables.getOnlyElement; +import static dagger.internal.codegen.BindingType.CONTRIBUTION_TYPES; +import static dagger.internal.codegen.BindingType.MEMBERS_INJECTION; +import static dagger.internal.codegen.BindingType.PRODUCTION; +import static dagger.internal.codegen.BindingType.PROVISION; + +import com.google.common.base.Function; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableSet; +import dagger.producers.Producer; +import javax.inject.Provider; + +/** + * A mapper for associating a {@link DependencyRequest.Kind} to a {@link BindingType}, dependent on + * the type of code to be generated (e.g., for {@link Provider} or {@link Producer}). + */ +enum BindingTypeMapper { + FOR_PROVIDER() { + @Override public BindingType getBindingType(DependencyRequest.Kind requestKind) { + switch (requestKind) { + case INSTANCE: + case PROVIDER: + case PROVIDER_OF_LAZY: + case LAZY: + return PROVISION; + case MEMBERS_INJECTOR: + return MEMBERS_INJECTION; + case PRODUCED: + case PRODUCER: + throw new IllegalArgumentException(requestKind.toString()); + default: + throw new AssertionError(requestKind); + } + } + }, + FOR_PRODUCER() { + @Override public BindingType getBindingType(DependencyRequest.Kind requestKind) { + switch (requestKind) { + case INSTANCE: + case PRODUCED: + case PRODUCER: + return PRODUCTION; + case PROVIDER: + case PROVIDER_OF_LAZY: + case LAZY: + return PROVISION; + case MEMBERS_INJECTOR: + return MEMBERS_INJECTION; + default: + throw new AssertionError(requestKind); + } + } + }; + + static BindingTypeMapper forBindingType(BindingType bindingType) { + return bindingType.equals(PRODUCTION) ? FOR_PRODUCER : FOR_PROVIDER; + } + + abstract BindingType getBindingType(DependencyRequest.Kind requestKind); + + /** + * Returns the {@link BindingType} to use for a collection of requests of the same + * {@link BindingKey}. This allows factories to only take a single argument for multiple requests + * of the same key. + */ + BindingType getBindingType(Iterable requests) { + ImmutableSet classes = FluentIterable.from(requests) + .transform(new Function() { + @Override public BindingType apply(DependencyRequest request) { + return getBindingType(request.kind()); + } + }) + .toSet(); + if (classes.size() == 1) { + return getOnlyElement(classes); + } else if (classes.equals(CONTRIBUTION_TYPES)) { + return PROVISION; + } else { + throw new IllegalArgumentException("Bad set of framework classes: " + classes); + } + } +} diff --git a/compiler/src/main/java/dagger/internal/codegen/ContributionBinding.java b/compiler/src/main/java/dagger/internal/codegen/ContributionBinding.java index 48ac39a012f..eec00e88fe8 100644 --- a/compiler/src/main/java/dagger/internal/codegen/ContributionBinding.java +++ b/compiler/src/main/java/dagger/internal/codegen/ContributionBinding.java @@ -214,7 +214,7 @@ FactoryCreationStrategy factoryCreationStrategy() { final TypeMirror factoryType() { switch (contributionType()) { case MAP: - return MapType.from(key()).unwrappedValueType(frameworkClass()); + return MapType.from(key()).unwrappedValueType(bindingType().frameworkClass()); case SET: return SetType.from(key()).elementType(); case SET_VALUES: diff --git a/compiler/src/main/java/dagger/internal/codegen/DependencyRequestMapper.java b/compiler/src/main/java/dagger/internal/codegen/DependencyRequestMapper.java deleted file mode 100644 index 1a8f644a153..00000000000 --- a/compiler/src/main/java/dagger/internal/codegen/DependencyRequestMapper.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2014 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 com.google.common.collect.Iterables.getOnlyElement; - -import com.google.common.base.Function; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableSet; -import dagger.MembersInjector; -import dagger.producers.Producer; -import javax.inject.Provider; - -/** - * A mapper for associating a {@link DependencyRequest} to a framework class, dependent on - * the type of code to be generated (e.g., for {@link Provider} or {@link Producer}). - * - * @author Jesse Beder - * @since 2.0 - */ -abstract class DependencyRequestMapper { - abstract Class getFrameworkClass(DependencyRequest request); - - /** - * Returns the framework class to use for a collection of requests of the same {@link BindingKey}. - * This allows factories to only take a single argument for multiple requests of the same key. - */ - Class getFrameworkClass(Iterable requests) { - ImmutableSet> classes = FluentIterable.from(requests) - .transform(new Function>() { - @Override public Class apply(DependencyRequest request) { - return getFrameworkClass(request); - } - }) - .toSet(); - if (classes.size() == 1) { - return getOnlyElement(classes); - } else if (classes.equals(ImmutableSet.of(Producer.class, Provider.class))) { - return Provider.class; - } else { - throw new IllegalStateException("Bad set of framework classes: " + classes); - } - } - - private static final class MapperForProvider extends DependencyRequestMapper { - @Override public Class getFrameworkClass(DependencyRequest request) { - switch (request.kind()) { - case INSTANCE: - case PROVIDER: - case PROVIDER_OF_LAZY: - case LAZY: - return Provider.class; - case MEMBERS_INJECTOR: - return MembersInjector.class; - case PRODUCED: - case PRODUCER: - throw new IllegalArgumentException(); - default: - throw new AssertionError(); - } - } - } - - static final DependencyRequestMapper FOR_PROVIDER = new MapperForProvider(); - - private static final class MapperForProducer extends DependencyRequestMapper { - @Override public Class getFrameworkClass(DependencyRequest request) { - switch (request.kind()) { - case INSTANCE: - case PRODUCED: - case PRODUCER: - return Producer.class; - case PROVIDER: - case PROVIDER_OF_LAZY: - case LAZY: - return Provider.class; - case MEMBERS_INJECTOR: - return MembersInjector.class; - default: - throw new AssertionError(); - } - } - } - - static final DependencyRequestMapper FOR_PRODUCER = new MapperForProducer(); - - static DependencyRequestMapper forBindingType(BindingType bindingType) { - return bindingType.equals(BindingType.PRODUCTION) ? FOR_PRODUCER : FOR_PROVIDER; - } -} diff --git a/compiler/src/main/java/dagger/internal/codegen/FrameworkDependency.java b/compiler/src/main/java/dagger/internal/codegen/FrameworkDependency.java index a5dfed2dde8..ceb82035013 100644 --- a/compiler/src/main/java/dagger/internal/codegen/FrameworkDependency.java +++ b/compiler/src/main/java/dagger/internal/codegen/FrameworkDependency.java @@ -57,10 +57,13 @@ abstract class FrameworkDependency { */ abstract BindingKey bindingKey(); - /** - * The framework class to use for these requests. - */ - abstract Class frameworkClass(); + /** The binding type of the framework dependency. */ + abstract BindingType bindingType(); + + /** The framework class to use for these requests. */ + final Class frameworkClass() { + return bindingType().frameworkClass(); + } /** * The dependency requests that are all satisfied by one framework instance. @@ -99,8 +102,8 @@ abstract class FrameworkDependency { * instances of Binding, because it really depends on the order of the binding's dependencies, * and two equal instances of Binding may have the same dependencies in a different order. */ static ImmutableSet frameworkDependenciesForBinding(Binding binding) { - DependencyRequestMapper dependencyRequestMapper = - DependencyRequestMapper.forBindingType(binding.bindingType()); + BindingTypeMapper bindingTypeMapper = + BindingTypeMapper.forBindingType(binding.bindingType()); ImmutableSet.Builder frameworkDependencies = ImmutableSet.builder(); for (Collection requests : groupByUnresolvedKey(binding)) { frameworkDependencies.add( @@ -109,7 +112,7 @@ static ImmutableSet frameworkDependenciesForBinding(Binding FluentIterable.from(requests) .transform(DependencyRequest.BINDING_KEY_FUNCTION) .toSet()), - dependencyRequestMapper.getFrameworkClass(requests), + bindingTypeMapper.getBindingType(requests), ImmutableSet.copyOf(requests))); } return frameworkDependencies.build(); diff --git a/compiler/src/test/java/dagger/internal/codegen/BindingTypeMapperTest.java b/compiler/src/test/java/dagger/internal/codegen/BindingTypeMapperTest.java new file mode 100644 index 00000000000..51b91f6b7df --- /dev/null +++ b/compiler/src/test/java/dagger/internal/codegen/BindingTypeMapperTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2014 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 com.google.common.truth.Truth.assertThat; +import static dagger.internal.codegen.BindingType.MEMBERS_INJECTION; +import static dagger.internal.codegen.BindingType.PRODUCTION; +import static dagger.internal.codegen.BindingType.PROVISION; +import static dagger.internal.codegen.DependencyRequest.Kind.INSTANCE; +import static dagger.internal.codegen.DependencyRequest.Kind.LAZY; +import static dagger.internal.codegen.DependencyRequest.Kind.MEMBERS_INJECTOR; +import static dagger.internal.codegen.DependencyRequest.Kind.PRODUCED; +import static dagger.internal.codegen.DependencyRequest.Kind.PRODUCER; +import static dagger.internal.codegen.DependencyRequest.Kind.PROVIDER; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Test case for {@link BindingTypeMapper}. + */ +@RunWith(JUnit4.class) +public class BindingTypeMapperTest { + @Test public void forProvider() { + BindingTypeMapper mapper = BindingTypeMapper.FOR_PROVIDER; + assertThat(mapper.getBindingType(INSTANCE)) + .isEqualTo(PROVISION); + assertThat(mapper.getBindingType(LAZY)) + .isEqualTo(PROVISION); + assertThat(mapper.getBindingType(PROVIDER)) + .isEqualTo(PROVISION); + assertThat(mapper.getBindingType(MEMBERS_INJECTOR)) + .isEqualTo(MEMBERS_INJECTION); + } + + @Test public void forProducer() { + BindingTypeMapper mapper = BindingTypeMapper.FOR_PRODUCER; + assertThat(mapper.getBindingType(INSTANCE)) + .isEqualTo(PRODUCTION); + assertThat(mapper.getBindingType(LAZY)) + .isEqualTo(PROVISION); + assertThat(mapper.getBindingType(PROVIDER)) + .isEqualTo(PROVISION); + assertThat(mapper.getBindingType(MEMBERS_INJECTOR)) + .isEqualTo(MEMBERS_INJECTION); + assertThat(mapper.getBindingType(PRODUCER)) + .isEqualTo(PRODUCTION); + assertThat(mapper.getBindingType(PRODUCED)) + .isEqualTo(PRODUCTION); + } +} diff --git a/compiler/src/test/java/dagger/internal/codegen/DependencyRequestMapperTest.java b/compiler/src/test/java/dagger/internal/codegen/DependencyRequestMapperTest.java deleted file mode 100644 index 40a12db0b47..00000000000 --- a/compiler/src/test/java/dagger/internal/codegen/DependencyRequestMapperTest.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2014 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 com.google.common.truth.Truth.assertThat; - -import com.google.common.collect.Iterables; -import com.google.testing.compile.CompilationRule; -import dagger.Lazy; -import dagger.MembersInjector; -import dagger.Module; -import dagger.Provides; -import dagger.producers.Produced; -import dagger.producers.Producer; -import dagger.producers.ProducerModule; -import dagger.producers.Produces; -import java.util.List; -import javax.inject.Provider; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.util.ElementFilter; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Test case for {@link DependencyRequestMapper}. - */ -@RunWith(JUnit4.class) -public class DependencyRequestMapperTest { - @Rule public CompilationRule compilationRule = new CompilationRule(); - - private Elements elements; - private Types types; - private Key.Factory keyFactory; - private DependencyRequest.Factory dependencyRequestFactory; - - @Before public void setUp() { - this.types = compilationRule.getTypes(); - this.elements = compilationRule.getElements(); - this.keyFactory = new Key.Factory(types, elements); - this.dependencyRequestFactory = new DependencyRequest.Factory(keyFactory); - } - - private List sampleProviderParameters() { - TypeElement moduleElement = - elements.getTypeElement(ProvidesMethodModule.class.getCanonicalName()); - ExecutableElement providesMethod = - Iterables.getOnlyElement(ElementFilter.methodsIn(moduleElement.getEnclosedElements())); - return providesMethod.getParameters(); - } - - private List sampleProducerParameters() { - TypeElement moduleElement = - elements.getTypeElement(ProducesMethodModule.class.getCanonicalName()); - ExecutableElement producesMethod = - Iterables.getOnlyElement(ElementFilter.methodsIn(moduleElement.getEnclosedElements())); - return producesMethod.getParameters(); - } - - private DependencyRequest dependencyRequestForInstance() { - return dependencyRequestFactory.forRequiredVariable(sampleProviderParameters().get(0)); - } - - private DependencyRequest dependencyRequestForLazy() { - return dependencyRequestFactory.forRequiredVariable(sampleProviderParameters().get(1)); - } - - private DependencyRequest dependencyRequestForProvider() { - return dependencyRequestFactory.forRequiredVariable(sampleProviderParameters().get(2)); - } - - private DependencyRequest dependencyRequestForMembersInjector() { - return dependencyRequestFactory.forRequiredVariable(sampleProviderParameters().get(3)); - } - - private DependencyRequest dependencyRequestForProducer() { - return dependencyRequestFactory.forRequiredVariable(sampleProducerParameters().get(0)); - } - - private DependencyRequest dependencyRequestForProduced() { - return dependencyRequestFactory.forRequiredVariable(sampleProducerParameters().get(1)); - } - - @Test public void forProvider() { - DependencyRequestMapper mapper = DependencyRequestMapper.FOR_PROVIDER; - assertThat(mapper.getFrameworkClass(dependencyRequestForInstance())) - .isEqualTo(Provider.class); - assertThat(mapper.getFrameworkClass(dependencyRequestForLazy())) - .isEqualTo(Provider.class); - assertThat(mapper.getFrameworkClass(dependencyRequestForProvider())) - .isEqualTo(Provider.class); - assertThat(mapper.getFrameworkClass(dependencyRequestForMembersInjector())) - .isEqualTo(MembersInjector.class); - } - - @Test public void forProducer() { - DependencyRequestMapper mapper = DependencyRequestMapper.FOR_PRODUCER; - assertThat(mapper.getFrameworkClass(dependencyRequestForInstance())) - .isEqualTo(Producer.class); - assertThat(mapper.getFrameworkClass(dependencyRequestForLazy())) - .isEqualTo(Provider.class); - assertThat(mapper.getFrameworkClass(dependencyRequestForProvider())) - .isEqualTo(Provider.class); - assertThat(mapper.getFrameworkClass(dependencyRequestForMembersInjector())) - .isEqualTo(MembersInjector.class); - assertThat(mapper.getFrameworkClass(dependencyRequestForProducer())) - .isEqualTo(Producer.class); - assertThat(mapper.getFrameworkClass(dependencyRequestForProduced())) - .isEqualTo(Producer.class); - } - - @Module - static final class ProvidesMethodModule { - @Provides - static String provideString( - @SuppressWarnings("unused") Integer a, - @SuppressWarnings("unused") Lazy b, - @SuppressWarnings("unused") Provider c, - @SuppressWarnings("unused") MembersInjector d) { - throw new UnsupportedOperationException(); - } - } - - @ProducerModule - static final class ProducesMethodModule { - @Produces - static String produceString( - @SuppressWarnings("unused") Producer a, - @SuppressWarnings("unused") Produced b) { - return null; - } - } - - static final class Y {} -} From d434756d2aa3144dc68759128d0dba162e251742 Mon Sep 17 00:00:00 2001 From: ronshapiro Date: Fri, 19 Aug 2016 14:07:34 -0700 Subject: [PATCH 4/4] Check component dependencies for invalid class types ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=130789545 --- .../internal/codegen/ComponentValidator.java | 5 +++ .../codegen/ConfigurationAnnotations.java | 25 +++++++++++++ .../codegen/ComponentProcessorTest.java | 36 +++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/compiler/src/main/java/dagger/internal/codegen/ComponentValidator.java b/compiler/src/main/java/dagger/internal/codegen/ComponentValidator.java index ed5a3479989..199c4a4bdab 100644 --- a/compiler/src/main/java/dagger/internal/codegen/ComponentValidator.java +++ b/compiler/src/main/java/dagger/internal/codegen/ComponentValidator.java @@ -18,8 +18,10 @@ import static com.google.auto.common.MoreElements.getAnnotationMirror; import static dagger.internal.codegen.ConfigurationAnnotations.enclosedBuilders; +import static dagger.internal.codegen.ConfigurationAnnotations.getComponentDependencies; import static dagger.internal.codegen.ConfigurationAnnotations.getComponentModules; import static dagger.internal.codegen.ConfigurationAnnotations.getTransitiveModules; +import static dagger.internal.codegen.ConfigurationAnnotations.validateComponentDependencies; import static dagger.internal.codegen.ErrorMessages.COMPONENT_ANNOTATED_REUSABLE; import static javax.lang.model.element.ElementKind.CLASS; import static javax.lang.model.element.ElementKind.INTERFACE; @@ -239,6 +241,9 @@ public ComponentValidationReport validate(final TypeElement subject, AnnotationMirror componentMirror = getAnnotationMirror(subject, componentKind.annotationType()).get(); + if (componentKind.isTopLevel()) { + validateComponentDependencies(builder, getComponentDependencies(componentMirror)); + } ImmutableList moduleTypes = getComponentModules(componentMirror); moduleValidator.validateReferencedModules( subject, builder, moduleTypes, componentKind.moduleKinds()); diff --git a/compiler/src/main/java/dagger/internal/codegen/ConfigurationAnnotations.java b/compiler/src/main/java/dagger/internal/codegen/ConfigurationAnnotations.java index e66efd92425..d1091550b67 100644 --- a/compiler/src/main/java/dagger/internal/codegen/ConfigurationAnnotations.java +++ b/compiler/src/main/java/dagger/internal/codegen/ConfigurationAnnotations.java @@ -48,6 +48,7 @@ import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; import javax.lang.model.util.SimpleAnnotationValueVisitor6; +import javax.lang.model.util.SimpleTypeVisitor6; import javax.lang.model.util.Types; /** @@ -110,6 +111,30 @@ static ImmutableList convertClassArrayToListOfTypes( return TO_LIST_OF_TYPES.visit(getAnnotationValue(annotationMirror, elementName), elementName); } + static void validateComponentDependencies( + ValidationReport.Builder report, Iterable types) { + validateTypesAreDeclared(report, types, "component dependency"); + } + + private static void validateTypesAreDeclared( + final ValidationReport.Builder report, Iterable types, final String typeName) { + for (TypeMirror type : types) { + type.accept(new SimpleTypeVisitor6(){ + @Override + protected Void defaultAction(TypeMirror e, Void aVoid) { + report.addError(String.format("%s is not a valid %s type", e, typeName)); + return null; + } + + @Override + public Void visitDeclared(DeclaredType t, Void aVoid) { + // Declared types are valid + return null; + } + }, null); + } + } + private static final AnnotationValueVisitor, String> TO_LIST_OF_TYPES = new SimpleAnnotationValueVisitor6, String>() { @Override diff --git a/compiler/src/test/java/dagger/internal/codegen/ComponentProcessorTest.java b/compiler/src/test/java/dagger/internal/codegen/ComponentProcessorTest.java index 25ff4dc0f68..be07f2366fa 100644 --- a/compiler/src/test/java/dagger/internal/codegen/ComponentProcessorTest.java +++ b/compiler/src/test/java/dagger/internal/codegen/ComponentProcessorTest.java @@ -2388,6 +2388,42 @@ public void attemptToInjectWildcardGenerics() { .onLine(10); } + @Test + public void invalidComponentDependencies() { + JavaFileObject testComponent = + JavaFileObjects.forSourceLines( + "test.TestComponent", + "package test;", + "", + "import dagger.Component;", + "", + "@Component(dependencies = int.class)", + "interface TestComponent {}"); + assertAbout(javaSources()) + .that(asList(testComponent)) + .processedWith(new ComponentProcessor()) + .failsToCompile() + .withErrorContaining("int is not a valid component dependency type"); + } + + @Test + public void invalidComponentModules() { + JavaFileObject testComponent = + JavaFileObjects.forSourceLines( + "test.TestComponent", + "package test;", + "", + "import dagger.Component;", + "", + "@Component(modules = int.class)", + "interface TestComponent {}"); + assertAbout(javaSources()) + .that(asList(testComponent)) + .processedWith(new ComponentProcessor()) + .failsToCompile() + .withErrorContaining("int is not a valid module type"); + } + /** * A {@link ComponentProcessor} that excludes elements using a {@link Predicate}. */