如何为我的 Xtext DSL 包含没有扩展名的文件?

发布于 2024-12-14 03:02:34 字数 3136 浏览 4 评论 0原文

默认情况下,Xtext 允许在创建新项目时为 DSL 文件指定单个扩展名。但是,可以为单个 DSL 添加更多扩展,如 Xtext 常见问题解答。但我无法让它处理没有扩展名的文件。

一个典型的例子是 Make 构建系统的 makefile 。可以使用 MakefileGNUmakefile*.mk 名称,Eclipse 将为这些文件打开相同的编辑器。

我想让 Xtext 识别 *.mydsl 文件和名为 Mydsl 的文件。

添加

filenames="Mydsl"

我尝试向 UI 项目的 plugin.xml 中的 org.eclipse.ui.editors 扩展点的 editor 节点 属性。这使得 Eclipse 能够在适当的编辑器中打开 Mydsl 文件。但当我尝试从任何其他文件引用 Mydsl 中定义的元素时,Xtext 不会索引这些文件并报告链接错误。

有没有办法让Xtext能够像处理普通文件一样处理固定名称但不带扩展名的源文件?

UPD。 1

根据 Sebastian 的回答 我尝试在主项目的 plugin.xml 中指定自定义内容类型:

<extension
      point="org.eclipse.core.contenttype.contentTypes">
    <content-type
         base-type="org.eclipse.core.runtime.text"
         file-extensions="mydsl"
         file-names="Mydsl"
         id="org.xtext.example.mydsl.contentType"
         name="My Language"
         priority="normal">
    </content-type>
</extension>

并按如下方式绑定它:

<extension
      point="org.eclipse.xtext.content_resourceServiceProvider">
    <resourceServiceProvider
         class="org.xtext.example.mydsl.MyDslResourceServiceProvider"
         contentTypeIdentifier="org.xtext.example.mydsl.contentType">
    </resourceServiceProvider>
</extension>

但我仍然得到链接如上所述的错误。我还在 MyDslResourceServiceProvider 的所有方法中添加了断点,它似乎甚至没有被实例化或以某种方式调用。

我还尝试将这些扩展移至 UI 项目,但也没有效果。

UPD。 2

终于,我做到了。 简而言之,工作步骤如下:

  • 使用 org.eclipse.core.contenttype.contentTypes 扩展点定义新的内容类型
  • 通过扩展 org.eclipse.emf.ecore.resource 创建内容处理程序.impl.PlatformContentHandlerImpl 类并重写 canHandle(URI) 方法,当且仅当参数不为 null 时才返回 true
  • 注册它与org.eclipse.emf.ecore.content_handler
  • 创建一个新的资源服务提供程序,canHandle(URI) 始终返回 true。可以扩展 org.eclipse.xtext.resource.impl.DefaultResourceServiceProvider 并重写相应方法
  • 在 UI 项目中将其绑定到 org.eclipse.xtext.content_resourceServiceProvider ,不要忘记在类名之前指定扩展工厂
  • 在 UI 项目中将 org.eclipse.xtext.resource.IResourceFactory 注册为org.eclipse.emf.ecore.content_parser,再次使用扩展工厂
  • 将内容类型绑定添加到org.eclipse.ui.editorsorg.eclipse.compare .contentViewersorg.eclipse.compare.contentMergeViewers
  • 根据您是否需要旧的扩展绑定,删除 org.eclipse.emf.ecore.extension_parserorg.eclipse.xtext.extension_resourceServiceProvider 扩展

我的案例的更改集(应用于新项目)可以在 此处

By default Xtext allows to specify a single extension for DSL files when creating a new project. However, it is possible to add more extensions for a single DSL as described in Xtext FAQ. But I couldn't get it working with files with no extension at all.

A typical example is a makefile for Make build system. One can use Makefile, GNUmakefile and *.mk names, and Eclipse will open the same editor for such files.

I want to get Xtext to recognize both *.mydsl files and a file named Mydsl.

I tried to add

filenames="Mydsl"

attribute to editor node of org.eclipse.ui.editors extension point in plugin.xml of my UI project. This enables Eclipse to open Mydsl files in the proper editor. But Xtext does not index these files and reports linking errors when I try to refer an element defined in Mydsl from any other file.

Is there a way to enable Xtext to process source files with fixed name but with no extension as well as regular files?

UPD. 1

Accordingly to Sebastian's answer I tried to specify a custom content type in plugin.xml of the main project:

<extension
      point="org.eclipse.core.contenttype.contentTypes">
    <content-type
         base-type="org.eclipse.core.runtime.text"
         file-extensions="mydsl"
         file-names="Mydsl"
         id="org.xtext.example.mydsl.contentType"
         name="My Language"
         priority="normal">
    </content-type>
</extension>

And binding it as follows:

<extension
      point="org.eclipse.xtext.content_resourceServiceProvider">
    <resourceServiceProvider
         class="org.xtext.example.mydsl.MyDslResourceServiceProvider"
         contentTypeIdentifier="org.xtext.example.mydsl.contentType">
    </resourceServiceProvider>
</extension>

But I still get linking errors as described above. I also added breakpoints into all methods of MyDslResourceServiceProvider and it seems that it doesn't even get instantiated or somehow invoked.

I also tried to move these extensions to the UI project but with no effect too.

UPD. 2

Finally, I've done it.
Steps to get things work in a nutshell:

  • Define new content type using org.eclipse.core.contenttype.contentTypes extension point
  • Create a content handler by extending org.eclipse.emf.ecore.resource.impl.PlatformContentHandlerImpl class and override canHandle(URI) method to return true if and only if the argument is not null
  • Register it with org.eclipse.emf.ecore.content_handler
  • Create a new resource service provider with canHandle(URI) returning true always. One can extend org.eclipse.xtext.resource.impl.DefaultResourceServiceProvider and override the corresponding method
  • In the UI project bind it to org.eclipse.xtext.content_resourceServiceProvider, do not forget to specify an extension factory before the class name
  • In the UI project register org.eclipse.xtext.resource.IResourceFactory as org.eclipse.emf.ecore.content_parser, again with the extension factory
  • Add content type bindings to org.eclipse.ui.editors, org.eclipse.compare.contentViewers and org.eclipse.compare.contentMergeViewers
  • Depending on whether you need an old extension binding or not, remove org.eclipse.emf.ecore.extension_parser and org.eclipse.xtext.extension_resourceServiceProvider extensions

A change set (applied to a fresh project) for my case can be found here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小霸王臭丫头 2024-12-21 03:02:34

您可以尝试利用资源服务提供者和资源工厂的扩展点。它允许通过文件扩展名或内容类型注册服务/工厂。我认为如果您为文件提供合适的内容类型,后者应该可以工作。

You could try to exploit the extension point for resource service providers and resource factories. It allows to register services / factory either by file extension or by content type. I think the latter should work if you provide a suitable content type for your files.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文