Я думаю, что самым простым способом было бы определить двунаправленную ссылку между родительским и дочерним пакетами.Таким образом, в вашей метамодели это будет двунаправленная ссылка класса пакета на себя, например:
+---------+
|Package |
| |<>--+
`---------+ | 0..* containedPackages
| |
+------+ 0..1 parentPackage
В Xpand вы сделаете (непроверенный, но этого должно быть достаточно, чтобы получить идею):
«DEFINE class FOR Class»
import «EXPAND packagename FOR this.package»;
class «this.name»{}
«ENDDEFINE»
«DEFINE packagename FOR Package»
«FOREACH this.packageHierarchy() as p SEPARATOR '.' -»«p»«ENDFOREACH»
«ENDDEFINE»
Xtend - рекурсивно найти родителей, добавить их в список и изменить порядок списков.Возможно, есть более чистый способ, который не требует метода flatten ():
List[Package] packageHierarchy(Package p):
let list = {}:
p.parentPackage == null ? list.add(p) : list.add(packageHierarchy(p.parentPackage)) ->
list.flatten().reverse()
;
Надеюсь, фрагменты кода не слишком повреждены:)