package com.sap.finex.interpreter.expressions; import java.lang.reflect.InvocationTargetException; import java.util.LinkedList; import java.util.List; import structure.Association; import structure.Field; import structure.FinexClass; import structure.Type; import behavior.actions.Statement; import behavior.expressions.Expression; import behavior.expressions.PathExpression; import behavior.functions.NativeImpl; import behavior.functions.SignatureImplementation; import com.sap.finex.interpreter.FinexInterpreter; import com.sap.finex.interpreter.FinexStackFrame; import com.sap.runlet.abstractinterpreter.Interpreter; import com.sap.runlet.abstractinterpreter.objects.ClassTypedObject; import com.sap.runlet.abstractinterpreter.objects.MultiValuedObject; import com.sap.runlet.abstractinterpreter.objects.RunletObject; import com.sap.tc.moin.repository.mmi.reflect.JmiException; public class PathExpressionInterpreter implements Interpreter<PathExpression, FinexClass, Type, FinexClass, Association, Field, Statement, Expression, SignatureImplementation, FinexStackFrame, NativeImpl, FinexInterpreter> { private PathExpression pe; public PathExpressionInterpreter(PathExpression pe) { this.pe = pe; } @Override public RunletObject<Field, Type, FinexClass> evaluate(FinexInterpreter interpreter) throws JmiException, SecurityException, IllegalArgumentException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { RunletObject<Field, Type, FinexClass> operand = interpreter.evaluate(pe.getOperand()); List<RunletObject<Field, Type, FinexClass>> resultList = new LinkedList<RunletObject<Field, Type, FinexClass>>(); for (RunletObject<Field, Type, FinexClass> o : operand.flatten()) { RunletObject<Field, Type, FinexClass> navigationResult; if (pe.getField().getDetermination() != null) { // determination is computed by evaluating the expression; set this to o FinexStackFrame newFrame = new FinexStackFrame(interpreter.getCallstack().peek()); newFrame.setThis((ClassTypedObject<Field, Type, FinexClass>) o); interpreter.push(newFrame); try { navigationResult = interpreter.evaluate(pe.getField().getDetermination()); } finally { interpreter.pop(); } } else { // independent field is obtained from link container navigationResult = interpreter.navigate( (ClassTypedObject<Field, Type, FinexClass>) o, pe.getField()); } resultList.add(navigationResult); for (RunletObject<Field, Type, FinexClass> singleResultObject : navigationResult) { interpreter.getCallstack().peek().getAliasValues().used(o, pe.getOperand(), singleResultObject, pe); } } // TODO what about orderedness and uniqueness? return FinexInterpreter.turnIntoObjectOfAppropriateMultiplicity(pe.getType(), interpreter, resultList, operand instanceof MultiValuedObject); } }