Search in sources :

Example 1 with SimpleFunctionExpression

use of org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.SimpleFunctionExpression in project legend-pure by finos.

the class FunctionExpressionProcessor method process.

@Override
public void process(FunctionExpression functionExpression, final ProcessorState state, final Matcher matcher, final ModelRepository repository, final Context context, final ProcessorSupport processorSupport) {
    TypeInferenceObserver observer = state.getObserver();
    state.pushTypeInferenceContext();
    ListIterable<? extends ValueSpecification> parametersValues = ListHelper.wrapListIterable(functionExpression._parametersValues());
    // Process the function's parameters (FIRST PASS)
    boolean inferenceSuccess = firstPassTypeInference(functionExpression, parametersValues, state, matcher, repository, context, processorSupport);
    // Function matching
    ListIterable<? extends Function<?>> foundFunctions = null != functionExpression._funcCoreInstance() ? Lists.immutable.with((Function<?>) ImportStub.withImportStubByPass(functionExpression._funcCoreInstance(), processorSupport)) : Lists.immutable.empty();
    String functionName = null;
    if (foundFunctions.isEmpty()) {
        // Check if the function is a property
        InstanceValue propertyNameInstanceVal = functionExpression._propertyName();
        if (null != propertyNameInstanceVal) {
            ValueSpecification source = parametersValues.get(0);
            String propertyName = ImportStub.withImportStubByPass(propertyNameInstanceVal._valuesCoreInstance().toList().get(0), processorSupport).getName();
            GenericType sourceGenericType = extractAndValidateGenericType(processorSupport, propertyName, source);
            // Is it an enum?
            if (org.finos.legend.pure.m3.navigation.generictype.GenericType.subTypeOf(sourceGenericType, org.finos.legend.pure.m3.navigation.type.Type.wrapGenericType(processorSupport.package_getByUserPath(M3Paths.Enumeration), processorSupport), processorSupport)) {
                reprocessEnumValueInExtractEnumValue(functionExpression, propertyName, state, repository, processorSupport);
            } else {
                Multiplicity sourceMultiplicity = source._multiplicity();
                if (org.finos.legend.pure.m3.navigation.multiplicity.Multiplicity.isToOne(sourceMultiplicity, true)) {
                    AbstractProperty<?> propertyFunc = findFunctionForPropertyBasedOnMultiplicity(functionExpression, sourceGenericType, state, processorSupport, matcher);
                    if (null != propertyFunc) {
                        if (MilestoningFunctions.isGeneratedMilestonedQualifiedPropertyWithMissingDates(propertyFunc, processorSupport)) {
                            propertyFunc = (AbstractProperty<?>) MilestoningDatesPropagationFunctions.getMilestoningQualifiedPropertyWithAllDatesSupplied(functionExpression, state, repository, context, processorSupport, propertyNameInstanceVal, source, propertyName, propertyFunc);
                        }
                        foundFunctions = Lists.immutable.with(propertyFunc);
                    }
                } else {
                    // Automap
                    reprocessPropertyForManySources(functionExpression, parametersValues, M3Properties.propertyName, sourceGenericType, repository, processorSupport);
                    // The parameters values are now different, so update
                    parametersValues = functionExpression._parametersValues().toList();
                    // Have another go at type inference
                    inferenceSuccess = firstPassTypeInference(functionExpression, parametersValues, state, matcher, repository, context, processorSupport);
                // return;
                }
            }
        } else // Check if the function is a qualifiedProperty
        {
            InstanceValue qualifiedPropertyNameVal = functionExpression._qualifiedPropertyName();
            if (null != qualifiedPropertyNameVal) {
                ValueSpecification source = parametersValues.get(0);
                String qualifiedPropertyName = ImportStub.withImportStubByPass(qualifiedPropertyNameVal._valuesCoreInstance().toList().get(0), processorSupport).getName();
                GenericType sourceGenericType = extractAndValidateGenericType(processorSupport, qualifiedPropertyName, source);
                Multiplicity sourceMultiplicity = source._multiplicity();
                // }
                if (org.finos.legend.pure.m3.navigation.multiplicity.Multiplicity.isToOne(sourceMultiplicity, true)) {
                    ListIterable<QualifiedProperty<?>> qualifiedPropertyFuncs = findFunctionsForQualifiedPropertyBasedOnMultiplicity(functionExpression, sourceGenericType, parametersValues, processorSupport, matcher, state);
                    if (qualifiedPropertyFuncs.size() == 1 && MilestoningFunctions.isGeneratedMilestonedQualifiedPropertyWithMissingDates(qualifiedPropertyFuncs.getFirst(), processorSupport)) {
                        Function<?> mqp = (Function<?>) MilestoningDatesPropagationFunctions.getMilestoningQualifiedPropertyWithAllDatesSupplied(functionExpression, state, repository, context, processorSupport, qualifiedPropertyNameVal, source, qualifiedPropertyName, qualifiedPropertyFuncs.getFirst());
                        foundFunctions = Lists.immutable.with(mqp);
                    } else {
                        foundFunctions = qualifiedPropertyFuncs;
                    }
                } else {
                    // Automap
                    reprocessPropertyForManySources(functionExpression, parametersValues, M3Properties.qualifiedPropertyName, sourceGenericType, repository, processorSupport);
                    // The parameters values are now different, so update
                    parametersValues = functionExpression._parametersValues().toList();
                    // Have another go at type inference
                    inferenceSuccess = firstPassTypeInference(functionExpression, parametersValues, state, matcher, repository, context, processorSupport);
                }
            }
        }
        if (foundFunctions.isEmpty()) {
            // Match the functionExpression with the Function library (may still need to do it even if the function is a property because it may have been reprocessed as a Collect!)
            foundFunctions = FunctionExpressionMatcher.findMatchingFunctionsInTheRepository(functionExpression, true, processorSupport);
            functionName = getFunctionName(functionExpression);
        }
    }
    Function<?> finalFunction = null;
    boolean someInferenceFailed = false;
    for (Function<?> foundFunction : foundFunctions) {
        functionExpression._funcRemove();
        functionExpression._funcCoreInstance(foundFunction);
        state.getTypeInferenceContext().setScope(foundFunction);
        FunctionType foundFunctionType = (FunctionType) processorSupport.function_getFunctionType(foundFunction);
        observer.functionMatched(foundFunction, foundFunctionType);
        // SECOND PASS
        ListIterable<? extends VariableExpression> paramsType = foundFunctionType._parameters().toList();
        // enumValues, autoMaps, etc...
        parametersValues = functionExpression._parametersValues().toList();
        boolean success = true;
        if (!inferenceSuccess) {
            observer.firstPassInferenceFailed();
            observer.shiftTab();
            observer.shiftTab();
            observer.matchTypeParamsFromFoundFunction(foundFunction);
            observer.shiftTab();
            for (int z = 0; z < parametersValues.size(); z++) {
                ValueSpecification instance = parametersValues.get(z);
                if (isInferenceSuccess(instance, processorSupport)) {
                    observer.matchParam(z);
                    GenericType templateGenType = paramsType.get(z)._genericType();
                    TypeInferenceContext typeInferenceContext = state.getTypeInferenceContext();
                    typeInferenceContext.register(templateGenType, instance._genericType(), typeInferenceContext.getTopContext(), observer);
                    typeInferenceContext.registerMul(paramsType.get(z)._multiplicity(), instance._multiplicity(), typeInferenceContext.getTopContext(), observer);
                } else {
                    observer.paramInferenceFailed(z);
                }
            }
            observer.unShiftTab();
            observer.reverseMatching();
            for (int z = 0; z < parametersValues.size(); z++) {
                final ValueSpecification instance = parametersValues.get(z);
                observer.processingParameter(functionExpression, z, instance);
                GenericType templateGenType = paramsType.get(z)._genericType();
                Multiplicity templateMultiplicity = paramsType.get(z)._multiplicity();
                GenericType resolvedGenericType = (GenericType) org.finos.legend.pure.m3.navigation.generictype.GenericType.makeTypeArgumentAsConcreteAsPossible(templateGenType, state.getTypeInferenceContext().getTypeParameterToGenericType(), state.getTypeInferenceContext().getMultiplicityParameterToMultiplicity(), processorSupport);
                Multiplicity resolvedMultiplicity = (Multiplicity) org.finos.legend.pure.m3.navigation.multiplicity.Multiplicity.makeMultiplicityAsConcreteAsPossible(templateMultiplicity, state.getTypeInferenceContext().getMultiplicityParameterToMultiplicity());
                if (isLambdaWithEmptyParamType(instance, processorSupport)) {
                    observer.shiftTab();
                    final VariableExpression templateToMatchLambdaTo = Objects.requireNonNull(getRawTypeFromGenericType(foundFunction, processorSupport))._parameters().toList().get(z);
                    observer.register(templateToMatchLambdaTo, templateToMatchLambdaTo, state.getTypeInferenceContext(), state.getTypeInferenceContext());
                    for (final CoreInstance val : ((InstanceValue) instance)._valuesCoreInstance()) {
                        if (val instanceof LambdaFunction) {
                            org.eclipse.collections.api.block.function.Function<CoreInstance, Boolean> processParamTypesOfLambdaUsedAsAFunctionExpressionParamValue = coreInstance -> !TypeInference.processParamTypesOfLambdaUsedAsAFunctionExpressionParamValue(instance, (LambdaFunction<?>) val, templateToMatchLambdaTo, matcher, state, repository, processorSupport);
                            success = success && MilestoningDatesPropagationFunctions.possiblyExecuteInNewMilestoningDateContext(functionExpression, val, processParamTypesOfLambdaUsedAsAFunctionExpressionParamValue, state, repository, context, processorSupport);
                            // Manage return type in any case
                            GenericType templateGenericType = templateToMatchLambdaTo._genericType();
                            ClassInstance functionClass = (ClassInstance) processorSupport.package_getByUserPath(M3Paths.Function);
                            if (org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(templateGenericType, processorSupport) && org.finos.legend.pure.m3.navigation.type.Type.subTypeOf(ImportStub.withImportStubByPass(templateGenericType._rawTypeCoreInstance(), processorSupport), functionClass, processorSupport)) {
                                GenericType templateGenFunctionType = templateGenericType._typeArguments().toList().get(0);
                                if (org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(templateGenFunctionType, processorSupport) && !org.finos.legend.pure.m3.navigation.type.Type.isTopType(Instance.getValueForMetaPropertyToOneResolved(templateGenFunctionType, M3Properties.rawType, processorSupport), processorSupport)) {
                                    GenericType templateReturnType = null != ImportStub.withImportStubByPass(templateGenFunctionType._rawTypeCoreInstance(), processorSupport) ? ((FunctionType) ImportStub.withImportStubByPass(templateGenFunctionType._rawTypeCoreInstance(), processorSupport))._returnType() : null;
                                    // Generics in lambdas are relative to their environment (i.e. the function in which they are defined)
                                    TypeInferenceContext lambdaInferenceContext = state.getTypeInferenceContext().getTopContext();
                                    if (null != templateReturnType) {
                                        FunctionType lambdaFunctionType = Objects.requireNonNull(getRawTypeFromGenericType((LambdaFunction<?>) val, processorSupport));
                                        GenericType concreteGenericType = (GenericType) org.finos.legend.pure.m3.navigation.generictype.GenericType.makeTypeArgumentAsConcreteAsPossible(lambdaFunctionType._returnType(), lambdaInferenceContext.getTypeParameterToGenericType(), lambdaInferenceContext.getMultiplicityParameterToMultiplicity(), processorSupport);
                                        lambdaFunctionType._returnTypeRemove();
                                        lambdaFunctionType._returnType(concreteGenericType);
                                        if (!org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(templateReturnType, processorSupport)) {
                                            TypeInferenceContext typeInferenceContext = state.getTypeInferenceContext();
                                            typeInferenceContext.register(templateReturnType, concreteGenericType, typeInferenceContext.getParent(), observer);
                                        }
                                    }
                                    Multiplicity templateReturnMultiplicity = null != ImportStub.withImportStubByPass(templateGenFunctionType._rawTypeCoreInstance(), processorSupport) ? ((FunctionType) ImportStub.withImportStubByPass(templateGenFunctionType._rawTypeCoreInstance(), processorSupport))._returnMultiplicity() : null;
                                    if (null != templateReturnMultiplicity) {
                                        FunctionType lambdaFunctionType = Objects.requireNonNull(getRawTypeFromGenericType((LambdaFunction<?>) val, processorSupport));
                                        Multiplicity concreteMultiplicity = (Multiplicity) org.finos.legend.pure.m3.navigation.multiplicity.Multiplicity.makeMultiplicityAsConcreteAsPossible(Instance.getValueForMetaPropertyToOneResolved(lambdaFunctionType, M3Properties.returnMultiplicity, processorSupport), lambdaInferenceContext.getMultiplicityParameterToMultiplicity());
                                        lambdaFunctionType._returnMultiplicityRemove();
                                        lambdaFunctionType._returnMultiplicity(concreteMultiplicity);
                                        if (null != concreteMultiplicity) {
                                            TypeInferenceContext typeInferenceContext = state.getTypeInferenceContext();
                                            typeInferenceContext.registerMul(templateReturnMultiplicity, concreteMultiplicity, typeInferenceContext.getParent(), observer);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    observer.unShiftTab();
                } else {
                    state.pushTypeInferenceContextAhead();
                    TypeInferenceContext typeInferenceContext = state.getTypeInferenceContext();
                    typeInferenceContext.setScope(instance instanceof SimpleFunctionExpression ? ((SimpleFunctionExpression) instance)._funcCoreInstance() : null);
                    typeInferenceContext.register(instance._genericType(), resolvedGenericType, typeInferenceContext.getParent(), observer);
                    typeInferenceContext.registerMul(instance._multiplicity(), resolvedMultiplicity, typeInferenceContext.getParent(), observer);
                    cleanProcess(instance, state, repository, context, processorSupport);
                    PostProcessor.processElement(matcher, instance, state, processorSupport);
                    state.popTypeInferenceContextAhead();
                }
            }
            observer.unShiftTab();
            observer.unShiftTab();
        } else {
            observer.parameterInferenceSucceeded();
            observer.shiftTab();
            observer.shiftTab();
            parametersValues.forEachWithIndex((instance, z) -> {
                TypeInferenceContext typeInferenceContext = state.getTypeInferenceContext();
                typeInferenceContext.register(paramsType.get(z)._genericType(), instance._genericType(), typeInferenceContext.getTopContext(), observer);
                typeInferenceContext.registerMul(paramsType.get(z)._multiplicity(), instance._multiplicity(), typeInferenceContext.getTopContext(), observer);
            });
            // WARNING / returnType may need reverse matching to be found
            GenericType returnGenericType = (GenericType) org.finos.legend.pure.m3.navigation.generictype.GenericType.makeTypeArgumentAsConcreteAsPossible(foundFunctionType._returnType(), state.getTypeInferenceContext().getTypeParameterToGenericType(), state.getTypeInferenceContext().getMultiplicityParameterToMultiplicity(), processorSupport);
            observer.returnType(returnGenericType);
            if (!org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(returnGenericType, processorSupport) && !state.getTypeInferenceContext().isTop(org.finos.legend.pure.m3.navigation.generictype.GenericType.getTypeParameterName(returnGenericType, processorSupport))) {
                observer.shiftTab();
                observer.returnTypeNotConcrete();
                // reverse matching
                parametersValues.forEachWithIndex((instance, z) -> {
                    GenericType templateGenType = paramsType.get(z)._genericType();
                    Multiplicity templateMultiplicity = paramsType.get(z)._multiplicity();
                    GenericType resolvedGenericType = (GenericType) org.finos.legend.pure.m3.navigation.generictype.GenericType.makeTypeArgumentAsConcreteAsPossible(templateGenType, state.getTypeInferenceContext().getTypeParameterToGenericType(), state.getTypeInferenceContext().getMultiplicityParameterToMultiplicity(), processorSupport);
                    Multiplicity resolvedMultiplicity = (Multiplicity) org.finos.legend.pure.m3.navigation.multiplicity.Multiplicity.makeMultiplicityAsConcreteAsPossible(templateMultiplicity, state.getTypeInferenceContext().getMultiplicityParameterToMultiplicity());
                    state.pushTypeInferenceContextAhead();
                    state.getTypeInferenceContext().setScope(instance instanceof FunctionExpression ? ((FunctionExpression) instance)._funcCoreInstance() : null);
                    observer.processingParameter(functionExpression, z, instance);
                    TypeInferenceContext typeInferenceContext = state.getTypeInferenceContext();
                    typeInferenceContext.register(instance._genericType(), resolvedGenericType, typeInferenceContext.getParent(), observer);
                    typeInferenceContext.registerMul(instance._multiplicity(), resolvedMultiplicity, typeInferenceContext.getParent(), observer);
                    observer.shiftTab();
                    observer.reprocessingTheParameter();
                    observer.shiftTab();
                    cleanProcess(instance, state, repository, context, processorSupport);
                    PostProcessor.processElement(matcher, instance, state, processorSupport);
                    observer.unShiftTab();
                    observer.finishedProcessParameter();
                    observer.unShiftTab();
                    state.popTypeInferenceContextAhead();
                });
                observer.unShiftTab();
                returnGenericType = (GenericType) org.finos.legend.pure.m3.navigation.generictype.GenericType.makeTypeArgumentAsConcreteAsPossible(foundFunctionType._returnType(), state.getTypeInferenceContext().getTypeParameterToGenericType(), state.getTypeInferenceContext().getMultiplicityParameterToMultiplicity(), processorSupport);
                observer.newReturnType(returnGenericType);
            }
            observer.unShiftTab();
            observer.unShiftTab();
            observer.finishedRegisteringParametersAndMultiplicities();
        }
        // We can infer the parameter types for Lambdas given as parameters (now that we know which function to use).
        if (success) {
            TypeInference.storeInferredTypeParametersInFunctionExpression(functionExpression, state, processorSupport, foundFunction);
            // Get the return type information
            // Pair<CoreInstance, CoreInstance> result = FunctionExpression.resolveFunctionGenericReturnTypeAndMultiplicity(functionExpression, context, processorSupport);
            // result.getOne();
            GenericType returnGenericType = (GenericType) org.finos.legend.pure.m3.navigation.generictype.GenericType.makeTypeArgumentAsConcreteAsPossible(foundFunctionType._returnType(), state.getTypeInferenceContext().getTypeParameterToGenericType(), state.getTypeInferenceContext().getMultiplicityParameterToMultiplicity(), processorSupport);
            Multiplicity returnMultiplicity = (Multiplicity) org.finos.legend.pure.m3.navigation.multiplicity.Multiplicity.makeMultiplicityAsConcreteAsPossible(foundFunctionType._returnMultiplicity(), state.getTypeInferenceContext().getMultiplicityParameterToMultiplicity());
            if (!org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(returnGenericType, processorSupport) && !state.getTypeInferenceContext().isTop(org.finos.legend.pure.m3.navigation.generictype.GenericType.getTypeParameterName(returnGenericType, processorSupport))) {
                throw new PureCompilationException(functionExpression.getSourceInformation(), "The system is not capable of inferring the return type of the function '" + functionExpression.getValueForMetaPropertyToOne(M3Properties.func).getValueForMetaPropertyToOne(M3Properties.functionName).getName() + "'. Check your signatures!");
            }
            // Update the type
            GenericType genericTypeCopy = (GenericType) org.finos.legend.pure.m3.navigation.generictype.GenericType.copyGenericTypeAsInferredGenericType(returnGenericType, functionExpression.getSourceInformation(), processorSupport);
            functionExpression._genericType(genericTypeCopy);
            // Update the multiplicity
            Multiplicity returnMultiplicityCopy = (Multiplicity) org.finos.legend.pure.m3.navigation.multiplicity.Multiplicity.copyMultiplicity(returnMultiplicity, functionExpression.getSourceInformation(), processorSupport);
            functionExpression._multiplicity(returnMultiplicityCopy);
        } else {
            // Inference failed...
            FunctionType functionType = (FunctionType) processorSupport.function_getFunctionType(foundFunction);
            GenericType returnGenericType = functionType._returnType();
            GenericType genericTypeCopy = (GenericType) org.finos.legend.pure.m3.navigation.generictype.GenericType.copyGenericTypeAsInferredGenericType(returnGenericType, functionExpression.getSourceInformation(), processorSupport);
            functionExpression._genericType(genericTypeCopy);
            Multiplicity returnMultiplicity = functionType._returnMultiplicity();
            Multiplicity returnMultiplicityCopy = (Multiplicity) org.finos.legend.pure.m3.navigation.multiplicity.Multiplicity.copyMultiplicity(returnMultiplicity, functionExpression.getSourceInformation(), processorSupport);
            functionExpression._multiplicity(returnMultiplicityCopy);
        }
        if (null == functionName) {
            finalFunction = foundFunction;
        } else if (!success) {
            someInferenceFailed = true;
        } else {
            Function<?> bestMatch = FunctionExpressionMatcher.getBestFunctionMatch(foundFunctions, parametersValues, functionName, functionExpression.getSourceInformation(), false, processorSupport);
            if (bestMatch == foundFunction) {
                finalFunction = foundFunction;
            }
        }
        if (null != finalFunction) {
            break;
        }
        // Clean up before re-trying
        if (1 < foundFunctions.size()) {
            for (ValueSpecification parameterValue : parametersValues) {
                cleanProcess(parameterValue, state, repository, context, processorSupport);
            }
            inferenceSuccess = firstPassTypeInference(functionExpression, parametersValues, state, matcher, repository, context, processorSupport);
        }
    }
    if (null != finalFunction) {
        finalFunction._applications(Lists.immutable.<FunctionExpression>withAll(finalFunction._applications()).newWith(functionExpression));
        // Update the function in the function expression in the reverse
        if ("new_Class_1__String_1__KeyExpression_MANY__T_1_".equals(finalFunction.getName()) || "new_Class_1__String_1__T_1_".equals(finalFunction.getName())) {
            this.addTraceForKeyExpressions(functionExpression, processorSupport);
        }
        if ("copy_T_1__String_1__KeyExpression_MANY__T_1_".equals(finalFunction.getName()) || "copy_T_1__String_1__T_1_".equals(finalFunction.getName())) {
            this.addTraceForKeyExpressions(functionExpression, processorSupport);
        }
        if ("letFunction_String_1__T_m__T_m_".equals(finalFunction.getName())) {
            try {
                state.getVariableContext().getParent().registerValue(((InstanceValue) parametersValues.get(0))._valuesCoreInstance().toList().get(0).getName(), parametersValues.get(1));
            } catch (VariableNameConflictException e) {
                throw new PureCompilationException(functionExpression.getSourceInformation(), e.getMessage());
            }
        }
    } else if (!someInferenceFailed) {
        throwNoMatchException(functionExpression, state, processorSupport);
    }
    observer.unShiftTab();
    observer.finishedProcessingFunctionExpression(functionExpression);
    state.popTypeInferenceContext();
}
Also used : ParameterValueSpecificationContext(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ParameterValueSpecificationContext) SimpleFunctionExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.SimpleFunctionExpression) ImportGroup(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel._import.ImportGroup) SetIterable(org.eclipse.collections.api.set.SetIterable) MilestonedPropertyMetaData(org.finos.legend.pure.m3.compiler.postprocessing.processor.milestoning.MilestonedPropertyMetaData) ClassProjection(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.ClassProjection) FunctionDefinitionProcessor(org.finos.legend.pure.m3.compiler.postprocessing.processor.FunctionDefinitionProcessor) MutableList(org.eclipse.collections.api.list.MutableList) ProcessorState(org.finos.legend.pure.m3.compiler.postprocessing.ProcessorState) PureUnmatchedFunctionException(org.finos.legend.pure.m3.exception.PureUnmatchedFunctionException) ProcessorSupport(org.finos.legend.pure.m3.navigation.ProcessorSupport) MutableSet(org.eclipse.collections.api.set.MutableSet) TypeInferenceContext(org.finos.legend.pure.m3.compiler.postprocessing.inference.TypeInferenceContext) FunctionType(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.FunctionType) RichIterable(org.eclipse.collections.api.RichIterable) GenericTypeTraceability(org.finos.legend.pure.m3.compiler.postprocessing.GenericTypeTraceability) PostProcessor(org.finos.legend.pure.m3.compiler.postprocessing.PostProcessor) Automap(org.finos.legend.pure.m3.compiler.postprocessing.processor.Automap) PureCompilationException(org.finos.legend.pure.m4.exception.PureCompilationException) ModelRepository(org.finos.legend.pure.m4.ModelRepository) KeyValueValueSpecificationContext(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.KeyValueValueSpecificationContext) TypeInference(org.finos.legend.pure.m3.compiler.postprocessing.inference.TypeInference) ListHelper(org.finos.legend.pure.m3.tools.ListHelper) Matcher(org.finos.legend.pure.m3.tools.matcher.Matcher) Objects(java.util.Objects) UnbindState(org.finos.legend.pure.m3.compiler.unload.unbind.UnbindState) Multiplicity(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.multiplicity.Multiplicity) GenericType(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.generics.GenericType) org.finos.legend.pure.m3.navigation._class._Class(org.finos.legend.pure.m3.navigation._class._Class) ValueSpecificationBootstrap(org.finos.legend.pure.m3.navigation.ValueSpecificationBootstrap) ImportStub(org.finos.legend.pure.m3.navigation.importstub.ImportStub) MilestoningDatesPropagationFunctions(org.finos.legend.pure.m3.compiler.postprocessing.processor.milestoning.MilestoningDatesPropagationFunctions) ListIterable(org.eclipse.collections.api.list.ListIterable) Processor(org.finos.legend.pure.m3.compiler.postprocessing.processor.Processor) FunctionExpressionMatcher(org.finos.legend.pure.m3.compiler.postprocessing.functionmatch.FunctionExpressionMatcher) VariableExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.VariableExpression) AbstractProperty(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.property.AbstractProperty) Instance(org.finos.legend.pure.m3.navigation.Instance) Unbinder(org.finos.legend.pure.m3.compiler.unload.Unbinder) QualifiedProperty(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.property.QualifiedProperty) Lists(org.eclipse.collections.api.factory.Lists) FunctionDefinition(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.FunctionDefinition) PartitionSet(org.eclipse.collections.api.partition.set.PartitionSet) M3Paths(org.finos.legend.pure.m3.navigation.M3Paths) Context(org.finos.legend.pure.m3.compiler.Context) VariableNameConflictException(org.finos.legend.pure.m3.compiler.postprocessing.VariableContext.VariableNameConflictException) ImportAccessor(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel._import.ImportAccessor) Function(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.Function) FunctionExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.FunctionExpression) TypeInferenceObserver(org.finos.legend.pure.m3.compiler.postprocessing.inference.TypeInferenceObserver) Package(org.finos.legend.pure.m3.coreinstance.Package) LambdaFunctionInstance(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.LambdaFunctionInstance) Sets(org.eclipse.collections.api.factory.Sets) PackageableElement(org.finos.legend.pure.m3.navigation.PackageableElement.PackageableElement) SourceInformation(org.finos.legend.pure.m4.coreinstance.SourceInformation) MilestoningFunctions(org.finos.legend.pure.m3.compiler.postprocessing.processor.milestoning.MilestoningFunctions) ClassInstance(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.ClassInstance) CoreInstance(org.finos.legend.pure.m4.coreinstance.CoreInstance) Type(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Type) ValueSpecification(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecification) LambdaFunction(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.LambdaFunction) InstanceValue(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.InstanceValue) Visibility(org.finos.legend.pure.m3.compiler.visibility.Visibility) KeyExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.functions.lang.KeyExpression) M3Properties(org.finos.legend.pure.m3.navigation.M3Properties) ValueSpecification(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecification) InstanceValue(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.InstanceValue) VariableNameConflictException(org.finos.legend.pure.m3.compiler.postprocessing.VariableContext.VariableNameConflictException) Function(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.Function) LambdaFunction(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.LambdaFunction) SimpleFunctionExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.SimpleFunctionExpression) FunctionExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.FunctionExpression) SimpleFunctionExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.SimpleFunctionExpression) Multiplicity(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.multiplicity.Multiplicity) TypeInferenceObserver(org.finos.legend.pure.m3.compiler.postprocessing.inference.TypeInferenceObserver) TypeInferenceContext(org.finos.legend.pure.m3.compiler.postprocessing.inference.TypeInferenceContext) ClassInstance(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.ClassInstance) PureCompilationException(org.finos.legend.pure.m4.exception.PureCompilationException) GenericType(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.generics.GenericType) FunctionType(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.FunctionType) VariableExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.VariableExpression) LambdaFunction(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.LambdaFunction) CoreInstance(org.finos.legend.pure.m4.coreinstance.CoreInstance) QualifiedProperty(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.property.QualifiedProperty)

Example 2 with SimpleFunctionExpression

use of org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.SimpleFunctionExpression in project legend-pure by finos.

the class FunctionExpressionProcessor method buildLambdaForMapWithProperty.

private static LambdaFunction<?> buildLambdaForMapWithProperty(FunctionExpression functionExpression, ListIterable<? extends ValueSpecification> qualifierParams, String propertyOrQualifiedPropertyNameProperty, GenericType sourceGenericType, ModelRepository repository, ProcessorSupport processorSupport) {
    VariableExpression lambdaVarExpr = buildLambdaVariableExpression(functionExpression, repository, processorSupport);
    GenericType varExpGenT = (GenericType) org.finos.legend.pure.m3.navigation.generictype.GenericType.copyGenericTypeAsInferredGenericType(sourceGenericType, functionExpression.getSourceInformation(), processorSupport);
    lambdaVarExpr._genericType(varExpGenT);
    lambdaVarExpr._multiplicity((Multiplicity) processorSupport.package_getByUserPath(M3Paths.PureOne));
    FunctionType functionType = (FunctionType) repository.newAnonymousCoreInstance(functionExpression.getSourceInformation(), processorSupport.package_getByUserPath(M3Paths.FunctionType), true);
    functionType._parameters(Lists.immutable.with(lambdaVarExpr));
    GenericType functionTypeGt = (GenericType) repository.newAnonymousCoreInstance(functionExpression.getSourceInformation(), processorSupport.package_getByUserPath(M3Paths.GenericType), true);
    functionTypeGt._rawTypeCoreInstance(functionType);
    ClassInstance lambdaFunctionClass = (ClassInstance) processorSupport.package_getByUserPath(M3Paths.LambdaFunction);
    GenericType lambdaGenericType = (GenericType) org.finos.legend.pure.m3.navigation.type.Type.wrapGenericType(lambdaFunctionClass, processorSupport);
    lambdaGenericType._typeArguments(Lists.immutable.with(functionTypeGt));
    VariableExpression paramVarExpr = buildLambdaVariableExpression(functionExpression, repository, processorSupport);
    SimpleFunctionExpression propertySfe = (SimpleFunctionExpression) repository.newAnonymousCoreInstance(functionExpression.getSourceInformation(), processorSupport.package_getByUserPath(M3Paths.SimpleFunctionExpression), true);
    String lambdaContextName;
    if (M3Properties.qualifiedPropertyName.equals(propertyOrQualifiedPropertyNameProperty)) {
        lambdaContextName = functionExpression._qualifiedPropertyName().getName();
        propertySfe._qualifiedPropertyName(functionExpression._qualifiedPropertyName());
    } else if (M3Properties.propertyName.equals(propertyOrQualifiedPropertyNameProperty)) {
        lambdaContextName = functionExpression._propertyName().getName();
        propertySfe._propertyName(functionExpression._propertyName());
    } else {
        throw new PureCompilationException("Unexpected property name" + propertyOrQualifiedPropertyNameProperty);
    }
    propertySfe._importGroup(functionExpression._importGroup());
    propertySfe._parametersValues(Lists.immutable.<ValueSpecification>with(paramVarExpr).newWithAll(qualifierParams));
    LambdaFunctionInstance lambdaFunctionInst = LambdaFunctionInstance.createPersistent(repository, lambdaContextName, functionExpression.getSourceInformation());
    lambdaFunctionInst._expressionSequence(Lists.immutable.with(propertySfe));
    lambdaFunctionInst._classifierGenericType(lambdaGenericType);
    return lambdaFunctionInst;
}
Also used : GenericType(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.generics.GenericType) SimpleFunctionExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.SimpleFunctionExpression) LambdaFunctionInstance(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.LambdaFunctionInstance) FunctionType(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.FunctionType) ValueSpecification(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecification) VariableExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.VariableExpression) ClassInstance(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.ClassInstance) PureCompilationException(org.finos.legend.pure.m4.exception.PureCompilationException)

Example 3 with SimpleFunctionExpression

use of org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.SimpleFunctionExpression in project legend-pure by finos.

the class InstanceValueUnbind method run.

@Override
public void run(InstanceValue instanceValue, MatcherState state, Matcher matcher, ModelRepository modelRepository, Context context) throws PureCompilationException {
    ProcessorSupport processorSupport = state.getProcessorSupport();
    for (CoreInstance value : instanceValue._valuesCoreInstance()) {
        if (!(value instanceof Property)) {
            ((UnbindState) state).freeProcessedAndValidated(value);
        }
        Shared.cleanUpReferenceUsage(value, instanceValue, processorSupport);
        // TODO replace call to Instance.instanceOf once we resolve issue with Path not being available in this module - circular dependency
        if (value instanceof LambdaFunction || value instanceof SimpleFunctionExpression || Instance.instanceOf(value, M3Paths.Path, processorSupport) || value instanceof RootRouteNode) {
            matcher.fullMatch(value, state);
        } else if (Instance.instanceOf(value, M3Paths.RootGraphFetchTree, processorSupport)) {
            matcher.fullMatch(value, state);
        } else if (value instanceof KeyExpression) {
            ((UnbindState) state).freeProcessedAndValidated(modelRepository.newBooleanCoreInstance(((KeyExpression) value)._add()));
            ((UnbindState) state).freeProcessedAndValidated(((KeyExpression) value)._key());
            matcher.fullMatch(((KeyExpression) value)._expression(), state);
        } else {
            Shared.cleanImportStub(value, processorSupport);
        }
        if (value instanceof ValueSpecification) {
            matcher.fullMatch(value, state);
            ((ValueSpecification) value)._usageContextRemove();
        }
    }
}
Also used : ProcessorSupport(org.finos.legend.pure.m3.navigation.ProcessorSupport) RootRouteNode(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.treepath.RootRouteNode) SimpleFunctionExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.SimpleFunctionExpression) CoreInstance(org.finos.legend.pure.m4.coreinstance.CoreInstance) KeyExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.functions.lang.KeyExpression) ValueSpecification(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecification) LambdaFunction(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.LambdaFunction) Property(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.property.Property)

Example 4 with SimpleFunctionExpression

use of org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.SimpleFunctionExpression in project legend-pure by finos.

the class SimpleFunctionExpressionUnbind method run.

@Override
public void run(SimpleFunctionExpression functionExpression, MatcherState state, Matcher matcher, ModelRepository modelRepository, Context context) throws PureCompilationException {
    ProcessorSupport processorSupport = state.getProcessorSupport();
    Function<?> function = (Function<?>) ImportStub.withImportStubByPass(functionExpression._funcCoreInstance(), processorSupport);
    if (function != null) {
        function._applicationsRemove(functionExpression);
        if (function._applications().isEmpty()) {
            function._applicationsRemove();
        }
    }
    cleanAutoMapPropertyIfNecessary(functionExpression, state, matcher);
    MilestoningDatesPropagationFunctions.undoAutoGenMilestonedQualifier(functionExpression, modelRepository, processorSupport);
    functionExpression._funcRemove();
    functionExpression._resolvedTypeParametersRemove();
    functionExpression._resolvedMultiplicityParametersRemove();
    functionExpression._parametersValues().forEach(pv -> matcher.fullMatch(pv, state));
}
Also used : Function(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.Function) ProcessorSupport(org.finos.legend.pure.m3.navigation.ProcessorSupport)

Example 5 with SimpleFunctionExpression

use of org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.SimpleFunctionExpression in project legend-pure by finos.

the class AntlrContextToM3CoreInstance method buildArithmeticWithListParam.

// Build arithmetic op which can handle list of params (like lisp eg (+ u v z y z))
private SimpleFunctionExpression buildArithmeticWithListParam(ArithmeticPartContext ctx, ArithOp op, CoreInstance initialValue, String exprName, MutableList<String> typeParametersNames, LambdaContext lambdaContext, String space, boolean wrapFlag, ImportGroup importId, boolean addLines) {
    MutableList<CoreInstance> others = Lists.mutable.empty();
    Function0<List<TerminalNode>> getTokens;
    Function<Integer, TerminalNode> getToken;
    switch(op) {
        case PLUS:
            getTokens = ctx::PLUS;
            getToken = ctx::PLUS;
            break;
        case TIMES:
            getTokens = ctx::STAR;
            getToken = ctx::STAR;
            break;
        case MINUS:
            getTokens = ctx::MINUS;
            getToken = ctx::MINUS;
            break;
        default:
            throw new IllegalStateException("Unexpected arithmetic operation for buildArithmeticWithListParam: " + op);
    }
    String op_str = op.toString().toLowerCase();
    for (ExpressionContext eCtx : ctx.expression()) {
        others.add(this.expression(eCtx, exprName, typeParametersNames, lambdaContext, space, wrapFlag, importId, addLines));
    }
    TerminalNode newOp = getToken.apply(getTokens.value().size() - 1);
    SimpleFunctionExpression sfe = SimpleFunctionExpressionInstance.createPersistent(this.repository, this.sourceInformation.getPureSourceInformation(newOp.getSymbol()), null, null, importId, null);
    sfe._functionName(op_str);
    sfe._parametersValues(Lists.mutable.<ValueSpecification>of(this.doWrap(Lists.mutable.with(initialValue).withAll(others))));
    return sfe;
}
Also used : NotExpressionContext(org.finos.legend.pure.m3.serialization.grammar.m3parser.antlr.M3Parser.NotExpressionContext) ExpressionContext(org.finos.legend.pure.m3.serialization.grammar.m3parser.antlr.M3Parser.ExpressionContext) LetExpressionContext(org.finos.legend.pure.m3.serialization.grammar.m3parser.antlr.M3Parser.LetExpressionContext) BuildMilestoningVariableExpressionContext(org.finos.legend.pure.m3.serialization.grammar.m3parser.antlr.M3Parser.BuildMilestoningVariableExpressionContext) PropertyExpressionContext(org.finos.legend.pure.m3.serialization.grammar.m3parser.antlr.M3Parser.PropertyExpressionContext) DefaultValueExpressionContext(org.finos.legend.pure.m3.serialization.grammar.m3parser.antlr.M3Parser.DefaultValueExpressionContext) FunctionVariableExpressionContext(org.finos.legend.pure.m3.serialization.grammar.m3parser.antlr.M3Parser.FunctionVariableExpressionContext) CombinedExpressionContext(org.finos.legend.pure.m3.serialization.grammar.m3parser.antlr.M3Parser.CombinedExpressionContext) AtomicExpressionContext(org.finos.legend.pure.m3.serialization.grammar.m3parser.antlr.M3Parser.AtomicExpressionContext) SignedExpressionContext(org.finos.legend.pure.m3.serialization.grammar.m3parser.antlr.M3Parser.SignedExpressionContext) PropertyOrFunctionExpressionContext(org.finos.legend.pure.m3.serialization.grammar.m3parser.antlr.M3Parser.PropertyOrFunctionExpressionContext) SimpleFunctionExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.SimpleFunctionExpression) PrimitiveCoreInstance(org.finos.legend.pure.m4.coreinstance.primitive.PrimitiveCoreInstance) CoreInstance(org.finos.legend.pure.m4.coreinstance.CoreInstance) MutableList(org.eclipse.collections.api.list.MutableList) FastList(org.eclipse.collections.impl.list.mutable.FastList) List(java.util.List) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode)

Aggregations

SimpleFunctionExpression (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.SimpleFunctionExpression)20 ValueSpecification (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecification)18 CoreInstance (org.finos.legend.pure.m4.coreinstance.CoreInstance)13 PrimitiveCoreInstance (org.finos.legend.pure.m4.coreinstance.primitive.PrimitiveCoreInstance)11 InstanceValue (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.InstanceValue)9 LambdaFunction (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.LambdaFunction)7 GenericType (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.generics.GenericType)6 VariableExpression (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.VariableExpression)6 FunctionType (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.FunctionType)5 MutableList (org.eclipse.collections.api.list.MutableList)4 Pair (org.eclipse.collections.api.tuple.Pair)4 Root_meta_pure_metamodel_valuespecification_VariableExpression_Impl (org.finos.legend.pure.generated.Root_meta_pure_metamodel_valuespecification_VariableExpression_Impl)4 List (java.util.List)3 TerminalNode (org.antlr.v4.runtime.tree.TerminalNode)3 Root_meta_pure_metamodel_function_LambdaFunction_Impl (org.finos.legend.pure.generated.Root_meta_pure_metamodel_function_LambdaFunction_Impl)3 Root_meta_pure_metamodel_type_generics_GenericType_Impl (org.finos.legend.pure.generated.Root_meta_pure_metamodel_type_generics_GenericType_Impl)3 Root_meta_pure_metamodel_valuespecification_InstanceValue_Impl (org.finos.legend.pure.generated.Root_meta_pure_metamodel_valuespecification_InstanceValue_Impl)3 Root_meta_pure_metamodel_valuespecification_SimpleFunctionExpression_Impl (org.finos.legend.pure.generated.Root_meta_pure_metamodel_valuespecification_SimpleFunctionExpression_Impl)3 KeyExpression (org.finos.legend.pure.m3.coreinstance.meta.pure.functions.lang.KeyExpression)3 Function (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.Function)3