Подтвердить что ты не робот

Понимание синтаксиса 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, который генерируется после запуска плагина компилятора?

4b9b3361

Ответ 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 и добавляет кавычки вокруг идентификатора (имени задачи), так что это очень круто могу скомпилировать это без проблем.