Is it possbile to modify "ImportURI Mechanism"? [message #714833] |
Thu, 11 August 2011 11:14  |
Eclipse User |
|
|
|
I learn the feature of "Global Scopes Based On Explicit Imports (ImportURI Mechanism)" from the tutorial and use it in my project for ATS IDE (www.ats-lang.org). It seems that the generated plugin searches the imported resource starting from the folder where the current file locates. Is it possible to change this behavior so that the user can specify an absolute path for the imported resource in the DSL source code or the search can start from the project's root folder? Thanks a lot.
|
|
|
|
Re: Is it possbile to modify "ImportURI Mechanism"? [message #715259 is a reply to message #714842] |
Fri, 12 August 2011 20:22   |
Eclipse User |
|
|
|
Thanks a lot for your help. I also got some useful info from the post (http://www.eclipse.org/forums/index.php/mv/msg/207406/664109/#msg_664109). The following is what I did, it works. If I did anything inappropriate, please point it out. For clairty, I use a sample project instead of the real ATS-IDE project. The grammar goes as follows:
=============================
grammar org.xtext.example.testimport.TestImport with org.eclipse.xtext.common.Terminals
generate testImport "http://www.xtext.org/example/testimport/TestImport"
Model:
imp+=myimport*
def+=valdef*
;
myimport:
'import' importURI=STRING
;
valdef:
'val' name=ID '=' (valint=INT | valref=[valdef])
; =============================
The source code would look like this
=============================
import "folder01/folder02/ti02.testimport"
val x = 3
val y = x
val z = ti02x
val q = ti03x
val xx = ti04x ===================================
I choose to use the "ImportUriGlobalScopeProvider" so my mwe2 file contains the following fragment
===================================
// scoping and exporting API
fragment = scoping.ImportURIScopingFragment {}
fragment = exporting.SimpleNamesFragment {}
// scoping and exporting API
// fragment = scoping.ImportNamespacesScopingFragment {}
// fragment = exporting.QualifiedNamesFragment {}
// fragment = builder.BuilderIntegrationFragment {}
// provides the necessary bindings for java types integration
// fragment = types.TypesGeneratorFragment {} ===================================
To use my own "ImportUriGlobalScopeProvider" and "ImportUriResolver", I add the following to my runtime module
==================================
public Class<? extends ImportUriResolver> bindImportUriResolver() {
return MyImportUriResolver.class;
}
public Class<? extends org.eclipse.xtext.scoping.IGlobalScopeProvider> bindIGlobalScopeProvider() {
return MyImportUriGlobalScopeProvider.class;
} ==================================
"MyImportUriResolver" goes as follows
====================================
public class MyImportUriResolver extends ImportUriResolver {
@Override
public String resolve(EObject from) {
String resolvename = super.resolve(from);
if (null == resolvename) {
return resolvename;
}
System.out.println("resolve: " + resolvename);
Resource resource = from.eResource();
URI importUri = URI.createURI(resolvename);
if (EcoreUtil2.isValidUri(resource, importUri)) {
return resolvename;
}
String projname = null;
String path = from.eResource().getURI().toString();
final String platform = "platform:/resource/";
final String filesys = "file://";
if (path.startsWith(platform)) {
projname = path.substring(platform.length()).split("/")[0];
System.out.println("projname is " + projname);
resolvename = platform + projname + "/" + resolvename;
}
return resolvename;
} ==================================
Basically, I try to find the imported file based on the path of the current file. If it failed, then I try to find the imported file based on the project folder.
To add the support of "default library", "MyImportUriGlobalScopeProvider" goes as follows
==================================
public class MyImportUriGlobalScopeProvider extends
ImportUriGlobalScopeProvider {
@Override
protected LinkedHashSet<URI> getImportedUris(final Resource resource) {
LinkedHashSet<URI> temp = super.getImportedUris(resource);
temp.add(URI.createURI("platform:/resource/atstest2/ti03.testimport"));
temp.add(URI.createURI("file://G:/WORKSPACE/ti04.testimport"));
return temp;
}
} ====================================
The "temp.add(URI.createURI("platform:/resource/atstest2/ti03.testimport"));" works fine. No need to import "ti03.testimport" explicitly in the source code. But "temp.add(URI.createURI("file://G:/WORKSPACE/ti04.testimport"));" leads to strange result. When I press CTRL and move the cursor over the name referencing to certain element defined in "ti04.testimport", the cursor turns into hyper-link. And there is no error report for "cross reference cannot be found". So it seems the cross-reference has been resolved successfully. But when I actually click the mouse, the file "ti04.testimport" is not opened at all. Is there certain kind of constraint that only files in the project can be opened? Thank you once again for your help.
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.50393 seconds