blob: eda0b7451b93c247dd1f5aa2ad3315b1d86f5237 [file] [log] [blame]
modeltype UML uses "http://www.eclipse.org/qvt/1.0.0/Operational/examples/simpleuml";
modeltype ECORE uses "http://www.eclipse.org/emf/2002/Ecore";
transformation lateresolve_col(in eModel :ECORE, out umlModel : UML);
property x : Sequence(UML::Package) = null;
property counter: Integer = 0;
property allClasscounter: Integer = 0;
query failure(message : String) : Boolean {
assert fatal (false) with log('Error: ' + message);
return null;
}
main() {
var empty : Sequence(UML::Package) := resolveIn(ECORE::EPackage::toPackage, p : UML::Package | true);
assert(empty <> null);
assert(empty->isEmpty());
assert(resolveoneIn(ECORE::EPackage::toPackage, p : UML::Package | true).oclIsUndefined());
var ePackages := eModel.objects()->select(oclIsKindOf(ECORE::EPackage))->collect(oclAsType(ECORE::EPackage));
var eClasses := eModel.objects()->select(oclIsKindOf(ECORE::EClass))->collect(oclAsType(ECORE::EClass));
-- map all elements first, then perform late link bindings
ePackages.map toPackage();
eClasses.map toClass();
var root := object UML::Package {
name := 'root';
-- dummy package checking its not reset by the next assginment
ownedElements += object UML::Package {
name := 'empty';
-- test late resolve not evaluated as deferred assignments
ownedElements += eModel.objectsOfType(ECORE::EClass).late resolve(UML::Class)->asOrderedSet()->collect(i|i); -- expect warn
ownedElements += if true then eModel.objectsOfType(ECORE::EClass).late resolve(UML::Class)->asOrderedSet() else null endif; -- expect warn
};
-- tests late resolve with condition
ownedElements += late resolveIn(ECORE::EPackage::toPackage, p : UML::Package | p.invresolveoneIn(ECORE::EPackage::toPackage, ECORE::EPackage).eSuperPackage = null)->asOrderedSet();
};
-- move last uncontained package into the common root package by using late resolve
-- checking assignment outside mapping
root.ownedElements += late resolveoneIn(ECORE::EPackage::toPackage, p : UML::Package | p.owner = null and p <> root);
this.counter := 0;
eClasses.resolve(c:Class | while(counter = 0) { this.counter:= counter+1; } <> null)
.late resolve(c:UML::Class | failure('should never get here as its 2nd late resolve'));
eClasses.late resolve(c:Class | if counter <= 0 then failure('counter has invalid value') else true endif);
eClasses.late resolve(c:Class | c.late invresolveone(ec:EClass |
if true then { this.allClasscounter:=allClasscounter+1; } else false endif) = null);
eClasses.late resolve(c:Class | if (allClasscounter <> eClasses->size()) then failure('all class counter has invalid value') endif = null);
}
mapping ECORE::EPackage::toPackage(): UML::Package {
init {
-- tests the module wide property deferred assignment as non-local
this.x := self.eSubpackages.late resolveIn(ECORE::EPackage::toPackage, UML::Package);
}
name := self.name;
ownedElements += self.eClassifiers.late resolve(UML::Class);
-- does nothing, tries to add the module property contents to check that nothing is added it is evaluated late time
ownedElements += this.x;
}
mapping ECORE::EClass::toClass(): UML::Class {
init {
self.eSuperTypes.mapGeneralization();
}
name := self.name;
-- late resolve call on collection source
generalizations := self.eSuperTypes.late resolve(UML::Generalization)->asOrderedSet();
attributes += object Property {
name := 'self';
-- test late resolve nested in object expression
type := self.late resolveone(UML::Type);
};
-- test a nested late resolve
attributes += object Property {
name := 'yetAnotherSelf';
type := result.attributes->collect(p:Property |
object Property {
owner := result;
name := p.name + '_Copied';
type := self.late resolveone(t: UML::Type |
-- expect warn -> condition of late resolve evaluated in the end, checked it works as non-late;
t.late invresolveone() = self);
}
)->collect(self).late resolveone(UML::Type)->any(true);
};
}
mapping ECORE::EClass::mapGeneralization() : UML::Generalization {
general := self.late resolveoneIn(EClass::toClass, UML::Class);
}