Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
core.pure.serialization.toPureGrammar.pure Maven / Gradle / Ivy
// Copyright 2020 Goldman Sachs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import meta::pure::store::*;
import meta::core::runtime::*;
import meta::pure::metamodel::relation::*;
import meta::pure::mapping::*;
import meta::pure::metamodel::serialization::grammar::*;
Class meta::pure::metamodel::serialization::grammar::Configuration
{
fullPath : Boolean[1];
extensions : meta::pure::metamodel::serialization::grammar::GrammarExtension[*];
}
Class meta::pure::metamodel::serialization::grammar::GrammarExtension
{
extraConnectionHandlers : Function<{Nil[0..1]->String[1]}>[*];
extraInstanceValueHandlers : Function<{Nil[0..1]->String[1]}>[*];
}
function meta::pure::metamodel::serialization::grammar::printValueSpecification(v:Any[1], space:String[1]):String[1]
{
printValueSpecification($v, [], $space);
}
function meta::pure::metamodel::serialization::grammar::printFunctionDefinition(functionDefinition:FunctionDefinition[1], space:String[1]):String[1]
{
printFunctionDefinition($functionDefinition, [], $space);
}
function meta::pure::metamodel::serialization::grammar::printFunctionExpression(functionExpression:FunctionExpression[1], space:String[1]):String[1]
{
printFunctionExpression($functionExpression, [], $space);
}
function meta::pure::metamodel::serialization::grammar::printFunctionDefinitionExpressions(functionDefinition:FunctionDefinition[1], space:String[1]):String[*]
{
printFunctionDefinitionExpressions($functionDefinition, [], $space);
}
function meta::pure::metamodel::serialization::grammar::printFunctionDefinitionExpressions(functionDefinition:FunctionDefinition[1], configuration:Configuration[0..1], space:String[1]):String[*]
{
$functionDefinition.expressionSequence->evaluateAndDeactivate()->map(vs|printValueSpecification($vs, $configuration, $space+' '));
}
function meta::pure::metamodel::serialization::grammar::printLambdaParameters(func:Function[1]):String[1]
{
let funcType = $func->genericType().typeArguments->at(0).rawType->toOne()->cast(@FunctionType);
$funcType.parameters->evaluateAndDeactivate()->map(v | $v.name)->joinStrings(', ');
}
function meta::pure::metamodel::serialization::grammar::printFunctionDefinition(functionDefinition:FunctionDefinition[1], configuration:Configuration[0..1], space:String[1]):String[1]
{
let expressions = printFunctionDefinitionExpressions($functionDefinition, $configuration, $space);
$functionDefinition->match([
lambda:LambdaFunction[1] | let functionParameters = '{'+printLambdaParameters($lambda)+'|';
let multipleLineIndent = repeat(' ', $functionParameters->length())->joinStrings('');
$functionParameters+($expressions->joinStrings(';\n'+$multipleLineIndent))+'}';,
other:FunctionDefinition[1] | $other->printFunctionSignature()+'\n'+
$space+'{\n'+
$expressions->joinStrings($space+' ', ';\n'+$space, ';\n')+
$space+'}';
]);
}
function meta::pure::metamodel::serialization::grammar::printValueSpecification(v:Any[1], configuration:Configuration[0..1], space:String[1]):String[1]
{
$v->match( [ f:FunctionExpression[1] |$f->meta::pure::functions::meta::removeAutomap()->cast(@FunctionExpression)->printPropertyOrFunctionExpression($configuration, $space),
i:InstanceValue[1] | printInstanceValue($i, $configuration, $space),
v:VariableExpression[1] | '$' + $v.name,
x:Enum[1] | $x->type()->elementToPath()+'.'+$x.name,
i:Integer[1] | $i->toRepresentation(),
d:Decimal[1] | $d->toRepresentation(),
f:Float[1] | $f->toRepresentation(),
a:Any[1] | 'UNKNOWN: ' + $a->type()->toOne()->id()
]
);
}
function <> meta::pure::metamodel::serialization::grammar::printConnection(c:Connection[0..1], configuration:Configuration[0..1]):String[1]
{
$c->match(
$configuration.extensions.extraConnectionHandlers->concatenate(
[
a:Any[1]|'UNKNOWN:'+$a->type().name->toOne()
]
)->toOneMany()
);
}
function meta::pure::metamodel::serialization::grammar::printInstanceValue(i:InstanceValue[1], configuration:Configuration[0..1], space:String[1]):String[1]
{
if ($i.multiplicity == PureOne && $i.values->isEmpty(),
|'@'+$i.genericType->printGenericType(),
|$i.values->map(v|$v->match(
$configuration.extensions.extraInstanceValueHandlers->concatenate([
f:FunctionDefinition[1] | $f->printFunctionDefinition($configuration, $space+' '),
f:FunctionExpression[1] | $f->printPropertyOrFunctionExpression($configuration, $space),
x:InstanceValue[1] | $x->printInstanceValue($configuration, $space),
z:KeyExpression[*] | $z->map(f|$f.key.values->toOne()->toString())->joinStrings(','),
r:Runtime[1]|'^meta::core::runtime::Runtime('+
'connectionStores='+$r.connectionStores->map(s|'^meta::core::runtime::ConnectionStore(connection='+$s.connection->printConnection($configuration)+', element='+$s.element->match([x:String[1]|$x,x:Store[1]|$x->elementToPath()])+')')->makeString(',')+
')',
s:RelationElementAccessor[1]|'RelationElementAccessor('+$s->genericType().rawType.name->toOne()+')',
a:Any[1] | $a->toRepresentation()
])->toOneMany()
)
)->match([
empty:String[0] |'[]';,
singular:String[1] |$singular;,
multiple:String[*] |$multiple->joinStrings('[', ', ', ']');
])
);
}
function <> meta::pure::metamodel::serialization::grammar::printPropertyOrFunctionExpression(functionExpression:FunctionExpression[1], configuration:Configuration[0..1], space:String[1]):String[1]
{
$functionExpression.func->match([
p:Property[1] | printProperty($p, $functionExpression.parametersValues->at(0), $configuration, $space),
q:QualifiedProperty[1]| printProperty($q, $functionExpression.parametersValues, $configuration, $space),
c:Column[1] | printColumn($c, $functionExpression.parametersValues->at(0), $configuration, $space),
a:Any[1] | printFunctionExpression($functionExpression, $configuration, $space)
])
}
function <> meta::pure::metamodel::serialization::grammar::special():Map[1]
{
[
pair('equal', '=='),
pair('lessThanEqual', '<='),
pair('lessThan', '<'),
pair('greaterThanEqual', '>='),
pair('greaterThan', '>'),
pair('plus', '+'),
pair('minus', '-'),
pair('times', '*'),
pair('divide', '/'),
pair('and', '&&'),
pair('or', '||')
]->newMap()
}
function <> meta::pure::metamodel::serialization::grammar::forceArrow():String[*]
{
'from'
}
function meta::pure::metamodel::serialization::grammar::printColSpec(functionExpression:FunctionExpression[1], configuration:Configuration[0..1], space:String[1]):String[1]
{
let isAgg = $functionExpression.parametersValues->size() > 3;
$functionExpression.parametersValues->at(if($isAgg,|2,|1))->cast(@InstanceValue).values->at(0)->toString()->printColName() +
':' + $functionExpression.parametersValues->at(0)->cast(@InstanceValue).values->at(0)->cast(@FunctionDefinition)->printFunctionDefinition($configuration, $space) +
if($isAgg,|':' + $functionExpression.parametersValues->at(1)->cast(@InstanceValue).values->at(0)->cast(@FunctionDefinition)->printFunctionDefinition($configuration, $space),|'');
}
function meta::pure::metamodel::serialization::grammar::printColName(name:String[1]):String[1]
{
if($name->contains(' '),|'\''+$name+'\'',|$name);
}
function meta::pure::metamodel::serialization::grammar::printFunctionExpression(functionExpression:FunctionExpression[1], configuration:Configuration[0..1], space:String[1]):String[1]
{
let name = if ($functionExpression.func.functionName->isEmpty(),|'UNKNOWN',|$functionExpression.func.functionName->toOne());
let special = special();
if (
[
pair(|$functionExpression.parametersValues->isEmpty(), | if($configuration->isNotEmpty() && $configuration->toOne().fullPath,|$functionExpression.func->cast(@PackageableElement).package->toOne()->elementToPath()+'::',|'')+$name->toOne()+'()'),
pair(|$name == 'getAll',|let genericType = $functionExpression.parametersValues->at(0)->cast(@InstanceValue).genericType;
let main = $genericType.rawType->toOne()->cast(@Class);
let val = if ($main == Class,
|$genericType.typeArguments->at(0).rawType->toOne()->cast(@Class),
|$main
);
$val->elementToPath() + '.all()';),
pair(|$name == 'letFunction',|'let '+$functionExpression.parametersValues->at(0)->cast(@InstanceValue).values->toOne()->toString()+ ' = ' +$functionExpression.parametersValues->at(0)->printValueSpecification($space)),
pair(|$name == 'colSpec', |'~'+$functionExpression.parametersValues->at(0)->cast(@InstanceValue).values->at(0)->toString()->printColName()),
pair(|$name == 'funcColSpec' || $name == 'funcColSpec2', | '~'+printColSpec($functionExpression, $configuration, $space)),
pair(|$name == 'aggColSpec' || $name == 'aggColSpec2', | '~'+printColSpec($functionExpression, $configuration, $space)),
pair(|$name == 'colSpecArray' || $name == 'colSpecArray2', | '~['+$functionExpression.parametersValues->at(0)->cast(@InstanceValue).values->map(z|$z->toString()->printColName())->joinStrings(',')+']'),
pair(|$name == 'aggColSpecArray' || $name == 'aggColSpecArray2', | '~['+$functionExpression.parametersValues->at(0)->cast(@InstanceValue).values->cast(@FunctionExpression)->map(z|printColSpec($z, $configuration, $space))->joinStrings(',')+']'),
pair(|$name == 'funcColSpecArray' || $name == 'funcColSpecArray2', | '~['+$functionExpression.parametersValues->at(0)->cast(@InstanceValue).values->cast(@FunctionExpression)->map(z|printColSpec($z, $configuration, $space))->joinStrings(',')+']'),
pair(|!$special->get($name)->isEmpty(),|let vals = if ($name->in(['plus', 'minus', 'times']),
|$functionExpression.parametersValues->match([
i:InstanceValue[1] | $i.values,
v:ValueSpecification[1] | $v
]),
|$functionExpression.parametersValues
);
if ([
pair(|$name == 'divide' && $vals->size() == 3, | $name + $functionExpression.parametersValues->map(vs | printValueSpecification($vs, $configuration, $space))->joinStrings('(', ', ', ')')),
pair(|$name == 'minus' && $vals->size() == 1, | $special->get($name)->toOne() + $functionExpression.parametersValues->at(0)->printValueSpecification($configuration, $space)),
pair(|$vals->size() == 1 && $vals->at(0)->instanceOf(VariableExpression), | $functionExpression.parametersValues->at(0)->printValueSpecification($configuration, $space)+'->'+$name+'()'),
pair(|$name->in(['and', 'or']) && $vals->size() == 1, |$name + '(' + $vals->at(0)->printValueSpecification($configuration, $space) + ')'),
pair(|$vals->size() > 1, |'(' + $vals->at(0)->printValueSpecification($configuration, $space) + ' ' + $vals->tail()->map(x| $special->get($name)->toOne() + ' ' + $x->printValueSpecification($configuration, $space))->joinStrings(' ') + ')')
],
|$special->get($name)->toOne()+'('+$vals->at(0)->printValueSpecification($configuration, $space)+')'
);
)
],
|let firstParam = $functionExpression.parametersValues->head()->toOne();
if(forceArrow()->contains($name) ||
!(
($firstParam->instanceOf(SimpleFunctionExpression) && $firstParam->cast(@SimpleFunctionExpression).functionName->isNotEmpty() && $special->get($firstParam->cast(@SimpleFunctionExpression).functionName->toOne())->isNotEmpty()) ||
($firstParam->instanceOf(FunctionExpression) && $firstParam->cast(@FunctionExpression).func.functionName->isNotEmpty() && $special->get($firstParam->cast(@FunctionExpression).func.functionName->toOne())->isNotEmpty())
) ,
| let element = $functionExpression.parametersValues->head()->toOne();
let t_element = $element->printValueSpecification($configuration, $space);
if ($element->instanceOf(FunctionExpression) && $element->cast(@FunctionExpression).func->in([minus_Integer_MANY__Integer_1_,plus_Integer_MANY__Integer_1_]),
|'('+$t_element+')',
| $t_element
) + '->' + if($functionExpression.func.functionName->isEmpty(),|'UNKNOWN',|if($configuration->isNotEmpty() && $configuration->toOne().fullPath, |$functionExpression.func->cast(@PackageableElement).package->toOne()->elementToPath()+'::',|'')+$functionExpression.func.functionName->toOne()) + $functionExpression.parametersValues->tail()->map(vs | printValueSpecification($vs, $configuration, $space))->joinStrings('(', ', ', ')');,
| if($configuration->isNotEmpty() && $configuration->toOne().fullPath, |$functionExpression.func->cast(@PackageableElement).package->toOne()->elementToPath()+'::',|'')+$functionExpression.func.functionName->toOne() + $functionExpression.parametersValues->map(vs | printValueSpecification($vs, $configuration, $space))->joinStrings('(', ', ', ')');
);
);
}
function meta::pure::metamodel::serialization::grammar::printProperty(p:Property[1], o:ValueSpecification[1], configuration:Configuration[0..1], space:String[1]):String[1]
{
$o->printValueSpecification($configuration, $space) + '.' + $p.name->toOne();
}
function meta::pure::metamodel::serialization::grammar::printColumn(c:Column[1], o:ValueSpecification[1], configuration:Configuration[0..1], space:String[1]):String[1]
{
$o->printValueSpecification($configuration, $space) + '.' + $c.name->toOne();
}
function meta::pure::metamodel::serialization::grammar::printProperty(p:QualifiedProperty[1], params:ValueSpecification[*], configuration:Configuration[0..1], space:String[1]):String[1]
{
$params->at(0)->printValueSpecification($configuration, $space) + '.' + $p.name->toOne() + '(%s)'->format($params->tail()->map(x | $x->printValueSpecification($configuration, $space))->joinStrings(', '));
}
function <> meta::pure::metamodel::serialization::grammar::printStatements(statements:String[*]):String[1]
{
$statements->match([
none: String[0] | '';,
many: String[1..*] | $statements->joinStrings('', ';\n', ';\n');
])
}
function meta::pure::metamodel::serialization::grammar::printEnumeration(enum:Enumeration[1]):String[1]
{
'Enum ' + printStereotypes($enum) + printTaggedValues($enum) + elementToPath($enum) + '\n' +
'{\n' +
$enum->enumValues()->map(p|printStereotypes($p->cast(@ElementWithStereotypes)) + printTaggedValues($p->cast(@ElementWithTaggedValues)) + ' ' + $p->id()) -> joinStrings('', ',\n', '\n') +
'}';
}
function meta::pure::metamodel::serialization::grammar::printAssociation(association:Association[1]):String[1]
{
'Association ' + printStereotypes($association) + printTaggedValues($association) + if($association.name->isEmpty(), |'', |' ' + elementToPath($association)) + '\n' +
'{\n' +
$association.properties->map(p:Property[1]| ' ' + $p.name->toOne() + ':' + printGenericType($p.genericType) + '[' + printMultiplicity($p.multiplicity) + ']') -> printStatements() +
'}';
}
function meta::pure::metamodel::serialization::grammar::printConstraint(constraint:meta::pure::metamodel::constraint::Constraint[1]):String[1]
{
assert($constraint.name->size() == 1, 'Constraints should have a name.');
assert($constraint.functionDefinition.expressionSequence->size() == 1, 'Constraints can only have a single expression.');
let expressions = printFunctionDefinitionExpressions($constraint.functionDefinition, [], '')->toOne();
$constraint.name->toOne()+' : '+$expressions;
}
function meta::pure::metamodel::serialization::grammar::printClass(cl:Class[1]):String[1]
{
let superClasses = $cl.generalizations->map(g:Generalization[1]| let type = $g.general->printGenericType();
if($type == 'meta::pure::metamodel::type::Any', | [], | $type););
'Class ' + printStereotypes($cl) + printTaggedValues($cl) + elementToPath($cl) + printClassTypeParameters($cl) + if($superClasses->isEmpty(),|'',|$superClasses->joinStrings(' extends ', ',', '')) + '\n' +
if($cl.constraints->isEmpty(), | '', |$cl.constraints->map(c|' '+printConstraint($c))->joinStrings('[\n',',\n','\n]\n')) +
'{\n' +
$cl.properties -> map(p:Property[1] |' ' + $p -> printProperty()) -> printStatements() +
$cl.propertiesFromAssociations -> map(p:Property[1] |' ~' + $p -> printProperty()) -> printStatements() +
$cl.qualifiedProperties -> map(p:QualifiedProperty[1] |' ' + printStereotypes($p) + printTaggedValues($p) + $p -> printFunctionSignature()) -> printStatements() +
$cl.qualifiedPropertiesFromAssociations -> map(p:QualifiedProperty[1] |' ~' + printStereotypes($p) + printTaggedValues($p) + $p -> printFunctionSignature()) -> printStatements() +
'}';
}
function meta::pure::metamodel::serialization::grammar::printClassTypeParameters(cl:Class[1]):String[1]
{
if ($cl.typeParameters->isNotEmpty(),
| if ($cl.multiplicityParameters->isNotEmpty(),
|'<' + $cl.typeParameters->map(p | $p.name)->joinStrings(',') + '|' + $cl.multiplicityParameters->evaluateAndDeactivate()->map(p | $p.values)->cast(@String)->joinStrings(',') + '>',
|$cl.typeParameters->map(p | $p.name)->joinStrings('<', ',', '>')),
| if ($cl.multiplicityParameters->isNotEmpty(),
| $cl.multiplicityParameters->evaluateAndDeactivate()->map(p | $p.values)->cast(@String)->joinStrings('<|', ',', '>'),
| ''));
}
function meta::pure::metamodel::serialization::grammar::printStereotypes(me:ElementWithStereotypes[1]):String[1]
{
if($me.stereotypes->isEmpty(), |'', |$me.stereotypes->map(c|$c.profile->elementToPath()+'.'+$c.value)->joinStrings('<<', ',', '>> '));
}
function meta::pure::metamodel::serialization::grammar::printTaggedValues(me:ElementWithTaggedValues[1]):String[1]
{
if($me.taggedValues->isEmpty(), |'', |$me.taggedValues->map(tv|$tv.tag.profile->elementToPath()+'.'+$tv.tag.value+'=\''+$tv.value+'\'')->joinStrings('{', ',', '} '));
}
function meta::pure::metamodel::serialization::grammar::printProperty(p:Property[1]):String[1]
{
printStereotypes($p) + printTaggedValues($p) + $p.name->toOne() + ' : ' + printGenericType($p.genericType) + '[' + printMultiplicity($p.multiplicity) + ']';
}
function meta::pure::metamodel::serialization::grammar::printGenericType(genericType:GenericType[1]):String[1]
{
if ($genericType->instanceOf(GenericTypeOperation),
|let go = $genericType->cast(@GenericTypeOperation);
if($go.left->isEmpty(),|'',|$go.left->toOne()->printGenericType()) +
if(
[
pair(|$go.type == GenericTypeOperationType.Union,|'+'),
pair(|$go.type == GenericTypeOperationType.Difference,|'-'),
pair(|$go.type == GenericTypeOperationType.Subset,|'⊆')
],
|'='
) +
$go.right->printGenericType();,
|if ($genericType.rawType->isEmpty(),
|if ($genericType.typeParameter->isEmpty(),
|'',
|$genericType.typeParameter->toOne().name->toOne()
),
|$genericType.rawType->toOne()->match(
[
f:FunctionType[1]|printFunctionType($f),
x:meta::pure::metamodel::relation::RelationType[1]|printRelationType($x),
c:Class[1]|if ($c.name->isEmpty(),|'?MappingClass?',|$c->elementToPath()),
e:Enumeration[1]|$e->elementToPath(),
a:Any[1]|$a->id()
]) +
if($genericType.typeArguments->isNotEmpty(),
|if($genericType.multiplicityArguments->isNotEmpty(),
|'<' + $genericType.typeArguments->map(g|$g->printGenericType())->joinStrings(',') + '|' + $genericType.multiplicityArguments->map(m | $m->printMultiplicity())->joinStrings(',') + '>',
|$genericType.typeArguments->map(g|$g->printGenericType())->joinStrings('<', ',', '>')),
|if($genericType.multiplicityArguments->isNotEmpty(),
|$genericType.multiplicityArguments->map(m | $m->printMultiplicity())->joinStrings('<|', ',', '>'),
|'')))
)
}
function meta::pure::metamodel::serialization::grammar::printFunctionType(functionType:FunctionType[1]):String[1]
{
'{'+$functionType.parameters->evaluateAndDeactivate()->map(v|printGenericType($v.genericType)+'['+printMultiplicity($v.multiplicity)+']')->joinStrings(',')
+'->'
+printGenericType($functionType.returnType)+'['+printMultiplicity($functionType.returnMultiplicity)+']}';
}
function meta::pure::metamodel::serialization::grammar::printRelationType(rType:meta::pure::metamodel::relation::RelationType[1]):String[1]
{
'('+$rType.columns->map(x|if($x.nameWildCard,|'?',|$x.name->toOne())+':'+$x.classifierGenericType.typeArguments->at(1)->printGenericType())->joinStrings(', ')+')';
}
function meta::pure::metamodel::serialization::grammar::printFunctionSignature(func:Function[1]):String[1]
{
let funcType = $func->genericType().typeArguments->at(0).rawType->toOne()->cast(@FunctionType);
let parameters = $funcType.parameters->evaluateAndDeactivate();
let returnType = $funcType.returnType;
let typeParams = $funcType.typeParameters->evaluateAndDeactivate();
if($func.functionName->isEmpty(), | 'LAMBDA', | $func.functionName->toOne()) + if($typeParams->isEmpty(), |'', |$typeParams->map(t:TypeParameter[1]|$t.name)->joinStrings('<', ', ','>')) + $parameters->map(v | $v.name + ': ' + printGenericType($v.genericType) + '[' + printMultiplicity($v.multiplicity) + ']')->joinStrings('(', ', ', ')') + ': ' + printGenericType($returnType) + '[' + printMultiplicity($funcType.returnMultiplicity) + ']';
}
function meta::pure::metamodel::serialization::grammar::printMultiplicity(multiplicity:Multiplicity[1]):String[1]
{
if ($multiplicity->isMultiplicityConcrete(),
| let lowerBound = $multiplicity->getLowerBound();
if ($multiplicity->hasUpperBound(),
| let upperBound = $multiplicity->getUpperBound();
if ($lowerBound == $upperBound,
| $lowerBound->toString(),
| $lowerBound->toString() + '..' + $upperBound->toString());,
| if ($lowerBound == 0,
| '*',
| $lowerBound->toString() + '..*'));,
| $multiplicity.multiplicityParameter->toOne())
}
function meta::pure::metamodel::serialization::grammar::printPath(path : meta::pure::metamodel::path::Path[1]) : String[1]
{
printPath($path, '.');
}
function meta::pure::metamodel::serialization::grammar::printPath(path : meta::pure::metamodel::path::Path[1], separator : String[1]) : String[1]
{
printGenericType($path.start)
+ $separator
+ $path.path->map(e | $e->match([
propertyPathElement : meta::pure::metamodel::path::PropertyPathElement[1] | $propertyPathElement.property.name->toOne(),
castPathElement : meta::pure::metamodel::path::CastPathElement[1] | printGenericType($castPathElement.type)
]))->makeString($separator);
}
function meta::pure::metamodel::serialization::grammar::printType(type : meta::pure::metamodel::type::Type[1]):String[1]
{
$type->match([
c:Class[1] | $c->printClass();,
e:Enumeration[1] | $e->printEnumeration();,
a:Any[1] | $a->toRepresentation();
]);
}
function meta::pure::metamodel::serialization::grammar::printPackageableElements(packageableElements:PackageableElement[*]): String[1]
{
$packageableElements->map(pe| $pe->match([
t:Type[1] | $t->printType(),
a:Association[1] | $a->printAssociation();
]))->joinStrings('\n\n');
}