Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Context sensitive implicit namespace imports
Context sensitive implicit namespace imports [message #922934] Tue, 25 September 2012 13:16 Go to next message
Andrew Gacek is currently offline Andrew Gacek
Messages: 32
Registered: October 2011
Member
I have a language where a scope needs to be reopen in a different location from where it is initially introduced. My plan is to use context sensitive implicit namespace imports to implement this. I've created a toy language to illustrate the problems I'm having with this approach. An example is

node A
decls x y z
uses x y z

mixin_node A
decls w x
uses w x y z


Here node A introduces a scope where x, y, and z are declared. Then we introduce a mixin for node A which introduces new variables w and x, and it refers to both these new variables and y and z from node A. Here is a grammar I'm using for this example:

Model:
	(nodes+=Node)*
	(mixins+=MixinNode)*;
	
Node:
	'node' name=ID
	'decls' (decls+=Var)*
	'uses' (uses+=Use)*
;

Var:
	name=ID
;

Use:
	var=[Var]
;

MixinNode:
	'mixin_node' node=[Node]
	'decls' (decls+=Var)*
	'uses' (uses+=Use)*
;


I handle the scoping by overriding ImportedNamespaceAwareLocalScopeProvider as follows:

public class MydslImportedNamespaceAwareLocalScopeProvider extends
		ImportedNamespaceAwareLocalScopeProvider {

	@Override
	protected List<ImportNormalizer> internalGetImportedNamespaceResolvers(final EObject context,
			boolean ignoreCase) {

		List<ImportNormalizer> result = super.internalGetImportedNamespaceResolvers(context,
				ignoreCase);

		if (context instanceof Use) {
			MixinNode mixinNode = EcoreUtil2.getContainerOfType(context, MixinNode.class);
			if (mixinNode != null) {
				String namespace = mixinNode.getNode().getName() + ".*";
				ImportNormalizer resolver = createImportedNamespaceResolver(namespace, false);
				result.add(resolver);
			}
		}
		return result;
	}
}


This almost works, but leaves me with many questions.

1. Overall, is this the right way to go about this?

2. I only apply the implicit namespace when context is an instance of Use. Ideally I'd like to apply it to an instance of MixinNode, but this creates a cycle when I try to call mixinNode.getNode(). Really the implicit namespace should only apply to [Var] references and not [Node] references, but I don't see any way to do this without overriding a lot of code.

3. This solution does not properly handle shadowing. In the above example, a use of x in the mixin_node gets linked to the declaration of x in node A rather than in the local declaration in the mixin node. Is there a way to fix this?

Thanks,
Andrew
Re: Context sensitive implicit namespace imports [message #923065 is a reply to message #922934] Tue, 25 September 2012 15:16 Go to previous message
Andrew Gacek is currently offline Andrew Gacek
Messages: 32
Registered: October 2011
Member
I found this post which has given a lot of helpful information. In particular, overriding internalGetImportedNamespaceResolvers is reasonable and I can do it without triggering a cyclic error as follows:

@Override
protected List<ImportNormalizer> internalGetImportedNamespaceResolvers(final EObject context, boolean ignoreCase) {

	List<ImportNormalizer> result = super.internalGetImportedNamespaceResolvers(context, ignoreCase);

	if (context instanceof MixinNode) {
		MixinNode mixinNode = (MixinNode) context;
		INode node = NodeModelUtils.findNodesForFeature(mixinNode,
				MyDslPackage.Literals.MIXIN_NODE__NODE).get(0);
		String namespace = node.getText() + ".*";
		ImportNormalizer resolver = createImportedNamespaceResolver(namespace, false);
		result.add(resolver);
	}
	return result;
}


Also, I can fix the shadowing by defining my own local scope in this case:

public class MyDslScopeProvider extends AbstractDeclarativeScopeProvider {
	IScope scope_Var(MixinNode mixinNode, EReference ref) {
		return Scopes.scopeFor(mixinNode.getDecls(), delegateGetScope(mixinNode, ref));
	}
}


I'm not sure if delegateGetScope is the right thing to call here in order to get the outer scope, but it seems to work fine.

-Andrew
Previous Topic:Saving model in DSL format
Next Topic:Simple Xtext editor for a part of a complex grammar
Goto Forum:
  


Current Time: Tue Sep 16 11:37:03 GMT 2014

Powered by FUDForum. Page generated in 0.01738 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software