Skip to content

Commit 0cb2181

Browse files
committed
Qute: gizmo2 rewrite
1 parent 3a2803b commit 0cb2181

File tree

16 files changed

+1703
-1818
lines changed

16 files changed

+1703
-1818
lines changed
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
package io.quarkus.qute.deployment;
22

3-
import io.quarkus.gizmo.MethodDescriptor;
3+
import io.quarkus.gizmo2.desc.MethodDesc;
44
import io.quarkus.qute.Template;
55
import io.quarkus.qute.TemplateInstance;
66
import io.quarkus.qute.i18n.MessageBundles;
77

88
final class Descriptors {
99

10-
static final MethodDescriptor TEMPLATE_INSTANCE = MethodDescriptor.ofMethod(Template.class, "instance",
10+
static final MethodDesc TEMPLATE_INSTANCE = MethodDesc.of(Template.class, "instance",
1111
TemplateInstance.class);
12-
static final MethodDescriptor TEMPLATE_INSTANCE_DATA = MethodDescriptor.ofMethod(TemplateInstance.class, "data",
12+
static final MethodDesc TEMPLATE_INSTANCE_DATA = MethodDesc.of(TemplateInstance.class, "data",
1313
TemplateInstance.class, String.class, Object.class);
14-
static final MethodDescriptor TEMPLATE_INSTANCE_RENDER = MethodDescriptor.ofMethod(TemplateInstance.class, "render",
14+
static final MethodDesc TEMPLATE_INSTANCE_RENDER = MethodDesc.of(TemplateInstance.class, "render",
1515
String.class);
16-
static final MethodDescriptor BUNDLES_GET_TEMPLATE = MethodDescriptor.ofMethod(MessageBundles.class, "getTemplate",
16+
static final MethodDesc BUNDLES_GET_TEMPLATE = MethodDesc.of(MessageBundles.class, "getTemplate",
1717
Template.class, String.class);
1818

1919
}

extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/MessageBundleProcessor.java

Lines changed: 444 additions & 387 deletions
Large diffs are not rendered by default.

extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java

Lines changed: 45 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
import org.jboss.jandex.ParameterizedType;
5757
import org.jboss.jandex.PrimitiveType;
5858
import org.jboss.jandex.PrimitiveType.Primitive;
59-
import org.jboss.jandex.RecordComponentInfo;
6059
import org.jboss.jandex.Type;
6160
import org.jboss.jandex.TypeVariable;
6261
import org.jboss.logging.Logger;
@@ -80,7 +79,7 @@
8079
import io.quarkus.arc.processor.QualifierRegistrar;
8180
import io.quarkus.deployment.ApplicationArchive;
8281
import io.quarkus.deployment.Feature;
83-
import io.quarkus.deployment.GeneratedClassGizmoAdaptor;
82+
import io.quarkus.deployment.GeneratedClassGizmo2Adaptor;
8483
import io.quarkus.deployment.IsTest;
8584
import io.quarkus.deployment.annotations.BuildProducer;
8685
import io.quarkus.deployment.annotations.BuildStep;
@@ -89,15 +88,15 @@
8988
import io.quarkus.deployment.builditem.BytecodeTransformerBuildItem;
9089
import io.quarkus.deployment.builditem.FeatureBuildItem;
9190
import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
91+
import io.quarkus.deployment.builditem.GeneratedResourceBuildItem;
9292
import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem;
9393
import io.quarkus.deployment.builditem.LiveReloadBuildItem;
9494
import io.quarkus.deployment.builditem.ServiceStartBuildItem;
9595
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
9696
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
9797
import io.quarkus.deployment.pkg.NativeConfig;
9898
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
99-
import io.quarkus.gizmo.ClassOutput;
100-
import io.quarkus.gizmo.MethodDescriptor;
99+
import io.quarkus.gizmo2.ClassOutput;
101100
import io.quarkus.maven.dependency.ArtifactKey;
102101
import io.quarkus.maven.dependency.DependencyFlags;
103102
import io.quarkus.maven.dependency.ResolvedDependency;
@@ -139,8 +138,7 @@
139138
import io.quarkus.qute.deployment.TypeInfos.TypeInfo;
140139
import io.quarkus.qute.deployment.Types.AssignabilityCheck;
141140
import io.quarkus.qute.generator.ExtensionMethodGenerator;
142-
import io.quarkus.qute.generator.ExtensionMethodGenerator.NamespaceResolverCreator;
143-
import io.quarkus.qute.generator.ExtensionMethodGenerator.NamespaceResolverCreator.ResolveCreator;
141+
import io.quarkus.qute.generator.ExtensionMethodGenerator.ExtensionMethodInfo;
144142
import io.quarkus.qute.generator.ExtensionMethodGenerator.Param;
145143
import io.quarkus.qute.generator.TemplateGlobalGenerator;
146144
import io.quarkus.qute.generator.ValueResolverGenerator;
@@ -428,9 +426,7 @@ && isNotLocatedByCustomTemplateLocator(locatorPatternsBuildItem.getLocationPatte
428426
if (!recordClass.isRecord()) {
429427
continue;
430428
}
431-
MethodInfo canonicalConstructor = recordClass.method(MethodDescriptor.INIT,
432-
recordClass.recordComponentsInDeclarationOrder().stream().map(RecordComponentInfo::type)
433-
.toArray(Type[]::new));
429+
MethodInfo canonicalConstructor = recordClass.canonicalRecordConstructor();
434430

435431
AnnotationInstance checkedTemplateAnnotation = recordClass.declaredAnnotation(Names.CHECKED_TEMPLATE);
436432
String fragmentId = getCheckedFragmentId(recordClass, checkedTemplateAnnotation);
@@ -916,12 +912,8 @@ void validateCheckedFragments(List<CheckedFragmentValidationBuildItem> validatio
916912
String paramName = e.getKey();
917913
MethodInfo methodOrConstructor = null;
918914
if (validation.checkedTemplate.isRecord()) {
919-
Type[] componentTypes = validation.checkedTemplate.recordClass.recordComponentsInDeclarationOrder()
920-
.stream()
921-
.map(RecordComponentInfo::type)
922-
.toArray(Type[]::new);
923915
methodOrConstructor = validation.checkedTemplate.recordClass
924-
.method(MethodDescriptor.INIT, componentTypes);
916+
.canonicalRecordConstructor();
925917
} else {
926918
methodOrConstructor = validation.checkedTemplate.method;
927919
}
@@ -1938,7 +1930,9 @@ static String findTemplatePath(TemplatesAnalysisBuildItem analysis, String id) {
19381930
}
19391931

19401932
@BuildStep
1941-
void generateValueResolvers(QuteConfig config, BuildProducer<GeneratedClassBuildItem> generatedClasses,
1933+
void generateValueResolvers(QuteConfig config,
1934+
BuildProducer<GeneratedClassBuildItem> generatedClasses,
1935+
BuildProducer<GeneratedResourceBuildItem> generatedResources,
19421936
BeanArchiveIndexBuildItem beanArchiveIndex,
19431937
ApplicationArchivesBuildItem applicationArchivesBuildItem,
19441938
List<TemplateExtensionMethodBuildItem> templateExtensionMethods,
@@ -1960,29 +1954,30 @@ void generateValueResolvers(QuteConfig config, BuildProducer<GeneratedClassBuild
19601954
}
19611955

19621956
IndexView index = beanArchiveIndex.getIndex();
1963-
ClassOutput classOutput = new GeneratedClassGizmoAdaptor(generatedClasses, new Function<String, String>() {
1964-
@Override
1965-
public String apply(String name) {
1966-
int idx = name.lastIndexOf(ExtensionMethodGenerator.NAMESPACE_SUFFIX);
1967-
if (idx == -1) {
1968-
idx = name.lastIndexOf(ExtensionMethodGenerator.SUFFIX);
1969-
}
1970-
if (idx == -1) {
1971-
idx = name.lastIndexOf(ValueResolverGenerator.NAMESPACE_SUFFIX);
1972-
}
1973-
if (idx == -1) {
1974-
idx = name.lastIndexOf(ValueResolverGenerator.SUFFIX);
1975-
}
1976-
if (idx == -1) {
1977-
idx = name.lastIndexOf(TemplateGlobalGenerator.SUFFIX);
1978-
}
1979-
String className = name.substring(0, idx);
1980-
if (className.contains(ValueResolverGenerator.NESTED_SEPARATOR)) {
1981-
className = className.replace(ValueResolverGenerator.NESTED_SEPARATOR, "$");
1982-
}
1983-
return className;
1984-
}
1985-
});
1957+
ClassOutput classOutput = new GeneratedClassGizmo2Adaptor(generatedClasses, generatedResources,
1958+
new Function<String, String>() {
1959+
@Override
1960+
public String apply(String name) {
1961+
int idx = name.lastIndexOf(ExtensionMethodGenerator.NAMESPACE_SUFFIX);
1962+
if (idx == -1) {
1963+
idx = name.lastIndexOf(ExtensionMethodGenerator.SUFFIX);
1964+
}
1965+
if (idx == -1) {
1966+
idx = name.lastIndexOf(ValueResolverGenerator.NAMESPACE_SUFFIX);
1967+
}
1968+
if (idx == -1) {
1969+
idx = name.lastIndexOf(ValueResolverGenerator.SUFFIX);
1970+
}
1971+
if (idx == -1) {
1972+
idx = name.lastIndexOf(TemplateGlobalGenerator.SUFFIX);
1973+
}
1974+
String className = name.substring(0, idx);
1975+
if (className.contains(ValueResolverGenerator.NESTED_SEPARATOR)) {
1976+
className = className.replace(ValueResolverGenerator.NESTED_SEPARATOR, "$");
1977+
}
1978+
return className;
1979+
}
1980+
});
19861981

19871982
// NOTE: We can't use this optimization for classes generated by ValueResolverGenerator because we cannot easily
19881983
// map a target class to a specific set of generated classes
@@ -2094,19 +2089,18 @@ public Function<FieldInfo, String> apply(ClassInfo clazz) {
20942089
.collect(Collectors.groupingBy(TemplateExtensionMethodBuildItem::getPriority));
20952090

20962091
for (Entry<Integer, List<TemplateExtensionMethodBuildItem>> priorityEntry : priorityToMethods.entrySet()) {
2097-
try (NamespaceResolverCreator namespaceResolverCreator = extensionMethodGenerator
2098-
.createNamespaceResolver(priorityEntry.getValue().get(0).getMethod().declaringClass(),
2099-
nsEntry.getKey(), priorityEntry.getKey())) {
2100-
for (TemplateExtensionMethodBuildItem extensionMethod : priorityEntry.getValue()) {
2101-
existingValueResolvers.add(extensionMethod.getMethod(), namespaceResolverCreator.getClassName(),
2102-
applicationClassPredicate);
2103-
}
2104-
try (ResolveCreator resolveCreator = namespaceResolverCreator.implementResolve()) {
2105-
for (TemplateExtensionMethodBuildItem method : priorityEntry.getValue()) {
2106-
resolveCreator.addMethod(method.getMethod(), method.getMatchName(), method.getMatchNames(),
2107-
method.getMatchRegex());
2108-
}
2109-
}
2092+
List<ExtensionMethodGenerator.ExtensionMethodInfo> extensionMethods = new ArrayList<>(
2093+
priorityEntry.getValue().size());
2094+
for (TemplateExtensionMethodBuildItem method : priorityEntry.getValue()) {
2095+
extensionMethods
2096+
.add(new ExtensionMethodInfo(method.getMethod(), method.getMatchName(), method.getMatchNames(),
2097+
method.getMatchRegex()));
2098+
}
2099+
String generatedType = extensionMethodGenerator.generateNamespaceResolver(
2100+
priorityEntry.getValue().get(0).getMethod().declaringClass(), nsEntry.getKey(),
2101+
priorityEntry.getKey(), extensionMethods);
2102+
for (TemplateExtensionMethodBuildItem extensionMethod : priorityEntry.getValue()) {
2103+
existingValueResolvers.add(extensionMethod.getMethod(), generatedType, applicationClassPredicate);
21102104
}
21112105
}
21122106
}

extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/TemplateDataTest.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import java.math.BigDecimal;
66
import java.math.RoundingMode;
7+
import java.util.List;
8+
import java.util.stream.IntStream;
79

810
import jakarta.inject.Inject;
911

@@ -26,19 +28,26 @@ public class TemplateDataTest {
2628
"templates/foo.txt")
2729
.addAsResource(new StringAsset(
2830
"{#if tx == TransactionType:FOO}OK{/if}::{io_quarkus_qute_deployment_TemplateDataTest_Foos:BRAVO.toLowerCase}"),
29-
"templates/bar.txt"));
31+
"templates/bar.txt")
32+
.addAsResource(new StringAsset(
33+
"{io_quarkus_qute_deployment_TemplateDataTest_Foo:alphas.0}::{io_quarkus_qute_deployment_TemplateDataTest_Foo:alphas(2).size}"),
34+
"templates/alphas.txt"));
3035

3136
@Inject
3237
Template foo;
3338

3439
@Inject
3540
Template bar;
3641

42+
@Inject
43+
Template alphas;
44+
3745
@Test
3846
public void testTemplateData() {
3947
assertEquals("123.4563 is not 123.46 and true=true and false=false",
4048
foo.data("roundingMode", RoundingMode.HALF_UP).data("foo", new Foo(new BigDecimal("123.4563"))).render());
4149
assertEquals("OK::bravo", bar.data("tx", TransactionType.FOO).render());
50+
assertEquals("1::2", alphas.render());
4251
}
4352

4453
@TemplateData
@@ -59,6 +68,14 @@ public boolean isBaz() {
5968
return false;
6069
}
6170

71+
public static List<String> alphas() {
72+
return List.of("1", "2");
73+
}
74+
75+
public static List<Integer> alphas(int n) {
76+
return IntStream.range(0, n).mapToObj(Integer::valueOf).toList();
77+
}
78+
6279
}
6380

6481
// namespace is TransactionType

extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/extensions/ExtensionMethodCompletionStageTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public void testTemplateExtensions() throws InterruptedException, ExecutionExcep
3535
.toCompletableFuture();
3636
assertFalse(result.isDone());
3737
FooParentService.parent.complete(new Foo("bravo", 1l));
38-
assertEquals("bravo", result.toCompletableFuture().get());
38+
assertEquals("bravo", result.get());
3939
}
4040

4141
@Unremovable

extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/extensions/NamespaceTemplateExtensionTest.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,31 +34,31 @@ public class NamespaceTemplateExtensionTest {
3434
@Test
3535
public void testTemplateExtensions() {
3636
assertEquals("hello:1",
37-
engine.parse("{str:format('%s:%s','hello', 1)}").render());
37+
engine.parse("{string:format('%s:%s','hello', 1)}").render());
3838
assertEquals("1",
39-
engine.parse("{str:format('%s',1)}").render());
39+
engine.parse("{string:format('%s',1)}").render());
4040
assertEquals("olleh",
41-
engine.parse("{str:reverse('hello')}").render());
41+
engine.parse("{string:reverse('hello')}").render());
4242
try {
43-
engine.parse("{str:reverse(null)}").render();
43+
engine.parse("{string:reverse(null)}").render();
4444
fail();
4545
} catch (NullPointerException expected) {
4646
}
4747
assertEquals("foolish:olleh",
48-
engine.parse("{str:foolish('hello')}").render());
48+
engine.parse("{string:foolish('hello')}").render());
4949
assertEquals("ONE=ONE",
5050
engine.parse("{MyEnum:ONE}={MyEnum:one}").render());
5151
assertEquals("IN_PROGRESS=0",
5252
engine.parse("{txPhase:IN_PROGRESS}={txPhase:IN_PROGRESS.ordinal}").render());
5353
assertEquals("Quark!",
54-
engine.parse("{str:quark}").render());
54+
engine.parse("{string:quark}").render());
5555
assertEquals("QUARKUS!",
56-
engine.parse("{str:quarkus}").render());
56+
engine.parse("{string:quarkus}").render());
5757
assertEquals("openclosed",
5858
engine.getTemplate("foo").render());
5959
}
6060

61-
@TemplateExtension(namespace = "str")
61+
@TemplateExtension(namespace = "string")
6262
public static class StringExtensions {
6363

6464
static String format(String fmt, Object... args) {
@@ -69,7 +69,7 @@ static String reverse(String val) {
6969
return new StringBuilder(val).reverse().toString();
7070
}
7171

72-
@TemplateExtension(namespace = "str", matchRegex = "foo.*", priority = 5)
72+
@TemplateExtension(namespace = "string", matchRegex = "foo.*", priority = 5)
7373
static String foo(String name, String val) {
7474
return name + ":" + new StringBuilder(val).reverse().toString();
7575
}
@@ -78,7 +78,7 @@ static String quark() {
7878
return "Quark!";
7979
}
8080

81-
@TemplateExtension(namespace = "str", matchName = ANY, priority = 4)
81+
@TemplateExtension(namespace = "string", matchName = ANY, priority = 4)
8282
static String quarkAny(String key) {
8383
return key.toUpperCase() + "!";
8484
}

independent-projects/qute/generator/pom.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,13 @@
2626
<groupId>io.smallrye</groupId>
2727
<artifactId>jandex</artifactId>
2828
</dependency>
29+
<dependency>
30+
<groupId>io.smallrye</groupId>
31+
<artifactId>jandex-gizmo2</artifactId>
32+
</dependency>
2933
<dependency>
3034
<groupId>io.quarkus.gizmo</groupId>
31-
<artifactId>gizmo</artifactId>
35+
<artifactId>gizmo2</artifactId>
3236
</dependency>
3337
<dependency>
3438
<groupId>org.junit.jupiter</groupId>

0 commit comments

Comments
 (0)