Понимание синтаксиса groovy в определении задачи gradle
Я новичок в Gradle и Groovy и пытаюсь понять, что происходит на уровне Groovy, когда задана задача Gradle.
task hello {
println "configuring task hello"
doLast {
println "hello there"
}
}
Из чтения книги "Gradle In Action" я знаю, что task hello {}
- это действительно вызов метода task()
интерфейса Groovy Project
. На стр. 77 показано, что в интерфейсе Project
имеется 4 метода, называемых task
task(args: Map<String,?>, name:String)
task(args: Map<String,?>, name:String, c:Closure)
task(name: String)
task(name: String, c:Closure)
Я понимаю, что {}
- тело замыкания.
Я не понимаю, как Groovy интерпретировать hello
в task hello { }
в соответствии с qaru.site/info/117593/... есть плагин для компилятора Groovy который преобразует task hello { }
в task('hello', { })
Мои вопросы:
-
Где я могу найти информацию о плагине компилятора Gradle Groovy, который выполняет преобразование?
-
Является ли утверждение, что Gradle скрипты Groovy программны технически неправильно, так как Gradle каким-то образом расширяет язык программирования Groovy?
-
Есть ли способ заставить команду gradle
распечатать базовый код Groovy, который генерируется после запуска плагина компилятора?
Ответы
Ответ 1
Gradle использует AST Transformations для расширения синтаксиса Groovy. Синтаксис определения задачи, о котором вы говорите, является лишь одним из преобразований Gradle. Вы можете найти реализацию этого преобразования здесь. Чтобы ответить на ваши конкретные вопросы:
-
Индивидуальные преобразования, которые применяются Gradle, не описаны в любом месте, о котором я знаю. Однако вы можете посмотреть другие классы в том же пакете ссылки выше.
-
Gradle скрипты поддерживают супер-набор синтаксиса Groovy. Любой допустимый Groovy также действителен в Gradle script, однако Gradle script необязательно (и обычно не) действителен "по умолчанию" Groovy.
-
Невозможно получить вывод эквивалентного кода Groovy, так как это фактическое абстрактное синтаксическое дерево, которое обрабатывается в памяти.
Ответ 2
Если вы хотите узнать больше об этом, проверьте функцию transformVariableExpression в исходном коде TaskDefinitionScriptTransformer
классе TaskDefinitionScriptTransformer
private void transformVariableExpression(MethodCallExpression call, int index) {
ArgumentListExpression args = (ArgumentListExpression) call.getArguments();
VariableExpression arg = (VariableExpression) args.getExpression(index);
if (!isDynamicVar(arg)) {
return;
}
// Matches: task args?, <identifier>, args? or task(args?, <identifier>, args?)
// Map to: task(args?, '<identifier>', args?)
String taskName = arg.getText();
call.setMethod(new ConstantExpression("task"));
args.getExpressions().set(index, new ConstantExpression(taskName));
}
он преобразует task args?, <identifier>, args?
или task(args?, <identifier>, args?)
для task(args?, '<identifier>', args?)
находит определение задачи в build.gradle и добавляет кавычки вокруг идентификатора (имени задачи), так что это очень круто могу скомпилировать это без проблем.