Перегрузка лямбда-выражения 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 |
..
]