从项目代码遍历xtext ast

时间:2016-07-25 19:32:15

标签: java eclipse xtext

我在我的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都是空的。

我做错了什么?

_____ EDIT______ 每个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]

rsorg.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菜单的标准添加选项     static public class InsertEvents {         @覆盖         public Object execute(ExecutionEvent event)抛出ExecutionException {                     IWorkspace workspace = ResourcesPlugin.getWorkspace();                     IWorkbenchPage page = 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 ____EDIT 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());
        }
    }

}

这似乎有效。 因为我没有做以下任何事情         Injector i = new DomainmodelStandaloneSetup()。createInjectorAndDoEMFRegistration(); 在我的原始代码中,这应该是要走的路吗? 我应该将插件代码移动到blog.mydsl src文件夹吗? 我应该查看URI吗?

1 个答案:

答案 0 :(得分:1)

以下情况应该有效。

@Inject
IResourceSetProvider resourceSetProvider;
...
URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true);
ResourceSet rs = resourceSetProvider.get(project);
Resource r = rs.getResource(uri, true);

如果您不通过guice(YourDslExecutableExtensionFactory)创建代码,则可以通过Injector

获得IResourceSetProviderIResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(uri).get(IResourceSetProvider.class);

更新

你共享的代码(我不得不即兴发挥),它看起来更像是一个调试问题。见

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);
while(x1.hasNext()) {
    System.out.println(x1.next());
}
TreeIterator<Object> x2 = EcoreUtil.getAllContents(r, false);
while(x2.hasNext()) {
    System.out.println(x2.next());
}