@Override public boolean isCompilable() { SpelNodeImpl left = getLeftOperand(); SpelNodeImpl right = getRightOperand(); return (left.isCompilable() && right.isCompilable() && CodeFlow.isBooleanCompatible(left.exitTypeDescriptor) && CodeFlow.isBooleanCompatible(right.exitTypeDescriptor)); }
@Nullable private SpelNodeImpl eatLogicalAndExpression() { SpelNodeImpl expr = eatRelationalExpression(); while (peekIdentifierToken("and") || peekToken(TokenKind.SYMBOLIC_AND)) { Token t = takeToken(); // consume 'AND' SpelNodeImpl rhExpr = eatRelationalExpression(); checkOperands(t, expr, rhExpr); expr = new OpAnd(t.startPos, t.endPos, expr, rhExpr); } return expr; }
private boolean getBooleanValue(ExpressionState state, SpelNodeImpl operand) { try { Boolean value = operand.getValue(state, Boolean.class); assertValueNotNull(value); return value; } catch (SpelEvaluationException ex) { ex.setPosition(operand.getStartPosition()); throw ex; } }
@Override public TypedValue getValueInternal(ExpressionState state) throws EvaluationException { if (!getBooleanValue(state, getLeftOperand())) { // no need to evaluate right operand return BooleanTypedValue.FALSE; } return BooleanTypedValue.forValue(getBooleanValue(state, getRightOperand())); }
@Test public void positionalInformation() { SpelExpression expr = new SpelExpressionParser().parseRaw("true and true or false"); SpelNode rootAst = expr.getAST(); OpOr operatorOr = (OpOr) rootAst; OpAnd operatorAnd = (OpAnd) operatorOr.getLeftOperand(); SpelNode rightOrOperand = operatorOr.getRightOperand(); // check position for final 'false' assertEquals(17, rightOrOperand.getStartPosition()); assertEquals(22, rightOrOperand.getEndPosition()); // check position for first 'true' assertEquals(0, operatorAnd.getLeftOperand().getStartPosition()); assertEquals(4, operatorAnd.getLeftOperand().getEndPosition()); // check position for second 'true' assertEquals(9, operatorAnd.getRightOperand().getStartPosition()); assertEquals(13, operatorAnd.getRightOperand().getEndPosition()); // check position for OperatorAnd assertEquals(5, operatorAnd.getStartPosition()); assertEquals(8, operatorAnd.getEndPosition()); // check position for OperatorOr assertEquals(14, operatorOr.getStartPosition()); assertEquals(16, operatorOr.getEndPosition()); }
@Override public TypedValue getValueInternal(ExpressionState state) throws EvaluationException { if (!getBooleanValue(state, getLeftOperand())) { // no need to evaluate right operand return BooleanTypedValue.FALSE; } return BooleanTypedValue.forValue(getBooleanValue(state, getRightOperand())); }
@Override public boolean isCompilable() { SpelNodeImpl left = getLeftOperand(); SpelNodeImpl right = getRightOperand(); return (left.isCompilable() && right.isCompilable() && CodeFlow.isBooleanCompatible(left.exitTypeDescriptor) && CodeFlow.isBooleanCompatible(right.exitTypeDescriptor)); }
@Override public TypedValue getValueInternal(ExpressionState state) throws EvaluationException { if (!getBooleanValue(state, getLeftOperand())) { // no need to evaluate right operand return BooleanTypedValue.FALSE; } return BooleanTypedValue.forValue(getBooleanValue(state, getRightOperand())); }
@Nullable private SpelNodeImpl eatLogicalAndExpression() { SpelNodeImpl expr = eatRelationalExpression(); while (peekIdentifierToken("and") || peekToken(TokenKind.SYMBOLIC_AND)) { Token t = takeToken(); // consume 'AND' SpelNodeImpl rhExpr = eatRelationalExpression(); checkOperands(t, expr, rhExpr); expr = new OpAnd(toPos(t), expr, rhExpr); } return expr; }
private boolean getBooleanValue(ExpressionState state, SpelNodeImpl operand) { try { Boolean value = operand.getValue(state, Boolean.class); assertValueNotNull(value); return value; } catch (SpelEvaluationException ex) { ex.setPosition(operand.getStartPosition()); throw ex; } }
@Override public void generateCode(MethodVisitor mv, CodeFlow cf) { // Pseudo: if (!leftOperandValue) { result=false; } else { result=rightOperandValue; } Label elseTarget = new Label(); Label endOfIf = new Label(); cf.enterCompilationScope(); getLeftOperand().generateCode(mv, cf); cf.unboxBooleanIfNecessary(mv); cf.exitCompilationScope(); mv.visitJumpInsn(IFNE, elseTarget); mv.visitLdcInsn(0); // FALSE mv.visitJumpInsn(GOTO,endOfIf); mv.visitLabel(elseTarget); cf.enterCompilationScope(); getRightOperand().generateCode(mv, cf); cf.unboxBooleanIfNecessary(mv); cf.exitCompilationScope(); mv.visitLabel(endOfIf); cf.pushDescriptor(this.exitTypeDescriptor); }
@Nullable private SpelNodeImpl eatLogicalAndExpression() { SpelNodeImpl expr = eatRelationalExpression(); while (peekIdentifierToken("and") || peekToken(TokenKind.SYMBOLIC_AND)) { Token t = takeToken(); // consume 'AND' SpelNodeImpl rhExpr = eatRelationalExpression(); checkOperands(t, expr, rhExpr); expr = new OpAnd(toPos(t), expr, rhExpr); } return expr; }
private boolean getBooleanValue(ExpressionState state, SpelNodeImpl operand) { try { Boolean value = operand.getValue(state, Boolean.class); assertValueNotNull(value); return value; } catch (SpelEvaluationException ex) { ex.setPosition(operand.getStartPosition()); throw ex; } }
@Override public void generateCode(MethodVisitor mv, CodeFlow cf) { // Pseudo: if (!leftOperandValue) { result=false; } else { result=rightOperandValue; } Label elseTarget = new Label(); Label endOfIf = new Label(); cf.enterCompilationScope(); getLeftOperand().generateCode(mv, cf); cf.unboxBooleanIfNecessary(mv); cf.exitCompilationScope(); mv.visitJumpInsn(IFNE, elseTarget); mv.visitLdcInsn(0); // FALSE mv.visitJumpInsn(GOTO,endOfIf); mv.visitLabel(elseTarget); cf.enterCompilationScope(); getRightOperand().generateCode(mv, cf); cf.unboxBooleanIfNecessary(mv); cf.exitCompilationScope(); mv.visitLabel(endOfIf); cf.pushDescriptor(this.exitTypeDescriptor); }
@Override public boolean isCompilable() { SpelNodeImpl left = getLeftOperand(); SpelNodeImpl right = getRightOperand(); return (left.isCompilable() && right.isCompilable() && CodeFlow.isBooleanCompatible(left.exitTypeDescriptor) && CodeFlow.isBooleanCompatible(right.exitTypeDescriptor)); }
@Override public void generateCode(MethodVisitor mv, CodeFlow cf) { // Pseudo: if (!leftOperandValue) { result=false; } else { result=rightOperandValue; } Label elseTarget = new Label(); Label endOfIf = new Label(); cf.enterCompilationScope(); getLeftOperand().generateCode(mv, cf); cf.unboxBooleanIfNecessary(mv); cf.exitCompilationScope(); mv.visitJumpInsn(IFNE, elseTarget); mv.visitLdcInsn(0); // FALSE mv.visitJumpInsn(GOTO,endOfIf); mv.visitLabel(elseTarget); cf.enterCompilationScope(); getRightOperand().generateCode(mv, cf); cf.unboxBooleanIfNecessary(mv); cf.exitCompilationScope(); mv.visitLabel(endOfIf); cf.pushDescriptor(this.exitTypeDescriptor); }