Author: cbrisson Date: Sat Oct 8 15:59:05 2016 New Revision: 1763913 URL: http://svn.apache.org/viewvc?rev=1763913&view=rev Log: 1) added missing unary negate math operator
2) bugfix and AST nodes hierarchy cleaning: ASTBinaryOperator <--- ASTMathOperator <--- ASTAddNode, ASTSubstractNode, ... <--- ASTComparisonOperator <--- ASTLTNode, ASTLENode, ... <--- ASTLogicalOperator <--- ASTAndNode, ASTOrNode The ASTBinaryOperator defines the new abstract method getLiteralOperator(), which returns the string representing the operator. It is used when calculating the error message which is displayed whenever something goes wrong (since at runtime tokens are freed to reduce memory usage, arithmetic errors where sometimes throwing NPEs before this reeng) 3) test cases for 1) and 2) Added: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTBinaryOperator.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTLogicalOperator.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTNegateNode.java Modified: velocity/engine/trunk/src/changes/changes.xml velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTAddNode.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTAndNode.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTComparisonNode.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDivNode.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTEQNode.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTExpression.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTGENode.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTGTNode.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTLENode.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTLTNode.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTModNode.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMulNode.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTNotNode.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTOrNode.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTSubtractNode.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/MathUtils.java velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/MethodMap.java velocity/engine/trunk/velocity-engine-core/src/main/parser/Parser.jjt velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/ArithmeticTestCase.java velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/SetTestCase.java Modified: velocity/engine/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/changes/changes.xml?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/src/changes/changes.xml (original) +++ velocity/engine/trunk/src/changes/changes.xml Sat Oct 8 15:59:05 2016 @@ -28,6 +28,10 @@ <release version="2.0" date="In Subversion"> <action type="add" dev="cbrisson"> + Added unary negate math operator + </action> + + <action type="add" dev="cbrisson"> Add a configurable space gobbling feature, to control indentation in the generated code. <br/> Possible values for the 'space.gobbling' configuration key: Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTAddNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTAddNode.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTAddNode.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTAddNode.java Sat Oct 8 15:59:05 2016 @@ -75,6 +75,12 @@ public class ASTAddNode extends ASTMathN return null; } + @Override + public String getLiteralOperator() + { + return "+"; + } + public Number perform(Number left, Number right, InternalContextAdapter context) { return MathUtils.add(left, right); Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTAndNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTAndNode.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTAndNode.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTAndNode.java Sat Oct 8 15:59:05 2016 @@ -21,7 +21,6 @@ package org.apache.velocity.runtime.pars import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; -import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.parser.Parser; /** @@ -32,7 +31,7 @@ import org.apache.velocity.runtime.parse * @author <a href="mailto:ge...@optonline.net">Geir Magnusson Jr.</a> * @version $Id$ */ -public class ASTAndNode extends SimpleNode +public class ASTAndNode extends ASTLogicalOperator { /** * @param id @@ -51,6 +50,12 @@ public class ASTAndNode extends SimpleNo super(p, id); } + @Override + public String getLiteralOperator() + { + return "&&"; + } + /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ @@ -110,17 +115,5 @@ public class ASTAndNode extends SimpleNo return false; } - - /** - * @throws TemplateInitException - * @see org.apache.velocity.runtime.parser.node.Node#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) - */ - public Object init( InternalContextAdapter context, Object data) throws TemplateInitException - { - Object obj = super.init(context, data); - cleanupParserAndTokens(); // drop reference to Parser and all JavaCC Tokens - return obj; - } - } Added: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTBinaryOperator.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTBinaryOperator.java?rev=1763913&view=auto ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTBinaryOperator.java (added) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTBinaryOperator.java Sat Oct 8 15:59:05 2016 @@ -0,0 +1,46 @@ +package org.apache.velocity.runtime.parser.node; + +import org.apache.velocity.context.InternalContextAdapter; +import org.apache.velocity.exception.TemplateInitException; +import org.apache.velocity.runtime.parser.Parser; + +public abstract class ASTBinaryOperator extends SimpleNode +{ + public ASTBinaryOperator(int id) + { + super(id); + } + + public ASTBinaryOperator(Parser p, int id) + { + super(p, id); + } + + /** + * @throws TemplateInitException + * @see org.apache.velocity.runtime.parser.node.Node#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) + */ + public Object init( InternalContextAdapter context, Object data) throws TemplateInitException + { + Object obj = super.init(context, data); + cleanupParserAndTokens(); // drop reference to Parser and all JavaCC Tokens + return obj; + } + + /** + * get the string representing the mathematical operator + * @return operator string + */ + public abstract String getLiteralOperator(); + + @Override + public String literal() + { + StringBuilder builder = new StringBuilder(); + builder.append(jjtGetChild(0).literal()); + builder.append(' '); + builder.append(getLiteralOperator()); + builder.append(' '); + return builder.toString(); + } +} Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTComparisonNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTComparisonNode.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTComparisonNode.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTComparisonNode.java Sat Oct 8 15:59:05 2016 @@ -21,7 +21,6 @@ package org.apache.velocity.runtime.pars import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; -import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.parser.Parser; @@ -35,7 +34,7 @@ import org.apache.velocity.util.StringUt * @author <a href="mailto:p...@antaramusic.de">Peter Romianowski</a> * @author Nathan Bubna */ -public abstract class ASTComparisonNode extends SimpleNode +public abstract class ASTComparisonNode extends ASTBinaryOperator { /** * @param id @@ -123,6 +122,17 @@ public abstract class ASTComparisonNode return null; } + /** + * get the string representing the mathematical operator + * @return operator string + */ + public abstract String getLiteralOperator(); + + /** + * performs the actual comparison + * @param compareResult + * @return comparison result + */ public abstract boolean numberTest(int compareResult); public boolean compareNonNumber(Object left, Object right) @@ -151,17 +161,4 @@ public abstract class ASTComparisonNode { return Boolean.valueOf(evaluate(context)); } - - /** - * @throws TemplateInitException - * @see org.apache.velocity.runtime.parser.node.Node#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) - */ - public Object init( InternalContextAdapter context, Object data) throws TemplateInitException - { - Object obj = super.init(context, data); - cleanupParserAndTokens(); // drop reference to Parser and all JavaCC Tokens - return obj; - } - - } Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDivNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDivNode.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDivNode.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDivNode.java Sat Oct 8 15:59:05 2016 @@ -54,6 +54,12 @@ public class ASTDivNode extends ASTMathN super(p, id); } + @Override + public String getLiteralOperator() + { + return "/"; + } + public Number perform(Number left, Number right, InternalContextAdapter context) { /* Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTEQNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTEQNode.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTEQNode.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTEQNode.java Sat Oct 8 15:59:05 2016 @@ -51,6 +51,12 @@ public class ASTEQNode extends ASTCompar return left == right || DuckType.asNull(left == null ? right : left); } + @Override + public String getLiteralOperator() + { + return "=="; + } + public boolean numberTest(int compareResult) { return compareResult == 0; Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTExpression.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTExpression.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTExpression.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTExpression.java Sat Oct 8 15:59:05 2016 @@ -83,4 +83,10 @@ public class ASTExpression extends Simpl cleanupParserAndTokens(); // drop reference to Parser and all JavaCC Tokens return obj; } + + @Override + public String literal() + { + return jjtGetChild(0).literal(); + } } Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTGENode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTGENode.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTGENode.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTGENode.java Sat Oct 8 15:59:05 2016 @@ -36,6 +36,12 @@ public class ASTGENode extends ASTCompar super(p, id); } + @Override + public String getLiteralOperator() + { + return ">="; + } + public boolean numberTest(int compareResult) { return compareResult >= 0; Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTGTNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTGTNode.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTGTNode.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTGTNode.java Sat Oct 8 15:59:05 2016 @@ -36,6 +36,12 @@ public class ASTGTNode extends ASTCompar super(p, id); } + @Override + public String getLiteralOperator() + { + return ">"; + } + public boolean numberTest(int compareResult) { return compareResult == 1; Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTLENode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTLENode.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTLENode.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTLENode.java Sat Oct 8 15:59:05 2016 @@ -36,6 +36,12 @@ public class ASTLENode extends ASTCompar super(p, id); } + @Override + public String getLiteralOperator() + { + return "<="; + } + public boolean numberTest(int compareResult) { return compareResult <= 0; Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTLTNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTLTNode.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTLTNode.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTLTNode.java Sat Oct 8 15:59:05 2016 @@ -36,6 +36,12 @@ public class ASTLTNode extends ASTCompar super(p, id); } + @Override + public String getLiteralOperator() + { + return "<"; + } + public boolean numberTest(int compareResult) { return compareResult == -1; Added: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTLogicalOperator.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTLogicalOperator.java?rev=1763913&view=auto ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTLogicalOperator.java (added) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTLogicalOperator.java Sat Oct 8 15:59:05 2016 @@ -0,0 +1,29 @@ +package org.apache.velocity.runtime.parser.node; + +import org.apache.velocity.context.InternalContextAdapter; +import org.apache.velocity.exception.TemplateInitException; +import org.apache.velocity.runtime.parser.Parser; + +public abstract class ASTLogicalOperator extends ASTBinaryOperator +{ + public ASTLogicalOperator(int id) + { + super(id); + } + + public ASTLogicalOperator(Parser p, int id) + { + super(p, id); + } + + /** + * @throws TemplateInitException + * @see org.apache.velocity.runtime.parser.node.Node#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) + */ + public Object init( InternalContextAdapter context, Object data) throws TemplateInitException + { + Object obj = super.init(context, data); + cleanupParserAndTokens(); // drop reference to Parser and all JavaCC Tokens + return obj; + } +} Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java Sat Oct 8 15:59:05 2016 @@ -40,7 +40,7 @@ import org.apache.velocity.util.DuckType * @author Nathan Bubna * @version $Id: ASTMathNode.java 517553 2007-03-13 06:09:58Z wglass $ */ -public abstract class ASTMathNode extends SimpleNode +public abstract class ASTMathNode extends ASTBinaryOperator { protected boolean strictMode = false; Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTModNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTModNode.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTModNode.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTModNode.java Sat Oct 8 15:59:05 2016 @@ -88,5 +88,11 @@ public class ASTModNode extends ASTMathN return obj; } + @Override + public String getLiteralOperator() + { + return "%"; + } + } Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMulNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMulNode.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMulNode.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTMulNode.java Sat Oct 8 15:59:05 2016 @@ -70,6 +70,12 @@ public class ASTMulNode extends ASTMathN return obj; } + @Override + public String getLiteralOperator() + { + return "*"; + } + } Added: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTNegateNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTNegateNode.java?rev=1763913&view=auto ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTNegateNode.java (added) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTNegateNode.java Sat Oct 8 15:59:05 2016 @@ -0,0 +1,90 @@ +package org.apache.velocity.runtime.parser.node; + +import org.apache.velocity.context.InternalContextAdapter; +import org.apache.velocity.exception.MathException; +import org.apache.velocity.exception.MethodInvocationException; +import org.apache.velocity.exception.TemplateInitException; +import org.apache.velocity.runtime.RuntimeConstants; +import org.apache.velocity.runtime.parser.Parser; +import org.apache.velocity.util.DuckType; + +public class ASTNegateNode extends SimpleNode +{ + protected boolean strictMode = false; + + public ASTNegateNode(int i) + { + super(i); + } + + public ASTNegateNode(Parser p, int i) + { + super(p, i); + } + + /** + * {@inheritDoc} + */ + public Object init(InternalContextAdapter context, Object data) throws TemplateInitException + { + super.init(context, data); + /* save a literal image now (needed in case of error) */ + strictMode = rsvc.getBoolean(RuntimeConstants.STRICT_MATH, false); + cleanupParserAndTokens(); + return data; + } + + /** + * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) + */ + public Object jjtAccept(ParserVisitor visitor, Object data) + { + return visitor.visit(this, data); + } + + /** + * @see org.apache.velocity.runtime.parser.node.SimpleNode#evaluate(org.apache.velocity.context.InternalContextAdapter) + */ + public boolean evaluate( InternalContextAdapter context) + throws MethodInvocationException + { + return jjtGetChild(0).evaluate(context); + } + + /** + * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) + */ + public Object value( InternalContextAdapter context) + throws MethodInvocationException + { + Object value = jjtGetChild(0).evaluate( context ); + try + { + value = DuckType.asNumber(value); + } + catch (NumberFormatException nfe) {} + if (!(value instanceof Number)) + { + String msg = "Argument of unary negate (" + + jjtGetChild(0).literal() + + ") " + + (value == null ? "has a null value." : "is not a Number."); + if (strictMode) + { + log.error(msg); + throw new MathException(msg); + } + else + { + log.debug(msg); + return null; + } + } + return MathUtils.negate((Number) value); + } + @Override + public String literal() + { + return "-" + jjtGetChild(0).literal(); + } +} Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTNotNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTNotNode.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTNotNode.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTNotNode.java Sat Oct 8 15:59:05 2016 @@ -86,4 +86,10 @@ public class ASTNotNode extends SimpleNo cleanupParserAndTokens(); // drop reference to Parser and all JavaCC Tokens return obj; } + + @Override + public String literal() + { + return "!" + jjtGetChild(0).literal(); + } } Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTOrNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTOrNode.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTOrNode.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTOrNode.java Sat Oct 8 15:59:05 2016 @@ -21,7 +21,6 @@ package org.apache.velocity.runtime.pars import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; -import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.parser.Parser; /** @@ -32,7 +31,7 @@ import org.apache.velocity.runtime.parse * @author <a href="mailto:ge...@optonline.net">Geir Magnusson Jr.</a> * @version $Id$ */ -public class ASTOrNode extends SimpleNode +public class ASTOrNode extends ASTLogicalOperator { /** * @param id @@ -51,6 +50,12 @@ public class ASTOrNode extends SimpleNod super(p, id); } + @Override + public String getLiteralOperator() + { + return "||"; + } + /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ @@ -106,18 +111,6 @@ public class ASTOrNode extends SimpleNod return false; } - - /** - * @throws TemplateInitException - * @see org.apache.velocity.runtime.parser.node.Node#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) - */ - public Object init( InternalContextAdapter context, Object data) throws TemplateInitException - { - Object obj = super.init(context, data); - cleanupParserAndTokens(); // drop reference to Parser and all JavaCC Tokens - return obj; - } - } Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTSubtractNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTSubtractNode.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTSubtractNode.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTSubtractNode.java Sat Oct 8 15:59:05 2016 @@ -53,6 +53,12 @@ public class ASTSubtractNode extends AST super(p, id); } + @Override + public String getLiteralOperator() + { + return "-"; + } + public Number perform(Number left, Number right, InternalContextAdapter context) { return MathUtils.subtract(left, right); Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/MathUtils.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/MathUtils.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/MathUtils.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/MathUtils.java Sat Oct 8 15:59:05 2016 @@ -213,7 +213,7 @@ public abstract class MathUtils { return Long.valueOf(value); } - return BigInteger.valueOf( value); + return BigInteger.valueOf(value); } /** @@ -228,9 +228,9 @@ public abstract class MathUtils { if ( typesBySize.indexOf( op1.getClass()) > typesBySize.indexOf( op2.getClass())) { - return wrapPrimitive( value, op1.getClass()); + return wrapPrimitive(value, op1.getClass()); } - return wrapPrimitive( value, op2.getClass()); + return wrapPrimitive(value, op2.getClass()); } /** @@ -268,6 +268,31 @@ public abstract class MathUtils } /** + * Find the Number-type to be used for a single number + * + * @param op operand + * @return constant indicating type of Number to use in calculations + */ + public static int findCalculationBase(Number op) + { + if (isInteger(op)) + { + if (op instanceof BigInteger) + { + return BASE_BIGINTEGER; + } + return BASE_LONG; + } else if (op instanceof BigDecimal) + { + return BASE_BIGDECIMAL; + } else if (op instanceof Double) + { + return BASE_DOUBLE; + } + return BASE_FLOAT; + } + + /** * Add two numbers and return the correct value / type. * Overflow detection is done for integer values (byte, short, int, long) only! * @param op1 @@ -480,4 +505,35 @@ public abstract class MathUtils return toBigDecimal( op1 ).compareTo( toBigDecimal ( op2 )); } } + + /** + * Negate a number + * @param op n + * @return -n (unary negation of n) + */ + public static Number negate(Number op) + { + int calcBase = findCalculationBase( op); + switch (calcBase) { + case BASE_BIGINTEGER: + return toBigInteger(op).negate(); + case BASE_LONG: + long l = op.longValue(); + /* overflow check */ + if (l == Long.MIN_VALUE) + { + return toBigInteger(l).negate(); + } + return wrapPrimitive(-l, op.getClass()); + case BASE_FLOAT: + float f = op.floatValue(); + return -f; + case BASE_DOUBLE: + double d = op.doubleValue(); + return -d; + // Default is BigDecimal operation + default: + return toBigDecimal(op).negate(); + } + } } Modified: velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/MethodMap.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/MethodMap.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/MethodMap.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/MethodMap.java Sat Oct 8 15:59:05 2016 @@ -19,8 +19,6 @@ package org.apache.velocity.util.introsp * under the License. */ -import org.apache.commons.lang3.Conversion; - import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Iterator; Modified: velocity/engine/trunk/velocity-engine-core/src/main/parser/Parser.jjt URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/parser/Parser.jjt?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/main/parser/Parser.jjt (original) +++ velocity/engine/trunk/velocity-engine-core/src/main/parser/Parser.jjt Sat Oct 8 15:59:05 2016 @@ -2129,6 +2129,7 @@ void UnaryExpression() #void : {} ( <WHITESPACE> | <NEWLINE> )* ( <LOGICAL_NOT> UnaryExpression() #NotNode(1) + | <MINUS> PrimaryExpression() #NegateNode(1) | PrimaryExpression() ) } Modified: velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/ArithmeticTestCase.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/ArithmeticTestCase.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/ArithmeticTestCase.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/ArithmeticTestCase.java Sat Oct 8 15:59:05 2016 @@ -64,8 +64,8 @@ public class ArithmeticTestCase extends private void addHelper (Number n1, Number n2, double expectedResult, Class expectedResultType) { Number result = MathUtils.add( n1, n2); - assertEquals ("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); - assertEquals ("ResultType does not match.", expectedResultType, result.getClass()); + assertEquals("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); + assertEquals("ResultType does not match.", expectedResultType, result.getClass()); } public void testSubtract() @@ -79,15 +79,15 @@ public class ArithmeticTestCase extends // Test overflow subtractHelper (new Integer(Integer.MIN_VALUE), new Short( (short)20), (double)Integer.MIN_VALUE-20, Long.class); - subtractHelper (new Integer (-20), new Long(Long.MAX_VALUE), -20d-(double)Long.MAX_VALUE, BigInteger.class); - subtractHelper (new Integer (Integer.MAX_VALUE), new Long(Long.MIN_VALUE), (double)Long.MAX_VALUE+(double)Integer.MAX_VALUE, BigInteger.class); + subtractHelper(new Integer(-20), new Long(Long.MAX_VALUE), -20d - (double) Long.MAX_VALUE, BigInteger.class); + subtractHelper(new Integer(Integer.MAX_VALUE), new Long(Long.MIN_VALUE), (double) Long.MAX_VALUE + (double) Integer.MAX_VALUE, BigInteger.class); } private void subtractHelper (Number n1, Number n2, double expectedResult, Class expectedResultType) { Number result = MathUtils.subtract( n1, n2); - assertEquals ("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); - assertEquals ("ResultType does not match.", expectedResultType, result.getClass()); + assertEquals("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); + assertEquals("ResultType does not match.", expectedResultType, result.getClass()); } public void testMultiply() @@ -102,15 +102,15 @@ public class ArithmeticTestCase extends // Test overflow multiplyHelper (new Integer(Integer.MAX_VALUE), new Short( (short)10), (double)Integer.MAX_VALUE*10d, Long.class); - multiplyHelper (new Integer(Integer.MAX_VALUE), new Short( (short)-10), (double)Integer.MAX_VALUE*-10d, Long.class); - multiplyHelper (new Integer (20), new Long(Long.MAX_VALUE), 20d*(double)Long.MAX_VALUE, BigInteger.class); + multiplyHelper(new Integer(Integer.MAX_VALUE), new Short((short) -10), (double) Integer.MAX_VALUE * -10d, Long.class); + multiplyHelper(new Integer(20), new Long(Long.MAX_VALUE), 20d * (double) Long.MAX_VALUE, BigInteger.class); } private void multiplyHelper (Number n1, Number n2, double expectedResult, Class expectedResultType) { Number result = MathUtils.multiply( n1, n2); - assertEquals ("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); - assertEquals ("ResultType does not match.", expectedResultType, result.getClass()); + assertEquals("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); + assertEquals("ResultType does not match.", expectedResultType, result.getClass()); } public void testDivide() @@ -120,23 +120,23 @@ public class ArithmeticTestCase extends divideHelper (BigInteger.valueOf(10), new Short( (short)2), 5, BigInteger.class); divideHelper (new Integer(10), new Short( (short)4), 2, Integer.class); divideHelper (new Integer(10), new Float( 2.5f), 4, Float.class); - divideHelper (new Integer(10), new Double( 2.5), 4, Double.class); - divideHelper (new Integer(10), new BigDecimal( 2.5), 4, BigDecimal.class); + divideHelper(new Integer(10), new Double(2.5), 4, Double.class); + divideHelper(new Integer(10), new BigDecimal(2.5), 4, BigDecimal.class); } private void divideHelper (Number n1, Number n2, double expectedResult, Class expectedResultType) { Number result = MathUtils.divide( n1, n2); - assertEquals ("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); - assertEquals ("ResultType does not match.", expectedResultType, result.getClass()); + assertEquals("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); + assertEquals("ResultType does not match.", expectedResultType, result.getClass()); } public void testModulo() { moduloHelper (new Integer(10), new Short( (short)2), 0, Integer.class); moduloHelper (new Byte((byte)10), new Short( (short)3), 1, Short.class); - moduloHelper (BigInteger.valueOf(10), new Short( (short)4), 2, BigInteger.class); - moduloHelper (new Integer(10), new Float( 5.5f), 4.5, Float.class); + moduloHelper(BigInteger.valueOf(10), new Short((short) 4), 2, BigInteger.class); + moduloHelper(new Integer(10), new Float(5.5f), 4.5, Float.class); try { @@ -152,8 +152,8 @@ public class ArithmeticTestCase extends private void moduloHelper (Number n1, Number n2, double expectedResult, Class expectedResultType) { Number result = MathUtils.modulo( n1, n2); - assertEquals ("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); - assertEquals ("ResultType does not match.", expectedResultType, result.getClass()); + assertEquals("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); + assertEquals("ResultType does not match.", expectedResultType, result.getClass()); } public void testCompare() @@ -162,14 +162,32 @@ public class ArithmeticTestCase extends compareHelper (new Integer(10), new Short( (short)11), -1); compareHelper (BigInteger.valueOf(10), new Short( (short)11), -1); compareHelper (new Byte((byte)10), new Short( (short)3), 1); - compareHelper (new Float(10), new Short( (short)11), -1); - compareHelper (new Double(10), new Short( (short)11), -1); + compareHelper(new Float(10), new Short((short) 11), -1); + compareHelper(new Double(10), new Short((short) 11), -1); } private void compareHelper (Number n1, Number n2, int expectedResult) { int result = MathUtils.compare( n1, n2 ); - assertEquals ("The arithmetic operation produced an unexpected result.", expectedResult, result); + assertEquals("The arithmetic operation produced an unexpected result.", expectedResult, result); + } + + public void testNegate() + { + negateHelper(new Byte((byte) 1), -1, Byte.class); + negateHelper(new Short((short) 1), -1, Short.class); + negateHelper(new Integer(1), -1, Integer.class); + negateHelper(new Long(1), -1, Long.class); + negateHelper(BigInteger.valueOf(1), -1, BigInteger.class); + negateHelper(BigDecimal.valueOf(1), -1, BigDecimal.class); + negateHelper(new Long(Long.MIN_VALUE), BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.valueOf(1)).doubleValue(), BigInteger.class); + } + + private void negateHelper(Number n, double expectedResult, Class expectedResultType) + { + Number result = MathUtils.negate(n); + assertEquals ("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); + assertEquals ("ResultType does not match.", expectedResultType, result.getClass()); } /* Modified: velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/SetTestCase.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/SetTestCase.java?rev=1763913&r1=1763912&r2=1763913&view=diff ============================================================================== --- velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/SetTestCase.java (original) +++ velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/SetTestCase.java Sat Oct 8 15:59:05 2016 @@ -121,5 +121,24 @@ public class SetTestCase extends BaseTes } } + public void testInvalidSet() throws Exception + { + /* the purpose of this test is to check that in case of error, the calculation of the + literal representation of the expression, which is displayed in the logs, does not raise a null exception + */ + assertEvalEquals("", "#set($c = $a - $b - $c)"); + assertEvalEquals("", "#set($c = $a + $b + $c)"); + assertEvalEquals("", "#set($c = $a * $b * $c)"); + assertEvalEquals("", "#set($c = $a / $b / $c)"); + assertEvalEquals("", "#set($c = $a % $b % $c)"); + assertEvalEquals("", "#set($c = $a && $b && $c)"); + assertEvalEquals("", "#set($c = $a || $b || $c)"); + assertEvalEquals("", "#set($c = $a + $b + !$c)"); + assertEvalEquals("", "#set($c = $a + $b + (-$c))"); + assertEvalEquals("", "#set($c = $a && ($b < $c))"); + assertEvalEquals("", "#set($c = !$a)"); + assertEvalEquals("", "#set($c = ($a < $b) - ($c < $d))"); + assertEvalEquals("","#set($b = !$a)"); + } }