Workshop On Xtext
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Workshop On Xtext

  • 8,211 views
Uploaded on

With Sebastian Zarnekow and Moritz Eysholdt...

With Sebastian Zarnekow and Moritz Eysholdt
Hands-on Workshop at Code Generation 2009

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
8,211
On Slideshare
8,002
From Embeds
209
Number of Embeds
5

Actions

Shares
Downloads
226
Comments
0
Likes
5

Embeds 209

http://www.slideshare.net 101
http://www.itemis.de 65
http://www.itemis.com 38
https://onion.net 4
http://www.linkedin.com 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Software Installation • You‘ll find a CD with the required software on your desk • Unzip the Eclipse distribution matching your OS Windows users: Use a location close to the root directory • Run the Eclipse executable • Choose File -> Import -> Existing projects into workspace • Select Archive file and choose workspace.zip from the CD
  • 2. Workshop Moritz Eysholdt, Sebastian Zarnekow, Jan Köhnlein
  • 3. Moritz Eysholdt Jan Köhnlein Sebastian Zarnekow
  • 4. Moritz Eysholdt Jan Köhnlein Sebastian Zarnekow
  • 5. Moritz Eysholdt Jan Köhnlein Sebastian Zarnekow
  • 6. What is a Domain Specific Language (DSL)?
  • 7. A domain-specific language (DSL) is a formal, processable language targeting at a specific viewpoint or aspect of a system.
  • 8. A domain-specific language (DSL) is a formal, processable language targeting at a specific viewpoint or aspect of a system. Its semantics, flexibility and notation is designed in order to support working with that viewpoint as good as possible.
  • 9. Why would I want to use a DSL?
  • 10. GPL vs DSL
  • 11. GPL vs DSL
  • 12. GPL vs DSL
  • 13. Abstraction
  • 14. Why isn‘t everybody using DSLs?
  • 15. Complicated Expensive
  • 16. Isn‘t text a little bit old- fashioned?
  • 17. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } public boolean internalIsSameStructure(EObject left, EObject right) { ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().g } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
  • 18. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().g } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
  • 19. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
  • 20. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • ++counter; Suggests non-formalism if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
  • 21. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • ++counter; Suggests non-formalism if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g • Formal protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
  • 22. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • ++counter; Suggests non-formalism if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri • Individual tools return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g • Formal protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
  • 23. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • ++counter; Suggests non-formalism if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri • Individual tools return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g • Formal protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( • Well established tools for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
  • 24. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • ++counter; Suggests non-formalism if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri • Individual tools return false; } List<EObject> leftChildren = getRelevantChildren(left); • Hard to evolve List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g • Formal protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( • Well established tools for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
  • 25. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • ++counter; Suggests non-formalism if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri • Individual tools return false; } List<EObject> leftChildren = getRelevantChildren(left); • Hard to evolve List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g • Formal protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( • Well established tools for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { } } • Easy to evolve i.remove(); return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
  • 26. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • ++counter; Suggests non-formalism if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri • Individual tools return false; } List<EObject> leftChildren = getRelevantChildren(left); • Hard to evolve List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r • Editing with mouse } return false; for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g • Formal protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( • Well established tools for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { } } • Easy to evolve i.remove(); return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
  • 27. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • ++counter; Suggests non-formalism if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri • Individual tools return false; } List<EObject> leftChildren = getRelevantChildren(left); • Hard to evolve List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r • Editing with mouse } return false; for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g • Formal protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( • Well established tools for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { } • Easy to evolve i.remove(); • } } Editing with keyboard return relevantChildren; protected boolean isRelevantChild(EObject container, EObject child) { return true;
  • 28. Showtime ! • In your Eclipse workbench • Choose Run->Run configurations... • Double click on Eclipse Application • Go to the Arguments tab and add -XX:MaxPermSize=128m to the VM arguments • Click on Run
  • 29. A Guided Example entity Conference { property Name : String on Attendees refs many Pers Sp eakers refs many Speaker } entity Person { property Name : String } { enti ty Speaker extends Person n Sessions refs many Sessio } entity Session { property Title: String property IsTutorial : Bool }
  • 30. Grammar Language grammar org.xtext.cg2009.Entities with org.eclipse.xtext.common.Terminals generate entities "http://www.xtext.org/cg2009/Entities" Model : (entities += Entity)+; Entity returns Entity: 'entity' name=ID ('extends' superType=[Entity])? '{' (properties+=Property)* '}'; Property: SimpleProperty | ReferenceProperty; SimpleProperty: 'property' name=ID ':' type=('String'|'Number'|'Bool'); ReferenceProperty : name=ID 'refs' ('one' | many?='many')? type=[Entity];
  • 31. Edit SQL with Xtext CREATE TABLE Conferences ( id INTEGER NOT NULL PRIMARY KEY, • Only ) name CHAR(50) Create-Statements • List of columns
  • 32. Edit SQL with Xtext CREATE TABLE Conferences ( id INTEGER NOT NULL PRIMARY KEY, name CHAR(50) • Enhance with ) Foreign Keys CREATE TABLE Speaker ( name CHAR(50), id INTEGER, FOREIGN KEY (id) REFERENCES Conference(id) )
  • 33. What’s wrong with it?
  • 34. Cross References
  • 35. Cross References Model Element
  • 36. Cross References Element Name Model Element
  • 37. Cross References Element Name resolve Model Element
  • 38. Cross References Element Name resolve determin Model Element
  • 39. Problem: Names may not be ambiguous.
  • 40. Problem: Names may not be ambiguous. Solution: Implement a ScopeProvider!
  • 41. Problem: Names may not be ambiguous. Solution: Implement a ScopeProvider! A Scope is a context specific, hierarchical collection of all reachable model elements and their respective names.
  • 42. Scope Provider Make Foreign Keys work! public IScope scope_ForeignKey_from( ForeignKey context, EReference reference) { Table fromTable = (Table) context.eContainer(); return createTableScope(fromTable); }
  • 43. Meta-Model Inference grammar org.xtext.codeGeneration.Entities with org.eclipse.xtext.common.Terminals generate entities "http://www.xtext.org/CG2009/Entities" Model : (entities += Entity)+; Entity returns Entity: 'entity' name=ID ('extends' superType=[Entity])? '{' (properties+=Property)* '}'; Property: SimpleProperty | ReferenceProperty; SimpleProperty: 'property' name=ID ':' type=('String'|'Number'|'Bool'); ReferenceProperty : name=ID 'refs' ('one' | many?='many')? type=[Entity];
  • 44. Model Conferences with Xtext How do I create a language for an existing meta-model?
  • 45. Model Conferences with Xtext
  • 46. Validate Your Conference 1. Have a look at the generated Validator-Stub. 2. Implement some checks for your language. 3. Check out the results. @Check public void checkSpeakersName(Speaker speaker) { assertTrue("Speaker's name is to short.", ConferencesLanguagePackage.SPEAKER__NAME, speaker.getName().length() >= 2); }
  • 47. Convention over Configuration
  • 48. Configured with Google Guice class MyDslRuntimeModule extends DefaultRuntimeModule { Class<? extends ServiceInterface> bindService() { return MyServiceImplementation.class; } }
  • 49. Extensible Language Generator • Generates a lot of Java code • Composed of fragments • Customizable • Add your own fragments!
  • 50. http://www.wordle.net/
  • 51. Formatting Pretty Printing Code Beautification import <Literature.entities> entity City {Int id; String name;} entity Store { Int id; String name; Int city references City. id; }
  • 52. Formatting Pretty Printing Code Beautification import <Literature.entities> entity City {Int id; String name;} entity Store { Int id; String name; Int import <Literature.entities> city references entity City { City. Int id; id; } String name; } entity Store { Int id; String name; Int city references City.id; }
  • 53. Formatting Pretty Printing Code Beautification import <Literature.entities> entity City {Int id; String name;} entity Store { Int id; String name; Int import <Literature.entities> city references entity City { City. Int id; id; } String name; } entity Store { Int id; String name; Int city references City.id; }
  • 54. Formatting Pretty Printing Code Beautification import <Literature.entities> entity City {Int id; String name;} entity Store { Int id; String name; Int import <Literature.entities> city references entity City { City. Int id; id; } String name; } entity Store { Int id; String name; Int city references City.id; § 1. At ... do ... } § 2. At ... do ... § 3. At ... do ... § 4. At ... do ... ...
  • 55. Integration with EMF
  • 56. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component
  • 57. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMIResource Resource
  • 58. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMIResource Resource
  • 59. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMI XMIResource Resource
  • 60. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMI XMIResource Resource
  • 61. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMI XMIResource Resource XtextResource
  • 62. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMI XMIResource Resource XtextResource
  • 63. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMI XMIResource Resource XtextResource Text
  • 64. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMI XMIResource Resource XtextResource Text Parser Linker Serializer ValueConverter ScopeProvider Formatter
  • 65. EMF Index • Indexes all resources in workspace • Query elements and cross-references • Efficient scoping
  • 66. EMF Index • Indexes all resources in workspace • Query elements and cross-references • Efficient scoping Load Resources
  • 67. Learn more at http://www.xtext.org