use of org.finos.legend.pure.runtime.java.interpreted.natives.core.NativeFunction in project legend-pure by finos.
the class FunctionExecutionInterpreted method executeFunction.
public CoreInstance executeFunction(boolean limitScope, org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.Function<CoreInstance> function, ListIterable<? extends CoreInstance> params, final Stack<MutableMap<String, CoreInstance>> resolvedTypeParameters, final Stack<MutableMap<String, CoreInstance>> resolvedMultiplicityParameters, final VariableContext varContext, final CoreInstance functionExpressionToUseInStack, final Profiler profiler, final InstantiationContext instantiationContext, final ExecutionSupport executionSupport) {
try {
if (this.cancelExecution.compareAndSet(true, false)) {
throw new PureExecutionException("Cancelled!");
}
final ProcessorSupport processorSupport = this.runtime.getProcessorSupport();
ListIterable<? extends CoreInstance> signatureVars = Instance.getValueForMetaPropertyToManyResolved(processorSupport.function_getFunctionType(function), M3Properties.parameters, processorSupport);
if (signatureVars.size() != params.size()) {
StringBuilder builder = new StringBuilder();
Function.print(builder, function, processorSupport);
String message = "Error executing the function:" + builder + ". Mismatch between the number of function parameters (" + signatureVars.size() + ") and the number of supplied arguments (" + params.size() + ")\n" + params.collect(new org.eclipse.collections.api.block.function.Function<CoreInstance, String>() {
@Override
public String valueOf(CoreInstance coreInstance) {
return coreInstance.printWithoutDebug("", 3);
}
}).makeString("\n");
throw new PureExecutionException(functionExpressionToUseInStack == null ? null : functionExpressionToUseInStack.getSourceInformation(), message);
}
final VariableContext variableContext = this.moveParametersIntoVariableContext(varContext, signatureVars, params, functionExpressionToUseInStack);
if (limitScope) {
variableContext.markVariableScopeBoundary();
}
for (CoreInstance constraint : function._preConstraints()) {
CoreInstance definition = Instance.getValueForMetaPropertyToOneResolved(Instance.getValueForMetaPropertyToOneResolved(constraint, M3Properties.functionDefinition, processorSupport), M3Properties.expressionSequence, processorSupport);
String ruleId = Instance.getValueForMetaPropertyToOneResolved(constraint, M3Properties.name, processorSupport).getName();
CoreInstance evaluatedConstraint = this.executeValueSpecification(definition, new Stack<MutableMap<String, CoreInstance>>(), new Stack<MutableMap<String, CoreInstance>>(), null, variableContext, VoidProfiler.VOID_PROFILER, instantiationContext, executionSupport);
if ("false".equals(evaluatedConstraint.getValueForMetaPropertyToOne(M3Properties.values).getName())) {
throw new PureExecutionException(functionExpressionToUseInStack == null ? null : functionExpressionToUseInStack.getSourceInformation(), "Constraint (PRE):[" + ruleId + "] violated. (Function:" + function.getName() + ")");
}
}
// Execute
CoreInstance result;
if (Instance.instanceOf(function, M3Paths.NativeFunction, processorSupport)) {
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.NativeFunction function1 = NativeFunctionCoreInstanceWrapper.toNativeFunction(function);
NativeFunction nativeFunction = this.nativeFunctions.get(function1.getName());
if (nativeFunction == null) {
throw new PureExecutionException(functionExpressionToUseInStack.getSourceInformation(), "The function '" + function1.getName() + "' is not supported by this execution platform");
}
result = nativeFunction.execute(params, resolvedTypeParameters, resolvedMultiplicityParameters, variableContext, functionExpressionToUseInStack, profiler, instantiationContext, executionSupport, this.runtime.getContext(), this.runtime.getProcessorSupport());
} else if (Instance.instanceOf(function, M3Paths.Property, processorSupport)) {
result = this.executeProperty(PropertyCoreInstanceWrapper.toProperty(function), true, resolvedTypeParameters, resolvedMultiplicityParameters, varContext, profiler, params, functionExpressionToUseInStack, instantiationContext, executionSupport);
} else // Qualified properties also go here
if (Instance.instanceOf(function, M3Paths.FunctionDefinition, processorSupport)) {
RichIterable<? extends CoreInstance> expressions = FunctionDefinitionCoreInstanceWrapper.toFunctionDefinition(function)._expressionSequence();
CoreInstance returnVal = null;
for (CoreInstance expression : expressions) {
Executor executor = findValueSpecificationExecutor(expression, functionExpressionToUseInStack, processorSupport, this);
returnVal = executor.execute(expression, resolvedTypeParameters, resolvedMultiplicityParameters, functionExpressionToUseInStack, variableContext, profiler, instantiationContext, executionSupport, this, processorSupport);
}
result = returnVal;
} else if (Instance.instanceOf(function, M3Paths.Path, processorSupport)) {
final boolean executable = ValueSpecification.isExecutable(params.get(0), processorSupport);
CoreInstance value = params.get(0).getValueForMetaPropertyToOne(M3Properties.values);
MutableList<CoreInstance> res = function.getValueForMetaPropertyToMany(M3Properties.path).injectInto(FastList.newListWith(value), new CheckedFunction2<MutableList<CoreInstance>, CoreInstance, MutableList<CoreInstance>>() {
@Override
public MutableList<CoreInstance> safeValue(MutableList<CoreInstance> instances, final CoreInstance pathElement) throws Exception {
return instances.flatCollect(new CheckedFunction<CoreInstance, Iterable<CoreInstance>>() {
@Override
public Iterable<CoreInstance> safeValueOf(CoreInstance instance) throws Exception {
CoreInstance property = Instance.getValueForMetaPropertyToOneResolved(pathElement, M3Properties.property, processorSupport);
MutableList<CoreInstance> parameters = FastList.newListWith(ValueSpecificationBootstrap.wrapValueSpecification(instance, executable, processorSupport));
parameters.addAllIterable(Instance.getValueForMetaPropertyToManyResolved(pathElement, M3Properties.parameters, processorSupport).collect(new org.eclipse.collections.api.block.function.Function<CoreInstance, CoreInstance>() {
@Override
public CoreInstance valueOf(CoreInstance coreInstance) {
return ValueSpecificationBootstrap.wrapValueSpecification(Instance.getValueForMetaPropertyToManyResolved(coreInstance, M3Properties.values, processorSupport), executable, processorSupport);
}
}));
return (Iterable<CoreInstance>) FunctionExecutionInterpreted.this.executeFunction(false, PropertyCoreInstanceWrapper.toProperty(property), parameters, resolvedTypeParameters, resolvedMultiplicityParameters, variableContext, functionExpressionToUseInStack, profiler, instantiationContext, executionSupport).getValueForMetaPropertyToMany(M3Properties.values);
}
});
}
});
result = ValueSpecificationBootstrap.wrapValueSpecification(res, executable, processorSupport);
} else {
throw new PureExecutionException("Unsupported function for execution");
}
if (function._postConstraints().notEmpty()) {
try {
variableContext.registerValue("return", result);
} catch (VariableNameConflictException e) {
throw new PureExecutionException(functionExpressionToUseInStack.getSourceInformation(), e.getMessage(), e);
}
for (CoreInstance constraint : function._postConstraints()) {
CoreInstance definition = Instance.getValueForMetaPropertyToOneResolved(Instance.getValueForMetaPropertyToOneResolved(constraint, M3Properties.functionDefinition, processorSupport), M3Properties.expressionSequence, processorSupport);
String ruleId = Instance.getValueForMetaPropertyToOneResolved(constraint, M3Properties.name, processorSupport).getName();
CoreInstance evaluatedConstraint = this.executeValueSpecification(definition, new Stack<MutableMap<String, CoreInstance>>(), new Stack<MutableMap<String, CoreInstance>>(), null, variableContext, VoidProfiler.VOID_PROFILER, instantiationContext, executionSupport);
if ("false".equals(evaluatedConstraint.getValueForMetaPropertyToOne(M3Properties.values).getName())) {
throw new PureExecutionException(functionExpressionToUseInStack == null ? null : functionExpressionToUseInStack.getSourceInformation(), "Constraint (POST):[" + ruleId + "] violated. (Function:" + function.getName() + ")");
}
}
}
return result;
} catch (PureAssertFailException e) {
org.finos.legend.pure.m4.coreinstance.SourceInformation sourceInfo = (functionExpressionToUseInStack == null ? null : functionExpressionToUseInStack.getSourceInformation());
if (sourceInfo != null && sourceInfo != e.getSourceInformation()) {
String testPurePlatformFileName = "/platform/pure/corefunctions/test.pure";
boolean allFromAssert = true;
for (org.finos.legend.pure.m4.coreinstance.SourceInformation si : e.getPureStackSourceInformation()) {
allFromAssert = allFromAssert && si != null && testPurePlatformFileName.equals(si.getSourceId());
}
if (allFromAssert && !testPurePlatformFileName.equals(sourceInfo.getSourceId())) {
throw new PureAssertFailException(sourceInfo, e.getInfo());
} else {
throw new PureAssertFailException(sourceInfo, e.getInfo(), e);
}
} else {
throw e;
}
} catch (PureException e) {
if (functionExpressionToUseInStack != null) {
org.finos.legend.pure.m4.coreinstance.SourceInformation sourceInfo = functionExpressionToUseInStack.getSourceInformation();
if (sourceInfo != null && !sourceInfo.equals(e.getSourceInformation())) {
throw new PureExecutionException(sourceInfo, e.getInfo(), e);
}
}
throw e;
} catch (RuntimeException e) {
if (functionExpressionToUseInStack != null) {
org.finos.legend.pure.m4.coreinstance.SourceInformation sourceInfo = functionExpressionToUseInStack.getSourceInformation();
PureException pureException = PureException.findPureException(e);
if (pureException == null) {
if (sourceInfo != null) {
throw new PureExecutionException(sourceInfo, e.getMessage(), e);
}
} else if (sourceInfo != null && sourceInfo != pureException.getSourceInformation()) {
if (pureException instanceof PureAssertFailException) {
throw new PureAssertFailException(sourceInfo, pureException.getInfo(), (PureAssertFailException) pureException);
} else {
throw new PureExecutionException(sourceInfo, pureException.getInfo(), pureException);
}
} else {
throw pureException;
}
}
throw e;
}
}
Aggregations