Перегрузка лямбда-выражения Xtend для Xtext QuickFix API

Я использую Xtend для написания пользовательских QuickFix-ов для плагина Eclipse UI моего языка Xtext. Идея состоит в том, чтобы расширить org.eclipse.xtext.ui.editor.quickfix.DefaultQuickfixProvider и использовать вызов accept метод org.eclipse.xtext.ui.editor.quickfix.IssueResolutionAcceptor,

accept имеет несколько перегруженных подписей, в том числе:

  • void accept(Issue issue, String label, String description, String image, IModification modification)
  • void accept(Issue issue, String label, String description, String image, ISemanticModification semanticModification)

Использовать первую из этих сигнатур легко, используя синтаксис лямбда-выражений Xtend:

@Fix(MyDSLValidator::INVALID_TYPE_NAME)
def removeInitialUnderscore(Issue issue, IssueResolutionAcceptor acceptor) {
    acceptor.accept(issue,
    "Remove initial underscore",
    "Remove initial underscore",
    'upcase.png')
    [
        context |
        context.xtextDocument.replace(issue.offset, 1, "")
    ]
}

Компилятор Xtend создает следующий код Java:

public void removeInitialUnderscore(final Issue issue, final IssueResolutionAcceptor acceptor) {
  final IModification _function = new IModification() {
    public void apply(final IModificationContext context) throws Exception {
      IXtextDocument _xtextDocument = context.getXtextDocument();
      Integer _offset = issue.getOffset();
      _xtextDocument.replace((_offset).intValue(), 1, "");
    }
  };
  acceptor.accept(issue, 
    "Remove initial underscore", 
    "Remove initial underscore", 
    "upcase.png", _function);
}

Теперь я хочу написать второй QuickFix, который использует ISemanticModification вместо IModification так что я могу получить доступ к базовой модели EMF, а не только к строкам. Однако я пытаюсь сообщить компилятору Xtend, какую перегрузку метода я бы хотел использовать:

@Fix(MyDSLValidator::MISSING_USAGE)
def addMissingUseStatement(Issue issue, IssueResolutionAcceptor acceptor) {
    acceptor.accept(issue,
    "Add missing use statement",
    "Add missing use statement",
    "upcase.png",
    [
        EObject element |
        (element.eContainer as MyContainer).usages.add(
                    (element as MyElement).myattr.eContainer as MyOtherContainer
                )
    ])
}

Xtend всегда думает, что я хочу передать IModification вместо ISemanticModification и выдает ошибку в скомпилированном коде Java, потому что два apply методы имеют разные подписи, IModification занимает IModificationContext в то время как ISemanticModification занимает EObject,

@Fix(MyDSLValidator.MISSING_USAGE)
public void addMissingUseStatement(final Issue issue, final IssueResolutionAcceptor acceptor) {
  final IModification _function = new IModification() {
    public void apply(final IModificationContext element) throws Exception {
      EObject _eContainer = element.eContainer(); // COMPILE ERROR
      EList<Circuit> _usages = ((MyContainer) _eContainer).getUsages();
      MyAttr _myattr = ((MyAttr ) element).getMyattr();
      EObject _eContainer_1 = _myattr.eContainer();
      _usages.add(
        ((MyOtherContainer) _eContainer_1));
    }
  };
  acceptor.accept(issue, 
    "Add missing use statement", 
    "Add missing use statement", 
    "upcase.png", _function);
}

Как мне сказать Xtend, какую перегрузку использовать? Насколько я знаю, в Xtend невозможно создать анонимный объект, поэтому нужен другой способ вызова IssueResolutionAcceptor.accept прохождение ISemanticModification,

1 ответ

Решение

ISemanticModification принимает два аргумента, где IModification использует только один аргумент. Чтобы реализовать семантическую модификацию, вы должны использовать лямбду с двумя параметрами соответственно:

acceptor.accept(issue,
    "Add missing use statement",
    "Add missing use statement",
    "upcase.png") [ element, context |
      ..
    ]
Другие вопросы по тегам