#14 Model Inferrer & Scripting Language
Nov 10, 2012 |
11 minutes |
Beginners, 7 Languages
In this episode I will show you the first most simple language out of the 7 Languages For The JVM - the Scripting Language. The main focus will be on the ModelInferrer.
- Download:
- source code Project Files in Zip (695 KB)
- mp4 Full Size H.264 Video (28.4 MB)
- m4v Smaller H.264 Video (16.3 MB)
- webm Full Size VP8 Video (17 MB)
- ogv Full Size Theora Video (37.4 MB)
Referenced episodes
- 7 Languages For The JVM: http://xtextcasts.org/episodes/8-7-languages-for-the-jvm
- Debug Support: http://xtextcasts.org/episodes/5-debug-support
URLs
- 7 Languages For The JVM: http://www.eclipse.org/Xtext/7languages.html
- 7 Languages For The JVM on github: https://github.com/xtext-dev/seven-languages-xtext
Default Xtext project
MyDsl.xtext
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.xbase.Xbase
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
Model:
greetings+=Greeting*;
Greeting:
'Hello' name=ID '!';
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.xbase.Xbase generate myDsl "http://www.xtext.org/example/mydsl/MyDsl" Model: greetings+=Greeting*; Greeting: 'Hello' name=ID '!';
MyDslJvmModelInferrer.xtend
package org.xtext.example.mydsl.jvmmodel
import com.google.inject.Inject
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
import org.xtext.example.mydsl.myDsl.Model
class MyDslJvmModelInferrer extends AbstractModelInferrer {
@Inject extension JvmTypesBuilder
// Here you explain how your model is mapped to Java elements, by writing the actual translation code.
def dispatch void infer(Model element, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
acceptor.accept(element.toClass("my.company.greeting.MyGreetings"))
.initializeLater([
for (greeting : element.greetings) {
members += greeting.toMethod("hello" + greeting.name, greeting.newTypeRef(typeof(String))) [
body = [
append('''return "Hello «greeting.name»";''')
]
]
}
]
)
}
}
package org.xtext.example.mydsl.jvmmodel import com.google.inject.Inject import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder import org.xtext.example.mydsl.myDsl.Model class MyDslJvmModelInferrer extends AbstractModelInferrer { @Inject extension JvmTypesBuilder // Here you explain how your model is mapped to Java elements, by writing the actual translation code. def dispatch void infer(Model element, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) { acceptor.accept(element.toClass("my.company.greeting.MyGreetings")) .initializeLater([ for (greeting : element.greetings) { members += greeting.toMethod("hello" + greeting.name, greeting.newTypeRef(typeof(String))) [ body = [ append('''return "Hello «greeting.name»";''') ] ] } ] ) } }
test.mysql
Hello World!
Hello Xtext!
Hello World! Hello Xtext!
(generated) MyGreetings.java
package my.company.greeting;
public class MyGreetings {
public String helloWorld() {
return "Hello World";
}
public String helloXtext() {
return "Hello Xtext";
}
}
package my.company.greeting; public class MyGreetings { public String helloWorld() { return "Hello World"; } public String helloXtext() { return "Hello Xtext"; } }
Scripting Language
Scripting.xtext
/*******************************************************************************
* Copyright (c) 2012 itemis AG (http://www.itemis.eu) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
******************************************************************************/
grammar org.xtext.scripting.Scripting with org.eclipse.xtext.xbase.Xbase
generate scripting "http://www.xtext.org/scripting/Scripting"
import "http://www.eclipse.org/xtext/xbase/Xbase"
Script returns XBlockExpression:
{Script}
((expressions+=XExpressionInsideBlock | imports+=Import) ';'?)*;
Import:
'import' importedNamespace=QualifiedNameWithWildcard;
QualifiedNameWithWildcard:
QualifiedName '.*'?;
/******************************************************************************* * Copyright (c) 2012 itemis AG (http://www.itemis.eu) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html ******************************************************************************/ grammar org.xtext.scripting.Scripting with org.eclipse.xtext.xbase.Xbase generate scripting "http://www.xtext.org/scripting/Scripting" import "http://www.eclipse.org/xtext/xbase/Xbase" Script returns XBlockExpression: {Script} ((expressions+=XExpressionInsideBlock | imports+=Import) ';'?)*; Import: 'import' importedNamespace=QualifiedNameWithWildcard; QualifiedNameWithWildcard: QualifiedName '.*'?;
ScriptingJvmModelInferrer.xtend
/*******************************************************************************
* Copyright (c) 2012 itemis AG (http://www.itemis.eu) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
******************************************************************************/
package org.xtext.scripting.jvmmodel
import com.google.inject.Inject
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
import org.xtext.scripting.scripting.Script
import static org.xtext.scripting.jvmmodel.ScriptingJvmModelInferrer.*
/**
* Infers a Java class with a main method from a {@link Script}.
*/
class ScriptingJvmModelInferrer extends AbstractModelInferrer {
@Inject extension JvmTypesBuilder
def dispatch void infer(Script script, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
val className = script.eResource.URI.trimFileExtension.lastSegment
acceptor.accept(script.toClass(className)).initializeLater [
members += script.toMethod('main', script.newTypeRef(Void::TYPE)) [
parameters += script.toParameter("args", script.newTypeRef(typeof(String)).addArrayTypeDimension)
setStatic(true)
body = script
]
]
}
}
/******************************************************************************* * Copyright (c) 2012 itemis AG (http://www.itemis.eu) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html ******************************************************************************/ package org.xtext.scripting.jvmmodel import com.google.inject.Inject import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder import org.xtext.scripting.scripting.Script import static org.xtext.scripting.jvmmodel.ScriptingJvmModelInferrer.* /** * Infers a Java class with a main method from a {@link Script}. */ class ScriptingJvmModelInferrer extends AbstractModelInferrer { @Inject extension JvmTypesBuilder def dispatch void infer(Script script, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) { val className = script.eResource.URI.trimFileExtension.lastSegment acceptor.accept(script.toClass(className)).initializeLater [ members += script.toMethod('main', script.newTypeRef(Void::TYPE)) [ parameters += script.toParameter("args", script.newTypeRef(typeof(String)).addArrayTypeDimension) setStatic(true) body = script ] ] } }
Print.script
val a = 1
val b = 1
println(a + b)
val a = 1 val b = 1 println(a + b)
(generated) Print.java
import org.eclipse.xtext.xbase.lib.InputOutput;
public class Print {
public static void main(final String[] args) {
final int a = 1;
final int b = 1;
int _plus = (a + b);
InputOutput.<Integer>println(Integer.valueOf(_plus));
}
}
import org.eclipse.xtext.xbase.lib.InputOutput; public class Print { public static void main(final String[] args) { final int a = 1; final int b = 1; int _plus = (a + b); InputOutput.<Integer>println(Integer.valueOf(_plus)); } }