use of org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Type in project legend-pure by finos.
the class TypeInference method resolveTypeParameters.
private static void resolveTypeParameters(GenericType template, GenericType fromInstance, MutableMap<String, CoreInstance> rtypes, MutableMap<String, CoreInstance> rmultiplicities, MutableMap<String, CoreInstance> types, MutableMap<String, CoreInstance> multiplicities, ProcessorSupport processorSupport) {
GenericType g = (GenericType) org.finos.legend.pure.m3.navigation.generictype.GenericType.makeTypeArgumentAsConcreteAsPossible(org.finos.legend.pure.m3.navigation.generictype.GenericType.copyGenericType(fromInstance, false, processorSupport), types, multiplicities, processorSupport);
Type rawType = template._rawType();
if (rawType != null) {
if (org.finos.legend.pure.m3.navigation.type.Type.subTypeOf(rawType, processorSupport.package_getByUserPath(M3Paths.Function), processorSupport)) {
if (template._typeArguments().notEmpty() && g._typeArguments().notEmpty()) {
CoreInstance fTypR = template._typeArguments().getFirst()._rawType();
CoreInstance sTypeR = g._typeArguments().getFirst()._rawType();
if (fTypR instanceof FunctionType && sTypeR instanceof FunctionType) {
FunctionType fType = (FunctionType) fTypR;
FunctionType sType = (FunctionType) sTypeR;
resolveTypeParameters(fType._returnType(), sType._returnType(), rtypes, rmultiplicities, types, multiplicities, processorSupport);
resolveMultiplicityParameters(fType._returnMultiplicity(), sType._returnMultiplicity(), rmultiplicities, multiplicities);
fType._parameters().zip(sType._parameters()).forEach(pair -> {
resolveTypeParameters(pair.getOne()._genericType(), pair.getTwo()._genericType(), rtypes, rmultiplicities, types, multiplicities, processorSupport);
resolveMultiplicityParameters(pair.getOne()._multiplicity(), pair.getTwo()._multiplicity(), rmultiplicities, multiplicities);
});
}
}
}
} else {
rtypes.put(template._typeParameter()._name(), g);
}
template._typeArguments().zip(g._typeArguments()).forEach(pair -> resolveTypeParameters(pair.getOne(), pair.getTwo(), rtypes, rmultiplicities, types, multiplicities, processorSupport));
template._multiplicityArguments().zip(g._multiplicityArguments()).forEach(pair -> resolveMultiplicityParameters(pair.getOne(), pair.getTwo(), rmultiplicities, multiplicities));
}
use of org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Type 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;
}
use of org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Type in project legend-pure by finos.
the class TypeInference method storeInferredTypeParametersInFunctionExpression.
public static void storeInferredTypeParametersInFunctionExpression(FunctionExpression functionExpression, ProcessorState state, ProcessorSupport processorSupport, Function<?> foundFunction) throws PureCompilationException {
// Store the inferred params in the FunctionExpression
if (!(foundFunction instanceof QualifiedProperty)) {
TypeInferenceContext typeInferenceContext = state.getTypeInferenceContext();
FunctionType functionType = (FunctionType) processorSupport.function_getFunctionType(foundFunction);
functionType._typeParameters().forEach(typeParameter -> {
CoreInstance value = typeInferenceContext.getTypeParameterValue(typeParameter._name());
if (value != null) {
functionExpression._resolvedTypeParametersAdd((GenericType) value);
} else if (typeInferenceContext.getParent() == null) {
StringBuilder builder = new StringBuilder("The type parameter ").append(typeParameter._name()).append(" was not resolved (").append(foundFunction._functionName()).append(" / ");
org.finos.legend.pure.m3.navigation.function.FunctionType.print(builder, functionType, processorSupport).append(")!");
throw new PureCompilationException(functionExpression.getSourceInformation(), builder.toString());
}
});
functionType._multiplicityParameters().forEach(multiplicityParameter -> {
String parameterName = multiplicityParameter._valuesCoreInstance().getFirst().getName();
CoreInstance value = typeInferenceContext.getMultiplicityParameterValue(parameterName);
if (value != null) {
functionExpression._resolvedMultiplicityParametersAdd((Multiplicity) value);
} else {
throw new PureCompilationException(functionExpression.getSourceInformation(), "The multiplicity parameter " + parameterName + " was not resolved!");
}
});
}
}
use of org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Type 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);
}
}
}
}
}
}
use of org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Type in project legend-pure by finos.
the class AbstractTestFromJson method multiplicityIsInRange_Association.
@Test
public void multiplicityIsInRange_Association() {
String[] rawAssociationSource = { "import meta::json::*;", "import meta::pure::functions::json::tests::*;", "Association meta::pure::functions::json::tests::Employment", "{", "employer : Firm[1];", "employees : Person[7];", "}", "Class meta::pure::functions::json::tests::Person {}", "Class meta::pure::functions::json::tests::Firm {}", "function Association():Any[*]", "{", // this json describes a Firm with one employee, but the association states all Firms must have exactly 7 employees.
"let json = '{\"employees\":[{\"employer\":{\"employees\":[{}]}}]}';", "$json -> fromJson(Firm, ^meta::json::JSONDeserializationConfig(typeKeyName='@type', failOnUnknownProperties=false));", "}" };
String associationSource = StringUtils.join(rawAssociationSource, "\n") + "\n";
try {
this.compileTestSource("fromString.pure", associationSource);
CoreInstance func = this.runtime.getFunction("Association():Any[*]");
this.functionExecution.start(func, FastList.<CoreInstance>newList());
Assert.fail("Expected exception evaluating: \n" + associationSource);
} catch (PureExecutionException e) {
this.assertException(e, "Error populating property 'employees' on class 'meta::pure::functions::json::tests::Firm': \nExpected value(s) of multiplicity [7], found 1 value(s).");
}
}
Aggregations