Search code examples
eclipse-pluginxtext

Some features of Xtext-based editor don't work on files outside a project


I've written an Xtext-based plugin which works well when I open files inside one of the projects in my workspace; however, when I open a file outside the workspace (via File -> Open File...), some of the features don't work properly:

  • I get syntax coloring but I don't get syntax errors.
  • Quickfix options don't work, probably because context.getXtextDocument() returns null and I rely on it for my quickfix proposals.

There might be other things I'm missing, but most other features, such as content assist, definitions-on-hover, occurrence marking etc., work fine.

Is there a way I could make workspace-external source files behave the same as internal files? Alternatively, is there a workaround which will enable me to "trick" Xtext, somehow convincing it that the file is internal to the current project, for example by programmatically creating a link to it from the project?

This is a related question about the behavior with a workspace-external file, however I succeed in opening these files just fine, it's just that some features are not working.


Solution

  • As long a I know, currently there are no way to just make workspace-external source files behave the same as internal files.

    Here is the workaround for broken validation:

    • In xxx.ui plugin, XxxUiModule.java add

      public Class<? extends IResourceForEditorInputFactory> bindIResourceForEditorInputFactory() {
          return MyJavaClassPathResourceForIEditorInputFactory.class;
      }
      
      @Override
      public Class<? extends IXtextEditorCallback> bindIXtextEditorCallback() {
          return MyNatureAddingEditorCallback.class;
      }
      
    • Create MyJavaClassPathResourceForIEditorInputFactory.java

      // Reenable validation
      public class MyJavaClassPathResourceForIEditorInputFactory extends JavaClassPathResourceForIEditorInputFactory {
      
          @Override
          protected Resource createResource(java.net.URI uri) {
              XtextResource resource = (XtextResource) super.createResource(uri);
              resource.setValidationDisabled(false);
              return resource;
          }
      }
      
    • Create MyNatureAddingEditorCallback.java

      // With reenabled validation the syntax validation starts to work only after the first change made
      // Run the validation manually to show the syntax errors straight away
      // - CheckMode.ALL below should be probably changed to something else to improve the performance
      public class MyNatureAddingEditorCallback extends NatureAddingEditorCallback {
          @Inject
          private IResourceValidator resourceValidator;
          @Inject 
          private MarkerCreator markerCreator;
          @Inject
          private MarkerTypeProvider markerTypeProvider;
          @Inject
          private IssueResolutionProvider issueResolutionProvider;
      
          @Override
          public void afterCreatePartControl(XtextEditor editor) {
              super.afterCreatePartControl(editor);
              validate(editor);
          }
      
          private void validate(XtextEditor xtextEditor) {
              if (xtextEditor == null) {
                  return;
              }
              if (xtextEditor.getInternalSourceViewer() == null) {
                  return;
              }
              IValidationIssueProcessor issueProcessor;
              IXtextDocument xtextDocument = xtextEditor.getDocument();
              IResource resource = xtextEditor.getResource();
              if(resource != null)
                  issueProcessor = new MarkerIssueProcessor(resource, markerCreator, markerTypeProvider);
              else
                  issueProcessor = new AnnotationIssueProcessor(xtextDocument, xtextEditor.getInternalSourceViewer().getAnnotationModel(), issueResolutionProvider);
              ValidationJob validationJob = new ValidationJob(resourceValidator, xtextDocument, issueProcessor,
                      CheckMode.ALL); // Consider changing the CheckMode here
              validationJob.schedule();
          }
      }
      

    See also the corresponding bug report: https://bugs.eclipse.org/bugs/show_bug.cgi?id=388399