如何从 Xtext 中的 INode 获取资源?
How to get resource from INode in Xtext?
我的 XText 语法的值转换器取决于 eclipse 首选项,因此我需要获取当前文件的项目。我试过这个:
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
}
}
}
问题出在标有问号的行中。我试过:
assign.eContainer.eResource.URI
assign.eResource.URI
node.grammarElement.eResource.URI
所有这些 return 相同 URL:classpath:/my/Language.xtextbin
这是 XText 生成的文件,不是我的资源。我做错了什么,如何获取当前正在解析的资源?
你可以向节点询问它们的父节点。以及它们的语义元素。那应该允许您检索所需的信息。或者,您也可以自定义 DefaultEcoreElementFactory。
我最后做了什么:
我创建了一个作用于文件的 Guice 作用域,并扩展了 IResourceFactory(不是 DefaultEcoreElementFactory)实现以在正确的时间进入该作用域:
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);
}
}
这样我的 ValueConverter 就可以注入正确范围内的对象(显然,它是为每个需要转换的值创建的,所以没有副作用问题。获取资源不起作用的原因是ValueConverter 在解析期间使用,解析树实际上还没有与资源相关联。资源是什么的信息位于调用链的相当高的位置,IResourceFactory 似乎是放置范围的好地方,因为 Injector 设置在那里.
我的 XText 语法的值转换器取决于 eclipse 首选项,因此我需要获取当前文件的项目。我试过这个:
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
}
}
}
问题出在标有问号的行中。我试过:
assign.eContainer.eResource.URI
assign.eResource.URI
node.grammarElement.eResource.URI
所有这些 return 相同 URL:classpath:/my/Language.xtextbin
这是 XText 生成的文件,不是我的资源。我做错了什么,如何获取当前正在解析的资源?
你可以向节点询问它们的父节点。以及它们的语义元素。那应该允许您检索所需的信息。或者,您也可以自定义 DefaultEcoreElementFactory。
我最后做了什么:
我创建了一个作用于文件的 Guice 作用域,并扩展了 IResourceFactory(不是 DefaultEcoreElementFactory)实现以在正确的时间进入该作用域:
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);
}
}
这样我的 ValueConverter 就可以注入正确范围内的对象(显然,它是为每个需要转换的值创建的,所以没有副作用问题。获取资源不起作用的原因是ValueConverter 在解析期间使用,解析树实际上还没有与资源相关联。资源是什么的信息位于调用链的相当高的位置,IResourceFactory 似乎是放置范围的好地方,因为 Injector 设置在那里.