use of org.finos.legend.pure.m3.navigation.Instance in project legend-pure by finos.
the class TypeInference method potentiallyUpdateParentTypeParamForInstanceValueWithManyElements.
public static void potentiallyUpdateParentTypeParamForInstanceValueWithManyElements(InstanceValue instance, TypeInferenceContext typeInferenceContext, ProcessorState state, ProcessorSupport processorSupport) {
MutableList<TypeInferenceContextState> set = typeInferenceContext.drop(instance._values().size());
if (typeInferenceContext.getParent() != null) {
TypeInferenceContextState nonInstanceSpecificState = set.get(0);
RichIterable<TypeInferenceContextState> instanceStates = ListHelper.tail(set);
// Accumulate changes so as not to modify during iteration
MutableMap<GenericType, GenericType> toRegisterTypes = Maps.mutable.empty();
for (String typeParam : nonInstanceSpecificState.getTypeParameters()) {
CoreInstance possibleParentTypeParam = nonInstanceSpecificState.getTypeParameterValue(typeParam);
if (!org.finos.legend.pure.m3.navigation.generictype.GenericType.isGenericTypeConcrete(possibleParentTypeParam)) {
MutableList<CoreInstance> allGenericTypes = Lists.mutable.empty();
for (TypeInferenceContextState v : instanceStates) {
allGenericTypes.add(v.getTypeParameterValue(typeParam));
}
CoreInstance res = org.finos.legend.pure.m3.navigation.generictype.GenericType.findBestCommonGenericType(allGenericTypes, org.finos.legend.pure.m3.navigation.typeparameter.TypeParameter.isCovariant(possibleParentTypeParam), false, processorSupport);
toRegisterTypes.put((GenericType) possibleParentTypeParam, (GenericType) res);
}
}
// Accumulate changes so as not to modify during iteration
MutableMap<Multiplicity, Multiplicity> toRegisterMultiplicities = Maps.mutable.empty();
for (String multiplicityParam : nonInstanceSpecificState.getMultiplicityParameters()) {
CoreInstance possibleParentMultiplicityTypeParam = nonInstanceSpecificState.getMultiplicityParameterValue(multiplicityParam);
if (!org.finos.legend.pure.m3.navigation.multiplicity.Multiplicity.isMultiplicityConcrete(possibleParentMultiplicityTypeParam) && !instanceStates.isEmpty()) {
CoreInstance res = instanceStates.getFirst().getMultiplicityParameterValue(multiplicityParam);
for (TypeInferenceContextState v : instanceStates) {
res = org.finos.legend.pure.m3.navigation.multiplicity.Multiplicity.minSubsumingMultiplicity(res, v.getMultiplicityParameterValue(multiplicityParam), processorSupport);
}
toRegisterMultiplicities.put((Multiplicity) possibleParentMultiplicityTypeParam, (Multiplicity) res);
}
}
toRegisterTypes.forEachKeyValue((from, to) -> typeInferenceContext.getParent().register(from, to, typeInferenceContext.getParent(), state.getObserver()));
toRegisterMultiplicities.forEachKeyValue((from, to) -> typeInferenceContext.getParent().registerMul(from, to, typeInferenceContext.getParent(), state.getObserver()));
}
}
use of org.finos.legend.pure.m3.navigation.Instance 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;
}
use of org.finos.legend.pure.m3.navigation.Instance in project legend-pure by finos.
the class GenericTypeTraceability method addTraceForNewPropertyRouteNodeFunctionDefinition.
public static void addTraceForNewPropertyRouteNodeFunctionDefinition(NewPropertyRouteNodeFunctionDefinition<?, ?> instance, ModelRepository repository, ProcessorSupport processorSupport) {
GenericType classifierGenericType = instance._classifierGenericType();
addTraceForAllPossibleTypeArguments(instance, M3Properties.classifierGenericType, 0, classifierGenericType, repository, processorSupport);
}
use of org.finos.legend.pure.m3.navigation.Instance in project legend-pure by finos.
the class M3ToJavaGenerator method createWrapperClass.
private String createWrapperClass(final CoreInstance instance, String javaPackage, MutableSet<CoreInstance> properties, MutableSet<CoreInstance> propertiesFromAssociations, MutableSet<CoreInstance> qualifiedProperties, Imports imports, MutableMap<String, CoreInstance> propertyOwners) {
imports.addImports(Lists.mutable.of("org.finos.legend.pure.m4.coreinstance.simple.ValueHolder", "org.finos.legend.pure.m3.coreinstance.helper.PrimitiveHelper"));
final String interfaceName = getInterfaceName(instance);
String wrapperName = getWrapperName(instance);
String typeParamsWithExtendsCoreInstance = getTypeParams(instance, true);
final CoreInstance classGenericType = getClassGenericType(instance);
imports.setThisClassName(wrapperName);
PartitionIterable<CoreInstance> partition = properties.partition(M3ToJavaGenerator::isToOne);
RichIterable<CoreInstance> toOneProperties = partition.getSelected();
RichIterable<CoreInstance> toManyProperties = partition.getRejected();
RichIterable<CoreInstance> mandatoryToOneProps = toOneProperties.select(M3ToJavaGenerator::isMandatoryProperty);
RichIterable<Pair<String, String>> typesForMandatoryProps = buildMandatoryProperties(classGenericType, mandatoryToOneProps, imports).toSortedSetBy(Pair::getOne);
MutableList<String> mandatoryTypes = Lists.mutable.of();
MutableList<String> mandatoryProps = Lists.mutable.of();
for (Pair<String, String> pair : typesForMandatoryProps) {
mandatoryTypes.add(pair.getTwo() + " " + pair.getOne());
mandatoryProps.add(pair.getOne());
}
final String maybeFullyQualifiedInterfaceName = (imports.shouldFullyQualify(javaPackage + "." + interfaceName) ? javaPackage + "." + interfaceName : interfaceName);
String maybeFullyQualifiedInterfaceNameWithTypeParams = maybeFullyQualifiedInterfaceName + typeParamsWithExtendsCoreInstance;
String systemPathForPackageableElement = getUserObjectPathForPackageableElement(instance, true).makeString("::");
String value = "\n" + "package " + javaPackage + ";\n" + "\n" + "import org.eclipse.collections.api.RichIterable;\n" + "import org.eclipse.collections.api.block.predicate.Predicate;\n" + "import org.eclipse.collections.api.list.ListIterable;\n" + "import org.eclipse.collections.api.list.MutableList;\n" + "import org.eclipse.collections.api.set.SetIterable;\n" + "import org.eclipse.collections.impl.factory.Lists;\n" + "import org.eclipse.collections.impl.factory.Sets;\n" + "import org.finos.legend.pure.m3.coreinstance.BaseCoreInstance;\n" + "import org.finos.legend.pure.m4.coreinstance.AbstractCoreInstanceWrapper;\n" + "import org.finos.legend.pure.m3.coreinstance.BaseM3CoreInstanceFactory;\n" + "import org.finos.legend.pure.m4.coreinstance.AbstractCoreInstance;\n" + imports.toImportString() + "\n" + getPrimitiveImports() + "\n" + "import org.finos.legend.pure.m4.coreinstance.CoreInstance;\n" + "\n" + "public class " + wrapperName + " extends AbstractCoreInstanceWrapper implements " + maybeFullyQualifiedInterfaceNameWithTypeParams + "\n" + "{\n" + " public static final CoreInstanceFunction FROM_CORE_INSTANCE_FN = new CoreInstanceFunction();\n" + " public " + wrapperName + "(CoreInstance instance)\n" + " {\n" + " super(instance);\n" + " }\n" + "\n" + toOneProperties.collect(property -> {
CoreInstance propertyReturnGenericType = this.propertyTypeResolver.getPropertyReturnType(classGenericType, property);
return createWrapperPropertyGetterToOne(interfaceName, property, propertyReturnGenericType, imports);
}).makeString("") + toManyProperties.collect(property -> {
CoreInstance propertyReturnGenericType = this.propertyTypeResolver.getPropertyReturnType(classGenericType, property);
return createWrapperPropertyGetterToMany(interfaceName, property, propertyReturnGenericType, imports);
}).makeString("") + "\n" + toOneProperties.collect(property -> {
CoreInstance propertyReturnGenericType = this.propertyTypeResolver.getPropertyReturnType(classGenericType, property);
String sub = getSubstituteType(property, propertyReturnGenericType);
return sub == null ? "" : " public " + maybeFullyQualifiedInterfaceName + " " + getUnifiedMethodName(property) + "(" + sub + " value)\n" + " {\n" + " instance.setKeyValues(" + createPropertyKeyNameReference(property.getName(), propertyOwners.get(property.getName()), instance) + ", Lists.immutable.<CoreInstance>with((CoreInstance)value));\n" + " return this;\n" + " }\n" + "\n";
}).makeString("") + properties.collect(property -> {
CoreInstance propertyReturnGenericType = this.propertyTypeResolver.getPropertyReturnType(classGenericType, property);
return createWrapperPropertySetter(property, propertyReturnGenericType, imports, maybeFullyQualifiedInterfaceName, propertyOwners, instance);
}).makeString("") + propertiesFromAssociations.collect(property -> {
CoreInstance propertyReturnGenericType = this.propertyTypeResolver.getPropertyReturnType(classGenericType, property);
return createPropertyReverse(property, propertyReturnGenericType, imports, false, true) + createPropertyReverse(property, propertyReturnGenericType, imports, true, true);
}).makeString("") + qualifiedProperties.collect(property -> {
CoreInstance propertyReturnGenericType = this.propertyTypeResolver.getPropertyReturnType(classGenericType, property);
return createWrapperQualifiedPropertyGetter(property, propertyReturnGenericType, imports);
}).makeString("") + "\n" + " public static " + maybeFullyQualifiedInterfaceName + " to" + interfaceName + "(CoreInstance instance)\n" + " {\n" + " if (instance == null) { return null; }\n" + " return " + maybeFullyQualifiedInterfaceName + ".class.isInstance(instance) ? (" + maybeFullyQualifiedInterfaceName + ") instance : new " + wrapperName + "(instance);\n" + " }\n" + createWrapperStaticConversionFunction(interfaceName, wrapperName, maybeFullyQualifiedInterfaceNameWithTypeParams, getTypeParams(instance, false)) + createWrapperClassCopyMethod(instance, maybeFullyQualifiedInterfaceName) + createClassPackageableElement(systemPathForPackageableElement) + "}\n";
return value;
}
use of org.finos.legend.pure.m3.navigation.Instance in project legend-pure by finos.
the class AbstractTestFromJson method testFromJsonThrowsValidationErrors_ConstraintOnProperty.
@Test
public void testFromJsonThrowsValidationErrors_ConstraintOnProperty() {
try {
String[] source = { "import meta::json::*;", "Class meta::pure::functions::json::tests::A", "[ TEST_CONTROL: $this.a == 'dave' ]", "{ a:String[1]; }", "Class meta::pure::functions::json::tests::B", "{ b:meta::pure::functions::json::tests::A[1]; }", "function go():Any[*]", "{ let json='{ \"b\": {\"a\": \"fred\" } }'->meta::json::fromJson(meta::pure::functions::json::tests::B, ^meta::json::JSONDeserializationConfig(typeKeyName='@type', failOnUnknownProperties=false));", " assert(!$json->isEmpty(), |''); ", " assert(\'fred\' == $json.b.a, |''); ", "}" };
this.compileTestSource("fromString.pure", StringUtils.join(source, "\n") + "\n");
CoreInstance func = this.runtime.getFunction("go():Any[*]");
this.functionExecution.start(func, FastList.<CoreInstance>newList());
Assert.fail("Expected exception evaluating: \n" + source);
} catch (PureExecutionException e) {
this.assertException(e, "Error populating property 'b' on class 'meta::pure::functions::json::tests::B': \nCould not create new instance of meta::pure::functions::json::tests::A: \nConstraint :[TEST_CONTROL] violated in the Class A");
}
}
Aggregations