Search in sources :

Example 1 with VariableExpression

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

the class TypeInference method processParamTypesOfLambdaUsedAsAFunctionExpressionParamValue.

public static boolean processParamTypesOfLambdaUsedAsAFunctionExpressionParamValue(ValueSpecification instanceValueContainer, LambdaFunction<?> lambdaFunction, VariableExpression templateToMatchLambdaTo, Matcher matcher, ProcessorState state, ModelRepository repository, ProcessorSupport processorSupport) throws PureCompilationException {
    GenericType templateGenericType = templateToMatchLambdaTo._genericType();
    Type templateFunctionType = templateGenericType._typeArguments().notEmpty() ? (Type) ImportStub.withImportStubByPass(templateGenericType._typeArguments().getFirst()._rawTypeCoreInstance(), processorSupport) : null;
    FunctionType lambdaFunctionType = (FunctionType) ImportStub.withImportStubByPass(lambdaFunction._classifierGenericType()._typeArguments().getFirst()._rawTypeCoreInstance(), processorSupport);
    if (org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(templateGenericType) && org.finos.legend.pure.m3.navigation.type.Type.subTypeOf(ImportStub.withImportStubByPass(templateGenericType._rawTypeCoreInstance(), processorSupport), processorSupport.package_getByUserPath(M3Paths.Function), processorSupport)) {
        ListIterable<? extends VariableExpression> parameters = ListHelper.wrapListIterable(lambdaFunctionType._parameters());
        for (int j = 0; j < parameters.size(); j++) {
            VariableExpression param = parameters.get(j);
            if (param._genericType() == null) {
                if (org.finos.legend.pure.m3.navigation.type.Type.isBottomType(templateFunctionType, processorSupport) || org.finos.legend.pure.m3.navigation.type.Type.isTopType(templateFunctionType, processorSupport)) {
                    throw new PureCompilationException(lambdaFunction.getSourceInformation(), "Can't infer the parameters' types for the lambda. Please specify it in the signature.");
                }
                VariableExpression templateParam = ListHelper.wrapListIterable(((FunctionType) Objects.requireNonNull(templateFunctionType))._parameters()).get(j);
                CoreInstance genericType = org.finos.legend.pure.m3.navigation.generictype.GenericType.makeTypeArgumentAsConcreteAsPossible(templateParam._genericType(), state.getTypeInferenceContext().getTypeParameterToGenericType(), state.getTypeInferenceContext().getMultiplicityParameterToMultiplicity(), processorSupport);
                if (state.getTypeInferenceContext().isTypeParameterResolved(genericType)) {
                    genericType = state.getTypeInferenceContext().resolve(genericType);
                } else {
                    return true;
                }
                CoreInstance multiplicity = org.finos.legend.pure.m3.navigation.multiplicity.Multiplicity.makeMultiplicityAsConcreteAsPossible(templateParam._multiplicity(), state.getTypeInferenceContext().getMultiplicityParameterToMultiplicity());
                param._genericType((GenericType) org.finos.legend.pure.m3.navigation.generictype.GenericType.copyGenericTypeAsInferredGenericType(genericType, param.getSourceInformation(), processorSupport));
                param._multiplicity((Multiplicity) org.finos.legend.pure.m3.navigation.multiplicity.Multiplicity.copyMultiplicity(multiplicity, param.getSourceInformation(), processorSupport));
            }
        }
        state.pushVariableContext();
        FunctionDefinitionProcessor.process(lambdaFunction, state, matcher, repository);
        LambdaFunctionProcessor.process(lambdaFunction, state, matcher, repository);
        state.popVariableContext();
    } else {
        throw new PureCompilationException(lambdaFunction.getSourceInformation(), "Can't infer the parameters' types for the lambda. Please specify it in the signature.");
    }
    instanceValueContainer._genericTypeRemove();
    InstanceValueProcessor.updateInstanceValue(instanceValueContainer, processorSupport);
    return false;
}
Also used : 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) Type(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Type) 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) CoreInstance(org.finos.legend.pure.m4.coreinstance.CoreInstance) VariableExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.VariableExpression) PureCompilationException(org.finos.legend.pure.m4.exception.PureCompilationException)

Example 2 with VariableExpression

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

the class TypeInferenceContext method register.

public void register(GenericType templateGenType, GenericType genericType, TypeInferenceContext targetGenericsContext, TypeInferenceObserver observer) {
    Objects.requireNonNull(targetGenericsContext);
    if (genericType != null) {
        GenericType genericTypeCopy = (GenericType) org.finos.legend.pure.m3.navigation.generictype.GenericType.copyGenericType(genericType, true, this.processorSupport);
        String name = org.finos.legend.pure.m3.navigation.generictype.GenericType.getTypeParameterName(templateGenType);
        if (name != null) {
            ParameterValueWithFlag existing = this.states.getLast().getTypeParameterValueWithFlag(name);
            List<RegistrationRequest> forwards = Lists.mutable.empty();
            if (existing == null) {
                // New registration
                this.states.getLast().putTypeParameterValue(name, genericTypeCopy, targetGenericsContext, false);
            } else if (org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(existing.getParameterValue()) && org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(genericTypeCopy)) {
                // Merge two concrete types
                GenericType merged = (GenericType) org.finos.legend.pure.m3.navigation.generictype.GenericType.findBestCommonGenericType(Lists.mutable.with(existing.getParameterValue(), genericTypeCopy), TypeParameter.isCovariant(templateGenType), false, genericType.getSourceInformation(), this.processorSupport);
                this.states.getLast().putTypeParameterValue(name, merged, targetGenericsContext, false);
                // See if the replacement is the more concrete version of a previously semi-concrete type (List<T> replaced by List<String>)
                CoreInstance existingRawType = ((GenericType) existing.getParameterValue())._rawType();
                CoreInstance replacementRawType = merged._rawType();
                if (existingRawType.equals(replacementRawType)) {
                    Iterator<? extends GenericType> existingTypeArguments = ((GenericType) existing.getParameterValue())._typeArguments().iterator();
                    Iterator<? extends GenericType> replacementTypeArguments = merged._typeArguments().iterator();
                    while (existingTypeArguments.hasNext()) {
                        GenericType existingArgument = existingTypeArguments.next();
                        GenericType replacementArgument = replacementTypeArguments.next();
                        if (!org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(existingArgument) && org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(replacementArgument)) {
                            forwards.add(new RegistrationRequest(existing.getTargetGenericsContext(), existingArgument, replacementArgument));
                        }
                    }
                }
            } else if (this.states.size() > 1) {
                // We  are processing elements of a collection, record what we learn for the element which will later
                // be processed by TypeInference.potentiallyUpdateParentTypeParamForInstanceValueWithManyElements later
                this.states.getLast().putTypeParameterValue(name, genericTypeCopy, targetGenericsContext, false);
            } else if (org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(existing.getParameterValue())) {
                // Replace the existing concrete registration with a generic one and move the concrete one to the referenced type
                this.states.getLast().putTypeParameterValue(name, genericTypeCopy, targetGenericsContext, false);
                forwards.add(new RegistrationRequest(targetGenericsContext, genericTypeCopy, existing.getParameterValue()));
            } else if (org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(genericTypeCopy)) {
                if (!existing.getTargetGenericsContext().equals(this)) {
                    // forward the registration of this concrete type to the already referenced type
                    forwards.add(new RegistrationRequest(existing.getTargetGenericsContext(), existing.getParameterValue(), genericTypeCopy));
                }
            } else {
                if (!existing.getTargetGenericsContext().equals(this)) {
                    // forward the registration of this generic type to the already referenced type
                    forwards.add(new RegistrationRequest(existing.getTargetGenericsContext(), existing.getParameterValue(), genericTypeCopy));
                }
            }
            observer.register(templateGenType, genericTypeCopy, this, targetGenericsContext);
            observer.shiftTab();
            forwards.forEach(request -> request.context.register((GenericType) request.template, (GenericType) request.value, targetGenericsContext, observer));
            observer.unShiftTab();
        }
        if (org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(templateGenType) && org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(genericTypeCopy)) {
            if (!Type.isBottomType(ImportStub.withImportStubByPass(templateGenType._rawTypeCoreInstance(), this.processorSupport), this.processorSupport) && !Type.isBottomType(ImportStub.withImportStubByPass(genericTypeCopy._rawTypeCoreInstance(), this.processorSupport), this.processorSupport) && !Type.isTopType(ImportStub.withImportStubByPass(templateGenType._rawTypeCoreInstance(), this.processorSupport), this.processorSupport) && !Type.isTopType(ImportStub.withImportStubByPass(genericTypeCopy._rawTypeCoreInstance(), this.processorSupport), this.processorSupport)) {
                ListIterable<? extends CoreInstance> typeValues;
                ListIterable<? extends CoreInstance> mulValues;
                ListIterable<? extends CoreInstance> typeTemplates;
                ListIterable<? extends CoreInstance> mulTemplates;
                if (Type.subTypeOf(ImportStub.withImportStubByPass(templateGenType._rawTypeCoreInstance(), this.processorSupport), ImportStub.withImportStubByPass(genericTypeCopy._rawTypeCoreInstance(), this.processorSupport), this.processorSupport)) {
                    typeTemplates = extractTypes(org.finos.legend.pure.m3.navigation.generictype.GenericType.resolveClassTypeParameterUsingInheritance(templateGenType, genericTypeCopy, this.processorSupport));
                    mulTemplates = extractMuls(org.finos.legend.pure.m3.navigation.generictype.GenericType.resolveClassMultiplicityParameterUsingInheritance(templateGenType, ImportStub.withImportStubByPass(genericTypeCopy._rawTypeCoreInstance(), this.processorSupport), this.processorSupport));
                    typeValues = ListHelper.wrapListIterable(genericTypeCopy._typeArguments());
                    mulValues = ListHelper.wrapListIterable(genericTypeCopy._multiplicityArguments());
                } else {
                    typeTemplates = ListHelper.wrapListIterable(templateGenType._typeArguments());
                    mulTemplates = ListHelper.wrapListIterable(templateGenType._multiplicityArguments());
                    typeValues = extractTypes(org.finos.legend.pure.m3.navigation.generictype.GenericType.resolveClassTypeParameterUsingInheritance(genericTypeCopy, templateGenType, this.processorSupport));
                    mulValues = extractMuls(org.finos.legend.pure.m3.navigation.generictype.GenericType.resolveClassMultiplicityParameterUsingInheritance(genericTypeCopy, ImportStub.withImportStubByPass(templateGenType._rawTypeCoreInstance(), this.processorSupport), this.processorSupport));
                }
                for (int z = 0; z < mulValues.size(); z++) {
                    registerMul((Multiplicity) mulTemplates.get(z), (Multiplicity) mulValues.get(z), targetGenericsContext, observer);
                }
                for (int z = 0; z < typeValues.size(); z++) {
                    GenericType first = (GenericType) typeTemplates.get(z);
                    GenericType second = (GenericType) typeValues.get(z);
                    if (org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(first) && first._rawTypeCoreInstance() instanceof org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.FunctionType && org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(second) && second._rawTypeCoreInstance() instanceof org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.FunctionType) {
                        org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.FunctionType firstFuncType = (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.FunctionType) first._rawTypeCoreInstance();
                        org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.FunctionType secondFuncType = (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.FunctionType) second._rawTypeCoreInstance();
                        observer.register(first, second, this, targetGenericsContext);
                        observer.shiftTab();
                        ListIterable<? extends VariableExpression> firstParams = ListHelper.wrapListIterable(firstFuncType._parameters());
                        ListIterable<? extends VariableExpression> secondParams = ListHelper.wrapListIterable(secondFuncType._parameters());
                        for (int i = 0; i < firstParams.size(); i++) {
                            register(firstParams.get(i)._genericType(), secondParams.get(i)._genericType(), targetGenericsContext, observer);
                            registerMul(firstParams.get(i)._multiplicity(), secondParams.get(i)._multiplicity(), targetGenericsContext, observer);
                        }
                        register(firstFuncType._returnType(), secondFuncType._returnType(), targetGenericsContext, observer);
                        registerMul(firstFuncType._returnMultiplicity(), secondFuncType._returnMultiplicity(), targetGenericsContext, observer);
                        observer.unShiftTab();
                    } else {
                        register(first, second, targetGenericsContext, observer);
                    }
                }
            }
        }
    }
}
Also used : GenericType(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.generics.GenericType) FunctionType(org.finos.legend.pure.m3.navigation.function.FunctionType) CoreInstance(org.finos.legend.pure.m4.coreinstance.CoreInstance) Iterator(java.util.Iterator)

Example 3 with VariableExpression

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

the class AssociationProcessor method getPropertyNameForLeftSideOfQualifiedPropertyFilter.

private static String getPropertyNameForLeftSideOfQualifiedPropertyFilter(Association association, QualifiedProperty qualifiedProperty, ValueSpecification instance, Context context, ProcessorSupport processorSupport) {
    String functionName = instance instanceof FunctionExpression ? ((FunctionExpression) instance)._functionName() : null;
    String propertyNameForLeftSideOfQualifiedPropertyFilter;
    if ("filter".equals(functionName)) {
        ValueSpecification leftSideOfFilter = ((FunctionExpression) instance)._parametersValues().toList().getFirst();
        CoreInstance propertyName = leftSideOfFilter instanceof FunctionExpression ? ((FunctionExpression) leftSideOfFilter)._propertyName()._valuesCoreInstance().toList().getFirst() : null;
        ValueSpecification variableExpression = leftSideOfFilter instanceof FunctionExpression ? ((FunctionExpression) leftSideOfFilter)._parametersValues().toList().getFirst() : null;
        String variableExpressionName = variableExpression instanceof VariableExpression ? ((VariableExpression) variableExpression)._name() : null;
        if (!"this".equals(variableExpressionName)) {
            throw new PureCompilationException(instance.getSourceInformation(), validQualifiedPropertyInAssociationMsg() + qualifiedPropertyCompileErrorMsgPrefix(association, qualifiedProperty) + " left side of filter should refer to '$this' not '" + variableExpressionName + "'");
        }
        propertyNameForLeftSideOfQualifiedPropertyFilter = Objects.requireNonNull(propertyName).getName();
    } else {
        ValueSpecification firstParamValue = instance instanceof FunctionExpression ? ((FunctionExpression) instance)._parametersValues().toList().getFirst() : null;
        if (firstParamValue != null) {
            propertyNameForLeftSideOfQualifiedPropertyFilter = getPropertyNameForLeftSideOfQualifiedPropertyFilter(association, qualifiedProperty, firstParamValue, context, processorSupport);
        } else {
            throw new PureCompilationException(qualifiedProperty.getSourceInformation(), validQualifiedPropertyInAssociationMsg() + qualifiedPropertyCompileErrorMsgPrefix(association, qualifiedProperty) + " does not use the 'filter' function");
        }
    }
    return propertyNameForLeftSideOfQualifiedPropertyFilter;
}
Also used : FunctionExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.FunctionExpression) ValueSpecification(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecification) CoreInstance(org.finos.legend.pure.m4.coreinstance.CoreInstance) VariableExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.VariableExpression) PureCompilationException(org.finos.legend.pure.m4.exception.PureCompilationException)

Example 4 with VariableExpression

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

the class AssociationProcessor method updateClassifierGenericTypeForQualifiedPropertiesThisVarExprParams.

private static void updateClassifierGenericTypeForQualifiedPropertiesThisVarExprParams(Association association, QualifiedProperty qualifiedProperty, final Class qualifiedPropertyReturnType, ListIterable<? extends Property> assnProperties, final Context context, final ProcessorSupport processorSupport) {
    validateQualifiedPropertyLeftSideOfFilterByPropertyName(association, qualifiedProperty, qualifiedPropertyReturnType, assnProperties, context, processorSupport);
    Property leftSideOfFilterProperty = getQualifiedPropertiesFilterLeftSideParam(qualifiedPropertyReturnType, assnProperties, processorSupport);
    Property leftSideOfFilterOtherProperty = assnProperties.detect(Predicates.notEqual(leftSideOfFilterProperty));
    GenericType leftSideOfFilterOtherPropertyGenericType = leftSideOfFilterOtherProperty._genericType();
    FunctionType functionType = (FunctionType) qualifiedProperty._classifierGenericType()._typeArguments().toList().getFirst()._rawTypeCoreInstance();
    Iterable<? extends VariableExpression> functionTypeParams = functionType._parameters();
    for (VariableExpression functionTypeParam : functionTypeParams) {
        if (functionTypeParam != null && "this".equals(functionTypeParam._name())) {
            GenericType genericTypeCopy = (GenericType) org.finos.legend.pure.m3.navigation.generictype.GenericType.copyGenericType(leftSideOfFilterOtherPropertyGenericType, processorSupport);
            functionTypeParam._genericType(genericTypeCopy);
            context.update(functionTypeParam);
            if (functionTypeParam.hasBeenValidated()) {
                functionTypeParam.markNotValidated();
                context.update(functionTypeParam);
            }
        }
    }
}
Also used : 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) AbstractProperty(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.property.AbstractProperty) QualifiedProperty(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.property.QualifiedProperty) Property(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.property.Property)

Example 5 with VariableExpression

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

the class VariableContext method buildAndRegister.

public void buildAndRegister(String name, GenericType genericType, Multiplicity multiplicity, ProcessorSupport processorSupport) {
    VariableExpression variableExpression = (VariableExpression) processorSupport.newEphemeralAnonymousCoreInstance(M3Paths.VariableExpression);
    variableExpression._name(name);
    variableExpression._genericType(genericType);
    variableExpression._multiplicity(multiplicity);
    try {
        registerValue(name, variableExpression);
    } catch (VariableContext.VariableNameConflictException e) {
        throw new PureCompilationException(null, e.getMessage(), e);
    }
}
Also used : VariableExpression(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.VariableExpression) PureCompilationException(org.finos.legend.pure.m4.exception.PureCompilationException)

Aggregations

VariableExpression (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.VariableExpression)53 GenericType (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.generics.GenericType)40 FunctionType (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.FunctionType)39 ValueSpecification (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecification)28 CoreInstance (org.finos.legend.pure.m4.coreinstance.CoreInstance)19 InstanceValue (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.InstanceValue)17 LambdaFunction (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.LambdaFunction)15 Multiplicity (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.multiplicity.Multiplicity)15 PureCompilationException (org.finos.legend.pure.m4.exception.PureCompilationException)15 Type (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Type)13 QualifiedProperty (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.property.QualifiedProperty)12 SourceInformation (org.finos.legend.pure.m4.coreinstance.SourceInformation)12 RichIterable (org.eclipse.collections.api.RichIterable)11 SimpleFunctionExpression (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.SimpleFunctionExpression)9 MutableList (org.eclipse.collections.api.list.MutableList)8 AbstractProperty (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.property.AbstractProperty)8 ListIterable (org.eclipse.collections.api.list.ListIterable)7 Pair (org.eclipse.collections.api.tuple.Pair)7 Root_meta_pure_metamodel_valuespecification_VariableExpression_Impl (org.finos.legend.pure.generated.Root_meta_pure_metamodel_valuespecification_VariableExpression_Impl)7 Property (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.property.Property)7