Reputation: 8163
A value converter for my XText grammar depends on an eclipse preference, so I need to get the project of the current file. I have tried this:
class IStringValueConverter extends OtherIStringValueConverter {
@Inject MyLanguageGrammarAccess grammarAccess
// this is called in toValue(String string, INode node) if some conditions are fullfilled
override correctAssignementValue(String path, INode node, AssignmentImpl assign) {
try {
val uri = assign.eContainer.eResource.URI //<<<<<< ?????
val root = ResourcesPlugin.getWorkspace().getRoot();
val file = root.getFile(new Path(uri.toPlatformString(true)));
[do something for which I need the file]
return super.correctAssignementValue(path, node, assign)
} catch (Exception ex) {
ex.printStackTrace
return path
}
}
}
The issue is in the line marked with question marks. I have tried:
assign.eContainer.eResource.URI
assign.eResource.URI
node.grammarElement.eResource.URI
All of those return the same URL: classpath:/my/Language.xtextbin
Which is a file generated by XText, and not my resource. What am I doing wrong, how can I get the resource that is currently being parsed?
Upvotes: 0
Views: 285
Reputation: 8163
What I did in the end:
I created a Guice scope which scopes on the file, and extended the IResourceFactory (not DefaultEcoreElementFactory) implementation to enter this scope at the correct time:
public class UiResourceFactory extends MyResourceFactory {
private FileScope scope;
@Inject
public UiResourceFactory(Injector injector) {
super(injector);
}
/**
* {@inheritDoc}
*/
@Override
public Resource createResource(URI uri) {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IFile file = root.getFile(new Path(uri.toPlatformString(true)));
scope.enter(file);
try {
return super.createResource(uri);
} finally {
scope.exit();
}
}
/**
* {@inheritDoc}
*/
@Override
public void setInjector(Injector injector) {
super.setInjector(injector);
scope = getInjector().getInstance(FileScope.class);
}
}
That way my ValueConverter can get correctly scoped objects injected (it is created for each value that needs to be converted, apparently, so there are no issues with side effects. The reason why getting the resource did not work is that the ValueConverter is used during parsing, the parse tree is not actually associated to the resource yet. The information what the resource is is located quite high in the call chain, IResourceFactory seemed like a good place to put the scope since the Injector is set there.
Upvotes: 0
Reputation: 11868
you can ask nodes for their parent. and for their semantic element. that should allow you to retrieve the information you need. alternatively you can customize DefaultEcoreElementFactory too.
Upvotes: 0