Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 331984

Summary: Java annotations are not regererated when using @generated blocks
Product: [Modeling] EMF Reporter: Ari Suutari <ari.suutari>
Component: CoreAssignee: Ed Merks <Ed.Merks>
Status: RESOLVED WONTFIX QA Contact:
Severity: enhancement    
Priority: P3 CC: laurent.goubet
Version: 2.7.0   
Target Milestone: ---   
Hardware: PC   
OS: Windows 7   
Whiteboard:

Description Ari Suutari CLA 2010-12-07 02:48:08 EST
I'm using acceleo to generate java source, which contains annotations, like this:

	/**
	 * @generated
	 */
	public @SDFieldSize(value = 100)
	String countryName;

This generates OK for first time. But when I regenerate the code after changing the annotation (it comes from UML stereotype) the annotation does not change.
So my .mtl emits code which has "@SDFieldSize(value = 200)" but it doesn't end up into generated source file.

If I change the name of the field or it's datatype then also annotation changes. Also, if I delete the field from old generated source file and regenerate the new
annotation appears.

So it looks like my templates work ok, but there is something wrong in  @generated logic (JMerge ?), it seems to ignore annotation changes.

This is kind of annoying, because now if someone makes a change or fix in UML model and regenerates sources the change/fix doesn't end up into source code at all.
Comment 1 Laurent Goubet CLA 2010-12-07 03:00:25 EST
Hi Ari,

This can indeed be seen as a bug, but I believe it to be a feature : @generated means the content of the Java block will be regenerated, but not its definition (the signature of your method, of which the annotation is a part). Either way, it is not an Acceleo issue, you'll need to ask someone that is more familiar to its code than me.

Reaffecting to EMF Core as I believe the Java JMerge configuration comes from there.

Laurent
Comment 2 Ari Suutari CLA 2010-12-07 03:14:30 EST
Hi,

> This can indeed be seen as a bug, but I believe it to be a feature : @generated
> means the content of the Java block will be regenerated, but not its definition
> (the signature of your method, of which the annotation is a part). Either way,
> it is not an Acceleo issue, you'll need to ask someone that is more familiar to
> its code than me.

I think that datatype is also part of signature and it *is* regenerated correctly. Annotation is not. So I might think it is more a bug than a feature. Certainly not a feature one wishes to have :-)

I could even take a look at this myself, but there are so many eclipse
components involved in code generation that it looked difficult to find 
the correct place to start.
Comment 3 Ed Merks CLA 2010-12-07 13:14:13 EST
One would really need rules for how annotations are merged (and which ones are merged as to which ones aren't).  How to deal with annotations the users adds but the template never generated?  What about when users won't to block the generation and take it over?  We've never looked into all the complexities associated with this and aren't likely to find time.
Comment 4 Ari Suutari CLA 2010-12-08 01:20:26 EST
(In reply to comment #3)
> One would really need rules for how annotations are merged (and which ones are
> merged as to which ones aren't).  How to deal with annotations the users adds
> but the template never generated?  What about when users won't to block the
> generation and take it over?  We've never looked into all the complexities
> associated with this and aren't likely to find time.


For our case, whole method/field which is marked with @generated is considered something that user should not edit at all. So everything (visibility, datatype, annotations and field/method name) is regenerated.

I was under impression that user can remove the @generated if he/she wishes to modify generated stuff.
Comment 5 Ed Merks CLA 2010-12-08 07:39:11 EST
The current behavior is that if you add annotations by hand, they aren't removed even if they aren't in the template so the behavior is not the same as for the rest of the stuff (signature and body). Adding different behavior will certainly require some significant design changes, i.e., new merge rules, or specialized behavior, e.g., for matching annotations, push in the arguments from the template.  Someone will need to look at implementing such new support; the logic is all in the JMerge-related classes.
Comment 6 Ari Suutari CLA 2010-12-09 06:28:42 EST
(In reply to comment #5)
> The current behavior is that if you add annotations by hand, they aren't
> removed even if they aren't in the template so the behavior is not the same as
> for the rest of the stuff (signature and body)

I'm not sure if I understood this correctly. Our annotations are always generated
from template, nobody adds them by hand nor modifies generated ones. 

But if the UML model used to generate stuff changes next time the
generator might output same annotations with different parameters.

Between first generation and the next nobody has touched the generated file.
That is why I expected that the newly regenerated annotation would
get into generated file.

I can of course workaround this by using protected regions instead of @generated.
Comment 7 Ed Merks CLA 2010-12-09 10:23:40 EST
Keep in mind that EMF uses this for its own generator too, so changes in behavior are going to have to take that into account.  Arguing your point to the fullest conclusion (it must behave like for the signature and the body) any annotation not in the template must be swept away.  That's not going to be a good thing.  The premise that annotations with arguments should have their arguments merged is more palatable because EMF makes little use of that and modifying those arguments would typically be done because something else was modified too.  But someone needs to add support for pull in the arguments of the annotations.
Comment 8 Ari Suutari CLA 2010-12-10 02:13:03 EST
(In reply to comment #7)
> Keep in mind that EMF uses this for its own generator too, so changes in
> behavior are going to have to take that into account. 

Ok, this obviously makes this more difficult to solve.

As different use cases seem to have different requirements, it might
nice if a generator plugin could somehow provide it's own rules
for merge logic.
Comment 9 Ed Merks CLA 2010-12-10 07:58:59 EST
There already is a rules files for this purpose.
Comment 10 Ari Suutari CLA 2010-12-10 08:29:10 EST
(In reply to comment #9)
> There already is a rules files for this purpose.

Ok, great ! I found some examples of rules files, but
I wonder how can one tell Acceleo to use my rules file ?
Are there any Acceleo-related examples maybe ?
Comment 11 Laurent Goubet CLA 2010-12-11 13:37:07 EST
(In reply to comment #10)
> (In reply to comment #9)
> > There already is a rules files for this purpose.
> 
> Ok, great ! I found some examples of rules files, but
> I wonder how can one tell Acceleo to use my rules file ?
> Are there any Acceleo-related examples maybe ?

Hi Ed, Ari,

Ed, does this "rules files" thing relate to :

String jmergeFile = URI.createPlatformPluginURI("org.eclipse.emf.codegen.ecore/templates/emf-merge.xml", false).toString();
ControlModel model = new JControlModel();
model.initialize(new ASTFacadeHelper(), jmergeFile);

?

If yes, then this becomes an Acceleo enhancement request : we only support this single xml file for the JMerge configuration (this hard-coded string is what we use in Acceleo). I've never re-worked that code since I got it working, it could use some refactoring and customization capabilities ^^.

Laurent
Comment 12 Ed Merks CLA 2010-12-11 13:41:18 EST
Yes, that code helps find the default set of rules use by EMF's code generator.  Note though that part of what this bugzilla is asking for is the ability to pull in the contents of an existing matching annotation...
Comment 13 Ari Suutari CLA 2010-12-13 01:41:58 EST
Having possibility to provide own customized emf-merge.xml is just something I'm looking for. That would allow me to experiment with this more easily.
Comment 14 Ed Merks CLA 2012-10-05 01:22:08 EDT
I'm not sure there's anything to be done for this.