Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Class / Method Resolution Issue
Class / Method Resolution Issue [message #1107768] Thu, 12 September 2013 18:45 Go to next message
David Hofmann is currently offline David Hofmann
Messages: 14
Registered: March 2013
Junior Member
Hey all,

I implemented an Xtext-based DSL for an existing object-oriented language. Now I am struggling with the ScopeProvider.

Currently I have lots of classes in my Runtime Eclipse Workspace, which depend on each other (Classes extending other ones, expressions using methods of other classes, etc.)

I injected an instance of IResourceDescriptions to use the Index to resolve classes / methods. (is that the right way?)

The problem:
When I clean the project and it is rebuilt again (lots of resource descriptions are written), all resources have lots of errors, because methods can not be resolved (classes work). However, when I open a resource in the editor, do a small modification (e.g. adding a space or linebreak) the resource is re-validated and all resolution errors disappear. So the ScopeProvider logic seems to be implemented correctly. In "live-editing" mode everything is fine, but not when the workspace is (re)built.

Do you have any clue what could be wrong here?
Maybe it is a problem with the indexing order? When every class inherits from Object, then Object (and the contained methods) must be indexed before the other classes...right? Maybe this reference stays a proxy and that's why it can't be resolved? I had to do some manual resolving in the ScopeProvider, since some instances returned from IResourceDescriptions.getExportedObjects* are proxies.

Additional question regarding performance:
My current implementation is not performance optimized, e.g. for every method call applied to a expression (like someVar.method()) I don't know the type of (it's a dynamically typed language...) I query the IResourceDescriptions for all methods available. Does the IResourceDescriptions implementation use caching/optimization of any kind? Or do I have to care about optimization here?

Thanks for any hints!
Dave

[Updated on: Thu, 12 September 2013 18:54]

Report message to a moderator

Re: Class / Method Resolution Issue [message #1107946 is a reply to message #1107768] Fri, 13 September 2013 01:38 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 5847
Registered: July 2009
Senior Member
Hi the default mechanism uses the index as well. Could you show us
with an example what you are actually doing

--
Need training, onsite consulting or any other kind of help for Xtext?
Go visit http://xtext.itemis.com or send a mail to xtext at itemis dot de
Re: Class / Method Resolution Issue [message #1107962 is a reply to message #1107768] Fri, 13 September 2013 02:12 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 25744
Registered: July 2009
Senior Member
David,

Just a thought... This sounds like problems I had developing Xcore. In
that case it was very important to respect the second argument of
org.eclipse.xtext.resource.IDerivedStateComputer.installDerivedState(DerivedStateAwareResource,
boolean). I.e., resource descriptions are created without linking so
it's important to be able to load the resource in a way that doesn't
involve resolving proxies during the prelinking phase. It should be
possible to load a resource in order to index it, but that step should
not cause/require any other resources to be loaded (as happens when you
resolve cross document proxies).


On 13/09/2013 12:45 AM, David Hofmann wrote:
> Hey all,
>
> I implemented an Xtext-based DSL for an existing object-oriented
> language. Now I am struggling with the ScopeProvider.
>
> Currently I have lots of classes in my Runtime Eclipse Workspace,
> which depend on each other (Classes extending other ones, expressions
> using methods of other classes, etc.)
>
> I injected an instance of IResourceDescriptions to use the Index to
> resolve classes / methods. (is that the right way?)
>
> The problem:
> When I clean the project and it is rebuilt again (lots of resource
> descriptions are written), all resources have lots of errors, because
> methods can not be resolved (classes work). However, when I open a
> resource in the editor, do a small modification (e.g. adding a space
> or linebreak) the resource is re-validated and all resolution errors
> disappear. So the ScopeProvider logic seems to be implemented
> correctly. In "live-editing" mode everything is fine, but not when the
> workspace is (re)built.
>
> Do you have any clue what could be wrong here?
> Maybe it is a problem with the indexing order? When every class
> inherits from Object, then Object must be indexed before the other
> classes...right? Maybe this reference stays a proxy and that's why it
> can't be resolved?
>
> What made me wonder:
> I had to do some manual resolving in the ScopeProvider, since some
> instances returned from IResourceDescriptions.getExportedObjects* are
> proxies.
>
> Additional question regarding performance:
> My current implementation is not performance optimized, e.g. for every
> method call applied to a expression (like someVar.method()) I don't
> know the type of (it's a dynamically typed language...) I query the
> IResourceDescriptions for all methods available. Does the
> IResourceDescriptions implementation use caching/optimization of any
> kind? Or do I have to care about optimization here?
>
> Thanks for any hints!
> Dave
>
Re: Class / Method Resolution Issue [message #1108094 is a reply to message #1107768] Fri, 13 September 2013 06:27 Go to previous messageGo to next message
David Hofmann is currently offline David Hofmann
Messages: 14
Registered: March 2013
Junior Member
I'm trying to illustrate this with an example. The goal is to provide a scope for "chained" method calls like this:

identifier.methodA()[.methodB()...]


in some cases I can provide a specific Scope, e.g. for

"myString".asSymbol


I only provide a scope for the dynamic methods of the class String. In other cases, like in the following, I don't have any type information (language is dynamically typed) and therefore I have to provide a scope of all methods available in all classes:

printOn { arg stream;
    stream.putAll(this.asString);
}


Here we can not know of which type the parameter stream is, but for the instance variable "this" we can provide a more specific scope.

So basically, for all scopes to be provided the algorithm goes like this:
- Look for the element left of the method call
- If the type is derivable, provide a scope of all dynamic methods of that type
- else provide a scope of all methods available in all classes

Here comes the relevant ScopeProvider code:

The declarative entry point:

public IScope scope_ExplicitChainedMethodCall_method(ExplicitChainedMethodCall chainedMethodCall, EReference ref)
	{
		// get the element left of the chained method call
		final EObject contextObject = ScopingUtil.getContextObjectForCallSequence(chainedMethodCall);
		// ...and provide a scope for its type (if its derivable)
		return getScopeForContextObject(contextObject);
	}


The method trying to find out the type. If it cannot derive the type, it returns a scope for all methods (shortened):

public IScope getScopeForContextObject(final EObject contextObject) {
		final Resource resource = contextObject.eResource();
		if (contextObject instanceof StringLiteral) {
			return getDynamicMethodsOfClass("String", resource);
		}
[lots of else ifs here ...]
		else {
			return allMethods();
		}


The scope for all methods is retrieved like this:

@Inject
private IResourceDescriptions resourceDescriptions;

private IScope allMethods()
{
	final Iterable<IEObjectDescription> methodDeclarations = resourceDescriptions.getExportedObjectsByType(ClassLanguagePackage.Literals.METHOD_DECLARATION);
	return new SimpleScope(methodDeclarations);
}


And here are the methods to retrieve dynamic methods for a specific class:

private IScope getDynamicMethodsOfClass(String className, Resource resourceContext) {
		final ClassDeclaration classDeclaration = findClassByName(className, resourceContext);
		if(classDeclaration != null)
		{
			return getMethodsOfClass(classDeclaration, false, true);
		}
		LOGGER.warn("Could not find class by name: " + className);
		return IScope.NULLSCOPE;
	}

private ClassDeclaration findClassByName(String className, Resource resourceContext) {
		final QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(className);
		final Iterable<IEObjectDescription> exportedObjects = resourceDescriptions.getExportedObjects(ClassLanguagePackage.Literals.CLASS_DECLARATION, qualifiedName, false);
		for (IEObjectDescription ieObjectDescription : exportedObjects) {
			final EObject object = ieObjectDescription.getEObjectOrProxy();
			if (object instanceof ClassDeclaration) {
				ClassDeclaration classDeclaration = (ClassDeclaration) object;
				classDeclaration = ScopingUtil.resolveIfNecessary(classDeclaration, resourceContext);
				return classDeclaration;
			}
		}
		
		return null;
	}

private IScope getMethodsOfClass(ClassDeclaration classDeclaration, boolean staticMethods, boolean dynamicMethods) {
		if(classDeclaration == null || (!staticMethods && !dynamicMethods))
		{
			return IScope.NULLSCOPE;
		}
		
		Collection<MethodDeclaration> methodDeclarations = classDeclaration.getMethods();
		
		if(staticMethods && !dynamicMethods)
		{
			methodDeclarations = Collections2.filter(methodDeclarations, getStaticMethodDeclarationPredicate());
		}
		
		if(!staticMethods && dynamicMethods)
		{
			methodDeclarations = Collections2.filter(methodDeclarations, getDynamicMethodDeclarationPredicate());
		}
		
		ClassDeclaration superClass = getSuperClass(classDeclaration);
		IScope scope = Scopes.scopeFor(methodDeclarations, getMethodsOfClass(superClass, staticMethods, dynamicMethods));
		return scope;
		
	}

private ClassDeclaration getSuperClass(ClassDeclaration classDeclaration) {
		if(classDeclaration == null)
			return null;
		
		ClassReference extendedClass = classDeclaration.getExtendedClass();
		if(extendedClass == null)
		{			
			final String name = classDeclaration.getName();
			if(name == null || name.equals(OBJECT_CLASS_NAME))
			{
				return null;
			}
				
			// the class implicitly extends Object
			return findClassByName(OBJECT_CLASS_NAME, classDeclaration.eResource());
		}
		else
		{
			ClassDeclaration referencedClass = extendedClass.getReferencedClass();
			referencedClass = ScopingUtil.resolveIfNecessary(referencedClass, classDeclaration.eResource());
			return referencedClass;
		}
	}


The manual resolving stuff seems not to be the right way...
However as I said, as soon as I open files in the editor and trigger re-validation, everything is resolved properly (but not when the workspace is built, error markers everywhere).

@Ed: Thanks for your hint! I never worked with that interface, in which context do you use / call it?
Re: Class / Method Resolution Issue [message #1108102 is a reply to message #1108094] Fri, 13 September 2013 06:42 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 5847
Registered: July 2009
Senior Member
Hi did you try to simply call delegateGetScope(CTX,ref) in the "I
want all"case

--
Need training, onsite consulting or any other kind of help for Xtext?
Go visit http://xtext.itemis.com or send a mail to xtext at itemis dot de
Re: Class / Method Resolution Issue [message #1108116 is a reply to message #1108094] Fri, 13 September 2013 07:12 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 25744
Registered: July 2009
Senior Member
David,

If you're extending Xbase (I assumed you were but maybe not) then you'd
have

public Class<? extends org.eclipse.xtext.resource.IDerivedStateComputer>
bindIDerivedStateComputer() {
return org.eclipse.xtext.xbase.jvmmodel.JvmModelAssociator.class;
}

in your runtime module. That's something I needed to specialize for
Xcore, and something I needed to do carefully in a way that avoids
needing to do scoped lookups to resolve type names during the preLinking
phase...

Sorry if this isn't relevant for your scenario. It's just that your
symptoms sound exactly like the ones I saw, i.e., errors from the
validator run by the builder that just go away when you open the thing
in the editor....


On 13/09/2013 12:28 PM, David Hofmann wrote:
> I'm trying to illustrate this with an example. The goal is to provide
> a scope for "chained" method calls like this:
>
> identifier.methodA()[.methodB()...]
>
> in some cases I can provide a specific Scope, e.g. for
>
> "myString".asSymbol
>
> I only provide a scope for the dynamic methods of the class String. In
> other cases, like in the following, I don't have any type information
> (language is dynamically typed) and therefore I have to provide a
> scope of all methods available in all classes:
>
> printOn { arg stream;
> stream.putAll(this.asString);
> }
>
> Here we can not know of which type the parameter stream is, but for
> the instance variable "this" we can provide a more specific scope.
>
> So basically, for all scopes to be provided the algorithm goes like this:
> - Look for the element left of the method call
> - If the type is derivable, provide a scope of all dynamic methods of
> that type
> - else provide a scope of all methods available in all classes
>
> Here comes the relevant ScopeProvider code:
>
> The declarative entry point:
>
> public IScope
> scope_ExplicitChainedMethodCall_method(ExplicitChainedMethodCall
> chainedMethodCall, EReference ref)
> {
> // get the element left of the chained method call
> final EObject contextObject =
> ScopingUtil.getContextObjectForCallSequence(chainedMethodCall);
> // ...and provide a scope for its type (if its derivable)
> return getScopeForContextObject(contextObject);
> }
>
> The method trying to find out the type. If it cannot derive the type,
> it returns a scope for all methods (shortened):
>
> public IScope getScopeForContextObject(final EObject contextObject) {
> final Resource resource = contextObject.eResource();
> if (contextObject instanceof StringLiteral) {
> return getDynamicMethodsOfClass("String", resource);
> }
> [lots of else ifs here ...]
> else {
> return allMethods();
> }
>
>
> The scope for all methods is retrieved like this:
>
>
> @Inject
> private IResourceDescriptions resourceDescriptions;
>
> private IScope allMethods()
> {
> final Iterable<IEObjectDescription> methodDeclarations =
> resourceDescriptions.getExportedObjectsByType(ClassLanguagePackage.Literals.METHOD_DECLARATION);
>
> return new SimpleScope(methodDeclarations);
> }
>
>
> And here are the methods to retrieve dynamic methods for a specific
> class:
>
>
> private IScope getDynamicMethodsOfClass(String className, Resource
> resourceContext) {
> final ClassDeclaration classDeclaration =
> findClassByName(className, resourceContext);
> if(classDeclaration != null)
> {
> return getMethodsOfClass(classDeclaration, false, true);
> }
> LOGGER.warn("Could not find class by name: " + className);
> return IScope.NULLSCOPE;
> }
>
> private ClassDeclaration findClassByName(String className, Resource
> resourceContext) {
> final QualifiedName qualifiedName =
> qualifiedNameConverter.toQualifiedName(className);
> final Iterable<IEObjectDescription> exportedObjects =
> resourceDescriptions.getExportedObjects(ClassLanguagePackage.Literals.CLASS_DECLARATION,
> qualifiedName, false);
> for (IEObjectDescription ieObjectDescription : exportedObjects) {
> final EObject object =
> ieObjectDescription.getEObjectOrProxy();
> if (object instanceof ClassDeclaration) {
> ClassDeclaration classDeclaration = (ClassDeclaration)
> object;
> classDeclaration =
> ScopingUtil.resolveIfNecessary(classDeclaration, resourceContext);
> return classDeclaration;
> }
> }
>
> return null;
> }
>
> private IScope getMethodsOfClass(ClassDeclaration classDeclaration,
> boolean staticMethods, boolean dynamicMethods) {
> if(classDeclaration == null || (!staticMethods &&
> !dynamicMethods))
> {
> return IScope.NULLSCOPE;
> }
>
> Collection<MethodDeclaration> methodDeclarations =
> classDeclaration.getMethods();
>
> if(staticMethods && !dynamicMethods)
> {
> methodDeclarations =
> Collections2.filter(methodDeclarations,
> getStaticMethodDeclarationPredicate());
> }
>
> if(!staticMethods && dynamicMethods)
> {
> methodDeclarations =
> Collections2.filter(methodDeclarations,
> getDynamicMethodDeclarationPredicate());
> }
>
> ClassDeclaration superClass = getSuperClass(classDeclaration);
> IScope scope = Scopes.scopeFor(methodDeclarations,
> getMethodsOfClass(superClass, staticMethods, dynamicMethods));
> return scope;
>
> }
>
> private ClassDeclaration getSuperClass(ClassDeclaration
> classDeclaration) {
> if(classDeclaration == null)
> return null;
>
> ClassReference extendedClass =
> classDeclaration.getExtendedClass();
> if(extendedClass == null)
> {
> final String name = classDeclaration.getName();
> if(name == null || name.equals(OBJECT_CLASS_NAME))
> {
> return null;
> }
>
> // the class implicitly extends Object
> return findClassByName(OBJECT_CLASS_NAME,
> classDeclaration.eResource());
> }
> else
> {
> ClassDeclaration referencedClass =
> extendedClass.getReferencedClass();
> referencedClass =
> ScopingUtil.resolveIfNecessary(referencedClass,
> classDeclaration.eResource());
> return referencedClass;
> }
> }
>
>
> The manual resolving stuff seems not to be the right way...
> However as I said, as soon as I open files in the editor and trigger
> re-validation, everything is resolved properly (but not when the
> workspace is built, error markers everywhere).
>
> @Ed: Thanks for your hint! I never worked with that interface, in
> which context do you use / call it?
Re: Class / Method Resolution Issue [message #1108341 is a reply to message #1108116] Fri, 13 September 2013 14:19 Go to previous messageGo to next message
David Hofmann is currently offline David Hofmann
Messages: 14
Registered: March 2013
Junior Member
@Christian: Tried with delegation, but still no success Sad
@Ed: I'm not using Xbase, but anyway thanks very much for trying to help Smile

How would you approach this? I guess someone else must have had that chained method call problem, and possibly solved it?
Re: Class / Method Resolution Issue [message #1108443 is a reply to message #1108341] Fri, 13 September 2013 17:49 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 5847
Registered: July 2009
Senior Member
Hi,

if you use delegation:

did you change the nameprovider? what are the names shown in the open model element dialog (crtl + shift + f3)
it will only work if the methods have simple names (not containing a .)
Re: Class / Method Resolution Issue [message #1108946 is a reply to message #1108443] Sat, 14 September 2013 13:08 Go to previous messageGo to next message
David Hofmann is currently offline David Hofmann
Messages: 14
Registered: March 2013
Junior Member
Hi Christian,

the only thing I changed in my RuntimeModule is a ValueConverterService, no custom NameProvider used.
In the open model element dialog (filtered by Type MethodDeclaration) I see ~10.000 entries, method names are simple like

asString
add
build
...


Just to avoid confusion, if I use delegateGetScope() for
someVar.method()

I must provide method() as context EObject, not someVar, right?

Maybe it's a problem with the MWE Workflow configuration?
I currently use the fragment exporting.SimpleNamesFragment (since the language has no namespace concepts), but also fragment = scoping.ImportNamespacesScopingFragment {}, which might not be the right one?
Re: Class / Method Resolution Issue [message #1108953 is a reply to message #1108946] Sat, 14 September 2013 13:21 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 5847
Registered: July 2009
Senior Member
Hi,

simplenamesfragment looks perfect.
i have no idea what happens.
there must be something wrong in your code.

what happens if you do not implement scoping at all?
can you share complete copy & pasteable code?

and regarding the delegate get scope
simpy use object and erefernce from your scoping method.
Re: Class / Method Resolution Issue [message #1110459 is a reply to message #1107768] Mon, 16 September 2013 19:12 Go to previous messageGo to next message
David Hofmann is currently offline David Hofmann
Messages: 14
Registered: March 2013
Junior Member
Wow cool, if I uncomment my declarative scoping methods the method resolution works both in the editor and in the workspace build Smile (seems like my workflow fragments were not configured properly when I started to mess around with the ScopeProvider...)
However, now the resolution is only based on the name (e.g. does not respect static/dynamic context). I'm afraid the problem with multiple methods with the same name will appear frequently in a dynamically typed language anyway...Should I narrow the scopes based on the left element or simply leave it this way? What about Auto-Completion? I could restrict the proposals there but I thought it is better to restrict the scope (the "root" problem, so to say).

In the original "IDE" for the language, when trying to "jump" (CTRL+Click in Eclipse) to a method which is not unambigously resolvable, there is a dialog in which the classes having methods with that name are selectable. Is there a place where I can implement this custom behaviour with Xtext?

And there is another thing. Consider this class with some members:

MyClass
{
  var <a;
  var >b;
  classvar <>c;
}


The < sign next to the member a implies that there is a virtual getter method for that field, the > sign implies a setter method, named like the member followed by an underscore. The member c is both getable and setable in the static context. That means, the following expressions are valid:

instance.a();
instance.b_(value)
MyClass.c();
MyClass.c_(value)


My question is: Where is the best place where I can create those "virtual" derived methods (a, b_, c and c_) so that they can be resolved?

Thanks for your hints!
Re: Class / Method Resolution Issue [message #1110636 is a reply to message #1110459] Tue, 17 September 2013 02:10 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 5847
Registered: July 2009
Senior Member
Hi it should work with scoping as well

--
Need training, onsite consulting or any other kind of help for Xtext?
Go visit http://xtext.itemis.com or send a mail to xtext at itemis dot de
Re: Class / Method Resolution Issue [message #1219781 is a reply to message #1110636] Thu, 05 December 2013 13:47 Go to previous messageGo to next message
David Hofmann is currently offline David Hofmann
Messages: 14
Registered: March 2013
Junior Member
Hi Christian,
sorry for replying so late. Unfortunately I could not resolve the virtual methods issue yet.

The issue (described in my last post) was: I have members which are marked getable and setable, which implies "virtual" getter and setter methods which currently can not be resolved since they do not really exist.

Can you be more specific how I can resolve those "derived" methods in my ScopeProvider? Is it possible in a way that i can CTRL+click on the method call a() in order to jump to the member declaration "<a" in my previous example?

Thank you very much for any hints!
Re: Class / Method Resolution Issue [message #1219787 is a reply to message #1219781] Thu, 05 December 2013 14:15 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 5847
Registered: July 2009
Senior Member
Hi what about indexing The thingy under multiple names? Or aliasing
the existing ones ...

--
Need training, onsite consulting or any other kind of help for Xtext?
Go visit http://xtext.itemis.com or send a mail to xtext at itemis dot de
Re: Class / Method Resolution Issue [message #1219791 is a reply to message #1219787] Thu, 05 December 2013 14:42 Go to previous messageGo to next message
David Hofmann is currently offline David Hofmann
Messages: 14
Registered: March 2013
Junior Member
The problem is that the reference searches for objects of type "MethodDeclaration", whereas the members are of a different object type, so it won't resolve...I guess I would have to create some "dummy" method declarations then? Where would be the right place to do that? Can I customize the indexer behavior?
Re: Class / Method Resolution Issue [message #1219797 is a reply to message #1219791] Thu, 05 December 2013 15:05 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 5847
Registered: July 2009
Senior Member
Hi,

i dont know a clean solution then sry.

~Christian
Re: Class / Method Resolution Issue [message #1219798 is a reply to message #1219797] Thu, 05 December 2013 15:08 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 5847
Registered: July 2009
Senior Member
P:S: how does the derival work?
Re: Class / Method Resolution Issue [message #1219799 is a reply to message #1219798] Thu, 05 December 2013 15:14 Go to previous messageGo to next message
David Hofmann is currently offline David Hofmann
Messages: 14
Registered: March 2013
Junior Member
it basically goes like this:
member declaration <a -> virtual getter method a()
member declaration >a -> virtual setter method a_(value)
member declaration <>a -> virtual getter a() and setter a_(value)


The same is possible in the static context, but I'm gonna solve that afterwards, provided that we can find a solution here ^^
Thanks for trying to help!

[Updated on: Thu, 05 December 2013 15:15]

Report message to a moderator

Re: Class / Method Resolution Issue [message #1219801 is a reply to message #1219799] Thu, 05 December 2013 15:17 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 5847
Registered: July 2009
Senior Member
Hi,

i mean technically, what do you do?
Re: Class / Method Resolution Issue [message #1219802 is a reply to message #1219801] Thu, 05 December 2013 15:18 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 5847
Registered: July 2009
Senior Member
It sounds like:

it sounds you have a reference to member that is generated as a getter and setter but it is a reference to a member
Re: Class / Method Resolution Issue [message #1219804 is a reply to message #1219802] Thu, 05 December 2013 15:36 Go to previous messageGo to next message
David Hofmann is currently offline David Hofmann
Messages: 14
Registered: March 2013
Junior Member
I have method calls which refer to a MethodDeclaration:

ExplicitChainedMethodCall:
	(method=[MethodDeclaration|ID])
	('(' (arguments += Argument (',' arguments += Argument)*)? (',')? ')')?


In this (already existing) language you can get and set members which are marked getable and setable, but in fact the getter and setter methods are not physically there, all you need to do is to add these <> signs to the member...

So for this class:

MyClass {
    var <>member;
}


it is legal to call

myClassInstance.member()


and

myClassInstance.member_(newValue)


The ScopeProvider tries to resolve the methods member() and member_() but of course is not sucessful since they are not existing. The language uses some "standard" getter and setter implementations in the background. I want to provide an Eclipse IDE for this language, so I have to deal with those non-resolvable references somehow...hope this explains the problem more clearly.
Re: Class / Method Resolution Issue [message #1219808 is a reply to message #1219804] Thu, 05 December 2013 16:03 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 5847
Registered: July 2009
Senior Member
Hmmm,

i guess you have to rebuild half of xbase / Xtext JvmModelInferrer mechanism
Re: Class / Method Resolution Issue [message #1219876 is a reply to message #1219808] Fri, 06 December 2013 08:05 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 5847
Registered: July 2009
Senior Member
Hi,

Maybe the IDerivedStateComputer can help you with this too
icon14.gif  Re: Class / Method Resolution Issue [message #1220654 is a reply to message #1219876] Thu, 12 December 2013 17:11 Go to previous message
David Hofmann is currently offline David Hofmann
Messages: 14
Registered: March 2013
Junior Member
Thanks for the hint with the IDerivedStateComputer, Christian Smile I got it working!

Basically three bindings are needed for this (note that I am not using Xbase):

public Class<? extends IDerivedStateComputer> bindIDerivedStateComputer() {
		return ClassLanguageDerivedStateComputer.class;
	}
	
@Override
public Class<? extends XtextResource> bindXtextResource() {
	return DerivedStateAwareResource.class;
}
	
public Class<? extends IResourceDescription.Manager> bindIResourceDescriptionManager() {
		return DerivedStateAwareResourceDescriptionManager.class;
}


My IDerivedStateComputer simply adds the derived methods to the class by checking the members and their "getter/setter mark".

When Ctrl+Clicking on the references, the editor will not jump to the member but to the containing class declaration automatically, which is pretty cool! Any clue how one can specify the "textual jump target" for the derived methods to make it even better? Anyway, thank you very much for pointing me to the IDereivedStateComputer Smile
Previous Topic:Validation on a DSL file from outside the workspace
Next Topic:how to get tokens?
Goto Forum:
  


Current Time: Fri Apr 18 04:11:22 EDT 2014

Powered by FUDForum. Page generated in 0.02812 seconds