use of org.apache.commons.jexl2.parser.ASTNumberLiteral in project commons-jexl by apache.
the class Engine method getVariables.
/**
* Fills up the list of variables accessed by a node.
* @param script the owning script
* @param node the node
* @param collector the variable collector
*/
protected void getVariables(final ASTJexlScript script, final JexlNode node, final VarCollector collector) {
if (node instanceof ASTIdentifier) {
final JexlNode parent = node.jjtGetParent();
if (parent instanceof ASTMethodNode || parent instanceof ASTFunctionNode) {
// skip identifiers for methods and functions
collector.collect(null);
return;
}
final ASTIdentifier identifier = (ASTIdentifier) node;
final int symbol = identifier.getSymbol();
// symbols that are captured are considered "global" variables
if (symbol >= 0 && script != null && !script.isCapturedSymbol(symbol)) {
collector.collect(null);
} else {
// start collecting from identifier
collector.collect(identifier);
collector.add(identifier.getName());
}
} else if (node instanceof ASTIdentifierAccess) {
final JexlNode parent = node.jjtGetParent();
if (parent instanceof ASTMethodNode || parent instanceof ASTFunctionNode) {
// skip identifiers for methods and functions
collector.collect(null);
return;
}
// belt and suspender since an identifier should have been seen first
if (collector.isCollecting()) {
collector.add(((ASTIdentifierAccess) node).getName());
}
} else if (node instanceof ASTArrayAccess && collector.mode > 0) {
final int num = node.jjtGetNumChildren();
// collect only if array access is const and follows an identifier
boolean collecting = collector.isCollecting();
for (int i = 0; i < num; ++i) {
final JexlNode child = node.jjtGetChild(i);
if (collecting && child.isConstant()) {
// collect all constants or only string and number literals
final boolean collect = collector.mode > 1 || (child instanceof ASTStringLiteral || child instanceof ASTNumberLiteral);
if (collect) {
final String image = child.toString();
collector.add(image);
}
} else {
collecting = false;
collector.collect(null);
getVariables(script, child, collector);
collector.collect(null);
}
}
} else {
final int num = node.jjtGetNumChildren();
for (int i = 0; i < num; ++i) {
getVariables(script, node.jjtGetChild(i), collector);
}
collector.collect(null);
}
}
use of org.apache.commons.jexl2.parser.ASTNumberLiteral in project commons-jexl by apache.
the class Interpreter method visit.
@Override
protected Object visit(final ASTUnaryMinusNode node, final Object data) {
// use cached value if literal
final Object value = node.jjtGetValue();
if (value != null && !(value instanceof JexlMethod)) {
return value;
}
final JexlNode valNode = node.jjtGetChild(0);
final Object val = valNode.jjtAccept(this, data);
try {
final Object result = operators.tryOverload(node, JexlOperator.NEGATE, val);
if (result != JexlEngine.TRY_FAILED) {
return result;
}
Object number = arithmetic.negate(val);
// cache if number literal and negate is idempotent
if (number instanceof Number && valNode instanceof ASTNumberLiteral) {
number = arithmetic.narrowNumber((Number) number, ((ASTNumberLiteral) valNode).getLiteralClass());
if (arithmetic.isNegateStable()) {
node.jjtSetValue(number);
}
}
return number;
} catch (final ArithmeticException xrt) {
throw new JexlException(valNode, "- error", xrt);
}
}
use of org.apache.commons.jexl2.parser.ASTNumberLiteral in project commons-jexl by apache.
the class Interpreter method visit.
@Override
protected Object visit(final ASTUnaryPlusNode node, final Object data) {
// use cached value if literal
final Object value = node.jjtGetValue();
if (value != null && !(value instanceof JexlMethod)) {
return value;
}
final JexlNode valNode = node.jjtGetChild(0);
final Object val = valNode.jjtAccept(this, data);
try {
final Object result = operators.tryOverload(node, JexlOperator.POSITIVIZE, val);
if (result != JexlEngine.TRY_FAILED) {
return result;
}
final Object number = arithmetic.positivize(val);
if (valNode instanceof ASTNumberLiteral && number instanceof Number && arithmetic.isPositivizeStable()) {
node.jjtSetValue(number);
}
return number;
} catch (final ArithmeticException xrt) {
throw new JexlException(valNode, "- error", xrt);
}
}
use of org.apache.commons.jexl2.parser.ASTNumberLiteral in project commons-jexl by apache.
the class TemplateScript method collectPrintScope.
/**
* Collects the scope surrounding a call to jexl:print(i).
* <p>This allows to later parse the blocks with the known symbols
* in the frame visible to the parser.
* @param node the visited node
* @param minfo the map of printed expression number to node info
*/
private static void collectPrintScope(final JexlNode node, final Map<Integer, JexlNode.Info> minfo) {
final int nc = node.jjtGetNumChildren();
if (node instanceof ASTFunctionNode && nc == 2) {
// 0 must be the prefix jexl:
final ASTIdentifier nameNode = (ASTIdentifier) node.jjtGetChild(0);
if ("print".equals(nameNode.getName()) && "jexl".equals(nameNode.getNamespace())) {
final ASTArguments argNode = (ASTArguments) node.jjtGetChild(1);
if (argNode.jjtGetNumChildren() == 1) {
// seek the epression number
final JexlNode arg0 = argNode.jjtGetChild(0);
if (arg0 instanceof ASTNumberLiteral) {
final int exprNumber = ((ASTNumberLiteral) arg0).getLiteral().intValue();
minfo.put(exprNumber, new JexlNode.Info(nameNode));
return;
}
}
}
}
for (int c = 0; c < nc; ++c) {
collectPrintScope(node.jjtGetChild(c), minfo);
}
}
use of org.apache.commons.jexl2.parser.ASTNumberLiteral in project commons-jexl by apache.
the class TemplateDebugger method getPrintStatement.
/**
* In a template, any statement that is not 'jexl:print(n)' must be prefixed by "$$".
* @param child the node to check
* @return the expression number or -1 if the node is not a jexl:print
*/
private TemplateExpression getPrintStatement(final JexlNode child) {
if (exprs != null && child instanceof ASTFunctionNode) {
final ASTFunctionNode node = (ASTFunctionNode) child;
final ASTIdentifier ns = (ASTIdentifier) node.jjtGetChild(0);
final JexlNode args = node.jjtGetChild(1);
if ("jexl".equals(ns.getNamespace()) && "print".equals(ns.getName()) && args.jjtGetNumChildren() == 1 && args.jjtGetChild(0) instanceof ASTNumberLiteral) {
final ASTNumberLiteral exprn = (ASTNumberLiteral) args.jjtGetChild(0);
final int n = exprn.getLiteral().intValue();
if (n >= 0 && n < exprs.length) {
return exprs[n];
}
}
}
return null;
}
Aggregations