Search in sources :

Example 1 with NativeFunction

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;
    }
}
Also used : RichIterable(org.eclipse.collections.api.RichIterable) ListIterable(org.eclipse.collections.api.list.ListIterable) MutableMap(org.eclipse.collections.api.map.MutableMap) VariableNameConflictException(org.finos.legend.pure.runtime.java.interpreted.VariableContext.VariableNameConflictException) MutableList(org.eclipse.collections.api.list.MutableList) org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function) PureException(org.finos.legend.pure.m4.exception.PureException) PureExecutionException(org.finos.legend.pure.m3.exception.PureExecutionException) NativeFunction(org.finos.legend.pure.runtime.java.interpreted.natives.core.NativeFunction) CheckedFunction2(org.eclipse.collections.impl.block.function.checked.CheckedFunction2) PureAssertFailException(org.finos.legend.pure.m3.exception.PureAssertFailException) PureAssertFailException(org.finos.legend.pure.m3.exception.PureAssertFailException) VariableNameConflictException(org.finos.legend.pure.runtime.java.interpreted.VariableContext.VariableNameConflictException) PureExecutionException(org.finos.legend.pure.m3.exception.PureExecutionException) IOException(java.io.IOException) PureException(org.finos.legend.pure.m4.exception.PureException) CoreInstance(org.finos.legend.pure.m4.coreinstance.CoreInstance)

Aggregations

IOException (java.io.IOException)1 RichIterable (org.eclipse.collections.api.RichIterable)1 ListIterable (org.eclipse.collections.api.list.ListIterable)1 MutableList (org.eclipse.collections.api.list.MutableList)1 MutableMap (org.eclipse.collections.api.map.MutableMap)1 CheckedFunction2 (org.eclipse.collections.impl.block.function.checked.CheckedFunction2)1 org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function)1 PureAssertFailException (org.finos.legend.pure.m3.exception.PureAssertFailException)1 PureExecutionException (org.finos.legend.pure.m3.exception.PureExecutionException)1 CoreInstance (org.finos.legend.pure.m4.coreinstance.CoreInstance)1 PureException (org.finos.legend.pure.m4.exception.PureException)1 VariableNameConflictException (org.finos.legend.pure.runtime.java.interpreted.VariableContext.VariableNameConflictException)1 NativeFunction (org.finos.legend.pure.runtime.java.interpreted.natives.core.NativeFunction)1