Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » local scope, qualified name and Cyclic resolution of lazy links(How to get the name of a cross-reference)
local scope, qualified name and Cyclic resolution of lazy links [message #707310] Mon, 01 August 2011 13:35 Go to next message
alex.ren2006 is currently offline alex.ren2006Friend
Messages: 46
Registered: June 2011
Member
Hi all, I am currently building an IDE for ATS (www.ats-lang.org). With your help (http://www.eclipse.org/forums/index.php/t/226107/ http://www.eclipse.org/forums/index.php/t/226022/), I made progress dealing with local scope. Now I got into some problems dealing with both scope and cross-reference. For clarity, I use the following sample grammar for language "Myscope".
=================================================
grammar org.xtext.example.mydsl.MyScope with org.eclipse.xtext.common.Terminals

generate myScope "http://www.xtext.org/example/mydsl/MyScope"

Program:
	body
;

body: {body}
	mdec+=scopedec*
	(mscope+=scope
	| mdef+=def
	)*
;

scopedec:
	'extern' 'scope' ent=ID
;
scope: {scope}'scope' entity=[scopedec | ID] mbody=body 'end';

def: name=ID '=' (mint=INT | mval=[def | ID]);
=================================================
The corresponding source code would be something like this
=================================================
extern scope sz
xx = 3
ze = 4
scope sz  
  xx = 3
  qq = 4  
  rr = xx
  ze = 4
  ff = ze
end
=================================================

I bind my own "MyScopeQualifiedNameProvider" to the runtime. The code goes as follows
=======================================

public class MyScopeQualifiedNameProvider extends
		DefaultDeclarativeQualifiedNameProvider {
	
	@Inject
	private IQualifiedNameConverter converter = new IQualifiedNameConverter.DefaultImpl();
	
	private int counter = 3;
	private Hashtable<EObject, String> nametable = new Hashtable<EObject, String>();

	public QualifiedName getFullyQualifiedName(final EObject obj) {
		QualifiedName t = super.getFullyQualifiedName(obj);
		if (obj instanceof scope) {
			String name = nametable.get(obj);
			if (name == null) {
				name = ((scope)obj).getEntity().getEnt();
				// name = Integer.toString(counter++);
				System.out.println("====================" + name);
				
				nametable.put(obj, name);
			}
			t=converter.toQualifiedName(name);
		}
		if (t != null) {
			System.out.println("====================" + t.toString());
		}
		return t;
	}

}
=====================================

But when I run the eclipse application, I got the following error
====================
An internal error occurred during: "XtextReconcilerJob".
Cyclic resolution of lazy links : scope.entity->scope.entity
=====================

I guess it has something to do with the cross-reference which I didn't understand very well. In my code, I really want to get the corresponding string of scope. How can I do it? Thanks a lot.
Re: local scope, qualified name and Cyclic resolution of lazy links [message #707327 is a reply to message #707310] Mon, 01 August 2011 14:10 Go to previous messageGo to next message
Alexander Nittka is currently offline Alexander NittkaFriend
Messages: 1193
Registered: July 2009
Senior Member
Hi,

the basic problem is that your name calculation requires cross references to be resolved. If I understand you correctly, the solution to your problem should be simply to extract the text of the entity-feature from the node model. Check out available methods in the Node(Model)Utils class for navigating from the semantic model to the parse tree model.

Alex


Need training, onsite consulting or any other kind of help for Xtext?
Go visit http://xtext.itemis.com or send a mail to xtext@itemis.de
Re: local scope, qualified name and Cyclic resolution of lazy links [message #707341 is a reply to message #707327] Mon, 01 August 2011 14:22 Go to previous messageGo to next message
alex.ren2006 is currently offline alex.ren2006Friend
Messages: 46
Registered: June 2011
Member
Thank you very much Alexander.

Let me make it more clear. For the following code, I just want to get the string "bbb" when handle the "scope".
=======================
extern scope aaa
xx = 3
scope bbb
  xx = 3
  rr = xx
end
=======================

I don't want to jump to the actual referred ojbect. Therefore, I think your suggestion is what I need.

[Updated on: Mon, 01 August 2011 14:30]

Report message to a moderator

Re: local scope, qualified name and Cyclic resolution of lazy links [message #707383 is a reply to message #707341] Mon, 01 August 2011 15:26 Go to previous messageGo to next message
alex.ren2006 is currently offline alex.ren2006Friend
Messages: 46
Registered: June 2011
Member
The following is my new "MyScopeQualifiedNameProvider". It works well.
=============================================
package org.xtext.example.mydsl.naming;

import java.util.Collections;
import java.util.Hashtable;

import org.eclipse.xtext.nodemodel.BidiIterator;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.naming.DefaultDeclarativeQualifiedNameProvider;
import org.eclipse.xtext.naming.IQualifiedNameConverter;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.util.IResourceScopeCache;
import org.eclipse.xtext.util.PolymorphicDispatcher;
import org.eclipse.xtext.util.SimpleAttributeResolver;
import org.eclipse.xtext.util.Strings;
import org.eclipse.xtext.util.Tuples;

import org.xtext.example.mydsl.myScope.scope;
import org.xtext.example.mydsl.myScope.scopedec;

import com.google.common.base.Function;
import com.google.inject.Inject;
import com.google.inject.Provider;

public class MyScopeQualifiedNameProvider extends
		DefaultDeclarativeQualifiedNameProvider {

	private PolymorphicDispatcher<QualifiedName> qualifiedName = new PolymorphicDispatcher<QualifiedName>(
			"qualifiedName", 1, 1, Collections.singletonList(this),
			PolymorphicDispatcher.NullErrorHandler.<QualifiedName> get()) {
		@Override
		protected QualifiedName handleNoSuchMethod(Object... params) {
			return null;
		}
	};

	@Inject
	private IQualifiedNameConverter converter = new IQualifiedNameConverter.DefaultImpl();

	@Inject
	private IResourceScopeCache cache = IResourceScopeCache.NullImpl.INSTANCE;

	private Function<EObject, String> resolver = SimpleAttributeResolver
			.newResolver(String.class, "name");

	protected Function<EObject, String> getResolver() {
		return resolver;
	}

	private int counter = 0;
	private Hashtable<EObject, String> nametable = new Hashtable<EObject, String>();

	public QualifiedName getFullyQualifiedName(final EObject obj) {
		return cache.get(Tuples.pair(obj, "fqn"), obj.eResource(),
				new Provider<QualifiedName>() {

					public QualifiedName get() {
						EObject temp = obj;
						String name = null;
						if (temp instanceof scope) {
							name = nametable.get(temp);
							if (name == null) {
								// name = ((scope)temp).getEntity().getEnt();
								ICompositeNode cnode = NodeModelUtils
										.findActualNodeFor(temp);
								BidiIterator<INode> iter = cnode.getChildren()
										.iterator();
								int k = 0;
								while (iter.hasNext()) {
									name = NodeModelUtils.getTokenText(iter
											.next());
//									System.out.println("===================="
//											+ name + "_" + k);
									if (4 == k) {
										break;
									}
									k++;
								}
								nametable.put(temp, name);
							}
						} else if (temp instanceof scopedec) {
							name = ((scopedec) obj).getEnt();
						} else {
							QualifiedName qualifiedNameFromDispatcher = qualifiedName
									.invoke(temp);
							if (qualifiedNameFromDispatcher != null)
								return qualifiedNameFromDispatcher;
							name = getResolver().apply(temp);
							if (Strings.isEmpty(name))
								return null;
						}
						QualifiedName qualifiedNameFromConverter = converter
								.toQualifiedName(name);

						while (temp.eContainer() != null) {
							temp = temp.eContainer();
							QualifiedName parentsQualifiedName = getFullyQualifiedName(temp);
							if (parentsQualifiedName != null) {
								qualifiedNameFromConverter = parentsQualifiedName
										.append(qualifiedNameFromConverter);
								break;
							}
						}
						System.out.println("===================="
						+ qualifiedNameFromConverter.toString());
						return qualifiedNameFromConverter;
					}
				});
	}

}

=======================
The only thing which makes me to feel uncomfortable is the hard coded comparison "if (4 == k)". But in the end, something has to be hard coded.

[Updated on: Mon, 01 August 2011 15:30]

Report message to a moderator

Re: local scope, qualified name and Cyclic resolution of lazy links [message #708128 is a reply to message #707383] Tue, 02 August 2011 13:46 Go to previous messageGo to next message
Alexander Nittka is currently offline Alexander NittkaFriend
Messages: 1193
Registered: July 2009
Senior Member
Hi,

I think the hard coding should not be necessary. There are at least two alternatives

a) NodeModelUtils has a method findNodesForFeature that you could query with the entity feature of scope (Use DslPackage.Literals to obtain it analogous to the validation api)
b) you could use the grammar access of your language (have it injected) and check if the grammar element you get from INode is the correct one.

Alex
Re: local scope, qualified name and Cyclic resolution of lazy links [message #884688 is a reply to message #708128] Mon, 11 June 2012 15:50 Go to previous message
Michael Vorburger is currently offline Michael VorburgerFriend
Messages: 103
Registered: July 2009
Senior Member
Thank you for pointing to NodeModelUtils.findNodesForFeature here, very useful info. FTR: I've created a new bug report issue 382266 (I can't post links here yet) suggesting this may be added to documentation.
Previous Topic:Xtend 2.3 may has a bug for generic type support
Next Topic:QualifiedNameProvider not working
Goto Forum:
  


Current Time: Thu Oct 22 21:59:02 GMT 2020

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

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

Back to the top