Компиляция в каскадной памяти с помощью javax.tool
Компилятор Eclipse JDT предоставляет интерфейс INameEnvironment
, который определяет метод findType(...)
, позволяющий выполнять каскадную компиляцию. Любопытно, что я хотел бы знать, есть ли какие-либо средства для этого, используя стандартный набор инструментов компилятора JDK?
Примечание, сценарий - это механизм шаблонов, который делает в компиляции памяти для созданных шаблонов классов, которые имеют взаимозависимости, и не может прогнозировать порядок, в котором вы столкнулись с файлом шаблона, таким образом Foo
может потребоваться скомпилировать сначала, прежде чем он будет скомпилирован parent Bar
, поэтому вам нужен механизм для каскадной компиляции, то есть во время компиляции Foo
вам нужно сгенерировать еще один источник Bar
и скомпилировать его сначала, чтобы продолжить Foo
компиляция: некоторый код выглядит следующим образом:
private NameEnvironmentAnswer findType(final String name) {
try {
if (!name.contains(TemplateClass.CN_SUFFIX)) {
return findStandType(name);
}
char[] fileName = name.toCharArray();
TemplateClass templateClass = classCache.getByClassName(name);
// TemplateClass exists
if (templateClass != null) {
if (templateClass.javaByteCode != null) {
ClassFileReader classFileReader = new ClassFileReader(templateClass.javaByteCode, fileName, true);
return new NameEnvironmentAnswer(classFileReader, null);
}
// Cascade compilation
ICompilationUnit compilationUnit = new CompilationUnit(name);
return new NameEnvironmentAnswer(compilationUnit, null);
}
// So it a standard class
return findStandType(name);
} catch (ClassFormatException e) {
// Something very very bad
throw new RuntimeException(e);
}
}
Ответы
Ответ 1
На основе нашего комментария, я думаю, что ответ ясен: нет, вы не можете сделать это с помощью компилятора JDK. Это дает вам крючок, когда он запрашивает пакет, но не зависит от конкретного класса.
Примерно так же, как вы можете узнать, насколько я знаю:
Здесь хорошая статья с кодом, хотя она должна быть адаптирована для обработки в классах памяти. В частности, проблема, которую вы описываете, обрабатывается методом JavaFileManager.list(...)
. Вы должны вернуть обратно JavaFileObjects, которые вы кэшировали в памяти. Скорее всего, вам понадобится создать подкласс ForwardingJavaFileManager
, как описано в статье, хотя и изменен для обработки кэшированных классов, с которыми вы работаете.
Вы можете использовать это для компиляции. Если он возвращает ошибки, используйте регулярное выражение, чтобы узнать, чего не хватает. После генерации/компиляции кода для отсутствующей вещи повторите компиляцию исходного кода.
ПРИМЕЧАНИЕ. В какой-то момент он запрашивает FQN зависимого класса как аргумент packageName в ForwardingFileManager.list(...). Я не пытался вернуть класс в этот момент. Возможно, это не сработает, потому что пакет будет несоответствовать, но, возможно, это будет.
Ответ 2
Попробуйте прочитать этот пример HelloWorld, чтобы узнать, разрешает ли он вашу проблему. Не публикуя код, трудно сказать, какова ваша конкретная проблема.