public static InNode newInNode(ParserRuleContext ctx, BaseNode value, BaseNode list) { return new InNode( ctx, value, list ); }
@Override public Boolean evaluate(EvaluationContext ctx) { if (exprs == null) return null; Object value = this.value.evaluate( ctx ); Object expr = this.exprs.evaluate( ctx ); if ( expr != null ) { if ( expr instanceof Iterable ) { // evaluate in the collection for ( Object e : ((Iterable) expr) ) { // have to compare to Boolean.TRUE because in() might return null if ( in( ctx, value, e ) == Boolean.TRUE ) { return true; } } return false; } else { // evaluate single entity return in( ctx, value, expr ); } } ctx.notifyEvt( astEvent(Severity.ERROR, Msg.createMessage(Msg.IS_NULL, "Expression")) ); return null; }
@Test public void testInUnaryTest() { String inputExpression = "x - y in [(10+5)..(a*b))"; BaseNode inNode = parse( inputExpression ); assertThat( inNode, is( instanceOf( InNode.class ) ) ); assertThat( inNode.getResultType(), is( BuiltInType.BOOLEAN ) ); assertThat( inNode.getText(), is( inputExpression ) ); InNode in = (InNode) inNode; assertThat( in.getValue(), is( instanceOf( InfixOpNode.class ) ) ); assertThat( in.getValue().getText(), is( "x - y" ) ); assertThat( in.getExprs(), is( instanceOf( RangeNode.class ) ) ); assertThat( in.getExprs().getText(), is( "[(10+5)..(a*b))" ) ); }
private Boolean in(EvaluationContext ctx, Object value, Object expr) { // need to improve this to work with unary tests if ( expr == null ) { return value == expr; } else if ( expr instanceof UnaryTest ) { return ((UnaryTest) expr).apply( ctx, value ); } else if ( expr instanceof Range ) { try { return ((Range) expr).includes( value ); } catch ( Exception e ) { ctx.notifyEvt( astEvent(Severity.ERROR, Msg.createMessage(Msg.EXPRESSION_IS_RANGE_BUT_VALUE_IS_NOT_COMPARABLE, value.toString(), expr.toString() ), e ) ); return null; } } else if ( value != null ) { return value.equals( expr ); } else { // value == null, expr != null return Boolean.FALSE; } }
@Test public void testInValueList() { // TODO review this test might be wrong as list is not homogeneous String inputExpression = "x / 4 in ( 10+y, true, 80, someVar )"; BaseNode inNode = parse( inputExpression ); assertThat( inNode, is( instanceOf( InNode.class ) ) ); assertThat( inNode.getResultType(), is( BuiltInType.BOOLEAN ) ); assertThat( inNode.getText(), is( inputExpression ) ); InNode in = (InNode) inNode; assertThat( in.getValue(), is( instanceOf( InfixOpNode.class ) ) ); assertThat( in.getValue().getText(), is( "x / 4" ) ); assertThat( in.getExprs(), is( instanceOf( ListNode.class ) ) ); assertThat( in.getExprs().getText(), is( "10+y, true, 80, someVar" ) ); ListNode list = (ListNode) in.getExprs(); assertThat( list.getElements().get( 0 ), is( instanceOf( InfixOpNode.class ) ) ); assertThat( list.getElements().get( 1 ), is( instanceOf( BooleanNode.class ) ) ); assertThat( list.getElements().get( 2 ), is( instanceOf( NumberNode.class ) ) ); assertThat( list.getElements().get( 3 ), is( instanceOf( NameRefNode.class ) ) ); }
assertThat( in.getValue(), is( instanceOf( InfixOpNode.class ) ) ); assertThat( in.getValue().getText(), is( "x ** y" ) ); assertThat( in.getExprs(), is( instanceOf( ListNode.class ) ) ); assertThat( in.getExprs().getText(), is( "<=1000, >t, null, (2000..z[, ]z..2000], [(10+5)..(a*b))" ) ); ListNode list = (ListNode) in.getExprs(); assertThat( list.getElements().get( 0 ), is( instanceOf( UnaryTestNode.class ) ) ); assertThat( list.getElements().get( 0 ).getText(), is( "<=1000" ) );
@Override public DirectCompilerResult visit(InNode n) { DirectCompilerResult value = n.getValue().accept(this); DirectCompilerResult exprs = n.getExprs().accept(this); if (exprs.resultType == BuiltInType.LIST) { return DirectCompilerResult.of( Expressions.exists(exprs.getExpression(), value.getExpression()), BuiltInType.BOOLEAN).withFD(value).withFD(exprs); } else if (exprs.resultType == BuiltInType.RANGE) { return DirectCompilerResult.of( Expressions.includes(exprs.getExpression(), value.getExpression()), BuiltInType.BOOLEAN).withFD(value).withFD(exprs); } else { // this should be turned into a tree rewrite return DirectCompilerResult.of( Expressions.exists(exprs.getExpression(), value.getExpression()), BuiltInType.BOOLEAN).withFD(value).withFD(exprs); } }