Skip to content

Commit 3114a5e

Browse files
committed
fix: Check if record implement TemplateInstance to provide the support
Signed-off-by: azerr <azerr@redhat.com>
1 parent 8a47098 commit 3114a5e

File tree

5 files changed

+131
-11
lines changed

5 files changed

+131
-11
lines changed

projects/qute/projects/maven/qute-record/src/main/java/org/acme/sample/HelloResource.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ public class HelloResource {
1414

1515
record Hello(String name) implements TemplateInstance {}
1616

17+
record Bonjour(String name) implements TemplateInstance {}
18+
19+
record Status() {}
20+
1721
@GET
1822
@Produces(MediaType.TEXT_PLAIN)
1923
public TemplateInstance get(@QueryParam("name") String name) {

src/main/java/com/redhat/devtools/intellij/qute/psi/internal/java/AbstractQuteTemplateLinkCollector.java

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
import com.intellij.openapi.vfs.VfsUtilCore;
2020
import com.intellij.openapi.vfs.VirtualFile;
2121
import com.intellij.psi.*;
22+
import com.intellij.psi.impl.source.PsiClassReferenceType;
2223
import com.intellij.psi.util.PsiTreeUtil;
24+
import com.redhat.devtools.intellij.qute.psi.internal.QuteJavaConstants;
2325
import com.redhat.devtools.lsp4ij.LSPIJUtils;
2426
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.IPsiUtils;
2527
import com.redhat.devtools.intellij.qute.psi.internal.AnnotationLocationSupport;
@@ -92,8 +94,8 @@ public AbstractQuteTemplateLinkCollector(PsiFile typeRoot, IPsiUtils utils, Prog
9294
* </p>
9395
*
9496
* @see <a href=
95-
* "https://quarkus.io/guides/qute-reference#quarkus_integration">Quarkus
96-
* Integration</a>
97+
* "https://quarkus.io/guides/qute-reference#quarkus_integration">Quarkus
98+
* Integration</a>
9799
*/
98100
@Override
99101
public void visitField(PsiField node) {
@@ -154,12 +156,11 @@ public void visitClass(PsiClass node) {
154156
* <p>
155157
*
156158
* @CheckedTemplate public static class Templates { public static native
157-
* TemplateInstance book(Book book);
158-
* </p>
159-
*
159+
* TemplateInstance book(Book book);
160+
* </p>
160161
* @see <a href=
161-
* "https://quarkus.io/guides/qute-reference#typesafe_templates">TypeSafe
162-
* Templates</a>
162+
* "https://quarkus.io/guides/qute-reference#typesafe_templates">TypeSafe
163+
* Templates</a>
163164
*/
164165
private void visitClassType(PsiClass node) {
165166
levelTypeDecl++;
@@ -184,14 +185,36 @@ private void visitClassType(PsiClass node) {
184185
* Support for "Template Records"
185186
*
186187
* @see <a href=
187-
* "https://quarkus.io/guides/qute-reference#template-records">Template
188-
* Records</a>
188+
* "https://quarkus.io/guides/qute-reference#template-records">Template
189+
* Records</a>
189190
*/
190191
private void visitRecordType(PsiClass node) {
191-
String recordName = node.getName();
192-
collectTemplateLink(null, node, null, node.getContainingClass(), null, recordName, false);
192+
if (isImplementTemplateInstance(node)) {
193+
String recordName = node.getName();
194+
collectTemplateLink(null, node, null, node, null, recordName, false);
195+
}
196+
}
197+
198+
/**
199+
* Returns true if the record implements the "io.quarkus.qute.TemplateInstance"
200+
* interface and false otherwise.
201+
*
202+
* @param node the record node.
203+
* @return true if the record implements the "io.quarkus.qute.TemplateInstance"
204+
* interface and false otherwise.
205+
*/
206+
private static boolean isImplementTemplateInstance(PsiClass node) {
207+
for (var current : node.getImplementsListTypes()) {
208+
if (current instanceof PsiClassReferenceType type &&
209+
type.getReference() != null &&
210+
QuteJavaConstants.TEMPLATE_INSTANCE_INTERFACE.equals(type.getReference().getQualifiedName())) {
211+
return true;
212+
}
213+
}
214+
return false;
193215
}
194216

217+
195218
private static PsiClass getTypeDeclaration(PsiElement node) {
196219
return PsiTreeUtil.getParentOfType(node, PsiClass.class);
197220
}
@@ -303,6 +326,11 @@ protected Range createRange(PsiElement fieldOrMethod) {
303326
TextRange tr = fieldOrMethod.getTextRange();
304327
return utils.toRange(typeRoot, tr.getStartOffset(), tr.getLength());
305328
}
329+
if (fieldOrMethod instanceof PsiClass) {
330+
// record
331+
TextRange tr = ((PsiClass) fieldOrMethod).getNameIdentifier().getTextRange();
332+
return utils.toRange(typeRoot, tr.getStartOffset(), tr.getLength());
333+
}
306334
PsiMethod method = (PsiMethod) fieldOrMethod;
307335
PsiIdentifier methodName = method.getNameIdentifier();
308336
TextRange tr = methodName.getTextRange();

src/test/java/com/redhat/devtools/intellij/qute/psi/java/MavenJavaCodeLensTest.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ public void testCheckedTemplateInInnerClassWithCustomBasePath() throws Exception
304304
"qute.command.generate.template.file", Arrays.asList(items3Uri)));
305305

306306
}
307+
307308
@Test
308309
public void testCheckedTemplateInInnerClassWithFragment() throws Exception {
309310

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

347+
@Test
348+
public void testTemplateRecord() throws Exception {
349+
// public class HelloResource {
350+
351+
// record Hello(String name) implements TemplateInstance {}
352+
353+
// record Bonjour(String name) implements TemplateInstance {}
354+
355+
// record Status() {}
356+
var module = loadMavenProject(QuteMavenProjectName.qute_record);
357+
358+
QuteJavaCodeLensParams params = new QuteJavaCodeLensParams();
359+
String javaFileUri = LSPIJUtils.toUri(module).resolve("src/main/java/org/acme/sample/HelloResource.java").toASCIIString();
360+
params.setUri(javaFileUri);
361+
362+
List<? extends CodeLens> lenses = QuteSupportForJava.getInstance().codeLens(params, PsiUtilsLSImpl.getInstance(myProject),
363+
new EmptyProgressIndicator());
364+
365+
String helloFileUri = LSPIJUtils.toUri(module).resolve("/src/main/resources/templates/Hello.html").toASCIIString();
366+
String bonjourFileUri = LSPIJUtils.toUri(module).resolve("/src/main/resources/templates/Bonjour.html").toASCIIString();
367+
368+
assertCodeLens(lenses, //
369+
cl(r(14, 4, 14, 60), //
370+
"Open `src/main/resources/templates/Hello.html`", //
371+
"qute.command.open.uri", Arrays.asList(helloFileUri)), //
372+
cl(r(16, 4, 16, 62), //
373+
"Create `src/main/resources/templates/Bonjour.html`", //
374+
"qute.command.generate.template.file", Arrays.asList(bonjourFileUri)));
375+
}
376+
346377
public static Range r(int line, int startChar, int endChar) {
347378
return r(line, startChar, line, endChar);
348379
}

src/test/java/com/redhat/devtools/intellij/qute/psi/java/MavenJavaDiagnosticsTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,35 @@ public void testCheckedTemplateInInnerClassWithCustomBasePath() throws Exception
277277
);
278278
}
279279

280+
@Test
281+
public void testTemplateRecord() throws Exception {
282+
283+
// public class HelloResource {
284+
285+
// record Hello(String name) implements TemplateInstance {}
286+
287+
// record Bonjour(String name) implements TemplateInstance {}
288+
289+
// record Status() {}
290+
291+
var module = loadMavenProject(QuteMavenProjectName.qute_record);
292+
QuteJavaDiagnosticsParams params = new QuteJavaDiagnosticsParams();
293+
String javaFileUri = LSPIJUtils.toUri(module).resolve("src/main/java/org/acme/sample/HelloResource.java").toASCIIString();
294+
params.setUris(Arrays.asList(javaFileUri));
295+
296+
List<PublishDiagnosticsParams> publishDiagnostics = QuteSupportForJava.getInstance().diagnostics(params,
297+
PsiUtilsLSImpl.getInstance(myProject), new EmptyProgressIndicator());
298+
assertEquals(1, publishDiagnostics.size());
299+
300+
List<Diagnostic> diagnostics = publishDiagnostics.get(0).getDiagnostics();
301+
assertEquals(1, diagnostics.size());
302+
303+
assertDiagnostic(diagnostics, //
304+
new Diagnostic(r(16, 11, 16, 18),
305+
"No template matching the path Bonjour could be found for: org.acme.sample.HelloResource$Bonjour",
306+
DiagnosticSeverity.Error, "qute", QuteErrorCode.NoMatchingTemplate.name()));
307+
}
308+
280309

281310
public static Range r(int line, int startChar, int endChar) {
282311
return r(line, startChar, line, endChar);

src/test/java/com/redhat/devtools/intellij/qute/psi/java/MavenJavaDocumentLinkTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,34 @@ public void testCheckedTemplateInInnerClassWithCustomBasePath() throws Exception
280280
templateFileUri, "Create `src/main/resources/templates/ItemResourceWithFragment/items3.html`")); //
281281
}
282282

283+
@Test
284+
public void testTemplateRecord() throws Exception {
285+
286+
// public class HelloResource {
287+
288+
// record Hello(String name) implements TemplateInstance {}
289+
290+
// record Bonjour(String name) implements TemplateInstance {}
291+
292+
// record Status() {}
293+
var module = loadMavenProject(QuteMavenProjectName.qute_record);
294+
QuteJavaDocumentLinkParams params = new QuteJavaDocumentLinkParams();
295+
String javaFileUri = LSPIJUtils.toUri(module).resolve("src/main/java/org/acme/sample/HelloResource.java").toASCIIString();
296+
params.setUri(javaFileUri);
297+
298+
List<DocumentLink> links = QuteSupportForJava.getInstance().documentLink(params, PsiUtilsLSImpl.getInstance(myProject),
299+
new EmptyProgressIndicator());
300+
assertEquals(2, links.size());
301+
302+
String templateFileUri = LSPIJUtils.toUri(module).resolve("src/main/resources/templates/Hello.html").toASCIIString();
303+
304+
assertDocumentLink(links, //
305+
dl(r(14, 11, 14, 16), //
306+
templateFileUri, "Open `src/main/resources/templates/Hello.html`"), //
307+
dl(r(16, 11, 16, 18), //
308+
templateFileUri, "Create `src/main/resources/templates/Bonjour.html`"));
309+
}
310+
283311

284312
public static Range r(int line, int startChar, int endChar) {
285313
return r(line, startChar, line, endChar);

0 commit comments

Comments
 (0)