【发布时间】:2016-07-25 19:32:15
【问题描述】:
我在我的 Eclipse 插件中使用的 xtext 中有一个 dsl 语法。 在插件中,用户手动创建一个新文件(如https://eclipse.org/Xtext/documentation/102_domainmodelwalkthrough.html 中的 blog.dmodel 文件)
在我的插件代码中,当用户在 dmodel 文件中右键单击时,他可以从右键菜单中选择一个选项,该选项会触发一个名为 traverseAST() 的方法 该方法目前找到了
IWorkspaceRoot root = workspace.getRoot();
IProject project = root.getProject(projectName);
IFolder folder = project.getFolder(path);
IFile file = folder.getFile(fileName);
我知道 IFile 不是我可以用来遍历 AST 的,所以我正在尝试以下方法
@Inject
static ResourceSet resourceSet;
public traverseAST(){
IWorkspaceRoot root = workspace.getRoot();
IProject project = root.getProject(projectName);
IFolder folder = project.getFolder(path);
IFile file = folder.getFile(fileName);
org.eclipse.emf.common.util.URI uri = org.eclipse.emf.common.util.URI.createPlatformResourceURI(file.getFullPath().toString(), true);
ResourceSet set = new ResourceSetImpl();
Resource resource = set.createResource(uri);
TreeIterator<Object> x1 = EcoreUtil.getAllContents(resource, true);
TreeIterator<Object> x2 = EcoreUtil.getAllContents(resource, false);
}
我的资源是org.eclipse.xtext.linking.lazy.LazyLinkingResource@1230a38d uri='platform:/resource/demo/src/blog.dmodel'
但是 x1 和 x2 都是空的。
我做错了什么?
_____编辑______ 根据 Christian Dietrich 的建议,我的代码现在是
IWorkspaceRoot root = workspace.getRoot();
IProject project = root.getProject(projectName);
IFolder folder = project.getFolder(path);
IFile file = folder.getFile(fileNameWithoutExtension + suffix);
org.eclipse.emf.common.util.URI uri = org.eclipse.emf.common.util.URI.createPlatformResourceURI(file.getFullPath().toString(), true);
IResourceSetProvider rs1 = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(uri).get(IResourceSetProvider.class);
ResourceSet rs = rs1.get(project);
Resource r = rs.getResource(uri, true);
uri 的值为
platform:/resource/demo/src/blog.dmodel
rs1 是
org.eclipse.xtext.ui.resource.XtextResourceSetProvider@2faab150
FactoryProxy[key=Key[type=org.eclipse.xtext.resource.XtextResourceSet, annotation=[none]], provider=com.google.inject.internal.ConstructorBindingImpl$Factory@6185cb4d]
rs 是org.eclipse.xtext.resource.SynchronizedXtextResourceSet@39fcefea resources=[org.eclipse.xtext.linking.lazy.LazyLinkingResource@25d48650 uri='platform:/resource/demo/src/blog.dmodel']
r 是
org.eclipse.xtext.linking.lazy.LazyLinkingResource@25d48650 uri='platform:/resource/demo/src/blog.dmodel'
但内容是[]
编辑 2_
每个请求共享更多代码。
我的 Eclipse 菜单处理程序代码 BaseMenuHandler.java 当用户单击下拉菜单中的选项时,将激活以下代码。这是 Eclipse 菜单的标准选项 静态公共类 InsertEvents { @覆盖 公共对象执行(ExecutionEvent 事件)抛出 ExecutionException { IWorkspace 工作区 = ResourcesPlugin.getWorkspace(); IWorkbenchPage 页面 = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); Traverse.traverseAST(页面,工作区); }
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.xtext.resource.IResourceServiceProvider;
import org.eclipse.xtext.ui.resource.IResourceSetProvider;
public class Traverse{
public static void traverseAST(IWorkbenchPage page, IWorkspace workspace) {
IFile ifile = getSelectedIFile();
if (ifile != null) {
String fileName = ifile.getName();
String fileNameWithoutExtension = fileName.replace(ifile.getFileExtension().toString(), "");
String projectName = ifile.getProject().getName();
String path = ifile.getProjectRelativePath().toString().replace("/" + fileName, "");
IWorkspaceRoot root = workspace.getRoot();
IProject project = root.getProject(projectName);
IFolder folder = project.getFolder(path);
IFile file = folder.getFile(fileNameWithoutExtension + "dmodel");
if (suffix.equals("dmodel")){
String path1 = file.getFullPath().toString();
org.eclipse.emf.common.util.URI uri = org.eclipse.emf.common.util.URI.createPlatformResourceURI(file.getFullPath().toString(), true);
IResourceSetProvider rs1 = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(uri).get(IResourceSetProvider.class);
ResourceSet rs = rs1.get(project);
Resource r = rs.getResource(uri, true);
TreeIterator<Object> x1 = EcoreUtil.getAllContents(r, true);
TreeIterator<Object> x2 = EcoreUtil.getAllContents(r, false);
}
}
blog.dmodel 代码是 15 分钟的教程,这里没有任何更改: https://eclipse.org/Xtext/documentation/102_domainmodelwalkthrough.html ____编辑 3____ 跟随我们的谈话 我在 xtext 项目 (blog.mydsl) 下创建了 main
package blog.mydsl;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.example.domainmodel.DomainmodelStandaloneSetup;
import com.google.inject.Injector;
public class Main {
public static void main(String[] args) {
URI uri = URI.createURI("/Users/Desktop/demo.mydsl");
Injector i = new DomainmodelStandaloneSetup().createInjectorAndDoEMFRegistration();
ResourceSet rs = i.getInstance(ResourceSet.class);
Resource r = rs.getResource(uri, true);
TreeIterator<Object> x1 = EcoreUtil.getAllContents(r, true);
while (x1.hasNext()) {
System.out.println(x1.next());
}
TreeIterator<Object> x2 = EcoreUtil.getAllContents(r, false);
while (x2.hasNext()) {
System.out.println(x2.next());
}
}
}
这似乎有效。 因为我没有做类似以下的事情 注射器 i = new DomainmodelStandaloneSetup().createInjectorAndDoEMFRegistration(); 在我的原始代码中,这应该是要走的路吗? 我应该将插件代码移动到 blog.mydsl src 文件夹吗? 我应该查看 URI 吗?
【问题讨论】: