From f77389874c7ee3ea7a1a5c73f292e54d3861aa27 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:55:16 -0500 Subject: [PATCH 1/5] fix unwrapping provider --- .../io/avaje/inject/generator/MetaData.java | 9 +++++++- .../avaje/inject/generator/MethodReader.java | 2 -- .../inject/generator/TypeExtendsReader.java | 4 ++-- .../java/io/avaje/inject/generator/Util.java | 8 +++++++ .../valid/provider/FactoryProvider.java | 21 +++++++++++++++++++ .../models/valid/provider/Grinder.java | 3 +++ .../models/valid/provider/ProviderUser.java | 18 ++++++++++++++++ 7 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/FactoryProvider.java create mode 100644 inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/Grinder.java create mode 100644 inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/ProviderUser.java diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/MetaData.java b/inject-generator/src/main/java/io/avaje/inject/generator/MetaData.java index d10621015..34fe113e6 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/MetaData.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/MetaData.java @@ -85,7 +85,10 @@ String buildName() { if (Util.isVoid(type)) { return "void_" + Util.trimMethod(method); } else { - final String trimType = Util.trimMethod(type); + final String trimType = + Util.isProvider(type) + ? Util.trimMethod(Util.unwrapProvider(type)) + : Util.trimMethod(type); if (name != null) { return trimType + "_" + name.replaceAll("[^a-zA-Z0-9_$]+", "_"); } else { @@ -243,7 +246,11 @@ private void appendProvides(Append sb, String attribute, List types) { if (size > 1) { sb.eol().append(" "); } + var seen = new HashSet(); for (int i = 0; i < types.size(); i++) { + if (!seen.add(types.get(i))) { + continue; + } if (i > 0) { sb.append(",").eol().append(" "); } diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java b/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java index 328776ffd..9a4b23492 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java @@ -424,8 +424,6 @@ void builderGetDependency(Append writer, String builderName) { writer.append(builderName).append(".").append(utilType.getMethod(nullable, isBeanMap)); if (!genericType.isGeneric() || genericType.param0().kind() == TypeKind.WILDCARD) { writer.append(Util.shortName(genericType.mainType())).append(".class"); - } else if (isProvider()) { - writer.append(providerParam()).append(".class"); } else { writer.append("TYPE_").append(Util.shortName(genericType).replace(".", "_")); } diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/TypeExtendsReader.java b/inject-generator/src/main/java/io/avaje/inject/generator/TypeExtendsReader.java index 1e6d83635..cc02d3c1c 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/TypeExtendsReader.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/TypeExtendsReader.java @@ -118,11 +118,11 @@ List autoProvides() { return List.of(); } if (baseTypeIsInterface) { - return List.of(Util.unwrapProvider(baseType.asType())); + return List.of(Util.unwrapProvider(baseUType)); } var autoProvides = new ArrayList<>(interfaceTypes); autoProvides.addAll(extendsTypes); - autoProvides.add(Util.unwrapProvider(baseType.asType())); + autoProvides.add(Util.unwrapProvider(baseUType)); return autoProvides; } diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/Util.java b/inject-generator/src/main/java/io/avaje/inject/generator/Util.java index c94e48eac..721e78f51 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/Util.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/Util.java @@ -91,6 +91,14 @@ static UType unwrapProvider(TypeMirror maybeProvider) { } } + static UType unwrapProvider(UType maybeProvider) { + if (isProvider(maybeProvider.mainType())) { + return maybeProvider.param0(); + } else { + return maybeProvider; + } + } + static String initLower(String name) { final StringBuilder sb = new StringBuilder(name.length()); boolean upper = true; diff --git a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/FactoryProvider.java b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/FactoryProvider.java new file mode 100644 index 000000000..8adb6bf3b --- /dev/null +++ b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/FactoryProvider.java @@ -0,0 +1,21 @@ +package io.avaje.inject.generator.models.valid.provider; + +import java.util.function.Supplier; + +import io.avaje.inject.Bean; +import io.avaje.inject.Factory; +import jakarta.inject.Provider; + +@Factory +public class FactoryProvider { + + @Bean + Provider grinder() { + return Grinder::new; + } + + @Bean + Provider> supply() { + return () -> () -> ""; + } +} diff --git a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/Grinder.java b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/Grinder.java new file mode 100644 index 000000000..96b3a3dce --- /dev/null +++ b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/Grinder.java @@ -0,0 +1,3 @@ +package io.avaje.inject.generator.models.valid.provider; + +public class Grinder {} diff --git a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/ProviderUser.java b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/ProviderUser.java new file mode 100644 index 000000000..2c46f5714 --- /dev/null +++ b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/ProviderUser.java @@ -0,0 +1,18 @@ +package io.avaje.inject.generator.models.valid.provider; + +import java.util.function.Supplier; + +import jakarta.inject.Provider; +import jakarta.inject.Singleton; + +@Singleton +public class ProviderUser { + + Provider grinder; + Provider> supplier; + + public ProviderUser(Provider grinder, Provider> supplier) { + this.grinder = grinder; + this.supplier = supplier; + } +} From b60a009549000dd8c411ee48dfd325bcd3286be5 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 9 Mar 2024 10:35:30 -0500 Subject: [PATCH 2/5] fix provider factory register --- .../avaje/inject/generator/MethodReader.java | 22 +++++++++++++------ .../inject/generator/SimpleBeanWriter.java | 11 ++++++++-- .../avaje/inject/generator/TypeAppender.java | 5 ++++- .../valid/provider/FactoryProvider.java | 2 ++ 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java b/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java index 9a4b23492..5a1c9195d 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java @@ -181,19 +181,23 @@ void builderBuildBean(Append writer) { void builderAddBeanProvider(Append writer) { if (isVoid) { - writer.append("Error - void @Prototype method ?").eol(); + APContext.logError("Error - void @Prototype method ?", element); return; } if (optionalType) { - writer.append("Error - Optional type with @Prototype method is not supported").eol(); + APContext.logError("Error - Optional type with @Prototype method is not supported", element); return; } String indent = " "; + writer.indent(indent).append(" builder."); if (prototype) { - writer.indent(indent).append(" builder.asPrototype().registerProvider(() -> {").eol(); - } else { - writer.indent(indent).append(" builder.asSecondary().registerProvider(() -> {").eol(); + writer.append("asPrototype()").eol(); + } else if(secondary) { + writer.append("asSecondary()").eol(); } + + writer.indent(".registerProvider(() -> {"); + writer.indent(indent).append(" return "); writer.append("factory.%s(", methodName); for (int i = 0; i < params.size(); i++) { @@ -224,7 +228,11 @@ void builderBuildAddBean(Append writer) { } else if (secondary) { writer.append(".asSecondary()"); } - writer.append(".register(bean);").eol(); + if (Util.isProvider(returnTypeRaw)) { + writer.append(".registerProvider(bean);").eol(); + } else { + writer.append(".register(bean);").eol(); + } if (notEmpty(initMethod)) { writer.indent(indent).append("builder.addPostConstruct($bean::%s);", initMethod).eol(); } @@ -340,7 +348,7 @@ boolean isProtoType() { } boolean isUseProviderForSecondary() { - return secondary && !optionalType; + return secondary && !optionalType && !Util.isProvider(returnTypeRaw); } boolean isPublic() { diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/SimpleBeanWriter.java b/inject-generator/src/main/java/io/avaje/inject/generator/SimpleBeanWriter.java index afa1bb7a6..ff0852d70 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/SimpleBeanWriter.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/SimpleBeanWriter.java @@ -2,6 +2,7 @@ import static io.avaje.inject.generator.APContext.createSourceFile; import static io.avaje.inject.generator.APContext.logError; +import static java.util.stream.Collectors.toSet; import java.io.IOException; import java.io.Writer; @@ -69,13 +70,19 @@ void write() throws IOException { private void writeGenericTypeFields() { // collect all types to prevent duplicates - Set genericTypes = beanReader.allGenericTypes(); + Set genericTypes = + beanReader.allGenericTypes().stream() + .map(Util::unwrapProvider) + .filter(UType::isGeneric) + .collect(toSet()); if (!genericTypes.isEmpty()) { final Map seenShortNames = new HashMap<>(); final Set writtenFields = new HashSet<>(); - for (final UType type : genericTypes) { + for (UType utype : genericTypes) { + + var type = Util.unwrapProvider(utype); final var fieldName = Util.shortName(type).replace(".", "_"); final var components = type.componentTypes(); if (components.size() == 1 && components.get(0).kind() == TypeKind.WILDCARD diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/TypeAppender.java b/inject-generator/src/main/java/io/avaje/inject/generator/TypeAppender.java index 364bc6c83..775814afa 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/TypeAppender.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/TypeAppender.java @@ -1,5 +1,7 @@ package io.avaje.inject.generator; +import static java.lang.annotation.ElementType.LOCAL_VARIABLE; + import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -19,7 +21,8 @@ final class TypeAppender { this.importTypes = importTypes; } - void add(UType type) { + void add(UType utype) { + var type = Util.unwrapProvider(utype); var components = type.componentTypes(); if (isAddGenericType(type, components)) { addUType(type); diff --git a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/FactoryProvider.java b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/FactoryProvider.java index 8adb6bf3b..7d7c5bc20 100644 --- a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/FactoryProvider.java +++ b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/provider/FactoryProvider.java @@ -4,12 +4,14 @@ import io.avaje.inject.Bean; import io.avaje.inject.Factory; +import io.avaje.inject.Secondary; import jakarta.inject.Provider; @Factory public class FactoryProvider { @Bean + @Secondary Provider grinder() { return Grinder::new; } From cc7fc1ea597f67895009b3374085926a054c0a8e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 10 Mar 2024 17:58:02 -0400 Subject: [PATCH 3/5] tests --- .../coffee/provider/FactoryProvider.java | 25 +++++++++++++++++++ .../coffee/provider/FactoryProviderTest.java | 23 +++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 inject-test/src/test/java/org/example/coffee/provider/FactoryProvider.java create mode 100644 inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java diff --git a/inject-test/src/test/java/org/example/coffee/provider/FactoryProvider.java b/inject-test/src/test/java/org/example/coffee/provider/FactoryProvider.java new file mode 100644 index 000000000..176d6da16 --- /dev/null +++ b/inject-test/src/test/java/org/example/coffee/provider/FactoryProvider.java @@ -0,0 +1,25 @@ +package org.example.coffee.provider; + +import java.util.function.Supplier; + +import io.avaje.inject.Bean; +import io.avaje.inject.Factory; +import io.avaje.inject.Secondary; +import jakarta.inject.Named; +import jakarta.inject.Provider; + +@Factory +public class FactoryProvider { + + @Bean + @Secondary + @Named("second") + Provider second() { + return () -> "Nah, I'd win"; + } + + @Bean + Provider> supply() { + return () -> () -> "Stand proud Provider, you were strong"; + } +} diff --git a/inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java b/inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java new file mode 100644 index 000000000..7769487e1 --- /dev/null +++ b/inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java @@ -0,0 +1,23 @@ +package org.example.coffee.provider; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.function.Supplier; + +import org.junit.jupiter.api.Test; + +import io.avaje.inject.BeanScope; +import io.avaje.inject.spi.GenericType; +import jakarta.inject.Provider; + +class FactoryProviderTest { + + @Test + void test() { + var scope = BeanScope.builder().build(); + + Supplier prov = BeanScope.builder().build().get(new GenericType>() {}); + assertThat(prov.get()).isEqualTo("Stand proud Provider, you were strong"); + assertThat(scope.get(String.class, "second")).isEqualTo("Nah, I'd win"); + } +} From 8fff526ab6524286529e1ac90a68559764173489 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 10 Mar 2024 18:01:32 -0400 Subject: [PATCH 4/5] Update FactoryProviderTest.java --- .../java/org/example/coffee/provider/FactoryProviderTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java b/inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java index 7769487e1..596307f8d 100644 --- a/inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java +++ b/inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java @@ -8,7 +8,6 @@ import io.avaje.inject.BeanScope; import io.avaje.inject.spi.GenericType; -import jakarta.inject.Provider; class FactoryProviderTest { From fc5726243048f640d3deec56970a9a37082eaf26 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 11 Mar 2024 23:30:56 +1300 Subject: [PATCH 5/5] Tidy only --- .../java/io/avaje/inject/generator/MetaData.java | 5 +---- .../io/avaje/inject/generator/MethodReader.java | 1 - .../avaje/inject/generator/SimpleBeanWriter.java | 14 ++++++-------- .../coffee/provider/FactoryProviderTest.java | 10 +++++----- 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/MetaData.java b/inject-generator/src/main/java/io/avaje/inject/generator/MetaData.java index 34fe113e6..faba30a13 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/MetaData.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/MetaData.java @@ -85,10 +85,7 @@ String buildName() { if (Util.isVoid(type)) { return "void_" + Util.trimMethod(method); } else { - final String trimType = - Util.isProvider(type) - ? Util.trimMethod(Util.unwrapProvider(type)) - : Util.trimMethod(type); + final String trimType = Util.trimMethod(Util.unwrapProvider(type)); if (name != null) { return trimType + "_" + name.replaceAll("[^a-zA-Z0-9_$]+", "_"); } else { diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java b/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java index 5a1c9195d..efa255836 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java @@ -195,7 +195,6 @@ void builderAddBeanProvider(Append writer) { } else if(secondary) { writer.append("asSecondary()").eol(); } - writer.indent(".registerProvider(() -> {"); writer.indent(indent).append(" return "); diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/SimpleBeanWriter.java b/inject-generator/src/main/java/io/avaje/inject/generator/SimpleBeanWriter.java index ff0852d70..2fdf2238e 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/SimpleBeanWriter.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/SimpleBeanWriter.java @@ -71,17 +71,16 @@ void write() throws IOException { private void writeGenericTypeFields() { // collect all types to prevent duplicates Set genericTypes = - beanReader.allGenericTypes().stream() - .map(Util::unwrapProvider) - .filter(UType::isGeneric) - .collect(toSet()); - if (!genericTypes.isEmpty()) { + beanReader.allGenericTypes().stream() + .map(Util::unwrapProvider) + .filter(UType::isGeneric) + .collect(toSet()); + if (!genericTypes.isEmpty()) { final Map seenShortNames = new HashMap<>(); final Set writtenFields = new HashSet<>(); - for (UType utype : genericTypes) { - + for (final UType utype : genericTypes) { var type = Util.unwrapProvider(utype); final var fieldName = Util.shortName(type).replace(".", "_"); final var components = type.componentTypes(); @@ -93,7 +92,6 @@ private void writeGenericTypeFields() { writer.append(" public static final Type TYPE_%s =", fieldName).eol() .append(" new GenericType<"); - writeGenericType(type, seenShortNames, writer); // use fully qualified types here rather than use type.writeShort(writer) writer.append(">(){}.type();").eol(); diff --git a/inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java b/inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java index 596307f8d..b1868a142 100644 --- a/inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java +++ b/inject-test/src/test/java/org/example/coffee/provider/FactoryProviderTest.java @@ -13,10 +13,10 @@ class FactoryProviderTest { @Test void test() { - var scope = BeanScope.builder().build(); - - Supplier prov = BeanScope.builder().build().get(new GenericType>() {}); - assertThat(prov.get()).isEqualTo("Stand proud Provider, you were strong"); - assertThat(scope.get(String.class, "second")).isEqualTo("Nah, I'd win"); + try (var scope = BeanScope.builder().build()) { + Supplier prov = scope.get(new GenericType>() {}); + assertThat(prov.get()).isEqualTo("Stand proud Provider, you were strong"); + assertThat(scope.get(String.class, "second")).isEqualTo("Nah, I'd win"); + } } }