Skip to content

Instantly share code, notes, and snippets.

Created January 30, 2013 08:13
Show Gist options
  • Save anonymous/4671578 to your computer and use it in GitHub Desktop.
Save anonymous/4671578 to your computer and use it in GitHub Desktop.
An Xtext workflow written as an Xtend class.
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)
}
}
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;
}
}
@knutwannheden
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment