importURI relative to reference in resource [message #760552] |
Fri, 02 December 2011 19:58 |
John J. Franey Messages: 31 Registered: July 2009 |
Member |
|
|
Here is a code sample from Task Juggler DSL (actually, TJ uses 'resource' not 'employee', but I wanted to avoid duplication of terms in my question below).
include bosses-resolves.tji
employee e1 {
managers boss
}
include bosses-not-resolves.tji
'boss' is a reference to a resource which might be defined in another file. Note that there are two include statements. If 'boss' is defined in the first resource, the reference should link. If 'boss' is only in the second resource, the reference should NOT link.
I want a global scope provider that would know not to read the resources which appear AFTER the reference. The default scope provider does not do this. In fact, the IGlobalScopeProvider interface does not support it.
Java wants all its imports up front, so I think the default IGlobalScopeProvider was designed for that. But, some languages, I think, permit import statements AFTER other statements and the names in that latter import files would not resolve in earlier statements. So, I don't think I am marking new territory with Task Juggler dsl.
I've been creating my own scope providers in this project. I have no issue creating a new one to replace the default global scope provider. I just want to make sure I'm on the right path before I go off and make some deep cuts.
I plan to derive from one of xtext's global scope providers (ImportUriGlobalScopeProvider) and add a method that takes an EObject corresponding to the reference's container. The implementation will calculate the position of this EObject in the model and filter out imports that appear later. Only resources that appear before the EObject will be scanned.
That is the heart. There are some other pieces I have to put up: the import scope delegate needs to be extended to cast the global scope provider and call the new method with the right EObject.
Alternatively, I looked into creating a validation that checks the reference is present in an earlier include. But if the linker is used without the validator (I don't know enough), this would not be a good answer.
Thanks for listening.
|
|
|
|
Re: importURI relative to reference in resource [message #760654 is a reply to message #760648] |
Sat, 03 December 2011 21:45 |
John J. Franey Messages: 55 Registered: July 2009 |
Member |
|
|
Quote:
validating if the import is defined before the actual reference would allow for helpful error messages (rather than just "could not resolve reference" without giving the cause). The bug/feature here is, that the element is still linked. I tend to consider this a feature. The user can still navigate to the linked object and see, if it is the one wanted (and in your use case possibly place the import correctly). If the element is not linked at all, it is harder to find out what the actual error is.
Well, I'll have to disagree on a few grounds, but you make a good case.
Even if I went along with your point of view, I still have to manage the possibility that there are two definitions, one in each include file, that could satisfy the reference and I would have to make sure the linker would pick the preceding one, in accordance to the language design. So, I still need the scope provider to populate scope related to the position of the reference in the model.
Quote:
Of course you would have to adapt code completion in order to suggest only correct elements. So you will have more work to do going this way, but the user gets better tooling.
I'm still learning xtext. I take if from your point that code completion is using the scoping api to suggest possible references to the user?
Quote:
As to adapting the scoping... Overriding the method for calculating the imported URIs in the ImportUriGlobalScopeProvider is not a deep cut at all.
Well, its not quite as simple. Both IScopeProvider and IGlobalScopeProvider do not have a getScope method that tracks the original reference's context. These getScope methods are called recursively and without passing down the original reference context. In other words, overriding the global scope provider's IGlobalScopeProvider.getScope method is not an option. So, the deep cut I have in mind is to implement a getScope replacement for each of these that the recursion calls could use to pass down the original context of the reference. Essentially, my idea is to replace and avoid the xtext provided IScopeProvider and IGlobalScopeProvider because getScope, the only method each have, is not useful. So that is why I call it a 'deep cut'.
I'm grateful that itemis has opened the source code so that I could learn how their default implementations work, and either extend them or replace them. Good stuff all around.
|
|
|
|
Powered by
FUDForum. Page generated in 0.03679 seconds