Мы используем преобразования AST, чтобы внедрить код в отличный скрипт.Мы статически компилируем скрипт.
В скрипте
- Есть частные функции
- Эти закрытые функции доступны в замыканиях в других функциях
- Это приводит к тому, что функции доступа $ 0 генерируются после статической компиляции
- После статической компиляции мы переключаем цель вызова метода на другой (генерируемый) метод, сигнатура которого соответствует исходному методу, за исключением некоторых дополнительных параметров (представьте, чтоэто как программирование в стиле AOP)
Мы заметили это
- Если мы не переключаем цель метода, groovy использует функцию доступа $ 0 для вызова закрытой функции изнутри замыкания
- Поскольку мы переключаем цель метода после статической компиляции, функции доступа $ не генерируются для новых методов, которые мы внедрили
- Когда мы переключаем цель, groovy / javac видит, что нет доступа $методы для закрытого метода и поэтому использует динамический вызов для вызова нового метода.
Это кажется приемлемым, но для дальнейшей оптимизации, как мы генерируем функции доступа к $ для новых внедренных методов?Есть ли способ всегда генерировать эти методы или переоценивать класс, чтобы определить, какой метод доступа нужно сгенерировать?
Мы попытались снова запустить аннотацию статической компиляции после переключения целевого метода.Он не изменил сгенерированные методы доступа.
Как заставить компилятор переоценить, какие методы доступа должны быть сгенерированы?
Этот код находится в скрипте
private function1() {
// Do somethig
}
public functionThatUsesClosure(Closure a) {
a.call()
}
public parentFunction() {
functionThatUsesClosure {
function1()
}
}
Это преобразуется в это с помощью преобразования AST
private function1() {
// Do something
}
private function1(MyExtraParameter param) {
// Do something
}
public functionThatUsesClosure(Closure a) {
a.call()
}
public parentFunction() {
functionThatUsesClosure {
function1(new MyExtraParameter())
}
}
Когда я проверяю файл класса с помощью javap, я вижу дополнительную функцию доступа $ 0, которая соответствует function1 ().Однако функция function1 () больше не используется, ее функция1 (MyExtraParameter) используется в замыкании.Это означает, что функция доступа $ 0 должна быть сопоставлена с функцией 1 (MyExtraParameter)
Этот код будет работать без функции доступа $ 0, потому что groovy выполняет динамический вызов правильной функции, но мне было интересно, есть ли способчтобы оптимизировать это также, сказав Groovy сгенерировать функцию доступа $ 1 для кода, который я внедрил