<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>5ise &#187; scoping</title>
	<atom:link href="http://5ise.quanxinquanyi.de/tag/scoping/feed/" rel="self" type="application/rss+xml" />
	<link>http://5ise.quanxinquanyi.de</link>
	<description>Andreas Graf&#039;s Software Engineering Blog</description>
	<lastBuildDate>Fri, 03 Sep 2010 13:56:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Scoping with Xtext/TMF 0.8</title>
		<link>http://5ise.quanxinquanyi.de/2010/01/29/scoping-with-xtexttmf-08/</link>
		<comments>http://5ise.quanxinquanyi.de/2010/01/29/scoping-with-xtexttmf-08/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 13:58:04 +0000</pubDate>
		<dc:creator>Andreas Graf</dc:creator>
				<category><![CDATA[MDSD]]></category>
		<category><![CDATA[scoping]]></category>
		<category><![CDATA[xtext]]></category>

		<guid isPermaLink="false">http://5ise.quanxinquanyi.de/?p=182</guid>
		<description><![CDATA[Usually I hate it when APIs break. TMF 0.8 introduces a different scoping API than Xtext 0.7. It took me a while to figure out. So I&#8217;ll show the changes below: Component : Â Â Â  "component" name = ID "{" Â Â Â  (ports+=Port)* Â Â Â  "}"; Port : Â Â Â  "port" dir=Direction name=ID ":"Â  ref=[Interface&#124;ID] ";" Â Â Â  ; enum [...]]]></description>
			<content:encoded><![CDATA[<p>Usually I hate it when APIs break. TMF 0.8 introduces a different scoping API than Xtext 0.7. It took me a while to figure out. So I&#8217;ll show the changes below:</p>
<pre>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] "-&gt;" in2=[Instance|ID]"."p2=[Port|ID] ";"
Â Â Â  ;</pre>
<p>The default code completion will traverse all defined Ports for the  references p and p2 in the Connection rule. A better behaviour would be:</p>
<ul>
<li>Show only the ports in the instances (in, in2)</li>
<li>For p, show only &#8220;OUT&#8221;-Ports, for p2, show only &#8220;IN&#8221;-ports.</li>
</ul>
<p>To do this, we need to define methods in a class derived from  AbstractDeclarativeScopeProvider. The method names follow the signature  scope_&lt;rule&gt;_&lt;element&gt;, so the the <strong>old code fragment for</strong> was:</p>
<pre>public class AutomotiveDSLScopeProvider extends AbstractDeclarativeScopeProvider {</pre>
<pre>Â Â Â  IScope scope_Connection_p2(Connection ctx, EReference ref)</pre>
<pre>Â Â Â  {</pre>
<pre>Â Â Â  Â Â Â  if(ctx.getIn2() == null )</pre>
<pre>Â Â Â  Â Â Â  Â Â Â  return IScope.NULLSCOPE;</pre>
<pre>Â Â Â  Â Â Â  else</pre>
<pre>Â Â Â  Â Â Â  Â Â Â  return new SimpleScope(IScope.NULLSCOPE, getRPorts(ctx.getIn2().getType()));</pre>
<pre>Â Â Â  }</pre>
<pre>Â Â Â  IScope scope_Connection_p(Connection ctx, EReference ref)</pre>
<pre>Â Â Â  {</pre>
<pre>Â Â Â  Â Â Â  if(ctx.getIn() == null )</pre>
<pre>Â Â Â  Â Â Â  Â Â Â  return IScope.NULLSCOPE;</pre>
<pre>Â Â Â  Â Â Â  else</pre>
<pre>Â Â Â  Â Â Â  Â Â Â  return new SimpleScope(IScope.NULLSCOPE, getPPorts(ctx.getIn().getType()));</pre>
<pre>Â Â Â  }</pre>
<pre>Â Â Â  private Iterable&lt;IScopedElement&gt; getPPorts(Component clazz) {</pre>
<pre>Â Â Â  Â Â Â  List&lt;IScopedElement&gt; result = new ArrayList&lt;IScopedElement&gt;();</pre>
<pre>Â Â Â  Â Â Â  for (Port f : clazz.getPorts())</pre>
<pre>Â Â Â  Â Â Â  Â Â Â  if (f instanceof Port &amp;&amp; f.getDir() == Direction.OUT)</pre>
<pre>Â Â Â  Â Â Â  Â Â Â  Â Â Â  result.add(ScopedElement.create(f.getName(), f,"("));</pre>
<pre>Â Â Â  Â Â Â  return result;</pre>
<pre>Â Â Â  }</pre>
<pre>Â Â Â  private Iterable&lt;IScopedElement&gt; getRPorts(Component clazz) {</pre>
<pre>Â Â Â  Â Â Â  List&lt;IScopedElement&gt; result = new ArrayList&lt;IScopedElement&gt;();</pre>
<pre>Â Â Â  Â Â Â  for (Port f : clazz.getPorts())</pre>
<pre>Â Â Â  Â Â Â  Â Â Â  if (f instanceof Port &amp;&amp; f.getDir() == Direction.IN)</pre>
<pre>Â Â Â  Â Â Â  Â Â Â  Â Â Â  result.add(ScopedElement.create(f.getName(), f));</pre>
<pre>Â Â Â  Â Â Â  return result;</pre>
<pre>Â Â Â  }</pre>
<pre>}</pre>
<p>One of the important changes that I use different imports, because  some are deprecated and some are generally nice to use. Newly introduced  are:</p>
<p>import static org.eclipse.xtext.scoping.Scopes.*;</p>
<p>for helpful functions and</p>
<p>import com.google.common.base.Predicate;<br />
import com.google.common.collect.Iterables;<br />
import com.google.inject.Inject;</p>
<p>for working with lists. So the new code looks like this:</p>
<pre>public class AutomotiveDSLScopeProvider extends AbstractDeclarativeScopeProvider {

	protected Predicate&lt;Port&gt; pPortPred = new Predicate&lt;Port&gt;(){
		public boolean  apply(Port input) { return input.getDir() == Direction.OUT ; }
	};

	protected Predicate&lt;Port&gt; rPortPred = new Predicate&lt;Port&gt;(){
		public boolean  apply(Port input) { return input.getDir() == Direction.IN ; }
	};

	public IScope scope_Connection_p2(Connection ctx, EReference eRef)
	{
		EList&lt;Port&gt; features = ctx.getIn2().getType().getPorts();
		return scopeFor(Iterables.filter(features,rPortPred));
	}

	public IScope scope_Connection_p(Connection ctx, EReference eRef)
	{
		EList&lt;Port&gt; features = ctx.getIn2().getType().getPorts();
		return scopeFor(Iterables.filter(features,pPortPred));
	}

}</pre>
<p>Note that the scopeFor helper takes away the work of creating the newly introduced IEObjectDescription that I struggled with at first. Once you know how, migrating seems not too bad.</p>
<pre></pre>
]]></content:encoded>
			<wfw:commentRss>http://5ise.quanxinquanyi.de/2010/01/29/scoping-with-xtexttmf-08/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
