2

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.

Community
  • 1
  • 1
Eldar Abusalimov
  • 24,387
  • 4
  • 67
  • 71

1 Answers1

1

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.

Sebastian Zarnekow
  • 6,609
  • 20
  • 23