diff --git a/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/store/m2m/tests/legend/functionInMapping.pure b/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/store/m2m/tests/legend/functionInMapping.pure index ae9708750e..17a33ecaeb 100644 --- a/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/store/m2m/tests/legend/functionInMapping.pure +++ b/legend-engine-core/legend-engine-core-pure/legend-engine-pure-code-compiled-core/src/main/resources/core/store/m2m/tests/legend/functionInMapping.pure @@ -108,6 +108,18 @@ meta::pure::mapping::modelToModel::test::alloy::simple::testMatchInMapping(): Bo assert(meta::json::jsonEquivalent($expected->meta::json::parseJSON(), $json->meta::json::parseJSON())); } +function <> +{ serverVersion.start='v1_29_0'} +meta::pure::mapping::modelToModel::test::alloy::simple::testNewOperatorInMapping(): Boolean[1] +{ + let runtime = testJsonRuntime(Firm, '[{"employees":[{"@type":"PersonA","role":"developer","firstNameA":"Smith","firstName":"testFirstName","lastName":"testLastName"}]}]'); + let lambda = {|CountPersonBMiddleNames.all()->meta::pure::graphFetch::execution::graphFetch(#{meta::pure::mapping::modelToModel::test::alloy::simple::function::CountPersonBMiddleNames{count}}#)->meta::pure::graphFetch::execution::serialize(#{meta::pure::mapping::modelToModel::test::alloy::simple::function::CountPersonBMiddleNames{count}}#)}; + let result = execute($lambda, meta::pure::mapping::modelToModel::test::alloy::simple::function::newOperatorMappingTest, $runtime, meta::pure::extension::defaultExtensions()); + let json = $result.values->toOne(); + let expected = '{"count":0}'; + assert(meta::json::jsonEquivalent($expected->meta::json::parseJSON(), $json->meta::json::parseJSON())); +} + Class meta::pure::mapping::modelToModel::test::alloy::simple::function::Firm { name: String[0..1]; @@ -149,6 +161,12 @@ Enum meta::pure::mapping::modelToModel::test::alloy::simple::function::EmployeeR projectManager } +Class meta::pure::mapping::modelToModel::test::alloy::simple::function::CountPersonBMiddleNames +{ + count: Integer[1]; +} + + ###Mapping Mapping meta::pure::mapping::modelToModel::test::alloy::simple::function::m1 @@ -198,4 +216,15 @@ Mapping meta::pure::mapping::modelToModel::test::alloy::simple::function::defaul ) ) } - ) \ No newline at end of file + ) + +###Mapping + + Mapping meta::pure::mapping::modelToModel::test::alloy::simple::function::newOperatorMappingTest + ( + meta::pure::mapping::modelToModel::test::alloy::simple::function::CountPersonBMiddleNames: Pure + { + ~src meta::pure::mapping::modelToModel::test::alloy::simple::function::Firm + count: ^meta::pure::mapping::modelToModel::test::alloy::simple::function::PersonB(firstNameB='VijayB',firstName='Vijay',lastName='Lather').middleNames->size() + } + ) diff --git a/legend-engine-xts-java/legend-engine-xt-javaGeneration-pure/src/main/resources/core_external_language_java/generation/conventions.pure b/legend-engine-xts-java/legend-engine-xt-javaGeneration-pure/src/main/resources/core_external_language_java/generation/conventions.pure index 7b9d488d69..11787535c2 100644 --- a/legend-engine-xts-java/legend-engine-xt-javaGeneration-pure/src/main/resources/core_external_language_java/generation/conventions.pure +++ b/legend-engine-xts-java/legend-engine-xt-javaGeneration-pure/src/main/resources/core_external_language_java/generation/conventions.pure @@ -1292,12 +1292,17 @@ function meta::external::language::java::transform::defaultProhibitedFunctions(e function <> meta::external::language::java::transform::listIfMulti(base: meta::external::language::java::metamodel::Type[1], mult:Multiplicity[1]): meta::external::language::java::metamodel::Type[1] { - if(!$mult->hasUpperBound() || ($mult->getUpperBound() > 1 || $mult->getUpperBound() == -1), + if($mult->isListMultiplicity(), | javaList($base), | $base ); } +function meta::external::language::java::transform::isListMultiplicity(mult:Multiplicity[1]): Boolean[1] +{ + !$mult->hasUpperBound() || ($mult->getUpperBound() > 1 || $mult->getUpperBound() == -1) +} + function meta::external::language::java::transform::typeConversion(conventions:Conventions[1], type:meta::pure::metamodel::type::Type[1]): TypeConversion[1] { $conventions.libraries->map(l|$l.typeConversions->get($type))->at(0); diff --git a/legend-engine-xts-java/legend-engine-xt-javaPlatformBinding-pure/src/main/resources/core_java_platform_binding/legendJavaPlatformBinding/planConventions/langLibrary.pure b/legend-engine-xts-java/legend-engine-xt-javaPlatformBinding-pure/src/main/resources/core_java_platform_binding/legendJavaPlatformBinding/planConventions/langLibrary.pure index 1c09e014b9..3966374b76 100644 --- a/legend-engine-xts-java/legend-engine-xt-javaPlatformBinding-pure/src/main/resources/core_java_platform_binding/legendJavaPlatformBinding/planConventions/langLibrary.pure +++ b/legend-engine-xts-java/legend-engine-xt-javaPlatformBinding-pure/src/main/resources/core_java_platform_binding/legendJavaPlatformBinding/planConventions/langLibrary.pure @@ -147,10 +147,12 @@ function meta::pure::executionPlan::platformBinding::legendJava::library::lang:: print(if($debug.debug,|$debug.space+'processNew: \n',|'')); let args = $fe.parametersValues->evaluateAndDeactivate(); + let cls = $args->at(0).genericType.typeArguments.rawType->cast(@meta::pure::metamodel::type::Class)->toOne(); assert($conventions.newFunctionProhibitedList->filter(c|$c == $cls)->size()==0, 'Cannot create new instance for class used in mapping: ' + $cls->elementToPath()); let kv = $args->at(2)->cast(@InstanceValue).values->cast(@KeyExpression); + let processedKV = $kv->map(k|let s = $k.key.values->toOne(); let e = $k.expression->generateJava($conventions, $debug); pair($s,$e);); @@ -158,9 +160,9 @@ function meta::pure::executionPlan::platformBinding::legendJava::library::lang:: let typeInfo = meta::pure::executionPlan::platformBinding::typeInfo::newTypeInfoSet()->enrichTypeInfos($cls, []); let props = $typeInfo->meta::pure::executionPlan::platformBinding::typeInfo::allProperties($cls); - + let proto = $conventions->implClassName($cls)->addModifiers(['public']); - + let name = 'new_' + $cls->elementToPath(); let dep = newDependency( $name, @@ -205,17 +207,25 @@ function meta::pure::executionPlan::platformBinding::legendJava::library::lang:: let project = mergeProjects(newProject()->addClass($interface)->concatenate($implementationProject)->concatenate($nestedDeps)->toOneMany()); $state->addDependencyProject($name, $project);}); - let processed_args = $processedKV->map(arg | let prop = $props->filter(p| $p.name == $arg.first)->toOne(); - let propType = $conventions->pureTypeToJavaType($prop); - let value = $arg.second->castExpressionToReturnType($propType); - pair($prop, $value);); - - let invoke = $processed_args - ->fold({p,code |let arg= $p.second; let prop = $p.first; - $code->j_invoke([], $conventions->setterName($prop), $arg, $proto); - }, j_new($proto, [])); - - $invoke->dependsOn($dep); + let processed_args = $processedKV->map(arg | let prop = $props->filter(p| $p.name == $arg.first)->toOne(); + let propType = $conventions->pureTypeToJavaType($prop); + let value = $arg.second->castExpressionToReturnType($propType); + pair($prop, $value);); + + let invoke = $processed_args + ->fold({p,code |let arg= $p.second; let prop = $p.first; + $code->j_invoke([], $conventions->setterName($prop), $arg, $proto); + }, j_new($proto, [])); + + let setProperties = $processedKV->map(k| $k.first); + let unsetListProperties = $props->filter(p| !$p.name->in($setProperties) && $p.multiplicity->isListMultiplicity()); + + let newInvoke = $unsetListProperties->fold({prop, code | + let javaType = $conventions->pureTypeToJavaType($prop); + $code->j_invoke([], $conventions->setterName($prop), j_emptyList($javaType), $proto); + }, $invoke); + + $newInvoke->dependsOn($dep); } function meta::pure::executionPlan::platformBinding::legendJava::library::lang::enrichTypeInfos(infos:meta::pure::executionPlan::platformBinding::typeInfo::TypeInfoSet[1], for:meta::pure::metamodel::type::Class[1], seen:meta::pure::metamodel::type::Class[*]): meta::pure::executionPlan::platformBinding::typeInfo::TypeInfoSet[1]