Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qute - support multiple namespace extension methods on the same class #14584

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ public boolean test(String name) {
generatedTypes.addAll(generator.getGeneratedTypes());

ExtensionMethodGenerator extensionMethodGenerator = new ExtensionMethodGenerator(index, classOutput);
Map<DotName, List<TemplateExtensionMethodBuildItem>> classToNamespaceExtensions = new HashMap<>();
Map<DotName, Map<String, List<TemplateExtensionMethodBuildItem>>> classToNamespaceExtensions = new HashMap<>();
Map<String, DotName> namespaceToClass = new HashMap<>();

for (TemplateExtensionMethodBuildItem templateExtension : templateExtensionMethods) {
Expand All @@ -864,17 +864,23 @@ public boolean test(String name) {
DotName declaringClassName = templateExtension.getMethod().declaringClass().name();
DotName namespaceClassName = namespaceToClass.get(templateExtension.getNamespace());
if (namespaceClassName == null) {
namespaceToClass.put(templateExtension.getNamespace(), declaringClassName);
namespaceToClass.put(templateExtension.getNamespace(), namespaceClassName);
} else if (!namespaceClassName.equals(declaringClassName)) {
throw new IllegalStateException("Template extension methods that share the namespace "
+ templateExtension.getNamespace() + " must be declared on the same class; but declared on "
+ namespaceClassName + " and " + declaringClassName);
}
List<TemplateExtensionMethodBuildItem> namespaceMethods = classToNamespaceExtensions
Map<String, List<TemplateExtensionMethodBuildItem>> namespaceToExtensions = classToNamespaceExtensions
.get(declaringClassName);
if (namespaceToExtensions == null) {
namespaceToExtensions = new HashMap<>();
classToNamespaceExtensions.put(declaringClassName, namespaceToExtensions);
}
List<TemplateExtensionMethodBuildItem> namespaceMethods = namespaceToExtensions
.get(templateExtension.getNamespace());
if (namespaceMethods == null) {
namespaceMethods = new ArrayList<>();
classToNamespaceExtensions.put(declaringClassName, namespaceMethods);
namespaceToExtensions.put(templateExtension.getNamespace(), namespaceMethods);
}
namespaceMethods.add(templateExtension);
} else {
Expand All @@ -885,15 +891,19 @@ public boolean test(String name) {
}

// Generate a namespace resolver for extension methods declared on the same class
for (Entry<DotName, List<TemplateExtensionMethodBuildItem>> entry : classToNamespaceExtensions.entrySet()) {
List<TemplateExtensionMethodBuildItem> methods = entry.getValue();
// Methods with higher priority take precedence
methods.sort(Comparator.comparingInt(TemplateExtensionMethodBuildItem::getPriority).reversed());
try (NamespaceResolverCreator namespaceResolverCreator = extensionMethodGenerator
.createNamespaceResolver(methods.get(0).getMethod().declaringClass(), methods.get(0).getNamespace())) {
try (ResolveCreator resolveCreator = namespaceResolverCreator.implementResolve()) {
for (TemplateExtensionMethodBuildItem method : methods) {
resolveCreator.addMethod(method.getMethod(), method.getMatchName(), method.getMatchRegex());
for (Entry<DotName, Map<String, List<TemplateExtensionMethodBuildItem>>> entry1 : classToNamespaceExtensions
.entrySet()) {
Map<String, List<TemplateExtensionMethodBuildItem>> namespaceToMethods = entry1.getValue();
for (Entry<String, List<TemplateExtensionMethodBuildItem>> entry2 : namespaceToMethods.entrySet()) {
List<TemplateExtensionMethodBuildItem> methods = entry2.getValue();
// Methods with higher priority take precedence
methods.sort(Comparator.comparingInt(TemplateExtensionMethodBuildItem::getPriority).reversed());
try (NamespaceResolverCreator namespaceResolverCreator = extensionMethodGenerator
.createNamespaceResolver(methods.get(0).getMethod().declaringClass(), entry2.getKey())) {
try (ResolveCreator resolveCreator = namespaceResolverCreator.implementResolve()) {
for (TemplateExtensionMethodBuildItem method : methods) {
resolveCreator.addMethod(method.getMethod(), method.getMatchName(), method.getMatchRegex());
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static io.quarkus.qute.TemplateExtension.ANY;
import static org.junit.jupiter.api.Assertions.assertEquals;

import javax.enterprise.event.TransactionPhase;
import javax.inject.Inject;

import org.jboss.shrinkwrap.api.ShrinkWrap;
Expand Down Expand Up @@ -36,6 +37,8 @@ public void testTemplateExtensions() {
engine.parse("{str:foolish('hello')}").render());
assertEquals("ONE=ONE",
engine.parse("{MyEnum:ONE}={MyEnum:one}").render());
assertEquals("IN_PROGRESS=0",
engine.parse("{txPhase:IN_PROGRESS}={txPhase:IN_PROGRESS.ordinal}").render());
}

@TemplateExtension(namespace = "str")
Expand Down Expand Up @@ -70,6 +73,11 @@ static MyEnum getVal(String val) {
return MyEnum.valueOf(val.toUpperCase());
}

@TemplateExtension(namespace = "txPhase", matchName = "*")
static TransactionPhase enumValue(String value) {
return TransactionPhase.valueOf(value);
}

}

}