Extending FAMIX

This page describes the most clean procedure to define/extend a metamodel. It does not eliminate all risks of errors but at least avoid redundant steps. After each modification of the metamodel, do not forget to run the lint rules to check its consistency.

Metamodel is described directly in the source code through Fame pragmas. See the essential documentation about Fame pragmas.

Also, a good rule of thumb is to have MooseEntity as root instead of Object to facilitate integration with Moose tools.

Sample case: RPG.Dragon and its hoard

1) declare your metamodel with Fame pragmas For the example below:

  • Create class RPGDragon from a class browser
  • add on class-side:
RPGDragon class>>annotation
<MSEClass: #Dragon super: #Object>
<package: #RPG>

Just define the method with pragmas, don’t add any code in the body. Method body will be overwritten at generation time.

For each attribute, I need to define an accessor (a reader, not the writer):

  • define (method declaration + pragma, no code):
RPGDragon>>hoard
<MSEProperty: #hoard type: #RPGTreasure opposite: #keeper><multivalued>

No need to add #initialize, it will be defined by the generator.

2) To generate the implementation, just do:

MooseModel generateClassesFrom: {RPGDragon. RPGHero. RPGWall}
"collection of classes defining the metamodel"

It should open a preview window, where you can see which method will be defined/overridden by the generator. You can always tap Cmd-x to remove the selected definition (in case you are doing some incremental metamodel definition). You can repeat the generation step as much as you want, provided you understand it will overwrite existing methods.

It works like a charm if you are doing your own metamodel. If you need to extend some existing Famix classes with new attributes, you should be a bit more careful not to overwrite existing code. You may have to modify the #initialise method by hand.

3) Check the consistency of your metamodel with lint rules Open the meta browser and run lint rules from the menu. The lint rules especially check the following:

  • soundness of opposite relationships (the opposite attribute/class points back to the original attribute/class)
  • name convention of Package.Class in Fame -> PackageClass in Smalltalk
  • superclass exists