Search in sources :

Example 1 with VariableContext

use of org.finos.legend.pure.m3.compiler.postprocessing.VariableContext in project legend-pure by finos.

the class FunctionDefinitionProcessor method process.

public static void process(FunctionDefinition<?> functionDefinition, ProcessorState state, Matcher matcher, ModelRepository repository) {
    ProcessorSupport processorSupport = state.getProcessorSupport();
    VariableContext variableContext = state.getVariableContext();
    FunctionType functionType = (FunctionType) processorSupport.function_getFunctionType(functionDefinition);
    state.getObserver().startProcessingFunction(functionDefinition, functionType);
    URLPatternLibrary urlPatternLibrary = state.getURLPatternLibrary();
    if (urlPatternLibrary != null) {
        urlPatternLibrary.possiblyRegister(functionDefinition, processorSupport);
    }
    boolean shouldSetTypeInferenceContext = (functionDefinition instanceof ConcreteFunctionDefinition) && (functionDefinition._classifierGenericType() != null) && (functionDefinition._classifierGenericType()._rawTypeCoreInstance() != null) && "ConcreteFunctionDefinition".equals(functionDefinition._classifierGenericType()._rawTypeCoreInstance().getName());
    if (shouldSetTypeInferenceContext) {
        state.newTypeInferenceContext(functionType);
    }
    functionType._parameters().forEach(var -> {
        try {
            variableContext.registerValue(var._name(), var);
        } catch (VariableNameConflictException e) {
            throw new PureCompilationException(functionDefinition.getSourceInformation(), e.getMessage());
        }
        GenericType propertyType = var._genericType();
        // The property type may be null if it's a lambda expression...
        if (propertyType != null) {
            // We resolve because we want to fail fast if a given type is unknown...
            org.finos.legend.pure.m3.navigation.generictype.GenericType.resolveGenericTypeUsingImports(propertyType, repository, processorSupport);
        }
    });
    ListIterable<? extends ValueSpecification> expressions = functionDefinition._expressionSequence().toList();
    if (expressions.isEmpty()) {
        throw new PureCompilationException(functionDefinition.getSourceInformation(), "Function definition must contain at least one expression");
    }
    // The function is going to be processed again after inference
    if (TypeInference.canProcessLambda(functionDefinition, state, processorSupport)) {
        state.getObserver().shiftTab();
        state.getObserver().startProcessingFunctionBody();
        processExpressions(functionDefinition, expressions, matcher, state, processorSupport);
        findReturnTypesForLambda(functionDefinition, functionType, processorSupport);
        FunctionDefinitionValidator.validateFunctionReturnType(functionDefinition, functionType, processorSupport);
        state.getObserver().finishedProcessingFunctionBody();
        state.getObserver().unShiftTab();
        state.addFunctionDefinition(functionDefinition);
    }
    if (shouldSetTypeInferenceContext) {
        state.deleteTypeInferenceContext();
    }
    state.getVariableContext().buildAndRegister("return", functionType._returnType(), functionType._returnMultiplicity(), processorSupport);
    RichIterable<? extends Constraint> constraints = functionDefinition._preConstraints();
    if (constraints.notEmpty()) {
        processConstraints(functionDefinition, constraints.toList(), matcher, state, processorSupport);
    }
    RichIterable<? extends Constraint> postConstraints = functionDefinition._postConstraints();
    if (postConstraints.notEmpty()) {
        processConstraints(functionDefinition, postConstraints.toList(), matcher, state, processorSupport);
    }
    state.getObserver().finishedProcessingFunction(functionType);
}
Also used : ConcreteFunctionDefinition(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.ConcreteFunctionDefinition) GenericType(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.generics.GenericType) ProcessorSupport(org.finos.legend.pure.m3.navigation.ProcessorSupport) URLPatternLibrary(org.finos.legend.pure.m3.serialization.runtime.pattern.URLPatternLibrary) FunctionType(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.FunctionType) VariableContext(org.finos.legend.pure.m3.compiler.postprocessing.VariableContext) VariableNameConflictException(org.finos.legend.pure.m3.compiler.postprocessing.VariableContext.VariableNameConflictException) PureCompilationException(org.finos.legend.pure.m4.exception.PureCompilationException)

Example 2 with VariableContext

use of org.finos.legend.pure.m3.compiler.postprocessing.VariableContext in project legend-pure by finos.

the class Tag method execute.

@Override
public CoreInstance execute(ListIterable<? extends CoreInstance> params, Stack<MutableMap<String, CoreInstance>> resolvedTypeParameters, Stack<MutableMap<String, CoreInstance>> resolvedMultiplicityParameters, VariableContext variableContext, CoreInstance functionExpressionToUseInStack, Profiler profiler, InstantiationContext instantiationContext, ExecutionSupport executionSupport, Context context, ProcessorSupport processorSupport) throws PureExecutionException {
    String tagName = Instance.getValueForMetaPropertyToOneResolved(params.get(1), M3Properties.values, processorSupport).getName();
    CoreInstance profile = Instance.getValueForMetaPropertyToOneResolved(params.get(0), M3Properties.values, processorSupport);
    CoreInstance tag = Profile.findTag(profile, tagName);
    if (tag == null) {
        throw new PureExecutionException(functionExpressionToUseInStack.getSourceInformation(), "The tag '" + tagName + "' can't be found in the profile '" + profile.getName() + "'");
    }
    return ValueSpecificationBootstrap.wrapValueSpecification(tag, ValueSpecification.isExecutable(params.get(0), processorSupport), processorSupport);
}
Also used : PureExecutionException(org.finos.legend.pure.m3.exception.PureExecutionException) CoreInstance(org.finos.legend.pure.m4.coreinstance.CoreInstance)

Example 3 with VariableContext

use of org.finos.legend.pure.m3.compiler.postprocessing.VariableContext in project legend-pure by finos.

the class ToMultiplicity method execute.

@Override
public CoreInstance execute(ListIterable<? extends CoreInstance> params, Stack<MutableMap<String, CoreInstance>> resolvedTypeParameters, Stack<MutableMap<String, CoreInstance>> resolvedMultiplicityParameters, VariableContext variableContext, CoreInstance functionExpressionToUseInStack, Profiler profiler, InstantiationContext instantiationContext, ExecutionSupport executionSupport, Context context, ProcessorSupport processorSupport) throws PureExecutionException {
    CoreInstance returnMultiplicity = getReturnMultiplicity(processorSupport);
    CoreInstance param = params.get(0);
    if (Multiplicity.multiplicitiesEqual(returnMultiplicity, Instance.getValueForMetaPropertyToOneResolved(param, M3Properties.multiplicity, processorSupport))) {
        return param;
    }
    ListIterable<? extends CoreInstance> values = Instance.getValueForMetaPropertyToManyResolved(param, M3Properties.values, processorSupport);
    if (!Multiplicity.isValid(returnMultiplicity, values.size())) {
        throw new PureExecutionException(functionExpressionToUseInStack.getSourceInformation(), "Cannot cast a collection of size " + values.size() + " to multiplicity " + Multiplicity.print(returnMultiplicity));
    }
    CoreInstance result = this.repository.newAnonymousCoreInstance(param.getSourceInformation(), param.getClassifier());
    Instance.addValueToProperty(result, M3Properties.genericType, Instance.getValueForMetaPropertyToOneResolved(param, M3Properties.genericType, processorSupport), processorSupport);
    Instance.setValuesForProperty(result, M3Properties.values, values, processorSupport);
    Instance.addValueToProperty(result, M3Properties.multiplicity, returnMultiplicity, processorSupport);
    return result;
}
Also used : PureExecutionException(org.finos.legend.pure.m3.exception.PureExecutionException) CoreInstance(org.finos.legend.pure.m4.coreinstance.CoreInstance)

Example 4 with VariableContext

use of org.finos.legend.pure.m3.compiler.postprocessing.VariableContext in project legend-pure by finos.

the class Cast method execute.

@Override
public CoreInstance execute(ListIterable<? extends CoreInstance> params, Stack<MutableMap<String, CoreInstance>> resolvedTypeParameters, Stack<MutableMap<String, CoreInstance>> resolvedMultiplicityParameters, VariableContext variableContext, CoreInstance functionExpressionToUseInStack, Profiler profiler, InstantiationContext instantiationContext, ExecutionSupport executionSupport, Context context, ProcessorSupport processorSupport) throws PureExecutionException {
    CoreInstance valuesParam = params.get(0);
    CoreInstance sourceGenericType = valuesParam.getValueForMetaPropertyToOne(M3Properties.genericType);
    CoreInstance targetGenericType = params.get(1).getValueForMetaPropertyToOne(M3Properties.genericType);
    targetGenericType = makeGenericTypeAsConcreteAsPossible(targetGenericType, resolvedTypeParameters, resolvedMultiplicityParameters, processorSupport);
    CoreInstance inst = this.repository.newAnonymousCoreInstance(functionExpressionToUseInStack.getSourceInformation(), valuesParam.getClassifier());
    Instance.addValueToProperty(inst, M3Properties.genericType, targetGenericType, processorSupport);
    Instance.addValueToProperty(inst, M3Properties.multiplicity, Instance.getValueForMetaPropertyToOneResolved(valuesParam, M3Properties.multiplicity, processorSupport), processorSupport);
    if (GenericTypeMatch.genericTypeMatches(targetGenericType, sourceGenericType, true, ParameterMatchBehavior.MATCH_CAUTIOUSLY, ParameterMatchBehavior.MATCH_CAUTIOUSLY, processorSupport)) {
        CoreInstance sourceRawType = Instance.getValueForMetaPropertyToOneResolved(sourceGenericType, M3Properties.rawType, processorSupport);
        CoreInstance targetRawType = Instance.getValueForMetaPropertyToOneResolved(targetGenericType, M3Properties.rawType, processorSupport);
        // If up-casting unit type to measure type, keep unit type.
        if (sourceRawType instanceof Unit && targetRawType instanceof Measure) {
            Instance.setValueForProperty(inst, M3Properties.genericType, sourceGenericType, processorSupport);
        }
        // Up cast (e.g., List<Integer> to Any) - no further type checking required
        Instance.setValuesForProperty(inst, M3Properties.values, valuesParam.getValueForMetaPropertyToMany(M3Properties.values), processorSupport);
    } else {
        // Down cast (e.g., Number to Integer) - must check types of individual values
        ListIterable<? extends CoreInstance> values = valuesParam.getValueForMetaPropertyToMany(M3Properties.values);
        for (CoreInstance val : values) {
            CoreInstance valGenericType = Instance.extractGenericTypeFromInstance(val, processorSupport);
            if (!GenericTypeMatch.genericTypeMatches(targetGenericType, valGenericType, true, ParameterMatchBehavior.MATCH_ANYTHING, ParameterMatchBehavior.MATCH_ANYTHING, processorSupport)) {
                throw new PureExecutionException(functionExpressionToUseInStack.getSourceInformation(), "Cast exception: " + GenericType.print(valGenericType, processorSupport) + " cannot be cast to " + GenericType.print(targetGenericType, processorSupport));
            }
        }
        Instance.setValuesForProperty(inst, M3Properties.values, valuesParam.getValueForMetaPropertyToMany(M3Properties.values), processorSupport);
    }
    return inst;
}
Also used : PureExecutionException(org.finos.legend.pure.m3.exception.PureExecutionException) CoreInstance(org.finos.legend.pure.m4.coreinstance.CoreInstance) Measure(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Measure) Unit(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Unit)

Example 5 with VariableContext

use of org.finos.legend.pure.m3.compiler.postprocessing.VariableContext in project legend-pure by finos.

the class Copy method execute.

@Override
public CoreInstance execute(ListIterable<? extends CoreInstance> params, Stack<MutableMap<String, CoreInstance>> resolvedTypeParameters, Stack<MutableMap<String, CoreInstance>> resolvedMultiplicityParameters, VariableContext variableContext, final CoreInstance functionExpressionToUseInStack, Profiler profiler, final InstantiationContext instantiationContext, final ExecutionSupport executionSupport, final Context context, final ProcessorSupport processorSupport) throws PureExecutionException {
    final CoreInstance instance = Instance.getValueForMetaPropertyToOneResolved(params.get(0), M3Properties.values, processorSupport);
    CoreInstance classifierGenericType = Instance.extractGenericTypeFromInstance(instance, processorSupport);
    final CoreInstance sourceClassifier = Instance.getValueForMetaPropertyToOneResolved(classifierGenericType, M3Properties.rawType, processorSupport);
    instantiationContext.push(sourceClassifier);
    // TODO should we start a repository transaction here?
    final CoreInstance newInstance = this.repository.newEphemeralAnonymousCoreInstance(null, sourceClassifier);
    ListIterable<? extends CoreInstance> keyValues = (params.size() > 2) ? Instance.getValueForMetaPropertyToManyResolved(params.get(2), M3Properties.values, processorSupport) : Lists.immutable.<CoreInstance>with();
    MutableSet<CoreInstance> addedValues = UnifiedSet.newSet();
    MutableMap<CoreInstance, MutableMap> propertyTree = Maps.mutable.empty();
    // Add the modified properties
    VariableContext evaluationVariableContext = getParentOrEmptyVariableContext(variableContext);
    for (CoreInstance keyValue : keyValues) {
        CoreInstance classifier = sourceClassifier;
        // Find Property and newInstanceCurrent
        ListIterable<? extends CoreInstance> keys = Instance.getValueForMetaPropertyToManyResolved(Instance.getValueForMetaPropertyToOneResolved(keyValue, M3Properties.key, processorSupport), M3Properties.values, processorSupport);
        String finalPropertyName = keys.getLast().getName();
        CoreInstance property = null;
        CoreInstance newInstanceCurrent = newInstance;
        CoreInstance instanceCurrent = instance;
        int size = keys.size() - 1;
        MutableMap<CoreInstance, MutableMap> treeNode = propertyTree;
        for (CoreInstance key : keys) {
            property = processorSupport.class_findPropertyUsingGeneralization(classifier, key.getName());
            if (property == null) {
                throw new PureExecutionException(Instance.getValueForMetaPropertyToOneResolved(keyValue, M3Properties.key, processorSupport).getSourceInformation(), "The property '" + key.getName() + "' can't be found in the type '" + classifier.getName() + "' or in its hierarchy.");
            }
            treeNode = treeNode.getIfAbsentPut(property, Maps.mutable.empty());
            classifier = Instance.getValueForMetaPropertyToOneResolved(property, M3Properties.genericType, M3Properties.rawType, processorSupport);
            if (size > 0) {
                if (Multiplicity.isToOne(Instance.getValueForMetaPropertyToOneResolved(property, M3Properties.multiplicity, processorSupport), false)) {
                    instanceCurrent = Instance.getValueForMetaPropertyToOneResolved(instanceCurrent, property, processorSupport);
                    CoreInstance res = Instance.getValueForMetaPropertyToOneResolved(newInstanceCurrent, property, processorSupport);
                    if (res == null) {
                        res = this.repository.newEphemeralAnonymousCoreInstance(null, classifier);
                        Instance.addValueToProperty(newInstanceCurrent, key.getName(), res, processorSupport);
                    }
                    newInstanceCurrent = res;
                } else {
                    throw new RuntimeException("Not supported yet!");
                }
            }
            size--;
        }
        // Maybe add the existing ones
        CoreInstance addValue = Instance.getValueForMetaPropertyToOneResolved(keyValue, M3Properties.add, processorSupport);
        boolean add = (addValue != null) && PrimitiveUtilities.getBooleanValue(addValue);
        if (add) {
            ListIterable<? extends CoreInstance> existingOnes = Instance.getValueForMetaPropertyToManyResolved(instanceCurrent, property, processorSupport);
            for (CoreInstance existing : existingOnes) {
                Instance.addValueToProperty(newInstanceCurrent, finalPropertyName, existing, processorSupport);
                addedValues.add(existing);
            }
        }
        // Add the requested ones
        CoreInstance propertyGenericType = GenericType.resolvePropertyReturnType(Instance.extractGenericTypeFromInstance(instanceCurrent, processorSupport), property, processorSupport);
        CoreInstance expression = Instance.getValueForMetaPropertyToOneResolved(keyValue, M3Properties.expression, processorSupport);
        Executor executor = FunctionExecutionInterpreted.findValueSpecificationExecutor(expression, functionExpressionToUseInStack, processorSupport, this.functionExecution);
        CoreInstance instanceValResult = executor.execute(expression, resolvedTypeParameters, resolvedMultiplicityParameters, functionExpressionToUseInStack, evaluationVariableContext, profiler, instantiationContext, executionSupport, this.functionExecution, processorSupport);
        ListIterable<? extends CoreInstance> values = Instance.getValueForMetaPropertyToManyResolved(instanceValResult, M3Properties.values, processorSupport);
        New.validateRangeUsingMultiplicity(instance, keyValue, property, values, processorSupport);
        if (values.isEmpty()) {
            if (newInstanceCurrent.isValueDefinedForKey(finalPropertyName)) {
                if (!add) {
                    Instance.removeProperty(newInstanceCurrent, finalPropertyName, processorSupport);
                    Instance.addPropertyWithEmptyList(newInstanceCurrent, finalPropertyName, processorSupport);
                }
            }
        } else {
            New.validateTypeFromGenericType(propertyGenericType, Instance.getValueForMetaPropertyToOneResolved(instanceValResult, M3Properties.genericType, processorSupport), expression, processorSupport);
            for (CoreInstance value : values) {
                Instance.addValueToProperty(newInstanceCurrent, finalPropertyName, value, processorSupport);
                addedValues.add(value);
            }
        }
    }
    this.copy(instance, newInstance, sourceClassifier, addedValues, functionExpressionToUseInStack.getSourceInformation(), processorSupport, instantiationContext, propertyTree);
    if (addedValues.isEmpty()) {
        newInstance.setSourceInformation(instance.getSourceInformation());
    } else {
        newInstance.setSourceInformation(functionExpressionToUseInStack.getSourceInformation());
    }
    CoreInstance value = ValueSpecificationBootstrap.wrapValueSpecification(newInstance, ValueSpecification.isExecutable(params.get(0), processorSupport), processorSupport);
    instantiationContext.popAndExecuteProcedures(value);
    if (instantiationContext.isEmpty()) {
        instantiationContext.runValidations();
        instantiationContext.reset();
    }
    return DefaultConstraintHandler.handleConstraints(sourceClassifier, value, functionExpressionToUseInStack.getSourceInformation(), this.functionExecution, resolvedTypeParameters, resolvedMultiplicityParameters, variableContext, functionExpressionToUseInStack, profiler, instantiationContext, executionSupport);
}
Also used : Executor(org.finos.legend.pure.runtime.java.interpreted.Executor) PureExecutionException(org.finos.legend.pure.m3.exception.PureExecutionException) CoreInstance(org.finos.legend.pure.m4.coreinstance.CoreInstance) MutableMap(org.eclipse.collections.api.map.MutableMap) VariableContext(org.finos.legend.pure.runtime.java.interpreted.VariableContext)

Aggregations

CoreInstance (org.finos.legend.pure.m4.coreinstance.CoreInstance)42 PureExecutionException (org.finos.legend.pure.m3.exception.PureExecutionException)36 VariableContext (org.finos.legend.pure.runtime.java.interpreted.VariableContext)6 MapCoreInstance (org.finos.legend.pure.runtime.java.interpreted.natives.core.collection.map.MapCoreInstance)5 ListIterable (org.eclipse.collections.api.list.ListIterable)4 MutableMap (org.eclipse.collections.api.map.MutableMap)4 SourceInformation (org.finos.legend.pure.m4.coreinstance.SourceInformation)4 BigDecimal (java.math.BigDecimal)3 RichIterable (org.eclipse.collections.api.RichIterable)3 FunctionType (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.FunctionType)3 PureDate (org.finos.legend.pure.m4.coreinstance.primitive.date.PureDate)3 Stack (java.util.Stack)2 FastList (org.eclipse.collections.impl.list.mutable.FastList)2 Property (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.property.Property)2 InstanceValue (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.InstanceValue)2 ValueSpecification (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecification)2 PureAssertFailException (org.finos.legend.pure.m3.exception.PureAssertFailException)2 ProcessorSupport (org.finos.legend.pure.m3.navigation.ProcessorSupport)2 BooleanCoreInstance (org.finos.legend.pure.m4.coreinstance.primitive.BooleanCoreInstance)2 PureCompilationException (org.finos.legend.pure.m4.exception.PureCompilationException)2