Merged master into issue/SLING-7681
* brought in fixes for SLING-7710, SLING-7549
diff --git a/pom.xml b/pom.xml
index ce2529a..6e9b88c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,7 +37,7 @@
The versioning scheme defined here corresponds to SLING-7406 (<module_version>-<htl_specification_version>). Take care when
releasing to only increase the first part, unless the module provides support for a newer version of the HTL specification.
-->
- <version>1.0.21-1.3.1-SNAPSHOT</version>
+ <version>1.0.21-1.4.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>Apache Sling Scripting HTL Compiler</name>
@@ -85,7 +85,8 @@
io.sightly.compiler; version:Version=1.1,
io.sightly.compiler; version:Version=1.2,
io.sightly.compiler; version:Version=1.3,
- io.sightly.compiler; version:Version=1.3.1
+ io.sightly.compiler; version:Version=1.3.1,
+ io.sightly.compiler; version:Version=1.4.0
</Provide-Capability>
</instructions>
</configuration>
diff --git a/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyLexer.g4 b/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyLexer.g4
index 9dc6ebf..429dfb4 100644
--- a/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyLexer.g4
+++ b/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyLexer.g4
@@ -38,6 +38,8 @@
RBRACKET: ')';
+IN_OP: 'in';
+
AND_OP: '&&';
OR_OP: '||';
@@ -72,16 +74,17 @@
// tokens
-ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|':')*
+ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|':')*
;
-INT : '0'..'9'+
+INT : '-'? '1'..'9'+ '0'..'9'*
+ | '0'
;
FLOAT
- : ('0'..'9')+ '.' ('0'..'9')+ EXPONENT?
-// | '.' ('0'..'9')+ EXPONENT? --> conflicts with a.2 notation
- | ('0'..'9')+ EXPONENT
+ : '-'? '1'..'9'+ '0'..'9'* '.' '0'..'9'+ EXPONENT?
+ | '-'? '0.' '0'..'9'+ EXPONENT?
+ | '-'? '1'..'9'+ '0'..'9'* EXPONENT
;
COMMENT: '<!--/*' .*? '*/-->' -> skip;
@@ -113,7 +116,7 @@
fragment
ESC_SEQ
- : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
+ : '\\' ('b'|'t'|'n'|'f'|'r'|'"'|'\''|'\\')
| UNICODE_ESC
;
diff --git a/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyParser.g4 b/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyParser.g4
index 81d511a..e605fca 100644
--- a/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyParser.g4
+++ b/src/main/antlr4/org/apache/sling/scripting/sightly/impl/parser/expr/generated/SightlyParser.g4
@@ -72,18 +72,21 @@
exprNode returns [ExpressionNode node]
- : condition=binaryOp TERNARY_Q_OP thenBranch=binaryOp TERNARY_BRANCHES_OP elseBranch=binaryOp
+ : condition=orBinaryOp TERNARY_Q_OP thenBranch=orBinaryOp TERNARY_BRANCHES_OP elseBranch=orBinaryOp
{$node = new TernaryOperator($condition.node, $thenBranch.node, $elseBranch.node);}
- | binaryOp {$node = $binaryOp.node;}
+ | orBinaryOp {$node = $orBinaryOp.node;}
;
-binaryOp returns [ExpressionNode node] //is there any priority precedence between AND & OR ?
- : left=comparisonTerm { $node = $left.node; }
- (operator right=comparisonTerm { $node = new BinaryOperation($operator.op, $node, $right.node); })*
+orBinaryOp returns [ExpressionNode node]
+ : left=andBinaryOp { $node = $left.node; } (OR_OP right=andBinaryOp { $node = new BinaryOperation(BinaryOperator.OR, $node, $right.node);})*
;
-
-operator returns [BinaryOperator op]
- : AND_OP { $op = BinaryOperator.AND; } | OR_OP { $op = BinaryOperator.OR; }
+
+andBinaryOp returns [ExpressionNode node]
+ : left=inBinaryOp { $node = $left.node; } (AND_OP right=inBinaryOp{ $node = new BinaryOperation(BinaryOperator.AND, $node, $right.node);})*
+ ;
+
+inBinaryOp returns [ExpressionNode node]
+ : left=comparisonTerm { $node = $left.node; } (IN_OP right=comparisonTerm { $node = new BinaryOperation(BinaryOperator.IN, $node, $right.node); })*
;
comparisonTerm returns [ExpressionNode node]
diff --git a/src/main/java/org/apache/sling/scripting/sightly/compiler/SightlyCompiler.java b/src/main/java/org/apache/sling/scripting/sightly/compiler/SightlyCompiler.java
index 7c14e0e..6aeecde 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/compiler/SightlyCompiler.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/compiler/SightlyCompiler.java
@@ -54,6 +54,7 @@
import org.apache.sling.scripting.sightly.impl.plugin.Plugin;
import org.apache.sling.scripting.sightly.impl.plugin.RepeatPlugin;
import org.apache.sling.scripting.sightly.impl.plugin.ResourcePlugin;
+import org.apache.sling.scripting.sightly.impl.plugin.SetPlugin;
import org.apache.sling.scripting.sightly.impl.plugin.TemplatePlugin;
import org.apache.sling.scripting.sightly.impl.plugin.TestPlugin;
import org.apache.sling.scripting.sightly.impl.plugin.TextPlugin;
@@ -96,6 +97,7 @@
plugins.add(new ResourcePlugin());
plugins.add(new TemplatePlugin());
plugins.add(new TestPlugin());
+ plugins.add(new SetPlugin());
plugins.add(new TextPlugin());
plugins.add(new UnwrapPlugin());
plugins.add(new UsePlugin());
diff --git a/src/main/java/org/apache/sling/scripting/sightly/compiler/commands/Loop.java b/src/main/java/org/apache/sling/scripting/sightly/compiler/commands/Loop.java
index 74dd016..4b3cc8c 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/compiler/commands/Loop.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/compiler/commands/Loop.java
@@ -28,11 +28,21 @@
private String listVariable;
private String itemVariable;
private String indexVariable;
+ private String beginVariable;
+ private String stepVariable;
+ private String endVariable;
public Start(String listVariable, String itemVariable, String indexVariable) {
+ this(listVariable, itemVariable, indexVariable, null, null, null);
+ }
+
+ public Start(String listVariable, String itemVariable, String indexVariable, String beginVariable, String stepVariable, String endVariable) {
this.listVariable = listVariable;
this.itemVariable = itemVariable;
this.indexVariable = indexVariable;
+ this.beginVariable = beginVariable;
+ this.stepVariable = stepVariable;
+ this.endVariable = endVariable;
}
public String getListVariable() {
@@ -47,6 +57,18 @@
return indexVariable;
}
+ public String getBeginVariable() {
+ return beginVariable;
+ }
+
+ public String getStepVariable() {
+ return stepVariable;
+ }
+
+ public String getEndVariable() {
+ return endVariable;
+ }
+
@Override
public void accept(CommandVisitor visitor) {
visitor.visit(this);
@@ -58,6 +80,9 @@
"listVariable='" + listVariable + '\'' +
", itemVariable='" + itemVariable + '\'' +
", indexVariable='" + indexVariable + '\'' +
+ ", beginVariable='" + beginVariable + '\'' +
+ ", stepVariable='" + stepVariable + '\'' +
+ ", endVariable='" + endVariable + '\'' +
'}';
}
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/compiler/commands/package-info.java b/src/main/java/org/apache/sling/scripting/sightly/compiler/commands/package-info.java
index dd2f081..7656a51 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/compiler/commands/package-info.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/compiler/commands/package-info.java
@@ -21,7 +21,7 @@
* The {@code org.apache.sling.scripting.sightly.compiler.commands} package defines the API for
* {@link org.apache.sling.scripting.sightly.compiler.commands.Command} processing.
*/
-@Version("1.0.0")
+@Version("1.1.0")
package org.apache.sling.scripting.sightly.compiler.commands;
import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/BinaryOperator.java b/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/BinaryOperator.java
index d689093..ff6bb9a 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/BinaryOperator.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/BinaryOperator.java
@@ -18,6 +18,8 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.compiler.expression.nodes;
+import java.util.Collection;
+
import org.apache.sling.scripting.sightly.compiler.SightlyCompilerException;
import org.apache.sling.scripting.sightly.compiler.util.ObjectModel;
@@ -182,6 +184,13 @@
% ObjectModel.toNumber(right).intValue());
}
+ },
+
+ IN {
+ @Override
+ public Object eval(Object left, Object right) {
+ return inOp(left, right);
+ }
};
public static boolean eq(Object left, Object right) {
@@ -239,6 +248,21 @@
" and Boolean types.");
}
+ public static boolean inOp(Object left, Object right) {
+ if (left instanceof String && right instanceof String) {
+ String leftString = (String) left;
+ String rightString = (String) right;
+ return rightString.contains(leftString);
+ }
+ Collection rightElements = ObjectModel.toCollection(right);
+ for (Object element : rightElements) {
+ if (element.equals(left)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private static Number adjust(double x) {
if (Math.floor(x) == x) {
return (int) x;
diff --git a/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/NumericConstant.java b/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/NumericConstant.java
index d03056c..cee38a0 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/NumericConstant.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/NumericConstant.java
@@ -80,8 +80,12 @@
}
private Number parseNumber(String s) {
- if (s.contains(".")) {
- return Double.parseDouble(s);
+ if (s.contains(".") || s.contains("e") || s.contains("E")) {
+ double interim = Double.parseDouble(s);
+ if (interim == 0) {
+ return 0.0;
+ }
+ return interim;
}
return Long.parseLong(s);
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/package-info.java b/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/package-info.java
index 69398b9..104dfe7 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/package-info.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/package-info.java
@@ -19,7 +19,7 @@
* The {@code org.apache.sling.scripting.sightly.compiler.expression.nodes} package exposes the various
* {@link org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode} types.
*/
-@Version("1.0.0")
+@Version("1.1.0")
package org.apache.sling.scripting.sightly.compiler.expression.nodes;
import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/scripting/sightly/compiler/util/VariableTracker.java b/src/main/java/org/apache/sling/scripting/sightly/compiler/util/VariableTracker.java
index 54c4189..1157486 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/compiler/util/VariableTracker.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/compiler/util/VariableTracker.java
@@ -50,14 +50,16 @@
* @param data the data associated with the variable
*/
public void pushVariable(String name, T data) {
- name = name.toLowerCase();
- Stack<T> dataStack = variableData.get(name);
- if (dataStack == null) {
- dataStack = new Stack<>();
- variableData.put(name, dataStack);
+ if (name != null) {
+ name = name.toLowerCase();
+ Stack<T> dataStack = variableData.get(name);
+ if (dataStack == null) {
+ dataStack = new Stack<>();
+ variableData.put(name, dataStack);
+ }
+ dataStack.push(data);
+ declarationStack.push(name);
}
- dataStack.push(data);
- declarationStack.push(name);
}
/**
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/TrackingVisitor.java b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/TrackingVisitor.java
index 246a8c9..2f773d9 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/TrackingVisitor.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/visitor/TrackingVisitor.java
@@ -47,6 +47,9 @@
super.visit(loopStart);
tracker.pushVariable(loopStart.getIndexVariable(), assignDefault(loopStart));
tracker.pushVariable(loopStart.getItemVariable(), assignDefault(loopStart));
+ tracker.pushVariable(loopStart.getBeginVariable(), assignDefault(loopStart));
+ tracker.pushVariable(loopStart.getStepVariable(), assignDefault(loopStart));
+ tracker.pushVariable(loopStart.getEndVariable(), assignDefault(loopStart));
}
@Override
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/ExpressionContext.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/ExpressionContext.java
index b9cc06c..531e813 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/ExpressionContext.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/ExpressionContext.java
@@ -30,6 +30,7 @@
PLUGIN_DATA_SLY_ATTRIBUTE,
PLUGIN_DATA_SLY_ELEMENT,
PLUGIN_DATA_SLY_TEST,
+ PLUGIN_DATA_SLY_SET,
PLUGIN_DATA_SLY_LIST,
PLUGIN_DATA_SLY_REPEAT,
PLUGIN_DATA_SLY_INCLUDE,
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AbstractPlugin.java b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AbstractPlugin.java
index cd09ef7..5a204c1 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AbstractPlugin.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AbstractPlugin.java
@@ -37,4 +37,12 @@
public int compareTo(Plugin o) {
return this.priority - o.priority();
}
+
+ public String decodeVariableName(PluginCallInfo pluginCallInfo) {
+ String[] args = pluginCallInfo.getArguments();
+ if (args.length > 0) {
+ return args[0];
+ }
+ return null;
+ }
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AbstractRepeatPlugin.java b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AbstractRepeatPlugin.java
new file mode 100644
index 0000000..801d4e8
--- /dev/null
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/AbstractRepeatPlugin.java
@@ -0,0 +1,71 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.scripting.sightly.impl.plugin;
+
+import java.util.HashMap;
+
+import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperation;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperator;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.Identifier;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.MapLiteral;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.NumericConstant;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.UnaryOperation;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.UnaryOperator;
+
+public abstract class AbstractRepeatPlugin extends AbstractPlugin {
+
+ protected static final String INDEX = "index";
+ protected static final String COUNT = "count";
+ protected static final String FIRST = "first";
+ protected static final String MIDDLE = "middle";
+ protected static final String LAST = "last";
+ protected static final String ODD = "odd";
+ protected static final String EVEN = "even";
+ protected static final String BEGIN = "begin";
+ protected static final String STEP = "step";
+ protected static final String END = "end";
+
+ protected MapLiteral buildStatusObj(String indexVar, String sizeVar) {
+ HashMap<String, ExpressionNode> obj = new HashMap<>();
+ Identifier indexId = new Identifier(indexVar);
+ BinaryOperation firstExpr = new BinaryOperation(BinaryOperator.EQ, indexId, NumericConstant.ZERO);
+ BinaryOperation lastExpr = new BinaryOperation(
+ BinaryOperator.EQ,
+ indexId,
+ new BinaryOperation(BinaryOperator.SUB, new Identifier(sizeVar), NumericConstant.ONE));
+ obj.put(INDEX, indexId);
+ obj.put(COUNT, new BinaryOperation(BinaryOperator.ADD, indexId, NumericConstant.ONE));
+ obj.put(FIRST, firstExpr);
+ obj.put(MIDDLE, new UnaryOperation(
+ UnaryOperator.NOT,
+ new BinaryOperation(BinaryOperator.OR, firstExpr, lastExpr)));
+ obj.put(LAST, lastExpr);
+ obj.put(ODD, parityCheck(indexId, NumericConstant.ZERO));
+ obj.put(EVEN, parityCheck(indexId, NumericConstant.ONE));
+ return new MapLiteral(obj);
+ }
+
+ private ExpressionNode parityCheck(ExpressionNode numericExpression, NumericConstant expected) {
+ return new BinaryOperation(
+ BinaryOperator.EQ,
+ new BinaryOperation(BinaryOperator.REM, numericExpression, NumericConstant.TWO),
+ expected);
+ }
+}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ListPlugin.java b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ListPlugin.java
index 6a62c5a..a613a69 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ListPlugin.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ListPlugin.java
@@ -18,33 +18,24 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.plugin;
-import java.util.HashMap;
+import java.util.Map;
-import org.apache.sling.scripting.sightly.impl.compiler.Syntax;
+import org.apache.sling.scripting.sightly.compiler.commands.Conditional;
+import org.apache.sling.scripting.sightly.compiler.commands.Loop;
+import org.apache.sling.scripting.sightly.compiler.commands.VariableBinding;
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperation;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperator;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.Identifier;
-import org.apache.sling.scripting.sightly.compiler.expression.nodes.MapLiteral;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.NumericConstant;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.UnaryOperation;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.UnaryOperator;
-import org.apache.sling.scripting.sightly.compiler.commands.Conditional;
-import org.apache.sling.scripting.sightly.compiler.commands.Loop;
-import org.apache.sling.scripting.sightly.compiler.commands.VariableBinding;
-import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext;
import org.apache.sling.scripting.sightly.impl.compiler.PushStream;
+import org.apache.sling.scripting.sightly.impl.compiler.Syntax;
+import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext;
-public class ListPlugin extends AbstractPlugin {
-
- private static final String INDEX = "index";
- private static final String COUNT = "count";
- private static final String FIRST = "first";
- private static final String MIDDLE = "middle";
- private static final String LAST = "last";
- private static final String ODD = "odd";
- private static final String EVEN = "even";
+public class ListPlugin extends AbstractRepeatPlugin {
public ListPlugin() {
name = "list";
@@ -57,14 +48,51 @@
private String listVariable = compilerContext.generateVariable("collectionVar");
private String collectionSizeVar = compilerContext.generateVariable("size");
+ private String collectionNotEmpty = compilerContext.generateVariable("notEmpty");
+ private String beginVariable = compilerContext.generateVariable(BEGIN);
+ private String stepVariable = compilerContext.generateVariable(STEP);
+ private String endVariable = compilerContext.generateVariable(END);
+ private String validStartStepEnd = compilerContext.generateVariable("validStartStepEnd");
@Override
public void beforeElement(PushStream stream, String tagName) {
stream.write(new VariableBinding.Start(listVariable, expression.getRoot()));
stream.write(new VariableBinding.Start(collectionSizeVar,
new UnaryOperation(UnaryOperator.LENGTH, new Identifier(listVariable))));
- stream.write(new Conditional.Start(collectionSizeVar, true));
-
+ stream.write(new VariableBinding.Start(collectionNotEmpty, new BinaryOperation(BinaryOperator.GT, new Identifier
+ (collectionSizeVar), NumericConstant.ZERO)));
+ stream.write(new Conditional.Start(collectionNotEmpty, true));
+ Map<String, ExpressionNode> options = expression.getOptions();
+ if (options.containsKey(BEGIN)) {
+ stream.write(new VariableBinding.Start(beginVariable, expression.getOptions().get(BEGIN)));
+ } else {
+ stream.write(new VariableBinding.Start(beginVariable, NumericConstant.ZERO));
+ }
+ if (options.containsKey(STEP)) {
+ stream.write(new VariableBinding.Start(stepVariable, expression.getOptions().get(STEP)));
+ } else {
+ stream.write(new VariableBinding.Start(stepVariable, NumericConstant.ONE));
+ }
+ if (options.containsKey(END)) {
+ stream.write(new VariableBinding.Start(endVariable, expression.getOptions().get(END)));
+ } else {
+ stream.write(new VariableBinding.Start(endVariable, new Identifier(collectionSizeVar)));
+ }
+ stream.write(new VariableBinding.Start(validStartStepEnd,
+ new BinaryOperation(BinaryOperator.AND,
+ new BinaryOperation(BinaryOperator.AND,
+ new BinaryOperation(BinaryOperator.LT, new Identifier(beginVariable), new Identifier(collectionSizeVar)),
+ new BinaryOperation(
+ BinaryOperator.AND,
+ new BinaryOperation(BinaryOperator.GEQ, new Identifier(beginVariable), NumericConstant.ZERO),
+ new BinaryOperation(BinaryOperator.GT, new Identifier(stepVariable), NumericConstant.ZERO)
+ )
+ ),
+ new BinaryOperation(BinaryOperator.GT, new Identifier(endVariable), NumericConstant.ZERO)
+ )
+ )
+ );
+ stream.write(new Conditional.Start(validStartStepEnd, true));
}
@Override
@@ -74,10 +102,39 @@
String indexVariable = compilerContext.generateVariable("index");
stream.write(new Loop.Start(listVariable, itemVariable, indexVariable));
stream.write(new VariableBinding.Start(loopStatusVar, buildStatusObj(indexVariable, collectionSizeVar)));
+ String stepConditionVariable = compilerContext.generateVariable("stepCondition");
+ stream.write(new VariableBinding.Start(stepConditionVariable,
+ new BinaryOperation(
+ BinaryOperator.REM,
+ new BinaryOperation(
+ BinaryOperator.SUB,
+ new Identifier(indexVariable),
+ new Identifier(beginVariable)
+ ),
+ new Identifier(stepVariable))
+ )
+ );
+ String loopTraversalVariable = compilerContext.generateVariable("traversal");
+ stream.write(new VariableBinding.Start(loopTraversalVariable,
+ new BinaryOperation(
+ BinaryOperator.AND,
+ new BinaryOperation(
+ BinaryOperator.AND,
+ new BinaryOperation(BinaryOperator.GEQ, new Identifier(indexVariable), new Identifier(beginVariable)),
+ new BinaryOperation(BinaryOperator.LEQ, new Identifier(indexVariable), new Identifier(endVariable))
+ ),
+ new BinaryOperation(BinaryOperator.EQ, new Identifier(stepConditionVariable), NumericConstant.ZERO)
+ )
+ )
+ );
+ stream.write(new Conditional.Start(loopTraversalVariable, true));
}
@Override
public void afterChildren(PushStream stream) {
+ stream.write(Conditional.END);
+ stream.write(VariableBinding.END);
+ stream.write(VariableBinding.END);
stream.write(VariableBinding.END);
stream.write(Loop.END);
}
@@ -87,6 +144,12 @@
stream.write(Conditional.END);
stream.write(VariableBinding.END);
stream.write(VariableBinding.END);
+ stream.write(VariableBinding.END);
+ stream.write(VariableBinding.END);
+ stream.write(Conditional.END);
+ stream.write(VariableBinding.END);
+ stream.write(VariableBinding.END);
+ stream.write(VariableBinding.END);
}
@@ -97,33 +160,6 @@
}
return Syntax.DEFAULT_LIST_ITEM_VAR_NAME;
}
-
- private MapLiteral buildStatusObj(String indexVar, String sizeVar) {
- HashMap<String, ExpressionNode> obj = new HashMap<>();
- Identifier indexId = new Identifier(indexVar);
- BinaryOperation firstExpr = new BinaryOperation(BinaryOperator.EQ, indexId, NumericConstant.ZERO);
- BinaryOperation lastExpr = new BinaryOperation(
- BinaryOperator.EQ,
- indexId,
- new BinaryOperation(BinaryOperator.SUB, new Identifier(sizeVar), NumericConstant.ONE));
- obj.put(INDEX, indexId);
- obj.put(COUNT, new BinaryOperation(BinaryOperator.ADD, indexId, NumericConstant.ONE));
- obj.put(FIRST, firstExpr);
- obj.put(MIDDLE, new UnaryOperation(
- UnaryOperator.NOT,
- new BinaryOperation(BinaryOperator.OR, firstExpr, lastExpr)));
- obj.put(LAST, lastExpr);
- obj.put(ODD, parityCheck(indexId, NumericConstant.ZERO));
- obj.put(EVEN, parityCheck(indexId, NumericConstant.ONE));
- return new MapLiteral(obj);
- }
-
- private ExpressionNode parityCheck(ExpressionNode numericExpression, NumericConstant expected) {
- return new BinaryOperation(
- BinaryOperator.EQ,
- new BinaryOperation(BinaryOperator.REM, numericExpression, NumericConstant.TWO),
- expected);
- }
};
}
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/RepeatPlugin.java b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/RepeatPlugin.java
index e8ca678..ff8d41d 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/RepeatPlugin.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/RepeatPlugin.java
@@ -18,34 +18,26 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.plugin;
-import java.util.HashMap;
+import java.util.Map;
+import org.apache.sling.scripting.sightly.compiler.commands.Conditional;
+import org.apache.sling.scripting.sightly.compiler.commands.Loop;
import org.apache.sling.scripting.sightly.compiler.commands.OutText;
-import org.apache.sling.scripting.sightly.impl.compiler.Syntax;
+import org.apache.sling.scripting.sightly.compiler.commands.VariableBinding;
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperation;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperator;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.Identifier;
-import org.apache.sling.scripting.sightly.compiler.expression.nodes.MapLiteral;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.NumericConstant;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.UnaryOperation;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.UnaryOperator;
-import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext;
-import org.apache.sling.scripting.sightly.compiler.commands.Conditional;
-import org.apache.sling.scripting.sightly.compiler.commands.Loop;
-import org.apache.sling.scripting.sightly.compiler.commands.VariableBinding;
import org.apache.sling.scripting.sightly.impl.compiler.PushStream;
+import org.apache.sling.scripting.sightly.impl.compiler.Syntax;
+import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext;
-public class RepeatPlugin extends AbstractPlugin {
+public class RepeatPlugin extends AbstractRepeatPlugin {
- private static final String INDEX = "index";
- private static final String COUNT = "count";
- private static final String FIRST = "first";
- private static final String MIDDLE = "middle";
- private static final String LAST = "last";
- private static final String ODD = "odd";
- private static final String EVEN = "even";
private static final OutText NEW_LINE = new OutText("\n");
public RepeatPlugin() {
@@ -59,18 +51,83 @@
private String listVariable = compilerContext.generateVariable("collectionVar");
private String collectionSizeVar = compilerContext.generateVariable("size");
+ private String collectionNotEmpty = compilerContext.generateVariable("notEmpty");
+ private String beginVariable = compilerContext.generateVariable(BEGIN);
+ private String stepVariable = compilerContext.generateVariable(STEP);
+ private String endVariable = compilerContext.generateVariable(END);
+ private String validStartStepEnd = compilerContext.generateVariable("validStartStepEnd");
@Override
public void beforeElement(PushStream stream, String tagName) {
stream.write(new VariableBinding.Start(listVariable, expression.getRoot()));
stream.write(new VariableBinding.Start(collectionSizeVar,
new UnaryOperation(UnaryOperator.LENGTH, new Identifier(listVariable))));
- stream.write(new Conditional.Start(collectionSizeVar, true));
+ stream.write(new VariableBinding.Start(collectionNotEmpty, new BinaryOperation(BinaryOperator.GT, new Identifier
+ (collectionSizeVar), NumericConstant.ZERO)));
+ stream.write(new Conditional.Start(collectionNotEmpty, true));
+ Map<String, ExpressionNode> options = expression.getOptions();
+ if (options.containsKey(BEGIN)) {
+ stream.write(new VariableBinding.Start(beginVariable, expression.getOptions().get(BEGIN)));
+ } else {
+ stream.write(new VariableBinding.Start(beginVariable, NumericConstant.ZERO));
+ }
+ if (options.containsKey(STEP)) {
+ stream.write(new VariableBinding.Start(stepVariable, expression.getOptions().get(STEP)));
+ } else {
+ stream.write(new VariableBinding.Start(stepVariable, NumericConstant.ONE));
+ }
+ if (options.containsKey(END)) {
+ stream.write(new VariableBinding.Start(endVariable, expression.getOptions().get(END)));
+ } else {
+ stream.write(new VariableBinding.Start(endVariable, new Identifier(collectionSizeVar)));
+ }
+ stream.write(new VariableBinding.Start(validStartStepEnd,
+ new BinaryOperation(BinaryOperator.AND,
+ new BinaryOperation(BinaryOperator.AND,
+ new BinaryOperation(BinaryOperator.LT, new Identifier(beginVariable), new Identifier(collectionSizeVar)),
+ new BinaryOperation(
+ BinaryOperator.AND,
+ new BinaryOperation(BinaryOperator.GEQ, new Identifier(beginVariable), NumericConstant.ZERO),
+ new BinaryOperation(BinaryOperator.GT, new Identifier(stepVariable), NumericConstant.ZERO)
+ )
+ ),
+ new BinaryOperation(BinaryOperator.GT, new Identifier(endVariable), NumericConstant.ZERO)
+ )
+ )
+ );
+ stream.write(new Conditional.Start(validStartStepEnd, true));
String itemVariable = decodeItemVariable();
String loopStatusVar = Syntax.itemLoopStatusVariable(itemVariable);
String indexVariable = compilerContext.generateVariable("index");
stream.write(new Loop.Start(listVariable, itemVariable, indexVariable));
stream.write(new VariableBinding.Start(loopStatusVar, buildStatusObj(indexVariable, collectionSizeVar)));
+ String stepConditionVariable = compilerContext.generateVariable("stepCondition");
+ stream.write(new VariableBinding.Start(stepConditionVariable,
+ new BinaryOperation(
+ BinaryOperator.REM,
+ new BinaryOperation(
+ BinaryOperator.SUB,
+ new Identifier(indexVariable),
+ new Identifier(beginVariable)
+ ),
+ new Identifier(stepVariable))
+ )
+ );
+ String loopTraversalVariable = compilerContext.generateVariable("traversal");
+ stream.write(new VariableBinding.Start(loopTraversalVariable,
+ new BinaryOperation(
+ BinaryOperator.AND,
+ new BinaryOperation(
+ BinaryOperator.AND,
+ new BinaryOperation(BinaryOperator.GEQ, new Identifier(indexVariable), new Identifier(
+ beginVariable)),
+ new BinaryOperation(BinaryOperator.LEQ, new Identifier(indexVariable), new Identifier(endVariable))
+ ),
+ new BinaryOperation(BinaryOperator.EQ, new Identifier(stepConditionVariable), NumericConstant.ZERO)
+ )
+ )
+ );
+ stream.write(new Conditional.Start(loopTraversalVariable, true));
}
@@ -81,11 +138,20 @@
@Override
public void afterElement(PushStream stream) {
+ stream.write(Conditional.END);
+ stream.write(VariableBinding.END);
+ stream.write(VariableBinding.END);
stream.write(VariableBinding.END);
stream.write(Loop.END);
stream.write(Conditional.END);
stream.write(VariableBinding.END);
stream.write(VariableBinding.END);
+ stream.write(VariableBinding.END);
+ stream.write(VariableBinding.END);
+ stream.write(Conditional.END);
+ stream.write(VariableBinding.END);
+ stream.write(VariableBinding.END);
+ stream.write(VariableBinding.END);
}
@@ -97,26 +163,6 @@
return Syntax.DEFAULT_LIST_ITEM_VAR_NAME;
}
- private MapLiteral buildStatusObj(String indexVar, String sizeVar) {
- HashMap<String, ExpressionNode> obj = new HashMap<>();
- Identifier indexId = new Identifier(indexVar);
- BinaryOperation firstExpr = new BinaryOperation(BinaryOperator.EQ, indexId, NumericConstant.ZERO);
- BinaryOperation lastExpr = new BinaryOperation(
- BinaryOperator.EQ,
- indexId,
- new BinaryOperation(BinaryOperator.SUB, new Identifier(sizeVar), NumericConstant.ONE));
- obj.put(INDEX, indexId);
- obj.put(COUNT, new BinaryOperation(BinaryOperator.ADD, indexId, NumericConstant.ONE));
- obj.put(FIRST, firstExpr);
- obj.put(MIDDLE, new UnaryOperation(
- UnaryOperator.NOT,
- new BinaryOperation(BinaryOperator.OR, firstExpr, lastExpr)));
- obj.put(LAST, lastExpr);
- obj.put(ODD, parityCheck(indexId, NumericConstant.ZERO));
- obj.put(EVEN, parityCheck(indexId, NumericConstant.ONE));
- return new MapLiteral(obj);
- }
-
private ExpressionNode parityCheck(ExpressionNode numericExpression, NumericConstant expected) {
return new BinaryOperation(
BinaryOperator.EQ,
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/SetPlugin.java b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/SetPlugin.java
new file mode 100644
index 0000000..f4fe975
--- /dev/null
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/SetPlugin.java
@@ -0,0 +1,57 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.scripting.sightly.impl.plugin;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.scripting.sightly.compiler.SightlyCompilerException;
+import org.apache.sling.scripting.sightly.compiler.commands.VariableBinding;
+import org.apache.sling.scripting.sightly.compiler.expression.Expression;
+import org.apache.sling.scripting.sightly.impl.compiler.PushStream;
+import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext;
+
+/**
+ * Implementation for the {@code data-sly-set} plugin
+ */
+public class SetPlugin extends AbstractPlugin {
+
+ public SetPlugin() {
+ name = "set";
+ priority = 1;
+ }
+
+ @Override
+ public PluginInvoke invoke(final Expression expressionNode, final PluginCallInfo callInfo, final CompilerContext compilerContext) {
+
+ final String variableName = decodeVariableName(callInfo);
+ if (StringUtils.isEmpty(variableName)) {
+ throw new SightlyCompilerException("Identifier name was not provided.");
+ }
+
+ return new DefaultPluginInvoke() {
+
+ @Override
+ public void beforeElement(PushStream stream, String tagName) {
+ stream.write(new VariableBinding.Global(variableName, expressionNode.getRoot()));
+ }
+
+
+ };
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TestPlugin.java b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TestPlugin.java
index 66570d4..202bfb4 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TestPlugin.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/TestPlugin.java
@@ -43,7 +43,7 @@
@Override
public void beforeElement(PushStream stream, String tagName) {
- String variableName = decodeVariableName();
+ String variableName = decodeVariableName(callInfo);
globalBinding = variableName != null;
if (variableName == null) {
variableName = compilerContext.generateVariable("testVariable");
@@ -63,15 +63,6 @@
stream.write(VariableBinding.END);
}
}
-
- private String decodeVariableName() {
- String[] args = callInfo.getArguments();
- if (args.length > 0) {
- return args[0];
- }
- return null;
- }
-
};
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/UnwrapPlugin.java b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/UnwrapPlugin.java
index 104ecf7..51e2594 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/UnwrapPlugin.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/UnwrapPlugin.java
@@ -40,17 +40,28 @@
}
@Override
- public PluginInvoke invoke(final Expression expression, PluginCallInfo callInfo, final CompilerContext compilerContext) {
+ public PluginInvoke invoke(final Expression expression, final PluginCallInfo callInfo, final CompilerContext compilerContext) {
+
return new DefaultPluginInvoke() {
- private final String variable = compilerContext.generateVariable("unwrapCondition");
- private final Command unwrapTest = new Conditional.Start(variable, false);
+ private Command unwrapTest;
private boolean isSlyTag = false;
+ private String identifierName = decodeVariableName(callInfo);
+ private boolean globalBinding;
@Override
public void beforeElement(PushStream stream, String tagName) {
+ globalBinding = identifierName != null;
+ if (identifierName == null) {
+ identifierName = compilerContext.generateVariable("unwrapCondition");
+ }
+ if (globalBinding) {
+ stream.write(new VariableBinding.Global(identifierName, expression.getRoot()));
+ } else {
+ stream.write(new VariableBinding.Start(identifierName, testNode()));
+ }
isSlyTag = "sly".equals(tagName.toLowerCase());
- stream.write(new VariableBinding.Start(variable, testNode()));
+ unwrapTest = new Conditional.Start(identifierName, false);
}
@Override
@@ -87,7 +98,9 @@
@Override
public void afterElement(PushStream stream) {
- stream.write(VariableBinding.END);
+ if (!globalBinding) {
+ stream.write(VariableBinding.END);
+ }
}
private ExpressionNode testNode() {
diff --git a/src/test/java/org/apache/sling/scripting/sightly/impl/TestUtils.java b/src/test/java/org/apache/sling/scripting/sightly/impl/TestUtils.java
deleted file mode 100644
index bcc014a..0000000
--- a/src/test/java/org/apache/sling/scripting/sightly/impl/TestUtils.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ******************************************************************************/
-package org.apache.sling.scripting.sightly.impl;
-
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-
-import org.apache.sling.scripting.sightly.compiler.CompilationUnit;
-
-/**
- * Testing static utilities that simplify writing tests for the HTL compiler.
- */
-public class TestUtils {
-
- public static CompilationUnit readScriptFromClasspath(final String scriptResource) {
- InputStream stream = TestUtils.class.getResourceAsStream(scriptResource);
- final Reader reader = new InputStreamReader(stream);
- return new CompilationUnit() {
- @Override
- public String getScriptName() {
- return scriptResource;
- }
-
- @Override
- public Reader getScriptReader() {
- return reader;
- }
- };
- }
-}
diff --git a/src/test/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyCompilerTest.java b/src/test/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyCompilerTest.java
index e861b5f..7d95e1d 100644
--- a/src/test/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyCompilerTest.java
+++ b/src/test/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyCompilerTest.java
@@ -18,13 +18,16 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.compiler;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
import java.util.List;
import org.apache.sling.scripting.sightly.compiler.CompilationResult;
import org.apache.sling.scripting.sightly.compiler.CompilationUnit;
import org.apache.sling.scripting.sightly.compiler.CompilerMessage;
import org.apache.sling.scripting.sightly.compiler.SightlyCompiler;
-import org.apache.sling.scripting.sightly.impl.TestUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
@@ -42,7 +45,7 @@
@Test
public void testEmptyExpression() {
- CompilationResult result = compile("/empty-expression.html");
+ CompilationResult result = compileFile("/empty-expression.html");
assertTrue("Didn't expect any warnings or errors.", result.getErrors().size() == 0 && result.getWarnings().size() == 0);
}
@@ -55,7 +58,7 @@
}
private void testMissingExplicitContext(String script) {
- CompilationResult result = compile(script);
+ CompilationResult result = compileFile(script);
List<CompilerMessage> warnings = result.getWarnings();
assertTrue(script + ": Expected compilation warnings.", warnings.size() == 1);
CompilerMessage warningMessage = warnings.get(0);
@@ -91,7 +94,7 @@
@Test
public void testSensitiveAttributes() {
String script = "/sensitive-attributes.html";
- CompilationResult result = compile(script);
+ CompilationResult result = compileFile(script);
List<CompilerMessage> warnings = result.getWarnings();
assertTrue("Expected compilation warnings.", warnings.size() == 2);
CompilerMessage _1stWarning = warnings.get(0);
@@ -110,15 +113,72 @@
@Test
public void testErrorReporting1() {
String script = "/error-1.html";
- CompilationResult result = compile(script);
+ CompilationResult result = compileFile(script);
List<CompilerMessage> errors = result.getErrors();
assertTrue("Expected compilation errors.", errors.size() == 1);
CompilerMessage error = errors.get(0);
assertEquals("Error is not reported at the expected line.", 18, error.getLine());
}
- private CompilationResult compile(String file) {
- CompilationUnit compilationUnit = TestUtils.readScriptFromClasspath(file);
+ @Test
+ public void testNumberParsing() {
+ // integers
+ int integerTestRange = 20;
+ for (int i = -1 * integerTestRange; i < integerTestRange; i++) {
+ assertEquals(0, compileSource("${" + i + "}").getErrors().size());
+ }
+
+ // doubles
+ double doubleTestRange = 20.00;
+ for (double i = -1.00 * doubleTestRange; i < doubleTestRange; i+= 0.1) {
+ assertEquals(0, compileSource("${" + i + "}").getErrors().size());
+ }
+
+ assertEquals(0, compileSource("${-0.0}").getErrors().size());
+ assertEquals(0, compileSource("${-0.000}").getErrors().size());
+ assertEquals(1, compileSource("${-00.0}").getErrors().size());
+ assertEquals(1, compileSource("${00.0}").getErrors().size());
+ assertEquals(1, compileSource("${00}").getErrors().size());
+ assertEquals(1, compileSource("${-0}").getErrors().size());
+ assertEquals(1, compileSource("${01}").getErrors().size());
+ assertEquals(0, compileSource("${0.1e-2}").getErrors().size());
+ assertEquals(0, compileSource("${0.1e+2}").getErrors().size());
+ assertEquals(1, compileSource("${00.1e-2}").getErrors().size());
+ assertEquals(1, compileSource("${0e-2}").getErrors().size());
+ assertEquals(1, compileSource("${01e-2}").getErrors().size());
+ assertEquals(0, compileSource("${1e-2}").getErrors().size());
+ assertEquals(0, compileSource("${1e+2}").getErrors().size());
+ }
+
+ private CompilationResult compileFile(final String file) {
+ InputStream stream = this.getClass().getResourceAsStream(file);
+ final Reader reader = new InputStreamReader(stream);
+ CompilationUnit compilationUnit = new CompilationUnit() {
+ @Override
+ public String getScriptName() {
+ return file;
+ }
+
+ @Override
+ public Reader getScriptReader() {
+ return reader;
+ }
+ };
+ return compiler.compile(compilationUnit);
+ }
+
+ private CompilationResult compileSource(final String source) {
+ CompilationUnit compilationUnit = new CompilationUnit() {
+ @Override
+ public String getScriptName() {
+ return "NO_NAME";
+ }
+
+ @Override
+ public Reader getScriptReader() {
+ return new StringReader(source);
+ }
+ };
return compiler.compile(compilationUnit);
}