У меня есть плагин Javac (реализация com.sun.source.util.Plugin
), и я хочу, чтобы он изменил поведение анализатора.
Я могу расширить com.sun.tools.javac.parser.ParserFactory
и зарегистрировать его в своем com.sun.tools.javac.util.Context
, когда мой плагинin инициализируется, но есть проблема: плагины инициализируются сразу после инициализации JavacProcessingEnvironment
, что создает все необходимое для компиляции, включая ParserFactory
, но я могу только добавить свой ParserFactory
в контекст, но не перезаписать существующий.
Вот фрагмент кода, который меня интересует (com.sun.tools.javac.api.BasicJavacTask
):
public void initPlugins(Set<List<String>> pluginOpts) {
PlatformDescription platformProvider = context.get(PlatformDescription.class);
if (platformProvider != null) {
for (PluginInfo<Plugin> pluginDesc : platformProvider.getPlugins()) {
//Init platform plugins
}
}
if (pluginOpts.isEmpty())
return;
Set<List<String>> pluginsToCall = new LinkedHashSet<>(pluginOpts);
//JavacProcessingEnvironment is created here
JavacProcessingEnvironment pEnv = JavacProcessingEnvironment.instance(context);
//Since here, following will fail:
//context.put(ParserFactory.parserFactoryKey, new MyParserFactory())
ServiceLoader<Plugin> sl = pEnv.getServiceLoader(Plugin.class);
for (Plugin plugin : sl) {
for (List<String> p : pluginsToCall) {
if (plugin.getName().equals(p.head)) {
pluginsToCall.remove(p);
try {
//My plugin is initialized here
plugin.init(this, p.tail.toArray(new String[p.tail.size()]));
} catch (RuntimeException ex) {
throw new PropagatedException(ex);
}
break;
}
}
}
}
Если бы у меня была возможность добавить свой плагин к platformProvider
, он решит мою проблему следующим образом:ранняя инициализация плагина.
Что я делаю не так?Есть ли способ зарегистрировать мою собственную фабрику парсеров?Или, может быть, com.sun.tools.javac.util.Context
не предназначен для использования разработчиками плагинов, а только разработчиками JDK?