Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Linking with custom bind algorithm
Linking with custom bind algorithm [message #891838] Tue, 26 June 2012 09:00 Go to next message
Jens von Pilgrim is currently offline Jens von PilgrimFriend
Messages: 313
Registered: July 2009
Senior Member
Hi,

I'm wondering how to best implement a custom bind (aka linking)
algorithm. With "custom bind algorithm" I mean a linking algorithm not
only using a qualified name, but other information, such as types of
arguments and parameters of a method call. To make the issue easy, let's
assume I want to implement the binding of a method call to a method
declaration, taking overloading etc. into account.

Let's assume a simple language, in which a method call does include the
type. Such as:
----------------------------------------------------------------------
1: foo() {}
2: foo(A,A)
3: foo(A,B) {}
4:
5: bar() {
6: foo(A,B)
7: }
----------------------------------------------------------------------
In this example, the method call (line 6) should bind to the declaration
in line 3.

How can that be implemented with Xtext. Actually, there are several
ways, I'm asking for the best solution ;-)

One trick would be to use qualified names internally, adding the type
information to the name. E.g., foo(A,A) becomes "foo_A_A" or foo(A,B)
"foo_A_B". However, this will probably cause some problematic side
effects, such as showing the weird qualified name in content assist.
Moreover, it does not work if the binding has to consider things like
type hierarchies (e.g., B could extend A).

I tried to provide a custom scope provider, filtering out non-matching
declarations. E.g.
----------------------------------------------------------------------
01: public IScope getScope(EObject context, EReference reference) {
02: if (context instanceof FunctionCall
03: && "func".equals(reference.getName())) {
04: final FunctionCall functionCall = (FunctionCall) context;
05: EObject container = functionCall.eContainer();
06: IScope scope = super.getScope(container, reference);
07:
08: Predicate<IEObjectDescription> filter =
09: new Predicate<IEObjectDescription>() {
10: public boolean apply(IEObjectDescription input) {
11: if (input.getEObjectOrProxy()
12: instanceof FunctionDecl) {
13: FunctionDecl functionDecl = (FunctionDecl)
14: input.getEObjectOrProxy();
15: return match(functionCall, functionDecl);
16: }
17: return false;
18: }
19: };
20: return new FilteringScope(scope, filter);
21: }
22: return super.getScope(context, reference);
23: }
----------------------------------------------------------------------

The match function used for filtering here (line 15) does then implement
the custom algorithm. Alternatively, this filtering could have been
implemented in the linking service.

Unfortunately, this does only work if only one match is found. That is,
in the example given, it would work if A and B are independent types. It
won't work if B is a subtype of A, which means that the function call
could bind to foo(A,A) and foo(A,B). So, while this solution would work
in certain cases, it does not work if the actual binding has to be
selected from a set of possible matches.

I was thinking about implementing my matching algorithm in the linking
resource. The ideal method would be
org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(String).
It already handles the cases of 0 or n (n>1) possible matches (by
throwing exceptions) -- all I have to to would be to adjust the n>1 case
little bit.
Unfortunately, this method does not look like intended to be overridden,
and if I try to override it, copy and paste the existing code, I run
into the problem that the it accesses some private fields.
(Besides, I'm not sure how to inject my custom resource implementation,
but I'd assume this is possible somehow).

Actually, at the moment I have a working version, using Xtext 1.x (in
which I have written a whole bunch of custom providers, services etc.).
However, I want to minimize my custom code, and since Xtext 2 provides
this nice "importedNamespace=QualifiedNameWithWildcard" feature, more or
less solving all of my problems, I'm looking for "best practice"
solution with Xtext 2.

Cheers,

Jens
Re: Linking with custom bind algorithm [message #891847 is a reply to message #891838] Tue, 26 June 2012 09:34 Go to previous messageGo to next message
Vlad Dumitrescu is currently offline Vlad DumitrescuFriend
Messages: 431
Registered: July 2009
Location: Gothenburg
Senior Member
Hi Jens,

This is no authoritative answer, but I think you should define and bind your own ILinkingService (inheriting from DefaultLinkingService and overriding getLinkedObjects). This is how I solved it for a similar situation that I have and it seems to work.

regards,
Vlad
Re: Linking with custom bind algorithm [message #891854 is a reply to message #891847] Tue, 26 June 2012 09:50 Go to previous messageGo to next message
Jens von Pilgrim is currently offline Jens von PilgrimFriend
Messages: 313
Registered: July 2009
Senior Member
Hi Vlad,

On 26.06.12 11:34, Vlad Dumitrescu wrote:
> This is no authoritative answer, but I think you should define and bind
> your own ILinkingService (inheriting from DefaultLinkingService and
> overriding getLinkedObjects).

Yeah, that's what I'm doing at this very moment ;-) However, I'm not
sure how to deal with error handling. That is, how do I best propagate
nice error messages in case of ambiguous calls, or if no method is found
at all (due to wrong types, in my case). The LazyLinkingResource has
some methods for propagating error messages to the user. How did you
solved that issue? (And thank you for the fast reply!)

Cheers,
Jens
Re: Linking with custom bind algorithm [message #891860 is a reply to message #891854] Tue, 26 June 2012 10:48 Go to previous messageGo to next message
Vlad Dumitrescu is currently offline Vlad DumitrescuFriend
Messages: 431
Registered: July 2009
Location: Gothenburg
Senior Member
I am also extending LinkingDiagnosticMessageProvider, where the messages can be customized. In my case, it's easier because I just suppress any messages: the code will get through a proper compiler anyway where all messages will be generated.

regards,
Vlad
Re: Linking with custom bind algorithm [message #891869 is a reply to message #891860] Tue, 26 June 2012 11:38 Go to previous messageGo to next message
Jens von Pilgrim is currently offline Jens von PilgrimFriend
Messages: 313
Registered: July 2009
Senior Member
On 26.06.12 12:48, Vlad Dumitrescu wrote:
> I am also extending LinkingDiagnosticMessageProvider, where the messages
> can be customized.

Thanks for that hint, I will have a look at this class.

> In my case, it's easier because I just suppress any
> messages: the code will get through a proper compiler anyway where all
> messages will be generated.

That's what I have done so far as well. However, I want to "optimize" my
code and remove redundant things, such as redundant error checking.

Cheers,
Jens
Re: Linking with custom bind algorithm [message #891873 is a reply to message #891869] Tue, 26 June 2012 11:51 Go to previous message
Vlad Dumitrescu is currently offline Vlad DumitrescuFriend
Messages: 431
Registered: July 2009
Location: Gothenburg
Senior Member
Then I hope that we are on the right track Smile It's not straightforward to get Xtext working once it needs things that don't work out of the box.

I just realized that there is more work ahead: the Xtext linker has some knowledge that the compiler doesn't and I will probably want to be able to at least warn the user that some things are not as they should. So just returning null from LinkingDiagnosticMessageProvider is just going to be the first step...

regards,
Vlad
Previous Topic:Very slow Serializer (why is it using BacktrackingSemanticSequencer?)
Next Topic:Improved ParseHelper suggestion
Goto Forum:
  


Current Time: Tue Apr 23 11:06:36 GMT 2024

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

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

Back to the top