Skip to content

Commit

Permalink
fix: Qute highlight errors due to formatting
Browse files Browse the repository at this point in the history
Fixes redhat-developer#966

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Jul 9, 2024
1 parent 51aa262 commit 15bc532
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import com.redhat.qute.parser.expression.PropertyPart;
import com.redhat.qute.parser.template.CaseOperator;
import com.redhat.qute.parser.template.Expression;
import com.redhat.qute.parser.template.ExpressionParameter;
import com.redhat.qute.parser.template.JavaTypeInfoProvider;
import com.redhat.qute.parser.template.LiteralSupport;
import com.redhat.qute.parser.template.Node;
Expand Down Expand Up @@ -232,7 +233,8 @@ private void validateDataModel(Node parent, Template template, QuteValidationSet
// validate expression parameters
boolean checkValidOperator = section.getSectionKind() == SectionKind.IF;
boolean shouldBeAnOperator = false;
for (Parameter parameter : parameters) {
for (int i = 0; i < parameters.size(); i++) {
Parameter parameter = parameters.get(i);
if (shouldBeAnOperator) {
// #if section, the current parameter name must be an operator
String operatorName = parameter.getName();
Expand All @@ -256,6 +258,11 @@ private void validateDataModel(Node parent, Template template, QuteValidationSet
switch (section.getSectionKind()) {
case FOR:
case EACH:
Part lastPart = expression.getLastPart();
if (result != null) {
result = validateIterable(lastPart, section, result, result.getSignature(),
diagnostics);
}
String alias = ((LoopSection) section).getAlias();
currentContext.put(alias, result);
break;
Expand Down Expand Up @@ -461,10 +468,11 @@ private static boolean canChangeContext(Section section) {
* Validate #include section.
*
* @param includeSection the include section
* @param project
* @param project
* @param diagnostics the diagnostics to fill.
*/
private static void validateIncludeSection(IncludeSection includeSection, QuteProject project, List<Diagnostic> diagnostics) {
private static void validateIncludeSection(IncludeSection includeSection, QuteProject project,
List<Diagnostic> diagnostics) {
Parameter templateParameter = includeSection.getTemplateParameter();
if (templateParameter != null) {
// Validate template id, only if project exists.
Expand Down Expand Up @@ -563,8 +571,7 @@ private ResolvedJavaTypeInfo validateExpression(Expression expression, Section o
if (QuteCompletableFutures.isResolvingJavaTypeOrNull(resolvedLiteralType)) {
return null;
}
return validateIterable(expression.getLastPart(), ownerSection, resolvedLiteralType,
resolvedLiteralType.getName(), diagnostics);
return resolvedLiteralType;
}
// The expression reference Java data model (ex : {item})
ResolvedJavaTypeInfo resolvedJavaType = null;
Expand Down Expand Up @@ -911,7 +918,7 @@ private ResolvedJavaTypeInfo validatePropertyPart(PropertyPart part, Section own
}
}
}

if (javaMember.getJavaElementKind() == JavaElementKind.METHOD && ((JavaMethodInfo) javaMember).isVoidMethod()) {
return null;
}
Expand Down Expand Up @@ -1232,26 +1239,24 @@ private ResolvedJavaTypeInfo validateJavaTypePart(Part part, Section ownerSectio
return null;
}

return validateIterable(part, ownerSection, resolvedJavaType, javaTypeToResolve, diagnostics);
return resolvedJavaType;
}

private ResolvedJavaTypeInfo validateIterable(Part part, Section ownerSection,
ResolvedJavaTypeInfo resolvedJavaType, String javaTypeToResolve, List<Diagnostic> diagnostics) {
if (part != null && part.isLast() && ownerSection != null && ownerSection.isIterable()) {
// The expression is declared inside an iterable section like #for, #each.
// Ex: {#for item in items}
if (!resolvedJavaType.isIterable() && !resolvedJavaType.isInteger()) {
// The Java class is not an iterable class like
// - java.util.List
// - object array
// - integer
String expression = part.getParent().getContent();
Range range = QutePositionUtility.createRange(part);
Diagnostic diagnostic = createDiagnostic(range, DiagnosticSeverity.Error, QuteErrorCode.IterationError,
expression, javaTypeToResolve);
diagnostics.add(diagnostic);
return null;
}
// The expression is declared inside an iterable section like #for, #each.
// Ex: {#for item in items}
if (!resolvedJavaType.isIterable() && !resolvedJavaType.isInteger()) {
// The Java class is not an iterable class like
// - java.util.List
// - object array
// - integer
String expression = part.getParent().getContent();
Range range = QutePositionUtility.createRange(part);
Diagnostic diagnostic = createDiagnostic(range, DiagnosticSeverity.Error, QuteErrorCode.IterationError,
expression, javaTypeToResolve);
diagnostics.add(diagnostic);
return null;
}
return resolvedJavaType;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ private void createBinaryTypes(List<ResolvedJavaTypeInfo> cache) {
list.setExtendedTypes(Arrays.asList("java.util.Collection<E>"));
registerMethod("size() : int", list);
registerMethod("get(index : int) : E", list);
registerMethod("subList(fromIndex : int, toIndex: int) : java.util.List<E>", list);

// Set
ResolvedJavaTypeInfo set = createResolvedJavaTypeInfo("java.util.Set<E>", cache, true);
Expand All @@ -113,6 +114,7 @@ private void createBinaryTypes(List<ResolvedJavaTypeInfo> cache) {
registerMethod("keySet() : java.util.Set<K>", map);
registerMethod("values() : java.util.Collection<V>", map);
registerMethod("entrySet() : java.util.Set<java.util.Map$Entry<K,V>>", map);
registerMethod("get(key : K) : V", map);

// Map.Entry
ResolvedJavaTypeInfo mapEntry = createResolvedJavaTypeInfo("java.util.Map$Entry<K,V>", cache, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ public void completion() throws Exception {
// test to check @java.lang.Integer(base : T[]) : T is not returned by the
// completion
testCompletionFor(template, //
11, //
12, //
c("iterator() : Iterator<Item>", "iterator", r(1, 13, 1, 13)), //
c("size() : int", "size", r(1, 13, 1, 13)), //
c("get(index : int) : Item", "get(${1:index})$0", r(1, 13, 1, 13)), //
c("subList(fromIndex : int, toIndex : int) : List<Item>", "subList(${1:fromIndex}, ${2:toIndex})$0", r(1, 13, 1, 13)), //
c("raw(base : Object) : RawString", "raw", r(1, 13, 1, 13)), //
c("safe(base : Object) : RawString", "safe", r(1, 13, 1, 13)));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ public void completion() throws Exception {
// test to check @java.lang.Integer(base : T[]) : T is not returned by the
// completion
testCompletionFor(template, //
11, //
12, //
c("iterator() : Iterator<Item>", "iterator", r(1, 13, 1, 13)), //
c("size() : int", "size", r(1, 13, 1, 13)), //
c("get(index : int) : Item", "get(${1:index})$0", r(1, 13, 1, 13)), //
c("subList(fromIndex : int, toIndex : int) : List<Item>", "subList(${1:fromIndex}, ${2:toIndex})$0", r(1, 13, 1, 13)), //
c("raw(base : Object) : RawString", "raw", r(1, 13, 1, 13)), //
c("safe(base : Object) : RawString", "safe", r(1, 13, 1, 13)));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
*******************************************************************************/
package com.redhat.qute.services.diagnostics;

import static com.redhat.qute.QuteAssert.c;
import static com.redhat.qute.QuteAssert.ca;
import static com.redhat.qute.QuteAssert.d;
import static com.redhat.qute.QuteAssert.te;
Expand All @@ -22,9 +21,6 @@
import org.eclipse.lsp4j.DiagnosticSeverity;
import org.junit.jupiter.api.Test;

import com.redhat.qute.ls.commons.client.ConfigurationItemEditType;
import com.redhat.qute.services.commands.QuteClientCommandConstants;

/**
* Test with #for section
*
Expand Down Expand Up @@ -252,4 +248,55 @@ public void twoManyTypeParameter() {
"{/for}";
testDiagnosticsFor(template);
}

@Test
public void listFromMethodWithIntParameter() throws Exception {
String template = "{@java.util.List<org.acme.Item> items}\r\n" + //
" \r\n" + //
"{#for item in items.subList(0,5)}\r\n" + //
" {item.name} \r\n" + //
"{/for}}";
testDiagnosticsFor(template);

template = "{@java.util.List<org.acme.Item> items}\r\n" + //
" \r\n" + //
"{#for item in items.subList(0,5).subList(0,5)}\r\n" + //
" {item.name} \r\n" + //
"{/for}}";
testDiagnosticsFor(template);
}

@Test
public void listFromMethodWithIntParameterAndLet() throws Exception {
String template = "{@java.util.List<org.acme.Item> items}\r\n" + //
"{#let index = 0 }\r\n" + //
" \r\n" + //
"{#for item in items.subList(index,index)}\r\n" + //
" {item.name} \r\n" + //
"{/for}}";
testDiagnosticsFor(template);
}

@Test
public void listFromMethodWithStringParameter() throws Exception {
String template = "{@java.util.Map<java.lang.String,java.util.List<org.acme.Item>> items}\r\n" + //
" \r\n" + //
"{#for item in items.get('foo')}\r\n" + //
" {item.name} \r\n" + //
"{/for}}";
testDiagnosticsFor(template);
}


@Test
public void listFromMethodWithStringParameterAndLet() throws Exception {
String template = "{@java.util.Map<java.lang.String,java.util.List<org.acme.Item>> items}\r\n" + //
"{#let key = 'foo' }\r\n" + //
" \r\n" + //
"{#for item in items.get(key)}\r\n" + //
" {item.name} \r\n" + //
"{/for}}";
testDiagnosticsFor(template);

}
}

0 comments on commit 15bc532

Please sign in to comment.