Skip to content

Commit

Permalink
feat:Qute: Cannot locate hyphenated template name
Browse files Browse the repository at this point in the history
Fixes redhat-developer#975

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Jul 14, 2024
1 parent cf93107 commit 353f9be
Show file tree
Hide file tree
Showing 13 changed files with 551 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.acme.sample;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

import io.quarkus.qute.CheckedTemplate;
import io.quarkus.qute.TemplateExtension;
import io.quarkus.qute.TemplateInstance;

@Path("items")
public class ItemResource {

@CheckedTemplate(defaultName=CheckedTemplate.HYPHENATED_ELEMENT_NAME)
static class Templates {
static native TemplateInstance HelloWorld(String name);

}

@CheckedTemplate(defaultName=CheckedTemplate.HYPHENATED_ELEMENT_NAME)
static class Templates2 {
static native TemplateInstance HelloWorld(String name);

}

@CheckedTemplate(defaultName=CheckedTemplate.UNDERSCORED_ELEMENT_NAME)3
static class Templates3 {
static native TemplateInstance HelloWorld(String name);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,41 @@ public void templateRecord() throws CoreException, Exception {
"qute.command.generate.template.file", Arrays.asList(boujourFileUri1)));
}

@Test
public void checkedTemplateWithDefaultName() throws CoreException, Exception {
// @CheckedTemplate(defaultName=CheckedTemplate.HYPHENATED_ELEMENT_NAME)
// static class Templates {
// static native TemplateInstance HelloWorld(String name);

IJavaProject javaProject = loadMavenProject(QuteMavenProjectName.qute_record);

QuteJavaCodeLensParams params = new QuteJavaCodeLensParams();
IFile javaFile = javaProject.getProject().getFile(new Path("src/main/java/org/acme/sample/ItemResource.java"));
params.setUri(javaFile.getLocation().toFile().toURI().toString());

List<? extends CodeLens> lenses = QuteSupportForJava.getInstance().codeLens(params, getJDTUtils(),
new NullProgressMonitor());
assertEquals(3, lenses.size());

String helloFileUri = javaProject.getProject().getFile("src/main/resources/templates/HelloWorld.html")
.getLocationURI().toString();
String hello2FileUri = javaProject.getProject().getFile("src/main/resources/templates/hello-world.html")
.getLocationURI().toString();
String hello3FileUri = javaProject.getProject().getFile("src/main/resources/templates/hello_world.html")
.getLocationURI().toString();

assertCodeLens(lenses, //
cl(r(19, 2, 19, 57), //
"Create `src/main/resources/templates/ItemResource/HelloWorld.html`", //
"qute.command.open.uri", Arrays.asList(helloFileUri)), //
cl(r(25, 2, 25, 57), //
"Create `src/main/resources/templates/ItemResource/hello-world.html`", //
"qute.command.generate.template.file", Arrays.asList(hello2FileUri)), //
cl(r(31, 2, 31, 57), //
"Create `src/main/resources/templates/ItemResource/hello_world.html`", //
"qute.command.generate.template.file", Arrays.asList(hello3FileUri)));
}

public static Range r(int line, int startChar, int endChar) {
return r(line, startChar, line, endChar);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,38 @@ public void templateRecord() throws Exception {
DiagnosticSeverity.Error, "qute", QuteErrorCode.NoMatchingTemplate.name()));
}

@Test
public void checkedTemplateWithDefaultName() throws Exception {

// @CheckedTemplate(defaultName=CheckedTemplate.HYPHENATED_ELEMENT_NAME)
// static class Templates {
// static native TemplateInstance HelloWorld(String name);

IJavaProject javaProject = loadMavenProject(QuteMavenProjectName.qute_record);

QuteJavaDiagnosticsParams params = new QuteJavaDiagnosticsParams();
IFile javaFile = javaProject.getProject().getFile(new Path("src/main/java/org/acme/sample/ItemResource.java"));
params.setUris(Arrays.asList(javaFile.getLocation().toFile().toURI().toString()));

List<PublishDiagnosticsParams> publishDiagnostics = QuteSupportForJava.getInstance().diagnostics(params,
getJDTUtils(), new NullProgressMonitor());
assertEquals(3, publishDiagnostics.size());

List<Diagnostic> diagnostics = publishDiagnostics.get(0).getDiagnostics();
assertEquals(1, diagnostics.size());

assertDiagnostic(diagnostics, //
new Diagnostic(r(19, 33, 19, 43),
"No template matching the path ItemResource/HelloWorld could be found for: org.acme.sample.ItemResource$Templates",
DiagnosticSeverity.Error, "qute", QuteErrorCode.NoMatchingTemplate.name()), //
new Diagnostic(r(25, 33, 25, 43),
"No template matching the path ItemResource/HelloWorld could be found for: org.acme.sample.ItemResource$Templates2",
DiagnosticSeverity.Error, "qute", QuteErrorCode.NoMatchingTemplate.name()), //
new Diagnostic(r(31, 33, 31, 43),
"No template matching the path ItemResource/HelloWorld could be found for: org.acme.sample.ItemResource$Templates3",
DiagnosticSeverity.Error, "qute", QuteErrorCode.NoMatchingTemplate.name()));
}

public static Range r(int line, int startChar, int endChar) {
return r(line, startChar, line, endChar);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,39 @@ public void templateRecord() throws Exception {
templateFileUri, "Create `src/main/resources/templates/Bonjour.html`"));
}

@Test
public void checkedTemplateWithDefaultName() throws Exception {

// @CheckedTemplate(defaultName=CheckedTemplate.HYPHENATED_ELEMENT_NAME)
// static class Templates {
// static native TemplateInstance HelloWorld(String name);

IJavaProject javaProject = loadMavenProject(QuteMavenProjectName.qute_record);

QuteJavaDocumentLinkParams params = new QuteJavaDocumentLinkParams();
IFile javaFile = javaProject.getProject().getFile(new Path("src/main/java/org/acme/sample/ItemResource.java"));
params.setUri(javaFile.getLocation().toFile().toURI().toString());

List<DocumentLink> links = QuteSupportForJava.getInstance().documentLink(params, getJDTUtils(),
new NullProgressMonitor());
assertEquals(3, links.size());

String helloFileUri = javaProject.getProject().getFile("src/main/resources/templates/HelloWorld.html")
.getLocationURI().toString();
String hello2FileUri = javaProject.getProject().getFile("src/main/resources/templates/hello-world.html")
.getLocationURI().toString();
String hello3FileUri = javaProject.getProject().getFile("src/main/resources/templates/hello_world.html")
.getLocationURI().toString();

assertDocumentLink(links, //
dl(r(19, 2, 19, 57), //
helloFileUri, "Create `src/main/resources/templates/HelloWorld.html`"), //
dl(r(25, 33, 25, 43), //
hello2FileUri, "Create `src/main/resources/templates/hello-world.html`"), //
dl(r(31, 33, 31, 43), //
hello3FileUri, "Create `src/main/resources/templates/hello_world.html`"));
}

public static Range r(int line, int startChar, int endChar) {
return r(line, startChar, line, endChar);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class QuteJavaConstants {
public static final String TEMPLATE_CLASS = "io.quarkus.qute.Template";

public static final String TEMPLATE_INSTANCE_INTERFACE = "io.quarkus.qute.TemplateInstance";

public static final String ENGINE_BUILDER_CLASS = "io.quarkus.qute.EngineBuilder";

public static final String VALUE_ANNOTATION_NAME = "value";
Expand All @@ -50,6 +50,9 @@ public class QuteJavaConstants {

public static final String CHECKED_TEMPLATE_ANNOTATION_IGNORE_FRAGMENTS = "ignoreFragments";
public static final String CHECKED_TEMPLATE_ANNOTATION_BASE_PATH = "basePath";
public static final String CHECKED_TEMPLATE_ANNOTATION_DEFAULT_NAME = "defaultName";
public static final String CHECKED_TEMPLATE_ANNOTATION_DEFAULT_NAME_HYPHENATED_ELEMENT_NAME = "<<hyphenated element name>>";
public static final String CHECKED_TEMPLATE_ANNOTATION_DEFAULT_NAME_UNDERSCORED_ELEMENT_NAME = "<<underscored element name>>";

// @TemplateExtension

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

import static com.redhat.qute.jdt.internal.QuteJavaConstants.CHECKED_TEMPLATE_ANNOTATION;
import static com.redhat.qute.jdt.internal.QuteJavaConstants.CHECKED_TEMPLATE_ANNOTATION_BASE_PATH;
import static com.redhat.qute.jdt.internal.QuteJavaConstants.CHECKED_TEMPLATE_ANNOTATION_DEFAULT_NAME;
import static com.redhat.qute.jdt.internal.QuteJavaConstants.CHECKED_TEMPLATE_ANNOTATION_DEFAULT_NAME_HYPHENATED_ELEMENT_NAME;
import static com.redhat.qute.jdt.internal.QuteJavaConstants.CHECKED_TEMPLATE_ANNOTATION_DEFAULT_NAME_UNDERSCORED_ELEMENT_NAME;
import static com.redhat.qute.jdt.internal.QuteJavaConstants.CHECKED_TEMPLATE_ANNOTATION_IGNORE_FRAGMENTS;
import static com.redhat.qute.jdt.internal.QuteJavaConstants.OLD_CHECKED_TEMPLATE_ANNOTATION;
import static com.redhat.qute.jdt.internal.QuteJavaConstants.TEMPLATE_CLASS;
Expand Down Expand Up @@ -51,6 +54,7 @@
import com.redhat.qute.jdt.utils.IJDTUtils;
import com.redhat.qute.jdt.utils.JDTQuteProjectUtils;
import com.redhat.qute.jdt.utils.JDTTypeUtils;
import com.redhat.qute.jdt.utils.TemplateNameStrategy;
import com.redhat.qute.jdt.utils.TemplatePathInfo;

/**
Expand Down Expand Up @@ -138,7 +142,8 @@ public boolean visit(FieldDeclaration node) {
.getLocationExpressionFromConstructorParameter(variable.getName().getIdentifier());
}
String fieldName = variable.getName().getIdentifier();
collectTemplateLink(null, node, locationExpression, getTypeDeclaration(node), null, fieldName, false);
collectTemplateLink(null, node, locationExpression, getTypeDeclaration(node), null, fieldName, false,
TemplateNameStrategy.ELEMENT_NAME);
}
}
return super.visit(node);
Expand Down Expand Up @@ -186,10 +191,12 @@ public boolean visit(TypeDeclaration node) {
// public static native TemplateInstance book(Book book);
boolean ignoreFragments = isIgnoreFragments(annotation);
String basePath = getBasePath(annotation);
TemplateNameStrategy templateNameStrategy = getDefaultName(annotation);
List body = node.bodyDeclarations();
for (Object declaration : body) {
if (declaration instanceof MethodDeclaration) {
collectTemplateLink(basePath, (MethodDeclaration) declaration, node, ignoreFragments);
collectTemplateLink(basePath, (MethodDeclaration) declaration, node, ignoreFragments,
templateNameStrategy);
}
}
}
Expand All @@ -209,7 +216,7 @@ public boolean visit(TypeDeclaration node) {
public boolean visit(RecordDeclaration node) {
if (isImplementTemplateInstance(node)) {
String recordName = node.getName().getIdentifier();
collectTemplateLink(null, node, null, node, null, recordName, false);
collectTemplateLink(null, node, null, node, null, recordName, false, TemplateNameStrategy.ELEMENT_NAME);
}
return super.visit(node);
}
Expand Down Expand Up @@ -275,18 +282,52 @@ private static boolean isIgnoreFragments(Annotation checkedTemplateAnnotation) {
* @return the <code>basePath</code> value declared in the @CheckedTemplate
* annotation
*/
public static String getBasePath(Annotation checkedTemplateAnnotation) {
private static String getBasePath(Annotation checkedTemplateAnnotation) {
String basePath = null;
try {
Expression ignoreFragmentExpr = AnnotationUtils.getAnnotationMemberValueExpression(
checkedTemplateAnnotation, CHECKED_TEMPLATE_ANNOTATION_BASE_PATH);
basePath = AnnotationUtils.getString(ignoreFragmentExpr);
Expression basePathExpr = AnnotationUtils.getAnnotationMemberValueExpression(checkedTemplateAnnotation,
CHECKED_TEMPLATE_ANNOTATION_BASE_PATH);
basePath = AnnotationUtils.getString(basePathExpr);
} catch (Exception e) {
// Do nothing
}
return basePath;
}

/**
* Returns the <code>defaultName</code> value declared in the @CheckedTemplate
* annotation, relative to the templates root, to search the templates from.
* <code>
* @CheckedTemplate([email protected]_ELEMENT_NAME)
*</code>
*
* @param checkedTemplateAnnotation the CheckedTemplate annotation.
* @return the <code>defaultName</code> value declared in the @CheckedTemplate
* annotation
*/
private static TemplateNameStrategy getDefaultName(Annotation checkedTemplateAnnotation) {
TemplateNameStrategy defaultName = TemplateNameStrategy.ELEMENT_NAME;
try {
Expression defaultNameExpr = AnnotationUtils.getAnnotationMemberValueExpression(checkedTemplateAnnotation,
CHECKED_TEMPLATE_ANNOTATION_DEFAULT_NAME);
defaultName = getDefaultName(AnnotationUtils.getString(defaultNameExpr));
} catch (Exception e) {
// Do nothing
}
return defaultName;
}

private static TemplateNameStrategy getDefaultName(String defaultName) {
switch (defaultName) {
case CHECKED_TEMPLATE_ANNOTATION_DEFAULT_NAME_HYPHENATED_ELEMENT_NAME:
return TemplateNameStrategy.HYPHENATED_ELEMENT_NAME;

case CHECKED_TEMPLATE_ANNOTATION_DEFAULT_NAME_UNDERSCORED_ELEMENT_NAME:
return TemplateNameStrategy.UNDERSCORED_ELEMENT_NAME;
}
return TemplateNameStrategy.ELEMENT_NAME;
}

@Override
public void endVisit(TypeDeclaration node) {
levelTypeDecl--;
Expand All @@ -302,24 +343,28 @@ private static TypeDeclaration getTypeDeclaration(ASTNode node) {
}

private void collectTemplateLink(String basePath, MethodDeclaration methodDeclaration, TypeDeclaration type,
boolean ignoreFragment) {
boolean ignoreFragment, TemplateNameStrategy templateNameStrategy) {
String className = null;
boolean innerClass = levelTypeDecl > 1;
if (innerClass) {
className = JDTTypeUtils.getSimpleClassName(typeRoot.getElementName());
}
String methodName = methodDeclaration.getName().getIdentifier();
collectTemplateLink(basePath, methodDeclaration, null, type, className, methodName, ignoreFragment);
collectTemplateLink(basePath, methodDeclaration, null, type, className, methodName, ignoreFragment,
templateNameStrategy);
}

private void collectTemplateLink(String basePath, ASTNode fieldOrMethod, StringLiteral locationAnnotation,
AbstractTypeDeclaration type, String className, String fieldOrMethodName, boolean ignoreFragment) {
AbstractTypeDeclaration type, String className, String fieldOrMethodName, boolean ignoreFragment,
TemplateNameStrategy templateNameStrategy) {
try {
String location = locationAnnotation != null ? locationAnnotation.getLiteralValue() : null;
IProject project = typeRoot.getJavaProject().getProject();
TemplatePathInfo templatePathInfo = location != null
? JDTQuteProjectUtils.getTemplatePath(basePath, null, location, ignoreFragment)
: JDTQuteProjectUtils.getTemplatePath(basePath, className, fieldOrMethodName, ignoreFragment);
? JDTQuteProjectUtils.getTemplatePath(basePath, null, location, ignoreFragment,
templateNameStrategy)
: JDTQuteProjectUtils.getTemplatePath(basePath, className, fieldOrMethodName, ignoreFragment,
templateNameStrategy);
IFile templateFile = null;
if (location == null) {
templateFile = getTemplateFile(project, templatePathInfo.getTemplateUri());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,12 @@ private static List<DataModelParameter> createParameter(MethodDeclaration method
String parameterName = variable.getName().getFullyQualifiedName();
Type parameterType = variable.getType();
ITypeBinding binding = parameterType.resolveBinding();
DataModelParameter parameter = new DataModelParameter();
parameter.setKey(parameterName);
parameter.setSourceType(binding.getQualifiedName());
parameters.add(parameter);
if (binding != null) {
DataModelParameter parameter = new DataModelParameter();
parameter.setKey(parameterName);
parameter.setSourceType(binding.getQualifiedName());
parameters.add(parameter);
}
}
return parameters;
}
Expand Down
Loading

0 comments on commit 353f9be

Please sign in to comment.