Xtext Tip: Context dependent FQNs in Xtext
One of my favorite features of Xtext is the ability to have context dependant FQNs. One application of the feature is the this
keyword, which is used to refer to the current instance in languages like Java. The full code for this example can be found here.
The basic block language
We are using the same block langague that we used in a previous tip. This time, however, we allow the aliases to use the this
keyword in the alias field.
block Block1 {
field field1
field field2
block SubBlock {
field field2
}
alias field3 aliases this.field2
}
The block language with this
support
The contextual FQNs are implemented at the level of the ScopeProvider
. Xtext allows us to provide a scope and a custom FQN for each element of that scope. In the following snippet, we can see how we create a custom FQN with the name and the keyword this
for all elements defined in the same block.
package com.idiomaticsoft.dsl.block.scoping;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.Scopes;
import com.idiomaticsoft.dsl.block.block.Block;
import com.idiomaticsoft.dsl.block.block.BlockPackage;
public class BlockScopeProvider extends AbstractBlockScopeProvider {
@Override
public IScope getScope(EObject context, EReference reference) {
if (reference.equals(BlockPackage.Literals.ALIAS__ALIAS)) {
Block block = (Block) context.eContainer();
return Scopes.scopeFor(block.getMembers(), p -> QualifiedName.create("this", p.getName()),
super.getScope(context, reference));
}
return super.getScope(context, reference);
}
}
This enables us to have a different FQN for different contexts but always referring to the same object.