Skip to content

Commit

Permalink
Ban @Inject protected field.
Browse files Browse the repository at this point in the history
RELNOTES=Ban @Inject protected field.
PiperOrigin-RevId: 595746282
  • Loading branch information
wanyingd1996 authored and Dagger Team committed Jan 4, 2024
1 parent 09289eb commit 408431a
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 1 deletion.
10 changes: 10 additions & 0 deletions java/dagger/internal/codegen/validation/InjectValidator.java
Expand Up @@ -64,6 +64,7 @@
*/
@Singleton
public final class InjectValidator implements ClearableCache {

private final XProcessingEnv processingEnv;
private final CompilerOptions compilerOptions;
private final DependencyRequestValidator dependencyRequestValidator;
Expand Down Expand Up @@ -298,6 +299,15 @@ private ValidationReport validateField(XFieldElement fieldElement) {
fieldElement);
}

if (fieldElement.isProtected()
&& fieldElement.getEnclosingElement().isFromKotlin()
) {
builder.addItem(
"Dagger injector does not have access to kotlin protected fields",
staticMemberDiagnosticKind(),
fieldElement);
}

validateDependencyRequest(builder, fieldElement);

return builder.build();
Expand Down
85 changes: 84 additions & 1 deletion javatests/dagger/internal/codegen/MembersInjectionTest.java
Expand Up @@ -45,6 +45,88 @@ public MembersInjectionTest(CompilerMode compilerMode) {
this.compilerMode = compilerMode;
}

@Test
public void injectKotlinProtectField_fails() {
Source injectFieldSrc =
CompilerTests.kotlinSource(
"MyClass.kt",
"package test",
"",
"import javax.inject.Inject",
"",
"class MyClass @Inject constructor() {",
" @Inject protected lateinit var protectedField: String",
"}");
Source moduleSrc =
CompilerTests.kotlinSource(
"MyModule.kt",
"package test",
"",
"import dagger.Module",
"import dagger.Provides",
"",
"@Module",
"object MyModule {",
" @Provides",
" fun providesString() = \"hello\"",
"}");
Source componentSrc =
CompilerTests.kotlinSource(
"MyComponent.kt",
"package test",
"",
"import dagger.Component",
"@Component(modules = [MyModule::class])",
"interface MyComponent {}");
CompilerTests.daggerCompiler(injectFieldSrc, moduleSrc, componentSrc)
.withProcessingOptions(compilerMode.processorOptions())
.compile(
subject -> {
subject.hasErrorCount(1);
subject.hasErrorContaining(
"Dagger injector does not have access to kotlin protected fields");
});
}

@Test
public void injectJavaProtectField_succeeds() {
Source injectFieldSrc =
CompilerTests.javaSource(
"test.MyClass",
"package test;",
"",
"import javax.inject.Inject;",
"",
"public final class MyClass {",
" @Inject MyClass() {}",
" @Inject protected String protectedField;",
"}");
Source moduleSrc =
CompilerTests.kotlinSource(
"MyModule.kt",
"package test",
"",
"import dagger.Module",
"import dagger.Provides",
"",
"@Module",
"object MyModule {",
" @Provides",
" fun providesString() = \"hello\"",
"}");
Source componentSrc =
CompilerTests.kotlinSource(
"MyComponent.kt",
"package test",
"",
"import dagger.Component",
"@Component(modules = [MyModule::class])",
"interface MyComponent {}");
CompilerTests.daggerCompiler(injectFieldSrc, moduleSrc, componentSrc)
.withProcessingOptions(compilerMode.processorOptions())
.compile(subject -> subject.hasErrorCount(0));
}

@Test
public void parentClass_noInjectedMembers() throws Exception {
Source childFile =
Expand Down Expand Up @@ -159,7 +241,8 @@ public void parentClass_injectedMembersInSupertype() throws Exception {
.compile(
subject -> {
subject.hasErrorCount(0);
subject.generatedSource(goldenFileRule.goldenSource("test/GenericClass_MembersInjector"));
subject.generatedSource(
goldenFileRule.goldenSource("test/GenericClass_MembersInjector"));
});
}

Expand Down

1 comment on commit 408431a

@wanyingd1996
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.