Home » Modeling » TMF (Xtext) » Restricting the scope / code suggestion(Understanding the scope provider)
Restricting the scope / code suggestion [message #697799] |
Mon, 18 July 2011 00:47  |
Eclipse User |
|
|
|
Hi,
first I want to say that I am very very happy about this framework. Thank you!
I read through many blog posts and documentations for some time, most of them very helpful. Unfortunately, some are quite hard to follow and lack of some good examples imo (i.e. the chapter about scoping[1]). I would love if someone could help me understanding this part better.
Domainmodel:
entities += Entity*
;
Entity:
'entity' name = ID '{'
features += Feature*
'}'
;
Feature:
'feature' name = ID ':' type = Type
;
Type:
baseType = BaseType | reference = [Entity]
;
enum BaseType:
String | Int
;
So here is a simple DSL similar to the one of the documentation. My questions are:
Image:[4]
- The type of a feature must not be the name of the entity wherein it is defined (so, no recursion allowed). This constraint can be easily implemented with a @Check in the validator, but it is then still contained in the proposal list.
I assume one just has to adapt the scope provider, but I am still puzzled on how to use it properly. I think one has to start with a function as described in the documentation[2]:
IScope scope_Feature_type(Type ctx, EReference ref)
But how can I restrict the automatically created scope, or simply create a new one? Does the injected IScopeProvider offer help here? I think I nee something similar to this[3], but this code seems to use a rather old version.
- The type of the feature can either be a predefined (static) type, or a reference to an entity. Is there a more easy or elegant way to express this rule? How would you do it?
Any help is very appreciated. Thank you.
(I cannot use links yet)
[1]http //www.eclipse.org/Xtext/documentation/2_0_0/080-scoping.php
[2]http //www.eclipse.org/Xtext/documentation/2_0_0/080-scoping.php#local_scoping
[3]http //chilifreak.wordpress.com/2010/02/22/extending-proposals-in-xtext-using-scoping/
[4]http //s4.postimage.org/5zfdmtfbh/Reference1.png
|
|
| | | |
Re: Restricting the scope / code suggestion [message #697982 is a reply to message #697828] |
Mon, 18 July 2011 10:37   |
Eclipse User |
|
|
|
Hi Alex,
thank you very much for your explanation and the hint to the code completion and the filtering methods.
In fact, I tried it the way you proposed and the concept for Content Assist[1] is much easier to understand than scoping (combined with debugging) 
I want to show the code that I used to make it more understandable for people coming to a similar issue. With the Validator and the ProposalProvider it pretty much does exactly what I was hoping for. Anyway I have a few further quetions.
  
At first, the code for the validator:
public class EntityDslJavaValidator extends AbstractEntityDslJavaValidator {
@Check
public void checkEntityRecursion(Feature feature) {
checkEntityRecursion(feature, (Entity)feature.eContainer());
}
public void checkEntityRecursion(Feature feature, Entity rootEntity) {
if (feature.getType() == null) return;
Entity referencedEntity = feature.getType().getReference();
if (referencedEntity == rootEntity) {
error("A type is not allowed to be used recursively by its feature list", EntityDslPackage.Literals.FEATURE__TYPE);
} else if (referencedEntity != null) {
for (Feature f: referencedEntity.getFeatures()) {
checkEntityRecursion(f, rootEntity);
}
}
}
}
And the code for the ProposalProvider:
public class EntityDslProposalProvider extends AbstractEntityDslProposalProvider {
@Override
public void completeType_Reference(EObject model, Assignment assignment,
ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
lookupCrossReference(((CrossReference)assignment.getTerminal()), context, acceptor,
new RecursiveReferenceDetector((Feature)model));
}
}
class RecursiveReferenceDetector implements Predicate<IEObjectDescription> {
private final Entity rootEntity;
public RecursiveReferenceDetector(Feature feature) {
rootEntity = (Entity)feature.eContainer();
}
@Override
public boolean apply(IEObjectDescription input) {
return checkEntityRecursion((Entity)input.getEObjectOrProxy());
}
public boolean checkEntityRecursion(Entity referencedEntity) {
if (referencedEntity == rootEntity) {
return false;
} else if (referencedEntity != null) {
for (Feature f: referencedEntity.getFeatures()) {
if (f.getType() == null) continue;
if (!checkEntityRecursion(f.getType().getReference())) {
return false;
}
}
}
return true;
}
}
- In the completeType_Reference function, both the context.currentModel and the model refer to the same object of type FeatureImpl. I indeed need this Feature (or its container) to complete the Type_Reference, but how does Xtext decides which model is passed? What if there are more Rules with references to Type?
- Is there a good source or example that makes the usage of the scope provider more clear? Maybe one where the scope is restricted or just somehow modified.
Moritz
[1]http //www.eclipse.org/Xtext/documentation/2_0_0/150-contentassist.php
|
|
|
Re: Restricting the scope / code suggestion [message #698064 is a reply to message #697982] |
Mon, 18 July 2011 13:51   |
Eclipse User |
|
|
|
Hi,
regarding 1) I can't give you the definition, but I can give you an idea. Usually when typing and using code completion, you have an incomplete model. The framework determines all possible continuations, i.e. valid semantic models with the given "document prefix". This is how different context objects are possible.
If there are different rules referring to Type, they would cause a different completion function to be invoked. Your job here would be to extract code to be used by all of them to helper methods.
regarding 2) Look at the community projects, the examples shipped with Xtext, search for AbstractDeclarativeScopeProvider... Search this forum for threads on scoping. And, as you did in your original post, ask specific questions about what you want to achieve. Then you are likely to get helpful pointers.
Alex
|
|
| |
Re: Restricting the scope / code suggestion [message #701342 is a reply to message #698064] |
Sun, 24 July 2011 21:38  |
Eclipse User |
|
|
|
Alexander Nittka wrote on Mon, 18 July 2011 13:51regarding 2) Look at the community projects, the examples shipped with Xtext, search for AbstractDeclarativeScopeProvider... Search this forum for threads on scoping. And, as you did in your original post, ask specific questions about what you want to achieve. Then you are likely to get helpful pointers.
Thanks again. I think the best way to get started is to I look at AbstractDeclarativeScopeProvider.getScope and and implement some of the computed methods..
I posted another question that fits to the topic of this thread, so if anyone is interested here is the link:
www.eclipse.org/forums/index.php/m/701329/#msg_701329
Daniel wrote on Tue, 19 July 2011 02:38I have an addition to this problem/solution: Think of a referenced child/parent customer or a bidirectional association you try to prevent.
Yes you're right, the code did not cover that.
blog.efftinge.de/2009/01/xtext-scopes-and-emf-index.html
zarnekow.blogspot.com/2009/01/xtext-corner-2-linking-and-scoping.html
|
|
|
Goto Forum:
Current Time: Tue Jul 22 11:41:09 EDT 2025
Powered by FUDForum. Page generated in 0.07840 seconds
|