Skip to content

Commit 2b5fc5b

Browse files
authored
fix generic wildcard field injection (#956)
1 parent 9bf19e7 commit 2b5fc5b

File tree

4 files changed

+34
-13
lines changed

4 files changed

+34
-13
lines changed

inject-generator/src/main/java/io/avaje/inject/generator/FieldReader.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package io.avaje.inject.generator;
22

3-
import javax.lang.model.element.Element;
43
import java.util.List;
54
import java.util.Set;
65

6+
import javax.lang.model.element.Element;
7+
import javax.lang.model.type.TypeKind;
8+
79
final class FieldReader {
810

911
private final Element element;
@@ -54,12 +56,13 @@ void addImports(ImportTypeMap importTypes) {
5456

5557
String builderGetDependency(String builder) {
5658
final var sb = new StringBuilder();
57-
sb.append(builder).append(".").append(utype.getMethod(nullable, isBeanMap));
58-
if (isGenericParam()) {
59+
final boolean wildcard = isWildcard();
60+
final var wildParam = wildcard ? String.format("<%s>", type.shortWithoutAnnotations()) : "";
61+
sb.append(builder).append(".").append(wildParam).append(utype.getMethod(nullable, isBeanMap));
62+
if (!wildcard && isGenericParam()) {
5963
sb.append("TYPE_").append(Util.shortName(type).replace(".", "_"));
6064
} else {
61-
var trimmed = ProcessorUtils.trimAnnotations(fieldType);
62-
sb.append(Util.shortName(trimmed)).append(".class");
65+
sb.append(Util.shortName(type.mainType())).append(".class");
6366
}
6467
if (name != null) {
6568
sb.append(",\"").append(name).append("\"");
@@ -68,6 +71,12 @@ String builderGetDependency(String builder) {
6871
return sb.toString();
6972
}
7073

74+
75+
private boolean isWildcard() {
76+
return type.isGeneric()
77+
&& type.componentTypes().stream().allMatch(g -> g.kind() == TypeKind.WILDCARD);
78+
}
79+
7180
void removeFromProvides(List<UType> provides) {
7281
provides.remove(type);
7382
}

inject-generator/src/main/java/io/avaje/inject/generator/ProcessingContext.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.TreeSet;
2929

3030
import javax.annotation.processing.FilerException;
31+
import javax.lang.model.element.ModuleElement;
3132
import javax.lang.model.element.TypeElement;
3233
import javax.lang.model.type.TypeMirror;
3334
import javax.tools.FileObject;
@@ -154,9 +155,8 @@ static FileObject createMetaInfWriterFor(String interfaceType) throws IOExceptio
154155
static TypeElement elementMaybe(String rawType) {
155156
if (rawType == null) {
156157
return null;
157-
} else {
158-
return elements().getTypeElement(rawType);
159158
}
159+
return elements().getTypeElement(rawType);
160160
}
161161

162162
static TypeElement asElement(TypeMirror returnType) {
@@ -290,10 +290,17 @@ static void writeSPIServicesFile() {
290290
}
291291

292292
private static boolean isOnModulePath(String service) {
293-
var module = APContext.elements().getModuleOf(APContext.typeElement(service)).getQualifiedName().toString();
294-
295-
return CTX.get().hasProvidesPlugin && AVAJE_PROVIDED_PLUGIN.contains(module)
296-
|| APContext.moduleInfoReader().orElseThrow().containsOnModulePath(module);
293+
var module =
294+
Optional.ofNullable(APContext.typeElement(service))
295+
.map(APContext.elements()::getModuleOf)
296+
.map(ModuleElement::getQualifiedName)
297+
.map(Object::toString);
298+
299+
return module.isPresent()
300+
&& (CTX.get().hasProvidesPlugin && AVAJE_PROVIDED_PLUGIN.contains(module.orElseThrow())
301+
|| module
302+
.map(APContext.moduleInfoReader().orElseThrow()::containsOnModulePath)
303+
.orElseThrow());
297304
}
298305

299306
private static void readExistingMetaInfServices() {

inject-test/src/test/java/org/example/coffee/generic/MultiGenericConsumer.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import org.example.coffee.grind.AMusher;
66

7+
import jakarta.inject.Inject;
78
import jakarta.inject.Singleton;
89

910
/**
@@ -20,6 +21,8 @@ class MultiGenericConsumer {
2021

2122
private List<SomeGeneric<?>> list;
2223

24+
@Inject List<SomeGeneric<?>> list2;
25+
2326
MultiGenericConsumer(
2427
Repository<Haz, Long> hazRepo,
2528
AMusher aMusher,

inject/src/main/java/io/avaje/inject/spi/DContextEntry.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,15 +176,17 @@ private void checkMatch(DContextEntryBean entry) {
176176
if (impliedName || (match.isNameEqual(name) && !entry.isNameEqual(name))) {
177177
ignoredSecondaryMatch = entry;
178178
return;
179-
} else if (!match.isNameEqual(name) && entry.isNameEqual(name)) {
179+
}
180+
if (!match.isNameEqual(name) && entry.isNameEqual(name)) {
180181
match = entry;
181182
return;
182183
}
183184
// if all else fails use the one provided by the current module
184185
if (entry.sourceModule() != currentModule) {
185186
ignoredSecondaryMatch = entry;
186187
return;
187-
} else if (entry.sourceModule() == currentModule && match.sourceModule() != currentModule) {
188+
}
189+
if (entry.sourceModule() == currentModule && match.sourceModule() != currentModule) {
188190
// match on module
189191
match = entry;
190192
return;

0 commit comments

Comments
 (0)