Created
January 30, 2013 08:13
-
-
Save anonymous/4671578 to your computer and use it in GitHub Desktop.
An Xtext workflow written as an Xtend class.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.xtext.example.mydsl | |
import org.eclipse.emf.mwe.utils.DirectoryCleaner | |
import org.eclipse.emf.mwe.utils.StandaloneSetup | |
import org.eclipse.xtext.generator.Generator | |
import org.eclipse.xtext.generator.LanguageConfig | |
import org.eclipse.xtext.generator.builder.BuilderIntegrationFragment | |
import org.eclipse.xtext.generator.ecore.EcoreGeneratorFragment | |
import org.eclipse.xtext.generator.exporting.QualifiedNamesFragment | |
import org.eclipse.xtext.generator.formatting.FormatterFragment | |
import org.eclipse.xtext.generator.generator.GeneratorFragment | |
import org.eclipse.xtext.generator.grammarAccess.GrammarAccessFragment | |
import org.eclipse.xtext.generator.junit.Junit4Fragment | |
import org.eclipse.xtext.generator.parser.antlr.XtextAntlrGeneratorFragment | |
import org.eclipse.xtext.generator.parser.antlr.XtextAntlrUiGeneratorFragment | |
import org.eclipse.xtext.generator.resourceFactory.ResourceFactoryFragment | |
import org.eclipse.xtext.generator.scoping.ImportNamespacesScopingFragment | |
import org.eclipse.xtext.generator.serializer.SerializerFragment | |
import org.eclipse.xtext.generator.types.TypesGeneratorFragment | |
import org.eclipse.xtext.generator.validation.ValidatorFragment | |
import org.eclipse.xtext.generator.xbase.XbaseGeneratorFragment | |
import org.eclipse.xtext.ui.generator.compare.CompareFragment | |
import org.eclipse.xtext.ui.generator.contentAssist.ContentAssistFragment | |
import org.eclipse.xtext.ui.generator.labeling.LabelProviderFragment | |
import org.eclipse.xtext.ui.generator.outline.OutlineTreeProviderFragment | |
import org.eclipse.xtext.ui.generator.outline.QuickOutlineFragment | |
import org.eclipse.xtext.ui.generator.quickfix.QuickfixProviderFragment | |
import org.eclipse.xtext.ui.generator.refactoring.RefactorElementNameFragment | |
import org.eclipse.xtext.ui.generator.templates.CodetemplatesGeneratorFragment | |
class GenerateMyDsl extends XtendWorkflow { | |
String grammarURI = "classpath:/org/xtext/example/mydsl/MyDsl.xtext" | |
String fileExtensions = "mydsl" | |
String projectName = "org.xtext.example.mydsl" | |
String runtimeProject = "../${projectName}".resolve | |
boolean generateXtendStub = true | |
new() { | |
beans += new StandaloneSetup => [ | |
scanClassPath = true | |
platformUri = "${runtimeProject}/..".resolve | |
// The following two lines can be removed, if Xbase is not used. | |
addRegisterGeneratedEPackage("org.eclipse.xtext.xbase.XbasePackage") | |
addRegisterGenModelFile("platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel") | |
] | |
components += new DirectoryCleaner => [ | |
directory = "${runtimeProject}/src-gen".resolve | |
] | |
components += new DirectoryCleaner => [ | |
directory = "${runtimeProject}.ui/src-gen".resolve | |
] | |
components += new Generator => [ | |
pathRtProject = runtimeProject | |
pathUiProject = "${runtimeProject}.ui".resolve | |
pathTestProject = "${runtimeProject}.tests".resolve | |
projectNameRt = projectName | |
projectNameUi = "${projectName}.ui".resolve | |
addLanguage( | |
new LanguageConfig => [ | |
autoInject | |
uri = grammarURI | |
// Java API to access grammar elements (required by several other fragments) | |
addFragment(new GrammarAccessFragment => [autoInject]) | |
// generates Java API for the generated EPackages | |
addFragment( | |
new EcoreGeneratorFragment => [ | |
autoInject | |
// referencedGenModels = " | |
// platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel, | |
// platform:/resource/org.eclipse.xtext.common.types/model/JavaVMTypes.genmodel | |
// " | |
]) | |
// the old serialization component | |
// fragment = parseTreeConstructor.ParseTreeConstructorFragment auto-inject {} | |
// serializer 2.0 | |
addFragment( | |
new SerializerFragment => [ | |
autoInject | |
generateStub = false | |
]) | |
// a custom ResourceFactory for use with EMF | |
addFragment( | |
new ResourceFactoryFragment => [ | |
autoInject | |
]) | |
// The antlr parser generator fragment. | |
addFragment( | |
new XtextAntlrGeneratorFragment => [ | |
autoInject | |
// options = { | |
// backtrack = true | |
// } | |
]) | |
// Xtend-based API for validation | |
addFragment( | |
new ValidatorFragment => [ | |
autoInject | |
// composedCheck = "org.eclipse.xtext.validation.ImportUriValidator" | |
// composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator" | |
]) | |
// old scoping and exporting API | |
// fragment = scoping.ImportURIScopingFragment auto-inject {} | |
// fragment = exporting.SimpleNamesFragment auto-inject {} | |
// scoping and exporting API | |
addFragment( | |
new ImportNamespacesScopingFragment => [ | |
autoInject | |
]) | |
addFragment( | |
new QualifiedNamesFragment => [ | |
autoInject | |
]) | |
addFragment( | |
new BuilderIntegrationFragment => [ | |
autoInject | |
]) | |
// generator API | |
addFragment( | |
new GeneratorFragment => [ | |
autoInject | |
]) | |
// formatter API | |
addFragment( | |
new FormatterFragment => [ | |
autoInject | |
]) | |
// labeling API | |
addFragment( | |
new LabelProviderFragment => [ | |
autoInject | |
]) | |
// outline API | |
addFragment( | |
new OutlineTreeProviderFragment => [ | |
autoInject | |
]) | |
addFragment( | |
new QuickOutlineFragment => [ | |
autoInject | |
]) | |
// quickfix API | |
addFragment( | |
new QuickfixProviderFragment => [ | |
autoInject | |
]) | |
// content assist API | |
addFragment( | |
new ContentAssistFragment => [ | |
autoInject | |
]) | |
// generates a more lightweight Antlr parser and lexer tailored for content assist | |
addFragment( | |
new XtextAntlrUiGeneratorFragment => [ | |
autoInject | |
]) | |
// generates junit test support classes into Generator#pathTestProject | |
addFragment( | |
new Junit4Fragment => [ | |
autoInject | |
]) | |
// project wizard (optional) | |
// fragment = projectWizard.SimpleProjectWizardFragment auto-inject { | |
// generatorProjectName = "${projectName}" | |
// } | |
// rename refactoring | |
addFragment( | |
new RefactorElementNameFragment => [ | |
autoInject | |
]) | |
// provides the necessary bindings for java types integration | |
addFragment( | |
new TypesGeneratorFragment => [ | |
autoInject | |
]) | |
// generates the required bindings only if the grammar inherits from Xbase | |
addFragment( | |
new XbaseGeneratorFragment => [ | |
autoInject | |
]) | |
// provides a preference page for template proposals | |
addFragment( | |
new CodetemplatesGeneratorFragment => [ | |
autoInject | |
]) | |
// provides a compare view | |
addFragment( | |
new CompareFragment => [ | |
autoInject | |
]) | |
]) | |
] | |
} | |
def static void main(String[] args) { | |
new GenerateMyDsl().run(null) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.xtext.example.mydsl; | |
import java.lang.reflect.Field; | |
import java.lang.reflect.InvocationTargetException; | |
import java.lang.reflect.Method; | |
import java.util.List; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
import org.eclipse.emf.mwe2.runtime.workflow.IWorkflowComponent; | |
import org.eclipse.emf.mwe2.runtime.workflow.Workflow; | |
import org.eclipse.xtext.util.Strings; | |
import com.google.common.collect.Lists; | |
public class XtendWorkflow extends Workflow { | |
protected List<Object> getBeans() { | |
return Lists.newArrayList(); | |
} | |
protected List<IWorkflowComponent> getComponents() { | |
return getChildren(); | |
} | |
protected <T> T autoInject(T t) { | |
Class<?> tClass = t.getClass(); | |
for (Field field : getClass().getFields()) { | |
String name = field.getName(); | |
Class<?> type = field.getType(); | |
try { | |
Method setter = tClass.getMethod( | |
"set" + Strings.toFirstUpper(name), type); | |
field.setAccessible(true); | |
setter.setAccessible(true); | |
setter.invoke(t, field.get(this)); | |
} catch (SecurityException e) { | |
e.printStackTrace(); | |
} catch (NoSuchMethodException e) { | |
// no problem | |
} catch (IllegalArgumentException e) { | |
e.printStackTrace(); | |
} catch (IllegalAccessException e) { | |
e.printStackTrace(); | |
} catch (InvocationTargetException e) { | |
e.printStackTrace(); | |
} | |
} | |
return t; | |
} | |
private static final Pattern VAR_PATTERN = Pattern.compile("\\$\\{([^\\}]+)\\}"); | |
protected String resolve(String s) { | |
Matcher matcher = VAR_PATTERN.matcher(s); | |
StringBuilder result = new StringBuilder(); | |
int last = 0; | |
while (matcher.find()) { | |
result.append(s.substring(last, matcher.start())); | |
String group = matcher.group(1); | |
result.append(getFieldValue(group)); | |
last = matcher.end(); | |
} | |
result.append(s.substring(last)); | |
return result.toString(); | |
} | |
private Object getFieldValue(String fieldName) { | |
try { | |
Field field = getClass().getDeclaredField(fieldName); | |
field.setAccessible(true); | |
return field.get(this); | |
} catch (IllegalArgumentException e) { | |
e.printStackTrace(); | |
} catch (SecurityException e) { | |
e.printStackTrace(); | |
} catch (IllegalAccessException e) { | |
e.printStackTrace(); | |
} catch (NoSuchFieldException e) { | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Somehow I managed to create this Gist in anonymous mode, so I've created a fork for the updated example: https://gist.github.com/4676978.