Skip to content

Commit

Permalink
Support Java expression for it user tag
Browse files Browse the repository at this point in the history
Signed-off-by: azerr <azerr@redhat.com>
  • Loading branch information
angelozerr authored and fbricon committed Mar 14, 2022
1 parent d9b8f83 commit 2de6096
Show file tree
Hide file tree
Showing 26 changed files with 144 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,42 +60,4 @@ public class Constants {
public final static int _AST = "*".codePointAt(0);
public final static int _PLS = "+".codePointAt(0);

public static final Pattern ENTITY_NAME_REGEX = Pattern.compile("");

public static final Pattern ELEMENT_NAME_REGEX = Pattern.compile("^[_:\\w][_:\\w-.\\d]*");

public static final Pattern ATTRIBUTE_NAME_REGEX = Pattern.compile("^[^\\s\\?\"'<>/=\\x00-\\x0F\\x7F\\x80-\\x9F]*");

public static final Pattern ATTRIBUTE_VALUE_REGEX = Pattern.compile("^(\"[^\"]*\"?)|(\'[^\']*\'?)");

public static final Pattern URL_VALUE_REGEX = Pattern.compile("^(\"[^<>\"]*\")|(\'[^<>\']*\')");

public static final Pattern PROLOG_NAME_OPTIONS = Pattern.compile("^(xml)[\\s<>?]?");

public static final Pattern PI_TAG_NAME = Pattern.compile("^[a-zA-Z0-9]+");

// Add coming processing instructions that are defined to have attributes as
// content
public static final Pattern PI_WITH_VARIABLES = Pattern.compile("^(xml-stylesheet)[\\s<>?]?");

public static final Pattern DOCTYPE_KIND_OPTIONS = Pattern.compile("^(PUBLIC|SYSTEM)([\\s<>\"'])");

public static final Pattern DTD_ELEMENT_CATEGORY = Pattern.compile("^(EMPTY|ANY)([\\s<>\"'])");

public static final Pattern DTD_ELEMENT_CONTENT = Pattern.compile("^(\\((([^\\s,]+,)*[^\\s,]+)\\))|\\(\\)");

public static final Pattern DTD_PCDATA = Pattern.compile("^#PCDATA");

public static final Pattern DTD_ATTLIST_ATTRIBUTE_TYPE = Pattern
.compile("^(CDATA|IDREFS|IDREF|ID|NMTOKENS|NMTOKEN|ENTITIES|ENTITY|NOTATION|xml:|\\(.*\\))([\\s<>\"'])");

public static final Pattern DTD_ATTLIST_ATTRIBUTE_VALUE = Pattern
.compile("^(#REQUIRED|#IMPLIED|\".*\"|#FIXED \".*\")([\\s<>\"'])");

public static final Pattern DTD_ENTITY_VALUE = Pattern.compile("^\".*\"");

public static final Pattern DOCTYPE_NAME = Pattern.compile("^[_:\\w][_:\\w-.\\d]*");

public static final Pattern DOCUMENTATION_CONTENT = Pattern.compile(".*<[\\S]+:?documentation[^\\>]*>(.*)<\\/[\\S]+:?documentation[\\s]*>.*");

}
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,15 @@ public SectionKind getSectionKind() {
protected void initializeParameters(List<Parameter> parameters) {
// All parameters can have expression (ex : {#user name=order.item.parent
// isActive=false age=10}
parameters.forEach(parameter -> {
parameter.setCanHaveExpression(parameter.hasValueAssigned());
});
boolean hasIt = false;
for (Parameter parameter : parameters) {
if (parameter.hasValueAssigned()) {
parameter.setCanHaveExpression(true);
} else if (!hasIt) {
parameter.setCanHaveExpression(true);
hasIt = true;
}
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class QuteCodeActions {

private static final Logger LOGGER = Logger.getLogger(QuteCodeActions.class.getName());

private static final String UNDEFINED_VARIABLE_CODEACTION_TITLE = "Declare `{0}` with parameter declaration.";
private static final String UNDEFINED_OBJECT_CODEACTION_TITLE = "Declare `{0}` with parameter declaration.";

private static final String UNDEFINED_SECTION_TAG_CODEACTION_TITLE = "Create the user tag file `{0}`.";

Expand Down Expand Up @@ -98,7 +98,7 @@ public CompletableFuture<List<CodeAction>> doCodeActions(Template template, Code
// will provide a quickfix like:
//
// Declare `undefinedObject` with parameter declaration."
doCodeActionsForUndefinedVariable(template, diagnostic, codeActions);
doCodeActionsForUndefinedObject(template, diagnostic, codeActions);
break;
case UndefinedSectionTag:
// The following Qute template:
Expand All @@ -118,7 +118,7 @@ public CompletableFuture<List<CodeAction>> doCodeActions(Template template, Code
return CompletableFuture.completedFuture(codeActions);
}

private static void doCodeActionsForUndefinedVariable(Template template, Diagnostic diagnostic,
private static void doCodeActionsForUndefinedObject(Template template, Diagnostic diagnostic,
List<CodeAction> codeActions) {
try {
String varName = null;
Expand All @@ -144,7 +144,7 @@ private static void doCodeActionsForUndefinedVariable(Template template, Diagnos
TextDocument document = template.getTextDocument();
String lineDelimiter = document.lineDelimiter(0);

String title = MessageFormat.format(UNDEFINED_VARIABLE_CODEACTION_TITLE, varName);
String title = MessageFormat.format(UNDEFINED_OBJECT_CODEACTION_TITLE, varName);

Position position = new Position(0, 0);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -534,16 +534,16 @@ private ResolvedJavaTypeInfo validateObjectPart(String namespace, ObjectPart obj
JavaTypeInfoProvider javaTypeInfo = objectPart.resolveJavaType();
if (javaTypeInfo == null) {
if (!resolvingJavaTypeContext.isDataModelTemplateResolved()) {
// The data model is not loaded, ignore the error of undefined variable
// The data model is not loaded, ignore the error of undefined object
return null;
}

if (UserTagUtils.isUserTag(template)) {
// Ignore undefined variable diagnostic for user tag
// Ignore undefined object diagnostic for user tag
return null;
}

// ex : {item} --> undefined variable
// ex : {item} --> undefined object
DiagnosticSeverity severity = validationSettings.getUndefinedObject().getDiagnosticSeverity();
if (severity == null) {
return null;
Expand All @@ -552,7 +552,7 @@ private ResolvedJavaTypeInfo validateObjectPart(String namespace, ObjectPart obj
Diagnostic diagnostic = createDiagnostic(range, severity, QuteErrorCode.UndefinedObject,
objectPart.getPartName());
// Create data information helpful for code action
diagnostic.setData(DiagnosticDataFactory.createUndefinedVariableData(objectPart.getPartName(),
diagnostic.setData(DiagnosticDataFactory.createUndefinedObjectData(objectPart.getPartName(),
ownerSection != null && ownerSection.isIterable()));
diagnostics.add(diagnostic);
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ private CompletableFuture<CompletionList> doCompleteExpressionForObjectPart(Comp
CompletionItem item = new CompletionItem();
item.setLabel(name);
item.setKind(CompletionItemKind.Keyword);
// Display metadata section (ex : count for #each) after declared variables
// Display metadata section (ex : count for #each) after declared objects
item.setSortText("Za" + name);
TextEdit textEdit = new TextEdit(range, name);
item.setTextEdit(Either.forLeft(textEdit));
Expand Down Expand Up @@ -548,7 +548,7 @@ public void doCompleteNamespaceResolvers(String namespace, Template template, Ra
range, completionSettings, formattingSettings, list);
item.setKind(CompletionItemKind.Function);
// Display namespace resolvers (ex : config:getConfigProperty(...)) after
// declared variables
// declared objects
item.setSortText("Zc" + item.getLabel());
break;
}
Expand All @@ -558,7 +558,7 @@ public void doCompleteNamespaceResolvers(String namespace, Template template, Ra
list);
item.setKind(CompletionItemKind.Field);
// Display namespace resolvers (ex : inject:bean) after
// declared variables
// declared objects
item.setSortText("Zb" + item.getLabel());
break;
}
Expand Down Expand Up @@ -597,7 +597,7 @@ private void doCompleteExpressionForObjectPartWithParentNodes(Node part, Node no
CompletionItem item = new CompletionItem();
item.setLabel(name);
item.setKind(CompletionItemKind.Keyword);
// Display metadata section (ex : count for #each) after declared variables
// Display metadata section (ex : count for #each) after declared objects
item.setSortText("Za" + name);
TextEdit textEdit = new TextEdit(range, name);
item.setTextEdit(Either.forLeft(textEdit));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*/
public class DiagnosticDataFactory {

public static JsonObject createUndefinedVariableData(String partName, boolean iterable) {
public static JsonObject createUndefinedObjectData(String partName, boolean iterable) {
JsonObject data = new JsonObject();
data.addProperty(DIAGNOSTIC_DATA_NAME, partName);
data.addProperty(DIAGNOSTIC_DATA_ITERABLE, iterable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void withoutDisableValidationQuickFix() throws Exception {
QuteErrorCode.UndefinedObject, //
"`item` cannot be resolved to an object.", //
DiagnosticSeverity.Warning);
d.setData(DiagnosticDataFactory.createUndefinedVariableData("item", false));
d.setData(DiagnosticDataFactory.createUndefinedObjectData("item", false));

testDiagnosticsFor(template, d);
testCodeActionsFor(template, d, //
Expand All @@ -66,7 +66,7 @@ public void withDisableValidationQuickFix() throws Exception {
QuteErrorCode.UndefinedObject, //
"`item` cannot be resolved to an object.", //
DiagnosticSeverity.Warning);
d.setData(DiagnosticDataFactory.createUndefinedVariableData("item", false));
d.setData(DiagnosticDataFactory.createUndefinedObjectData("item", false));

testDiagnosticsFor(template, d);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,33 @@ public void specialKeys() throws Exception {
c("inject:bean", "inject:bean", r(1, 1, 1, 1)), //
c("inject:plexux", "inject:plexux", r(1, 1, 1, 1)), //
c("config:*(propertyName : String) : Object", "config:propertyName", r(1, 1, 1, 1)),
c("config:property(propertyName : String) : Object", "config:property(propertyName)",
r(1, 1, 1, 1)), //
c("config:property(propertyName : String) : Object", "config:property(propertyName)", r(1, 1, 1, 1)), //
c("it", "it", r(1, 1, 1, 1)), //
c("nested-content", "nested-content", r(1, 1, 1, 1)));

}

@Test
public void itParameterExpressionInUserTag() throws Exception {
// With user tag
String template = "{@org.acme.Item item}\r\n" + //
"{#user | /}";
testCompletionFor(template, //
c("item", "item", r(1, 7, 1, 7)));

template = "{@org.acme.Item item}\r\n" + //
"{#user item.| /}";
testCompletionFor(template, //
c("base : String", "base", r(1, 12, 1, 12)), // comes from BaseItem extended by Item
c("name : String", "name", r(1, 12, 1, 12)), //
c("price : BigInteger", "price", r(1, 12, 1, 12)), //
c("review : Review", "review", r(1, 12, 1, 12)), //
c("review2 : Review", "review2", r(1, 12, 1, 12)), //
c("getReview2() : Review", "getReview2", r(1, 12, 1, 12)));

// With #let
template = "{@org.acme.Item item}\r\n" + //
"{#let item.| }";
testCompletionFor(template, 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@
public class QuteDefinitionInEachSectionTest {

@Test
public void undefinedVariable() throws Exception {
public void undefinedObject() throws Exception {
String template = "{#each ite|ms}\r\n" + //
" {it.name}\r\n" + //
"{/each}";
testDefinitionFor(template);
}

@Test
public void definedVariable() throws Exception {
public void definedObject() throws Exception {
String template = "{@java.util.List<org.acme.Item> items}\r\n" + //
"{#each ite|ms}\r\n" + //
" {it.name}\r\n" + //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@
public class QuteDefinitionInExpressionTest {

@Test
public void definitionInUndefinedVariable() throws Exception {
public void definitionInUndefinedObject() throws Exception {
String template = "{i|tem}";
testDefinitionFor(template);
}

@Test
public void definitionInDefinedVariable() throws Exception {
public void definitionInDefinedObject() throws Exception {
String template = "{@org.acme.Item item}\r\n" + //
"{i|tem}";
testDefinitionFor(template, "test.qute", //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@
public class QuteDefinitionInForSectionTest {

@Test
public void undefinedVariable() throws Exception {
public void undefinedObject() throws Exception {
String template = "{#for item in ite|ms}\r\n" + //
" {it.name}\r\n" + //
"{/for item in}";
testDefinitionFor(template);
}

@Test
public void definedVariable() throws Exception {
public void definedObject() throws Exception {
String template = "{@java.util.List<org.acme.Item> items}\r\n" + //
"{#for item in ite|ms}\r\n" + //
" {item.name}\r\n" + //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@
public class QuteDefinitionInIfSectionTest {

@Test
public void definedVariable() throws Exception {
public void definedObject() throws Exception {
String template = "{#let value=123}\r\n" + //
" {#if val|ue}";
testDefinitionFor(template, "test.qute", //
ll("test.qute", r(1, 7, 1, 12), r(0, 6, 0, 11)));
}

@Test
public void undefinedVariable() throws Exception {
public void undefinedObject() throws Exception {
String template = "{#if val|ue}";
testDefinitionFor(template);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
public class QuteDefinitionInLetSectionTest {

@Test
public void definedVariable() throws Exception {
public void definedObject() throws Exception {
String template = "{#set name=item.name age=10 long=10L negDouble=-10D isActive=true simpleQuote='abcd' doubleQuote=\"efgh\"}\r\n"
+ //
" {true}\r\n" + //
Expand Down
Loading

0 comments on commit 2de6096

Please sign in to comment.