Компиляция в каскадной памяти с помощью 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, чтобы узнать, разрешает ли он вашу проблему. Не публикуя код, трудно сказать, какова ваша конкретная проблема.