Skip to content

Commit

Permalink
fix: Check if record implement TemplateInstance to provide the support
Browse files Browse the repository at this point in the history
Signed-off-by: azerr <azerr@redhat.com>
  • Loading branch information
angelozerr committed Jul 12, 2024
1 parent 8a47098 commit 3114a5e
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ public class HelloResource {

record Hello(String name) implements TemplateInstance {}

record Bonjour(String name) implements TemplateInstance {}

record Status() {}

@GET
@Produces(MediaType.TEXT_PLAIN)
public TemplateInstance get(@QueryParam("name") String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.intellij.psi.util.PsiTreeUtil;
import com.redhat.devtools.intellij.qute.psi.internal.QuteJavaConstants;
import com.redhat.devtools.lsp4ij.LSPIJUtils;
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.IPsiUtils;
import com.redhat.devtools.intellij.qute.psi.internal.AnnotationLocationSupport;
Expand Down Expand Up @@ -92,8 +94,8 @@ public AbstractQuteTemplateLinkCollector(PsiFile typeRoot, IPsiUtils utils, Prog
* </p>
*
* @see <a href=
* "https://quarkus.io/guides/qute-reference#quarkus_integration">Quarkus
* Integration</a>
* "https://quarkus.io/guides/qute-reference#quarkus_integration">Quarkus
* Integration</a>
*/
@Override
public void visitField(PsiField node) {
Expand Down Expand Up @@ -154,12 +156,11 @@ public void visitClass(PsiClass node) {
* <p>
*
* @CheckedTemplate public static class Templates { public static native
* TemplateInstance book(Book book);
* </p>
*
* TemplateInstance book(Book book);
* </p>
* @see <a href=
* "https://quarkus.io/guides/qute-reference#typesafe_templates">TypeSafe
* Templates</a>
* "https://quarkus.io/guides/qute-reference#typesafe_templates">TypeSafe
* Templates</a>
*/
private void visitClassType(PsiClass node) {
levelTypeDecl++;
Expand All @@ -184,14 +185,36 @@ private void visitClassType(PsiClass node) {
* Support for "Template Records"
*
* @see <a href=
* "https://quarkus.io/guides/qute-reference#template-records">Template
* Records</a>
* "https://quarkus.io/guides/qute-reference#template-records">Template
* Records</a>
*/
private void visitRecordType(PsiClass node) {
String recordName = node.getName();
collectTemplateLink(null, node, null, node.getContainingClass(), null, recordName, false);
if (isImplementTemplateInstance(node)) {
String recordName = node.getName();
collectTemplateLink(null, node, null, node, null, recordName, false);
}
}

/**
* Returns true if the record implements the "io.quarkus.qute.TemplateInstance"
* interface and false otherwise.
*
* @param node the record node.
* @return true if the record implements the "io.quarkus.qute.TemplateInstance"
* interface and false otherwise.
*/
private static boolean isImplementTemplateInstance(PsiClass node) {
for (var current : node.getImplementsListTypes()) {
if (current instanceof PsiClassReferenceType type &&
type.getReference() != null &&
QuteJavaConstants.TEMPLATE_INSTANCE_INTERFACE.equals(type.getReference().getQualifiedName())) {
return true;
}
}
return false;
}


private static PsiClass getTypeDeclaration(PsiElement node) {
return PsiTreeUtil.getParentOfType(node, PsiClass.class);
}
Expand Down Expand Up @@ -303,6 +326,11 @@ protected Range createRange(PsiElement fieldOrMethod) {
TextRange tr = fieldOrMethod.getTextRange();
return utils.toRange(typeRoot, tr.getStartOffset(), tr.getLength());
}
if (fieldOrMethod instanceof PsiClass) {
// record
TextRange tr = ((PsiClass) fieldOrMethod).getNameIdentifier().getTextRange();
return utils.toRange(typeRoot, tr.getStartOffset(), tr.getLength());
}
PsiMethod method = (PsiMethod) fieldOrMethod;
PsiIdentifier methodName = method.getNameIdentifier();
TextRange tr = methodName.getTextRange();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ public void testCheckedTemplateInInnerClassWithCustomBasePath() throws Exception
"qute.command.generate.template.file", Arrays.asList(items3Uri)));

}

@Test
public void testCheckedTemplateInInnerClassWithFragment() throws Exception {

Expand Down Expand Up @@ -343,6 +344,36 @@ public void testCheckedTemplateInInnerClassWithFragment() throws Exception {
"qute.command.generate.template.file", Arrays.asList(items2Uri_id2)));
}

@Test
public void testTemplateRecord() throws Exception {
// public class HelloResource {

// record Hello(String name) implements TemplateInstance {}

// record Bonjour(String name) implements TemplateInstance {}

// record Status() {}
var module = loadMavenProject(QuteMavenProjectName.qute_record);

QuteJavaCodeLensParams params = new QuteJavaCodeLensParams();
String javaFileUri = LSPIJUtils.toUri(module).resolve("src/main/java/org/acme/sample/HelloResource.java").toASCIIString();
params.setUri(javaFileUri);

List<? extends CodeLens> lenses = QuteSupportForJava.getInstance().codeLens(params, PsiUtilsLSImpl.getInstance(myProject),
new EmptyProgressIndicator());

String helloFileUri = LSPIJUtils.toUri(module).resolve("/src/main/resources/templates/Hello.html").toASCIIString();
String bonjourFileUri = LSPIJUtils.toUri(module).resolve("/src/main/resources/templates/Bonjour.html").toASCIIString();

assertCodeLens(lenses, //
cl(r(14, 4, 14, 60), //
"Open `src/main/resources/templates/Hello.html`", //
"qute.command.open.uri", Arrays.asList(helloFileUri)), //
cl(r(16, 4, 16, 62), //
"Create `src/main/resources/templates/Bonjour.html`", //
"qute.command.generate.template.file", Arrays.asList(bonjourFileUri)));
}

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 @@ -277,6 +277,35 @@ public void testCheckedTemplateInInnerClassWithCustomBasePath() throws Exception
);
}

@Test
public void testTemplateRecord() throws Exception {

// public class HelloResource {

// record Hello(String name) implements TemplateInstance {}

// record Bonjour(String name) implements TemplateInstance {}

// record Status() {}

var module = loadMavenProject(QuteMavenProjectName.qute_record);
QuteJavaDiagnosticsParams params = new QuteJavaDiagnosticsParams();
String javaFileUri = LSPIJUtils.toUri(module).resolve("src/main/java/org/acme/sample/HelloResource.java").toASCIIString();
params.setUris(Arrays.asList(javaFileUri));

List<PublishDiagnosticsParams> publishDiagnostics = QuteSupportForJava.getInstance().diagnostics(params,
PsiUtilsLSImpl.getInstance(myProject), new EmptyProgressIndicator());
assertEquals(1, publishDiagnostics.size());

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

assertDiagnostic(diagnostics, //
new Diagnostic(r(16, 11, 16, 18),
"No template matching the path Bonjour could be found for: org.acme.sample.HelloResource$Bonjour",
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 @@ -280,6 +280,34 @@ public void testCheckedTemplateInInnerClassWithCustomBasePath() throws Exception
templateFileUri, "Create `src/main/resources/templates/ItemResourceWithFragment/items3.html`")); //
}

@Test
public void testTemplateRecord() throws Exception {

// public class HelloResource {

// record Hello(String name) implements TemplateInstance {}

// record Bonjour(String name) implements TemplateInstance {}

// record Status() {}
var module = loadMavenProject(QuteMavenProjectName.qute_record);
QuteJavaDocumentLinkParams params = new QuteJavaDocumentLinkParams();
String javaFileUri = LSPIJUtils.toUri(module).resolve("src/main/java/org/acme/sample/HelloResource.java").toASCIIString();
params.setUri(javaFileUri);

List<DocumentLink> links = QuteSupportForJava.getInstance().documentLink(params, PsiUtilsLSImpl.getInstance(myProject),
new EmptyProgressIndicator());
assertEquals(2, links.size());

String templateFileUri = LSPIJUtils.toUri(module).resolve("src/main/resources/templates/Hello.html").toASCIIString();

assertDocumentLink(links, //
dl(r(14, 11, 14, 16), //
templateFileUri, "Open `src/main/resources/templates/Hello.html`"), //
dl(r(16, 11, 16, 18), //
templateFileUri, "Create `src/main/resources/templates/Bonjour.html`"));
}


public static Range r(int line, int startChar, int endChar) {
return r(line, startChar, line, endChar);
Expand Down

0 comments on commit 3114a5e

Please sign in to comment.