Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Is Xtext generation gap support a myth?
Is Xtext generation gap support a myth? [message #1073414] Wed, 24 July 2013 18:22 Go to next message
Ed Staub is currently offline Ed StaubFriend
Messages: 12
Registered: July 2009
Junior Member
After looking at a few dozen email threads, StackOverflow, etc., I've come to the conclusion that generation-gap-pattern support in Xtext is largely mythical. Several people have had started threads asking how to do it; none of them appeared to arrive at anything successful (at least, with a reasonable amount of work). Many of the responses have appeared to either not work for Xtext in particular, or be useless because they require a lot more Ecore/EMF/whatever knowledge than I (or the other posters) are likely to have.

In my particular case, I simply want to be able to add a few methods and fields to a few of the grammar-derived generated classes/interfaces.

I'm rarely this intentionally provocative, but after reading through so much wasted attempts at communication, I think that on this topic answerers need to pause to think whether what they're suggesting actually works in Xtext in particular, and whether it is comprehensible to the folks asking the questions. Sorry if I've just given offense!

Re: Is Xtext generation gap support a myth? [message #1073588 is a reply to message #1073414] Thu, 25 July 2013 05:43 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 6499
Registered: July 2009
Senior Member
Hi,

hmmm i dont have the feeling that i have seen any of this threads.

first: what is generation gap

Quote:
Separate generated code from non-generated code by inheritance.


i know many many Xtext and non Xtext Projects that realize this.

so there are basically 2 options to realize this

(1) you generate only interfaces and abstract classes, use a naming convention for the concrete class.
(2) you do additionaly a generate once for the conctrete classes



the following took me a few minutes todo.

Model:
	entitites+=Entity*;
	
Entity:
	'entity' name=ID "{" 
		attributes+=Attribute*
	"}";

	Attribute:
		name=ID ":" type = Type
	;
	
enum Type :
	String | int | boolean
;	



class MyDslGenerator implements IGenerator {
	
	override void doGenerate(Resource resource, IFileSystemAccess fsa) {
		for (entity : resource.allContents.toIterable.filter(typeof(Entity))) {
			fsa.generateFile("test/"+entity.name+".java", '''
			package test;
			public abstract class «entity.name» {
				«FOR a : entity.attributes»
				public abstract «a.type.literal» get«a.name.toFirstUpper»();
				public abstract void set«a.name.toFirstUpper»(«a.type.literal» «a.name»);
				«ENDFOR»
				
				public static «entity.name» newInstance() {
					return new «entity.name»Impl();
                                }

			}
			''') 
		}
	}
}


so let us take five more minutes to get the generate once done

class MyDslGenerator implements IGenerator {
	
	override void doGenerate(Resource resource, IFileSystemAccess fsa) {
		for (entity : resource.allContents.toIterable.filter(typeof(Entity))) {
			fsa.generateFile("test/"+entity.name+".java", '''
			package test;
			public abstract class «entity.name» {
				«FOR a : entity.attributes»
				public abstract «a.type.literal» get«a.name.toFirstUpper»();
				public abstract void set«a.name.toFirstUpper»(«a.type.literal» «a.name»);
				«ENDFOR»
				
				public static «entity.name» newInstance() {
					return new «entity.name»Impl();
				}
			}
			''') 
			
			fsa.generateFile("test/"+entity.name+"Impl.java","gen_once", '''
			package test;
			public class «entity.name»Impl extends «entity.name» {
				«FOR a : entity.attributes»
				private «a.type.literal» «a.name»;
				public «a.type.literal» get«a.name.toFirstUpper»(){
					return this.«a.name»;
				}
				public void set«a.name.toFirstUpper»(«a.type.literal» «a.name»){
					this.«a.name» = «a.name»;
				}
				«ENDFOR»
				
			}
			''') 
		}
	}
}


public class MyDslOutputConfigurationProvider implements IOutputConfigurationProvider {
	
	public Set<OutputConfiguration> getOutputConfigurations() {
		OutputConfiguration defaultOutput = new OutputConfiguration(IFileSystemAccess.DEFAULT_OUTPUT);
		defaultOutput.setDescription("Output Folder");
		defaultOutput.setOutputDirectory("./src-gen");
		defaultOutput.setOverrideExistingResources(true);
		defaultOutput.setCreateOutputDirectory(true);
		defaultOutput.setCleanUpDerivedResources(true);
		defaultOutput.setSetDerivedProperty(true);
		OutputConfiguration genOnce = new OutputConfiguration("gen_once");
		genOnce.setDescription("Output Folder Gen Once");
		genOnce.setOutputDirectory("./src");
		genOnce.setOverrideExistingResources(false);
		genOnce.setCreateOutputDirectory(true);
		genOnce.setCleanUpDerivedResources(false);
		genOnce.setSetDerivedProperty(false);
		return newHashSet(defaultOutput, genOnce);
	}

}


public class MyDslRuntimeModule extends org.xtext.example.mydsl2.AbstractMyDslRuntimeModule {

	public Class<? extends IOutputConfigurationProvider> bindIOutputConfigurationProvider() {
		return MyDslOutputConfigurationProvider.class;
	}
	
}


Please note: in standalone mode you need a custom version of JavaIoFileSystemAccess
since it is lagging generate once support. (This is a stupid bug not a conceptual problem)
https://bugs.eclipse.org/bugs/show_bug.cgi?id=398979

~Christian
Re: Is Xtext generation gap support a myth? [message #1073668 is a reply to message #1073588] Thu, 25 July 2013 09:10 Go to previous messageGo to next message
Victor Noël is currently offline Victor NoëlFriend
Messages: 112
Registered: June 2010
Senior Member
Ed: Are you talking about generation gap for the EMF model with support for Custom implementations or generation gap from an xtext grammar to java?

If it is the former, then the answer I think is:
1) it works if you generate a EMF model defined as ecore (using the component org.eclipse.emf.mwe2.ecore.EcoreGenerator in you mwe2 as they do for xbase/xtype).
2) it does NOT work if you generate the EMF model from the grammar (using ecore.EcoreGeneratorFragment in the Generator component in your mwe2)

In that case, you are right about the myth or the fact it is complex, I faced the problem myself and a bug report exists on the matter: https://bugs.eclipse.org/bugs/show_bug.cgi?id=402669

I hope I didn't misunderstood your complaint Wink
Re: Is Xtext generation gap support a myth? [message #1073673 is a reply to message #1073668] Thu, 25 July 2013 09:22 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 6499
Registered: July 2009
Senior Member
Hmm i did not thought of the ecore inference.
yes indeed, generation gap works only with manually maintained metamodels and use of EcoreGenerator.
Re: Is Xtext generation gap support a myth? [message #1074075 is a reply to message #1073673] Fri, 26 July 2013 03:36 Go to previous messageGo to next message
Ed Staub is currently offline Ed StaubFriend
Messages: 12
Registered: July 2009
Junior Member
I'm a newbie, so I'm following the directions in the documentation, and using the Xtext-generated mwe2 - so I'm using EcoreGeneratorFragment. Googling for info on EcoreGenerator has been fruitless - AFAICT, there's no way one would find out about it other than reading, e.g., the xbase implementation. I don't want to harp on it, but this is a good example of the kind of disconnect I was trying to point out - the documentation gap between experts and novices.

Christian, search the forum for "generation gap" and see whether it looks like folks got what they needed. I'm working from the Xtext documentation, and most of what you kindly provided is, frankly, beyond me, in that I don't understand the context - maybe I need to learn a lot of EMF to understand?

It sounds like I might be able to save off the EcoreGeneratorFragment-generated Ecore file, modifying the mwe2 file to use it instead of generate it, using the xbase project as an example?
Re: Is Xtext generation gap support a myth? [message #1074102 is a reply to message #1074075] Fri, 26 July 2013 05:50 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 6499
Registered: July 2009
Senior Member
Hi,

first i want to state am not a Xtext committer but rather a normal user like you.
second documentation is always a heavily discussed topic. with a framework as Xtext where you can customize everything it is tons of work that nobody pays for and maybe is not needed since customizing the generated emf javaclasses may not be considered as usecase for the std. user. (you did not say what the particular wish for customization in your case is)
depending on the usecase there are basically 3 options
(1) you use the IXtext2EcorePostProcessor to change the generated ecore e.g. by adding methods.
(2) you use a manually maintained metamodel anyway and use EMFs Protected Region Approach (JMerge)
(3) the EcoreGenerator frees you from doing (2) by moving the implementations to custom impl classes.
in all cases you have to be willing to read into emf since Xtext is an EMF based framework.

if documentation is insufficient users can always find a enhancement request maybe with some text already attached. (hey Xtext is Open Source)

maybe i find the time to blog about ecoregenerator but this depends on my time.

~Christian

Re: Is Xtext generation gap support a myth? [message #1074169 is a reply to message #1074102] Fri, 26 July 2013 08:16 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 6499
Registered: July 2009
Senior Member
Here it is: http://christiandietrich.wordpress.com/2013/07/26/use-of-ecoregenerator-to-customize-emfs-generated-java-classes/
Re: Is Xtext generation gap support a myth? [message #1075612 is a reply to message #1073414] Mon, 29 July 2013 18:41 Go to previous message
Ed Staub is currently offline Ed StaubFriend
Messages: 12
Registered: July 2009
Junior Member
Thanks much.
The main thing I needed to hear was:
Quote:
in all cases you have to be willing to read into emf since Xtext is an EMF based framework.

So, after reading up a bit, I ended up creating an ecore project, importing the .ecore that was produced by Xtext. I then created a new "Xtext from existing ecore model" project, pointing at the ecore project, with all of my code, resources, et al from the old Xtext project. I'm just using JMerge to apply hand-coded model modifications. At this point, that's a tenable solution, even though the border between generated and authored code is of course a bit murky.
Previous Topic:Xtext 2.4.2: content assist: how to use a filter in completeRuleCall ?
Next Topic:Scoping: "Nested" references
Goto Forum:
  


Current Time: Fri Nov 28 21:00:35 GMT 2014

Powered by FUDForum. Page generated in 0.02686 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software