Как получить ресурс из INode в Xtext? - PullRequest
0 голосов
/ 04 июня 2019

Преобразователь значений для моей грамматики XText зависит от предпочтения затмения, поэтому мне нужно получить проект текущего файла.Я пробовал это:

class IStringValueConverter extends OtherIStringValueConverter {

    @Inject MyLanguageGrammarAccess grammarAccess

    // this is called in toValue(String string, INode node) if some conditions are fullfilled
    override correctAssignementValue(String path, INode node, AssignmentImpl assign) {

            try {
            val uri = assign.eContainer.eResource.URI //<<<<<< ?????

            val root = ResourcesPlugin.getWorkspace().getRoot();
            val file = root.getFile(new Path(uri.toPlatformString(true)));

            [do something for which I need the file]

                return super.correctAssignementValue(path, node, assign)
            } catch (Exception ex) {
                ex.printStackTrace
                return path
        }

    }
}

Проблема в строке, отмеченной вопросительными знаками.Я пытался:

assign.eContainer.eResource.URI
assign.eResource.URI
node.grammarElement.eResource.URI

Все они возвращают один и тот же URL: classpath:/my/Language.xtextbin

Это файл, созданный XText, а не мой ресурс.Что я делаю не так, как я могу получить ресурс, который в данный момент анализируется?

Ответы [ 2 ]

0 голосов
/ 05 июня 2019

Что я сделал в итоге:

Я создал область Guice, которая ограничивает область действия файла, и расширил реализацию IResourceFactory (не DefaultEcoreElementFactory), чтобы ввести эту область в нужное время:

public class UiResourceFactory extends MyResourceFactory {

  private FileScope scope;

  @Inject
  public UiResourceFactory(Injector injector) {
    super(injector);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public Resource createResource(URI uri) {
    IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
    IFile file = root.getFile(new Path(uri.toPlatformString(true)));
    scope.enter(file);
    try {
      return super.createResource(uri);
    } finally {
      scope.exit();
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void setInjector(Injector injector) {
    super.setInjector(injector);
    scope = getInjector().getInstance(FileScope.class);
  }

}

Таким образом, мой ValueConverter может вводить объекты с правильно заданной областью (очевидно, он создается для каждого значения, которое необходимо преобразовать, поэтому проблем с побочными эффектами нет. Причина, по которой получение ресурса не работает, заключается в том, чтоValueConverter используется во время синтаксического анализа, дерево синтаксического анализа на самом деле еще не связано с ресурсом.Информация о том, что ресурс расположен довольно высоко в цепочке вызовов, IResourceFactory выглядела как хорошее место для размещения области видимости, поскольку там установлен Инжектор.

0 голосов
/ 04 июня 2019

вы можете попросить узлы для их родителей и за их смысловой элемент. это должно позволить вам получить необходимую информацию. в качестве альтернативы вы также можете настроить DefaultEcoreElementFactory.

...