diff --git a/dagger-compiler/main/java/dagger/internal/codegen/validation/InjectValidator.java b/dagger-compiler/main/java/dagger/internal/codegen/validation/InjectValidator.java index 8eb22b2259e..736bb709812 100644 --- a/dagger-compiler/main/java/dagger/internal/codegen/validation/InjectValidator.java +++ b/dagger-compiler/main/java/dagger/internal/codegen/validation/InjectValidator.java @@ -19,6 +19,7 @@ import static com.google.common.collect.Iterables.getOnlyElement; import static dagger.internal.codegen.base.Util.reentrantComputeIfAbsent; import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.assistedInjectedConstructors; +import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.isAssistedParameter; import static dagger.internal.codegen.binding.InjectionAnnotations.injectedConstructors; import static dagger.internal.codegen.binding.SourceFiles.factoryNameForElement; import static dagger.internal.codegen.binding.SourceFiles.membersInjectorNameForType; @@ -204,6 +205,8 @@ private ValidationReport validateConstructor(XConstructorElement constructorElem .map(XAnnotations::asClassName) .get(); + boolean isAssistedInjectConstructor = XTypeNames.ASSISTED_INJECT.equals(injectAnnotation); + if (constructorElement.isPrivate()) { builder.addError( "Dagger does not support injection into private constructors", constructorElement); @@ -243,6 +246,9 @@ private ValidationReport validateConstructor(XConstructorElement constructorElem for (XExecutableParameterElement parameter : constructorElement.getParameters()) { superficialValidation.validateTypeOf(parameter); validateDependencyRequest(builder, parameter); + if (!isAssistedInjectConstructor && isAssistedParameter(parameter)) { + builder.addError(String.format("@Assisted parameter \"%s\" can only be used within an @AssistedInject-annotated constructor.", parameter.getName()), parameter); + } } if (throwsCheckedExceptions(constructorElement)) { @@ -277,7 +283,7 @@ private ValidationReport validateConstructor(XConstructorElement constructorElem // Note: superficial validation of the annotations is done as part of getting the scopes. ImmutableSet scopes = injectionAnnotations.getScopes(constructorElement.getEnclosingElement()); - if (injectAnnotation.equals(XTypeNames.ASSISTED_INJECT)) { + if (isAssistedInjectConstructor) { for (Scope scope : scopes) { builder.addError( "A type with an @AssistedInject-annotated constructor cannot be scoped", diff --git a/javatests/dagger/internal/codegen/AssistedFactoryErrorsTest.java b/javatests/dagger/internal/codegen/AssistedFactoryErrorsTest.java index a266fd111a6..b49f6d87716 100644 --- a/javatests/dagger/internal/codegen/AssistedFactoryErrorsTest.java +++ b/javatests/dagger/internal/codegen/AssistedFactoryErrorsTest.java @@ -762,9 +762,10 @@ public void testMultipleInjectAnnotations() { .withProcessingOptions(compilerMode.processorOptions()) .compile( subject -> { - subject.hasErrorCount(1); + subject.hasErrorCount(2); subject.hasErrorContaining( "Constructors cannot be annotated with both @Inject and @AssistedInject"); + subject.hasErrorContaining("@Assisted parameter \"i\" can only be used within an @AssistedInject-annotated constructor."); }); }