The new Xtext version in Galileo changed a few things. To do scoping, a little bit of Java development is necessary. Documentation is very brief, but with a little research it is quite easy. Consider the following grammar, that allows us to define components, instances of those components and – the interesting part here – connect ports of instances:
Component :
   "component" name = ID "{"
   (ports+=Port)*
   "}";
Port :
   "port" dir=Direction name=ID ":" ref=[Interface|ID] ";"
   ;
enum Direction :
   IN="in" | OUT="out";
Instance:
   "instance" name=ID ":" type=[Component|ID] ";"
   ;
Connection:
   "connect" in=[Instance|ID]"."p=[Port|ID] "->" in2=[Instance|ID]"."p2=[Port|ID] ";"
   ;
The default code completion will traverse all defined Ports for the references p and p2 in the Connection rule. A better behaviour would be:
- Show only the ports in the instances (in, in2)
- For p, show only “OUT”-Ports, for p2, show only “IN”-ports.
To do this, we need to define methods in a class derived from AbstractDeclarativeScopeProvider. The method names follow the signature scope_<rule>_<element>, so the code fragment for p2 is:
IScope scope_Connection_p2(Connection ctx, EReference ref)
   {
      if(ctx.getIn2() == null )
         return IScope.NULLSCOPE;
      else
         return new SimpleScope(IScope.NULLSCOPE, getRPorts(ctx.getIn2().getType()));
   }
With some additional code the full Provider for p and p2 looks like this:
public class AutomotiveDSLScopeProvider extends AbstractDeclarativeScopeProvider {
   IScope scope_Connection_p2(Connection ctx, EReference ref)
   {
      if(ctx.getIn2() == null )
         return IScope.NULLSCOPE;
      else
         return new SimpleScope(IScope.NULLSCOPE, getRPorts(ctx.getIn2().getType()));
   }
   IScope scope_Connection_p(Connection ctx, EReference ref)
   {
      if(ctx.getIn() == null )
         return IScope.NULLSCOPE;
      else
         return new SimpleScope(IScope.NULLSCOPE, getPPorts(ctx.getIn().getType()));
   }
   private Iterable<IScopedElement> getPPorts(Component clazz) {
      List<IScopedElement> result = new ArrayList<IScopedElement>();
      for (Port f : clazz.getPorts())
         if (f instanceof Port && f.getDir() == Direction.OUT)
            result.add(ScopedElement.create(f.getName(), f,"("));
      return result;
   }
   private Iterable<IScopedElement> getRPorts(Component clazz) {
      List<IScopedElement> result = new ArrayList<IScopedElement>();
      for (Port f : clazz.getPorts())
         if (f instanceof Port && f.getDir() == Direction.IN)
            result.add(ScopedElement.create(f.getName(), f));
      return result;
   }
}
Hello,
Please, can you post the whole Xtext-grammar?
It is not possible to write a “Instance” or “Connection”-rule in the created editor. And what do you mean with the rule “Interface”?
Thanks!
Thomas V.
The grammar is only an excerpt to show the scoping. I might publish more of it when I have time.
Scoping is not very well documented. Could you please provide an example for the new Xtext 1.0
Hmm, according to the documentation, the Declarative Scoping is still the same. The documentation about scoping is at http://www.eclipse.org/Xtext/documentation/1_0_0/xtext.html#scoping
Is there a specific problem that you encounter?