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.

comments powered by Disqus