#dsl #xtext #language-server-protocol
Вопрос:
У меня есть проект DSL, использующий Xtext вместе с протоколом языкового сервера.
Теперь я хочу запустить генератор от клиента (в моем случае VS-код), который будет выполняться на сервере. Не автоматически (я бы знал, как это сделать), но явно запускается пользователем из команды VS Code.
Я знаю о IExecutableCommandService в Xtext и знаю, как подключиться к нему. Но я не знаю, как получить соответствующий ресурс из заданного пути к файлу:
@Override
public Object execute(ExecuteCommandParams params, ILanguageServerAccess access, CancelIndicator cancelIndicator) {
if ("c4.generator.type".equals(params.getCommand())) {
// fileURI passed from client to the server
String fileURI = ((JsonPrimitive)params.getArguments().get(0)).getAsString();
// This is where I stuck
Resource resource = whatAPItoCallToRetrieveResourceFromFile(fileURI);
// Call the generator then
doGenerate(resource);
}
return "Unknown Command";
}
Пример использования такой же, как описано в этом блоге: https://dietrich-it.de/xtext/2011/10/15/xtext-calling-the-generator-from-a-context-menu/
Но описание предназначено только для Eclipse (без использования lsp).
Ответ №1:
Если у вас уже есть правильный URI, вы должны иметь возможность использовать XtextResourceSet
его для получения доступа к ресурсу:
final XtextResourceSet rs = new XtextResourceSet();
final Resource r = rs.getResource(fileURI, true);
doGenerate(r);
в противном случае вы можете получить доступ к индексу Xtext и выполнить итерацию по всем ресурсам в поисках интересующего ресурса, используя access.doReadIndex
:
final XtextResourceSet rs = new XtextResourceSet();
final Function<ILanguageServerAccess.IndexContext, Boolean> func = (
ILanguageServerAccess.IndexContext ctxt) -> {
for (final IResourceDescription rd: ctxt.getIndex().getAllResourceDescriptions()) {
if(<check_rd>) {
Resource r = rs.getResource(rd.getURI(), true);
doGenerate(r);
}
}
return true;
};
access.doReadIndex(func);