diff --git a/rosetta-lang/src/main/java/com/regnosys/rosetta/interpreternew/RosettaInterpreterVisitor.java b/rosetta-lang/src/main/java/com/regnosys/rosetta/interpreternew/RosettaInterpreterVisitor.java index ef5d87a2e..78347cccb 100644 --- a/rosetta-lang/src/main/java/com/regnosys/rosetta/interpreternew/RosettaInterpreterVisitor.java +++ b/rosetta-lang/src/main/java/com/regnosys/rosetta/interpreternew/RosettaInterpreterVisitor.java @@ -106,8 +106,7 @@ public RosettaInterpreterValue interp(RosettaExistsExpression exp) { @Override public RosettaInterpreterValue interp(RosettaAbsentExpression exp) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException(); + return new RosettaInterpreterListOperationsInterpreter().interp(exp); } @Override diff --git a/rosetta-lang/src/main/java/com/regnosys/rosetta/interpreternew/visitors/RosettaInterpreterListOperationsInterpreter.java b/rosetta-lang/src/main/java/com/regnosys/rosetta/interpreternew/visitors/RosettaInterpreterListOperationsInterpreter.java index da2d991ba..74e964816 100644 --- a/rosetta-lang/src/main/java/com/regnosys/rosetta/interpreternew/visitors/RosettaInterpreterListOperationsInterpreter.java +++ b/rosetta-lang/src/main/java/com/regnosys/rosetta/interpreternew/visitors/RosettaInterpreterListOperationsInterpreter.java @@ -10,6 +10,7 @@ import com.regnosys.rosetta.interpreternew.values.RosettaInterpreterErrorValue; import com.regnosys.rosetta.interpreternew.values.RosettaInterpreterStringValue; import com.regnosys.rosetta.rosetta.expression.JoinOperation; +import com.regnosys.rosetta.rosetta.expression.RosettaAbsentExpression; import com.regnosys.rosetta.rosetta.expression.RosettaContainsExpression; import com.regnosys.rosetta.rosetta.expression.RosettaDisjointExpression; import com.regnosys.rosetta.rosetta.expression.RosettaExistsExpression; @@ -169,5 +170,28 @@ public RosettaInterpreterValue interp(RosettaExistsExpression exp) { return new RosettaInterpreterBooleanValue(exists); } + + + /** + * Interprets an "is absent" expression. + * If the argument of the expression is of size 0, so: + * - either it is optional, (0..*), and it was not instantiated + * - or it is a list with 0 elements [] + * + * @param exp "Is absent" expression to intepret + * @return Boolean indicating if the interpreted argument is absent + */ + public RosettaInterpreterValue interp(RosettaAbsentExpression exp) { + RosettaExpression argument = exp.getArgument(); + RosettaInterpreterValue interpretedArgument = argument.accept(visitor); + + if (RosettaInterpreterErrorValue.errorsExist(interpretedArgument)) { + return interpretedArgument; + } + + long count = RosettaInterpreterBaseValue.valueStream(interpretedArgument).count(); + boolean isAbsent = count == 0; + return new RosettaInterpreterBooleanValue(isAbsent); + } } diff --git a/rosetta-testing/src/test/java/com/regnosys/rosetta/interpreternew/visitors/RosettaInterpreterListOperationsInterpreterTest.java b/rosetta-testing/src/test/java/com/regnosys/rosetta/interpreternew/visitors/RosettaInterpreterListOperationsInterpreterTest.java index de13fe65e..3cef03d6e 100644 --- a/rosetta-testing/src/test/java/com/regnosys/rosetta/interpreternew/visitors/RosettaInterpreterListOperationsInterpreterTest.java +++ b/rosetta-testing/src/test/java/com/regnosys/rosetta/interpreternew/visitors/RosettaInterpreterListOperationsInterpreterTest.java @@ -274,4 +274,37 @@ void testExistsError() { RosettaInterpreterErrorValue castedVal = (RosettaInterpreterErrorValue)val; assertEquals(expected, castedVal); } + + @Test + void testIsAbsentTrue() { + RosettaInterpreterBooleanValue expected = new RosettaInterpreterBooleanValue(true); + RosettaExpression expr = parser.parseExpression("[] is absent"); + RosettaInterpreterValue val = interpreter.interp(expr); + assertTrue(val instanceof RosettaInterpreterBooleanValue); + RosettaInterpreterBooleanValue castedVal = (RosettaInterpreterBooleanValue)val; + assertEquals(expected, castedVal); + } + + @Test + void testIsAbsentFalse() { + RosettaInterpreterBooleanValue expected = new RosettaInterpreterBooleanValue(false); + RosettaExpression expr = parser.parseExpression("[True] is absent"); + RosettaInterpreterValue val = interpreter.interp(expr); + assertTrue(val instanceof RosettaInterpreterBooleanValue); + RosettaInterpreterBooleanValue castedVal = (RosettaInterpreterBooleanValue)val; + assertEquals(expected, castedVal); + } + + @Test + void testIsAbsentError() { + RosettaInterpreterErrorValue expected = + new RosettaInterpreterErrorValue( + new RosettaInterpreterError("Logical Operation: " + + "Rightside is not of type Boolean")); + RosettaExpression expr = parser.parseExpression("(True and 1) is absent"); + RosettaInterpreterValue val = interpreter.interp(expr); + assertTrue(val instanceof RosettaInterpreterErrorValue); + RosettaInterpreterErrorValue castedVal = (RosettaInterpreterErrorValue)val; + assertEquals(expected, castedVal); + } }