Skip to content

Commit

Permalink
Fix issue with using generic types in Dagger's ClassKey
Browse files Browse the repository at this point in the history
The issue here was that `AnnotationExpression` was using `XType#getTypeName()` resulting in `GenericType<?>.class` in generated code. This CL fixes the issue by using `XTypeElement#getClassName()` instead so that the generated code results in `GenericType.class` instead.

See #4055.

Fixes #4055

RELNOTES=Fixes #4055:
PiperOrigin-RevId: 562096148
  • Loading branch information
bcorso authored and Dagger Team committed Sep 2, 2023
1 parent 7b3e523 commit 9852b42
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ CodeBlock getValueExpression(XAnnotationValue value) {
} else if (value.hasAnnotationValue()) {
return getAnnotationInstanceExpression(value.asAnnotation());
} else if (value.hasTypeValue()) {
return CodeBlock.of("$T.class", value.asType().getTypeName());
return CodeBlock.of("$T.class", value.asType().getTypeElement().getClassName());
} else if (value.hasStringValue()) {
return CodeBlock.of("$S", value.asString());
} else if (value.hasByteValue()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (C) 2023 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.functional.kotlinsrc.multibindings

import com.google.common.truth.Truth.assertThat
import dagger.Component
import dagger.Module
import dagger.Provides
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

@RunWith(JUnit4::class)
class ClassKeyWithGenericsTest {
@Component(modules = [TestModule::class])
interface TestComponent {
val map: Map<Class<*>, String>
}

@Module
internal object TestModule {
@Provides
@IntoMap
@ClassKey(Thing::class)
fun provideThingValue(): String = "Thing"

@Provides
@IntoMap
@ClassKey(GenericThing::class)
fun provideAbstractThingValue(): String = "GenericThing"
}

class Thing

class GenericThing<T>

@Test
fun test() {
val map = DaggerClassKeyWithGenericsTest_TestComponent.create().map
assertThat(map)
.containsExactly(
Thing::class.java, "Thing",
GenericThing::class.java, "GenericThing");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* 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.functional.multibindings;

import static com.google.common.truth.Truth.assertThat;

import dagger.Component;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.ClassKey;
import dagger.multibindings.IntoMap;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

// This is a regression test for https://github.com/google/dagger/issues/4055.
@RunWith(JUnit4.class)
public final class ClassKeyWithGenericsTest {
@Component(modules = TestModule.class)
interface TestComponent {
Map<Class<?>, String> map();
}

@Module
interface TestModule {
@Provides
@IntoMap
@ClassKey(Thing.class)
static String provideThingValue() {
return "Thing";
}

@Provides
@IntoMap
@ClassKey(GenericThing.class)
static String provideGenericThingValue() {
return "GenericThing";
}
}

class Thing {}

class GenericThing<T> {}

@Test
public void test() {
Map<Class<?>, String> map = DaggerClassKeyWithGenericsTest_TestComponent.create().map();
assertThat(map)
.containsExactly(
Thing.class, "Thing",
GenericThing.class, "GenericThing");
}
}

0 comments on commit 9852b42

Please sign in to comment.