Skip to content

Instantly share code, notes, and snippets.

@KKostya
Created November 24, 2016 18:45
Show Gist options
  • Select an option

  • Save KKostya/c380e86a67f94c5b7d45646149e29252 to your computer and use it in GitHub Desktop.

Select an option

Save KKostya/c380e86a67f94c5b7d45646149e29252 to your computer and use it in GitHub Desktop.
Simple import instruction in XText
A scoping example with simple import of another model.
http://stackoverflow.com/questions/40785253/simple-import-instruction-in-xtext
We want to be able to extend only the classes that are defined before a given class and only
those that start with the same first letter as the class being defined.
We also want to be able to use the classes from "libraries" -- classes defined in other files.
library XesYs
class Xlib
class Xextend extends Xlib
class Ylib
class Yextra extends Ylib
import XesYs
class Xmain extends Xlib
class Ymain extends Yextra
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
Model:
('library' name=ID )?
(imports += Import )*
(classes += ClassDef )*;
Import:
'import' model=[Model];
ClassDef:
'class' name=ID ('extends' extends=[ClassDef])?;
package org.xtext.example.mydsl.scoping
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.scoping.Scopes
import org.xtext.example.mydsl.myDsl.MyDslPackage
import org.xtext.example.mydsl.myDsl.ClassDef
import org.xtext.example.mydsl.myDsl.Import
import static extension org.eclipse.xtext.EcoreUtil2.*
class MyDslScopeProvider extends AbstractMyDslScopeProvider {
override getScope(EObject context, EReference reference){
if(reference == MyDslPackage.Literals.CLASS_DEF__EXTENDS){
if(! (context instanceof ClassDef) ) {return IScope.NULLSCOPE }
val root = (context as ClassDef).getRootContainer
val classes = root.getAllContentsOfType(ClassDef)
var before = classes.subList(0, classes.indexOf(context))
val imports = root.getAllContentsOfType(Import)
.map[model.getAllContentsOfType(ClassDef)]
.flatten
before.addAll(imports)
val fstLetter = (context as ClassDef).name.charAt(0)
val haveSame1stLetter = before.filter[name.charAt(0) == fstLetter]
return Scopes::scopeFor(haveSame1stLetter)
}
super.getScope(context, reference)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment