Skip to content

Commit

Permalink
Check if record implement TemplateInstance to provide the support
Browse files Browse the repository at this point in the history
Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Jul 12, 2024
1 parent c46f4f9 commit 116b60b
Show file tree
Hide file tree
Showing 12 changed files with 221 additions and 36 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
@@ -0,0 +1,12 @@
package org.acme.sample;

public class SomeService {

record RunnerState(Status status) {

public enum Status {
dead, alive, saved, inactive
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,40 @@ public void checkedTemplateWithFragment() throws CoreException, Exception {
"qute.command.generate.template.file", Arrays.asList(items2Uri_id2)));
}

@Test
public void templateRecord() throws CoreException, Exception {
// public class HelloResource {

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

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

// record Status() {}

IJavaProject javaProject = loadMavenProject(QuteMavenProjectName.qute_record);

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

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

String helloFileUri = javaProject.getProject().getFile("src/main/resources/templates/Hello.html")
.getLocationURI().toString();
String boujourFileUri1 = javaProject.getProject().getFile("src/main/resources/templates/Bonjour.html")
.getLocationURI().toString();

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(boujourFileUri1)));
}

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 @@ -230,6 +230,36 @@ public void checkedTemplateWithCustomBasePath() throws Exception {
DiagnosticSeverity.Error, "qute", QuteErrorCode.FragmentNotDefined.name()));
}

@Test
public void templateRecord() throws Exception {

// public class HelloResource {

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

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

// record Status() {}

IJavaProject javaProject = loadMavenProject(QuteMavenProjectName.qute_record);

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

List<PublishDiagnosticsParams> publishDiagnostics = QuteSupportForJava.getInstance().diagnostics(params,
getJDTUtils(), new NullProgressMonitor());
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 @@ -236,6 +236,37 @@ public void checkedTemplateWithCustomBasePath() throws Exception {
templateFileUri, "Create `src/main/resources/templates/ItemResourceWithFragment/items3.html`"));
}

@Test
public void templateRecord() throws Exception {

// public class HelloResource {

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

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

// record Status() {}

IJavaProject javaProject = loadMavenProject(QuteMavenProjectName.qute_record);

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

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

String templateFileUri = javaProject.getProject().getFile("src/main/resources/templates/Hello.html")
.getLocationURI().toString();

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
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,27 @@ public void record() throws Exception {
Assert.assertEquals("java.math.BigDecimal", result.getFields().get(1).getType());
}

@Test
public void enumDeclaredInRecord() throws Exception {
loadMavenProject(QuteMavenProjectName.qute_record);

QuteResolvedJavaTypeParams params = new QuteResolvedJavaTypeParams("org.acme.sample.SomeService$RunnerState$Status",
QuteMavenProjectName.qute_record);
ResolvedJavaTypeInfo result = QuteSupportForTemplate.getInstance().getResolvedJavaType(params, getJDTUtils(),
new NullProgressMonitor());
Assert.assertNotNull(result);
Assert.assertEquals("org.acme.sample.SomeService$RunnerState$Status", result.getSignature());
Assert.assertEquals(JavaTypeKind.Enum, result.getJavaTypeKind());

// Enum
Assert.assertNotNull(result.getFields());
Assert.assertEquals(4, result.getFields().size());
Assert.assertEquals("dead", result.getFields().get(0).getName());
Assert.assertEquals("org.acme.sample.SomeService$RunnerState$Status", result.getFields().get(0).getType());
Assert.assertEquals("alive", result.getFields().get(1).getName());
Assert.assertEquals("org.acme.sample.SomeService$RunnerState$Status", result.getFields().get(1).getType());
}

@Test
public void templateData() throws CoreException, Exception {
loadMavenProject(QuteMavenProjectName.qute_quickstart);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,27 +233,29 @@ public Location getJavaDefinition(QuteJavaDefinitionParams params, IJDTUtils uti
}

String parameterName = params.getSourceParameter();
String fieldName = params.getSourceField();
boolean dataMethodInvocation = parameterName != null && params.isDataMethodInvocation();

if (type.isRecord()) {
// The source type is a record
if (dataMethodInvocation) {
// returns the location of "data" method invocation with the given parameter
// name
return TemplateDataSupport.getDataMethodInvocationLocation(type, parameterName, utils,
monitor);

// returns the location of "data" method invocation with the given parameter
// name
return TemplateDataSupport.getDataMethodInvocationLocation(type, parameterName, utils, monitor);

} else {
// Search field of the record
IField recordField = type.getRecordComponent(parameterName);
if (recordField != null && recordField.exists()) {
// returns the record field location
return utils.toLocation(recordField);
String recordFieldName = parameterName != null ? parameterName : fieldName;
if (recordFieldName != null) {
IField recordField = type.getRecordComponent(recordFieldName);
if (recordField != null && recordField.exists()) {
// returns the record field location
return utils.toLocation(recordField);
}
}
}
} else {
// The source type is a class
String fieldName = params.getSourceField();
if (fieldName != null) {
IField field = type.getField(fieldName);
if (field == null || !field.exists()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.RecordDeclaration;
import org.eclipse.jdt.core.dom.SimpleName;
Expand All @@ -45,6 +46,7 @@
import org.eclipse.lsp4j.Range;

import com.redhat.qute.jdt.internal.AnnotationLocationSupport;
import com.redhat.qute.jdt.internal.QuteJavaConstants;
import com.redhat.qute.jdt.utils.AnnotationUtils;
import com.redhat.qute.jdt.utils.IJDTUtils;
import com.redhat.qute.jdt.utils.JDTQuteProjectUtils;
Expand Down Expand Up @@ -205,11 +207,38 @@ public boolean visit(TypeDeclaration node) {
*/
@Override
public boolean visit(RecordDeclaration node) {
String recordName = node.getName().getIdentifier();
collectTemplateLink(null, node, null, node, null, recordName, false);
if (isImplementTemplateInstance(node)) {
String recordName = node.getName().getIdentifier();
collectTemplateLink(null, node, null, node, null, recordName, false);
}
return super.visit(node);
}

/**
* 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(RecordDeclaration node) {
ITypeBinding binding = node.resolveBinding();
if (binding == null) {
return false;
}
ITypeBinding[] interfaces = binding.getInterfaces();
if (interfaces == null || interfaces.length == 0) {
return false;
}
for (ITypeBinding current : interfaces) {
if (QuteJavaConstants.TEMPLATE_INSTANCE_INTERFACE.equals(current.getQualifiedName())) {
return true;
}
}
return false;
}

/**
* Returns true if @CheckedTemplate annotation declares that fragment must be
* ignored and false otherwise.
Expand Down
Loading

0 comments on commit 116b60b

Please sign in to comment.