use of org.mvel2.ast.BinaryOperation in project drools by kiegroup.
the class ConditionAnalyzer method analyzeNode.
private Expression analyzeNode(ASTNode node) {
node = analyzeRegEx(analyzeSubstatement(node));
if (node instanceof LiteralNode) {
LiteralNode literalNode = (LiteralNode) node;
return new FixedExpression(literalNode.getEgressType(), literalNode.getLiteralValue());
}
if (node instanceof BinaryOperation) {
BinaryOperation op = (BinaryOperation) node;
return new AritmeticExpression(analyzeNode(op.getLeft()), AritmeticOperator.fromMvelOpCode(op.getOperation()), analyzeNode(op.getRight()));
}
if (node instanceof TypeCast) {
ExecutableStatement statement = ((TypeCast) node).getStatement();
if (statement instanceof ExecutableAccessor) {
ExecutableAccessor accessor = (ExecutableAccessor) statement;
return new CastExpression(node.getEgressType(), analyzeNode(accessor.getNode()));
} else {
ExecutableLiteral literal = (ExecutableLiteral) statement;
return new CastExpression(node.getEgressType(), new FixedExpression(literal.getLiteral()));
}
}
if (node instanceof Union) {
ASTNode main = ((Union) node).getMain();
Accessor accessor = node.getAccessor();
EvaluatedExpression expression = new EvaluatedExpression();
expression.firstExpression = analyzeNode(main);
if (accessor instanceof DynamicGetAccessor) {
AccessorNode accessorNode = (AccessorNode) ((DynamicGetAccessor) accessor).getSafeAccessor();
expression.addInvocation(analyzeAccessorInvocation(accessorNode, node, null, null));
} else if (accessor instanceof AccessorNode) {
AccessorNode accessorNode = (AccessorNode) accessor;
while (accessorNode != null) {
expression.addInvocation(analyzeAccessorInvocation(accessorNode, node, null, null));
accessorNode = accessorNode.getNextNode();
}
} else {
throw new RuntimeException("Unexpected accessor: " + accessor);
}
return expression;
}
if (node instanceof Sign) {
ExecutableStatement statement = getFieldValue(Sign.class, "stmt", (Sign) node);
if (statement instanceof ExecutableAccessor) {
ExecutableAccessor accessor = (ExecutableAccessor) statement;
return new AritmeticExpression(new FixedExpression(0), AritmeticOperator.SUB, analyzeNode(accessor.getNode()));
} else {
ExecutableLiteral literal = (ExecutableLiteral) statement;
return new AritmeticExpression(new FixedExpression(0), AritmeticOperator.SUB, new FixedExpression(literal.getLiteral()));
}
}
Accessor accessor = node.getAccessor();
if (accessor instanceof IndexedVariableAccessor) {
String variableName = node.getName();
int dot = variableName.indexOf('.');
if (dot > 0) {
variableName = variableName.substring(0, dot);
}
Class<?> variableType = getVariableType(variableName);
return new VariableExpression(variableName, analyzeExpressionNode(((AccessorNode) accessor).getNextNode(), node, variableType), variableType != null ? variableType : node.getEgressType());
}
if (accessor == null && node instanceof NewObjectNode) {
accessor = ((NewObjectNode) node).getNewObjectOptimizer();
}
if (accessor instanceof VariableAccessor) {
VariableAccessor variableAccessor = (VariableAccessor) accessor;
AccessorNode accessorNode = variableAccessor.getNextNode();
if (accessorNode == null || !isStaticAccessor(accessorNode)) {
String variableName = (String) (variableAccessor.getProperty());
Class<?> variableType = getVariableType(variableName);
if (variableType != null) {
return new VariableExpression(variableName, analyzeExpressionNode(accessorNode, node, variableType), variableType);
} else {
if (node.getLiteralValue() instanceof ParserContext) {
ParserContext pCtx = (ParserContext) node.getLiteralValue();
// it's not a variable but a method invocation on this
Class<?> thisClass = pCtx.getInputs().get("this");
try {
return new EvaluatedExpression(new MethodInvocation(thisClass.getMethod(variableName)));
} catch (NoSuchMethodException e) {
if (node.getEgressType() == Class.class) {
// there's no method on this with the given name, check if it is a class literal
Class<?> classLiteral = pCtx.getParserConfiguration().getImport(variableName);
if (classLiteral != null) {
return new FixedExpression(Class.class, classLiteral);
}
}
throw new RuntimeException(e);
}
}
}
}
}
if (accessor == null) {
throw new RuntimeException("Null accessor on node: " + node);
}
return analyzeNodeAccessor(accessor, node);
}
use of org.mvel2.ast.BinaryOperation in project mvel by mikebrock.
the class DebugTools method decompile.
private static String decompile(CompiledExpression cExp, boolean nest, DecompileContext context) {
ASTIterator iter = new ASTLinkedList(cExp.getFirstNode());
ASTNode tk;
StringBuffer sbuf = new StringBuffer();
if (!nest) {
sbuf.append("Expression Decompile\n-------------\n");
}
while (iter.hasMoreNodes()) {
sbuf.append("(").append(context.node++).append(") ");
if ((tk = iter.nextNode()) instanceof NestedStatement && ((NestedStatement) tk).getNestedStatement() instanceof CompiledExpression) {
// noinspection StringConcatenationInsideStringBufferAppend
sbuf.append("NEST [" + tk.getClass().getSimpleName() + "]: { " + tk.getName() + " }\n");
sbuf.append(decompile((CompiledExpression) ((NestedStatement) tk).getNestedStatement(), true, context));
}
if (tk instanceof Substatement && ((Substatement) tk).getStatement() instanceof CompiledExpression) {
// noinspection StringConcatenationInsideStringBufferAppend
sbuf.append("NEST [" + tk.getClass().getSimpleName() + "]: { " + tk.getName() + " }\n");
sbuf.append(decompile((CompiledExpression) ((Substatement) tk).getStatement(), true, context));
} else // }
if (tk.isDebuggingSymbol()) {
// noinspection StringConcatenationInsideStringBufferAppend
sbuf.append("DEBUG_SYMBOL :: " + tk.toString());
} else if (tk.isLiteral()) {
sbuf.append("LITERAL :: ").append(tk.getLiteralValue()).append("'");
} else if (tk.isOperator()) {
sbuf.append("OPERATOR [").append(getOperatorName(tk.getOperator())).append("]: ").append(tk.getName());
if (tk.isOperator(Operator.END_OF_STMT))
sbuf.append("\n");
} else if (tk.isIdentifier()) {
sbuf.append("REFERENCE :: ").append(tk.getClass().getSimpleName()).append(":").append(tk.getName());
} else if (tk instanceof BinaryOperation) {
BinaryOperation bo = (BinaryOperation) tk;
sbuf.append("OPERATION [" + getOperatorName(bo.getOperation()) + "] {").append(bo.getLeft().getName()).append("} {").append(bo.getRight().getName()).append("}");
} else {
// noinspection StringConcatenationInsideStringBufferAppend
sbuf.append("NODE [" + tk.getClass().getSimpleName() + "] :: " + tk.getName());
}
sbuf.append("\n");
}
sbuf.append("==END==");
return sbuf.toString();
}
use of org.mvel2.ast.BinaryOperation in project drools by kiegroup.
the class ConditionAnalyzer method analyzeSingleCondition.
private SingleCondition analyzeSingleCondition(ASTNode node, boolean isNegated) {
SingleCondition condition = new SingleCondition(isNegated);
if (node instanceof BinaryOperation) {
BinaryOperation binaryOperation = (BinaryOperation) node;
condition.left = analyzeNode(binaryOperation.getLeft());
condition.operation = BooleanOperator.fromMvelOpCode(binaryOperation.getOperation());
condition.right = analyzeNode(binaryOperation.getRight());
} else if (node instanceof RegExMatch) {
condition.left = analyzeNode(node);
condition.operation = BooleanOperator.MATCHES;
RegExMatch regExNode = (RegExMatch) node;
Pattern pattern = regExNode.getPattern();
if (pattern != null) {
condition.right = new FixedExpression(String.class, pattern.pattern());
} else {
condition.right = analyzeNode(((ExecutableAccessor) regExNode.getPatternStatement()).getNode());
}
} else if (node instanceof Contains) {
condition.left = analyzeNode(((Contains) node).getFirstStatement());
condition.operation = BooleanOperator.CONTAINS;
condition.right = analyzeNode(((Contains) node).getSecondStatement());
} else if (node instanceof Soundslike) {
condition.left = analyzeNode(((Soundslike) node).getStatement());
condition.operation = BooleanOperator.SOUNDSLIKE;
condition.right = analyzeNode(((Soundslike) node).getSoundslike());
} else if (node instanceof Instance) {
condition.left = analyzeNode(((Instance) node).getStatement());
condition.operation = BooleanOperator.INSTANCEOF;
condition.right = analyzeNode(((Instance) node).getClassStatement());
} else {
condition.left = analyzeNode(node);
}
return condition;
}
use of org.mvel2.ast.BinaryOperation in project mvel by mvel.
the class ExpressionCompiler method verify.
protected ASTNode verify(ParserContext pCtx, ASTNode tk) {
if (tk.isOperator() && (tk.getOperator().equals(Operator.AND) || tk.getOperator().equals(Operator.OR))) {
secondPassOptimization = true;
}
if (tk.isDiscard() || tk.isOperator()) {
return tk;
} else if (tk.isLiteral()) {
/**
* Convert literal values from the default ASTNode to the more-efficient LiteralNode.
*/
if ((fields & COMPILE_IMMEDIATE) != 0 && tk.getClass() == ASTNode.class) {
return new LiteralNode(tk.getLiteralValue(), pCtx);
} else {
return tk;
}
}
if (verifying) {
if (tk.isIdentifier()) {
PropertyVerifier propVerifier = new PropertyVerifier(expr, tk.getStart(), tk.getOffset(), pCtx);
if (tk instanceof Union) {
propVerifier.setCtx(((Union) tk).getLeftEgressType());
tk.setEgressType(returnType = propVerifier.analyze());
} else {
tk.setEgressType(returnType = propVerifier.analyze());
if (propVerifier.isFqcn()) {
tk.setAsFQCNReference();
}
if (propVerifier.isClassLiteral()) {
return new LiteralNode(returnType, pCtx);
}
if (propVerifier.isInput()) {
pCtx.addInput(tk.getAbsoluteName(), propVerifier.isDeepProperty() ? Object.class : returnType);
}
if (!propVerifier.isMethodCall() && !returnType.isEnum() && !pCtx.isOptimizerNotified() && pCtx.isStrongTyping() && !pCtx.isVariableVisible(tk.getAbsoluteName()) && !tk.isFQCN()) {
throw new CompileException("no such identifier: " + tk.getAbsoluteName(), expr, tk.getStart());
}
}
} else if (tk.isAssignment()) {
Assignment a = (Assignment) tk;
if (a.getAssignmentVar() != null) {
// pCtx.makeVisible(a.getAssignmentVar());
PropertyVerifier propVerifier = new PropertyVerifier(a.getAssignmentVar(), pCtx);
tk.setEgressType(returnType = propVerifier.analyze());
if (!a.isNewDeclaration() && propVerifier.isResolvedExternally()) {
pCtx.addInput(tk.getAbsoluteName(), returnType);
}
ExecutableStatement c = (ExecutableStatement) subCompileExpression(expr, tk.getStart(), tk.getOffset(), pCtx);
if (pCtx.isStrictTypeEnforcement()) {
/**
* If we're using strict type enforcement, we need to see if this coercion can be done now,
* or fail epicly.
*/
if (!returnType.isAssignableFrom(c.getKnownEgressType()) && c.isLiteralOnly()) {
if (canConvert(c.getKnownEgressType(), returnType)) {
/**
* We convert the literal to the proper type.
*/
try {
// Don't convert to a literal for DeepOperativeAssignmentNode. Coercion will be done by BinaryOperation
if (!(a instanceof DeepOperativeAssignmentNode)) {
a.setValueStatement(new ExecutableLiteral(convert(c.getValue(null, null), returnType)));
}
return tk;
} catch (Exception e) {
// fall through.
}
} else if (returnType.isPrimitive() && unboxPrimitive(c.getKnownEgressType()).equals(returnType)) {
/**
* We ignore boxed primitive cases, since MVEL does not recognize primitives.
*/
return tk;
}
throw new CompileException("cannot assign type " + c.getKnownEgressType().getName() + " to " + returnType.getName(), expr, st);
}
}
}
} else if (tk instanceof NewObjectNode) {
// this is a bit of a hack for now.
NewObjectNode n = (NewObjectNode) tk;
List<char[]> parms = ParseTools.parseMethodOrConstructor(tk.getNameAsArray());
if (parms != null) {
for (char[] p : parms) {
MVEL.analyze(p, pCtx);
}
}
}
returnType = tk.getEgressType();
}
if (!tk.isLiteral() && tk.getClass() == ASTNode.class && (tk.getFields() & ASTNode.ARRAY_TYPE_LITERAL) == 0) {
if (pCtx.isStrongTyping())
tk.strongTyping();
tk.storePctx();
tk.storeInLiteralRegister(pCtx);
}
return tk;
}
use of org.mvel2.ast.BinaryOperation in project mvel by mvel.
the class BasicVerifier method binaryOperation.
@Override
public BasicValue binaryOperation(final AbstractInsnNode insn, final BasicValue value1, final BasicValue value2) throws AnalyzerException {
BasicValue expected1;
BasicValue expected2;
switch(insn.getOpcode()) {
case IALOAD:
expected1 = newValue(Type.getType("[I"));
expected2 = BasicValue.INT_VALUE;
break;
case BALOAD:
if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
expected1 = newValue(Type.getType("[Z"));
} else {
expected1 = newValue(Type.getType("[B"));
}
expected2 = BasicValue.INT_VALUE;
break;
case CALOAD:
expected1 = newValue(Type.getType("[C"));
expected2 = BasicValue.INT_VALUE;
break;
case SALOAD:
expected1 = newValue(Type.getType("[S"));
expected2 = BasicValue.INT_VALUE;
break;
case LALOAD:
expected1 = newValue(Type.getType("[J"));
expected2 = BasicValue.INT_VALUE;
break;
case FALOAD:
expected1 = newValue(Type.getType("[F"));
expected2 = BasicValue.INT_VALUE;
break;
case DALOAD:
expected1 = newValue(Type.getType("[D"));
expected2 = BasicValue.INT_VALUE;
break;
case AALOAD:
expected1 = newValue(Type.getType("[Ljava/lang/Object;"));
expected2 = BasicValue.INT_VALUE;
break;
case IADD:
case ISUB:
case IMUL:
case IDIV:
case IREM:
case ISHL:
case ISHR:
case IUSHR:
case IAND:
case IOR:
case IXOR:
case IF_ICMPEQ:
case IF_ICMPNE:
case IF_ICMPLT:
case IF_ICMPGE:
case IF_ICMPGT:
case IF_ICMPLE:
expected1 = BasicValue.INT_VALUE;
expected2 = BasicValue.INT_VALUE;
break;
case FADD:
case FSUB:
case FMUL:
case FDIV:
case FREM:
case FCMPL:
case FCMPG:
expected1 = BasicValue.FLOAT_VALUE;
expected2 = BasicValue.FLOAT_VALUE;
break;
case LADD:
case LSUB:
case LMUL:
case LDIV:
case LREM:
case LAND:
case LOR:
case LXOR:
case LCMP:
expected1 = BasicValue.LONG_VALUE;
expected2 = BasicValue.LONG_VALUE;
break;
case LSHL:
case LSHR:
case LUSHR:
expected1 = BasicValue.LONG_VALUE;
expected2 = BasicValue.INT_VALUE;
break;
case DADD:
case DSUB:
case DMUL:
case DDIV:
case DREM:
case DCMPL:
case DCMPG:
expected1 = BasicValue.DOUBLE_VALUE;
expected2 = BasicValue.DOUBLE_VALUE;
break;
case IF_ACMPEQ:
case IF_ACMPNE:
expected1 = BasicValue.REFERENCE_VALUE;
expected2 = BasicValue.REFERENCE_VALUE;
break;
case PUTFIELD:
FieldInsnNode fin = (FieldInsnNode) insn;
expected1 = newValue(Type.getObjectType(fin.owner));
expected2 = newValue(Type.getType(fin.desc));
break;
default:
throw new Error("Internal error.");
}
if (!isSubTypeOf(value1, expected1)) {
throw new AnalyzerException(insn, "First argument", expected1, value1);
} else if (!isSubTypeOf(value2, expected2)) {
throw new AnalyzerException(insn, "Second argument", expected2, value2);
}
if (insn.getOpcode() == AALOAD) {
return getElementValue(value1);
} else {
return super.binaryOperation(insn, value1, value2);
}
}
Aggregations