moosetechnology/Moose

How to add (programmatically) accessors and mutators via Generator

fuhrmanator opened this issue · 2 comments

I'm trying to add generics support to FamixTypeScript. Thankfully, because of the tests (yes!) I saw that FamixJavaParameterizableClass has an accessor (and mutator) for #parameters:

parameters
	<FMProperty: #parameters type: #FamixJavaParameterType> <multivalued> <derived>
	<FMComment: 'Parameter types of this class.'>
	
	^self types select: [:each | each isParameterType]

It appears these were manually added to the entity (a similar case was #isInterface in FamixJavaClass I think), but I'm not sure.

Perhaps I'm being too strict, but I was thinking that such manual changes to generated classes is a tricky thing to maintain. If it's part of the official process in building a metamodel, then it should be documented on the Moose wiki - the tutorials for FamixNG seem to imply that everything is created by the generator.

Is it possible with the current generator DSL to add this kind of thing programmatically? FamixMetamodelGenerator #defineProperties seems like the place, but I don't see how one can put logic inside the properties (it seems to only allow simple get/set of basic types).

If not, then it would be good to document that such manual changes are necessary and explain that they're (hopefully) preserved when a metamodel is regenerated.

Also, would it be possible to tag the generated (or manual) parts of a MM? It would be useful to know what is what.

I found some help in the documentation for Booklet-FamixNG -- I had to re-build it on a docker on my machine, but I re-uploaded it on the SquareBracketAssociates/Booklet-FamixNG#9.

7.5 Custom extensions
During generation of the meta-model classes, the generator touches only the methods and slots it knows they can be changed. In case we want to provide an alternative code for generated methods, we need to remove the pragma <generated> else the generator will rewrite them during the next re-generation.
As we said, the generator creates for every meta-model entity two classes. One has a name with the suffix Generated and is the superclass of the other one. When such pair is created, the generator only checks if the class without suffix already exists and if yes, it stays untouched. That opens a possibility to move them to a separate package and extend such classes with own methods or instance variables if needed.
We want, for example, from methods to answer a package that owns method in case that the method package is not explicitly known. In this case we need to remove pragma <generated> from the parentPackage accessor.

DemoStMethod >> parentPackage
   <MSEComment: 'Package containing the entity in the code structure (if applicable)'>
   <container>

   ^ super parentPackage ifNil: [ self parentType parentPackage ]

Of course, now we have full responsibility of keeping such classes and method synchronized with the generated meta-model.

It seems that the answer has been found