Розуміння грузистого синтаксису у визначенні завдання gradle


79

Я новачок у 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)

Я розумію, що {}це орган закриття.

Те , що я не розумію, як робить заводний інтерпретувати helloв task hello { }відповідно до https://stackoverflow.com/a/25592665/438319 є заводний компілятор плагін , який перетворює task hello { }вtask('hello', { })

Мої запитання:

  • Де я можу знайти інформацію про плагін Gradle Groovy Compiler, який виконує перетворення?

  • Чи твердження про те, що сценарії Gradle є groovy-програмами, є технічно неправильним, оскільки gradle якимось чином розширює мову програмування Groovy?

  • Чи є спосіб отримати gradleкоманду для роздруківки базового groovy коду, який генерується після запуску модуля компілятора?

Відповіді:


86

Gradle використовує перетворення AST для розширення синтаксису Groovy. Згаданий вами синтаксис визначення завдання є лише одним із перетворень, які застосовується Gradle. Ви можете знайти реалізацію цього перетворення тут . Щоб відповісти на ваші конкретні запитання:

  • Індивідуальні перетворення, які застосовує Gradle, ніде не відомі. Однак ви можете переглянути інші класи в тому ж пакеті посилання вище.

  • Сценарії Gradle підтримують набір синтаксису Groovy. Будь-який дійсний Groovy також є дійсним у сценарії Gradle, однак скрипт Gradle не обов’язково (і, як правило, не є) дійсним Groovy за замовчуванням.

  • Немає способу отримати вихід еквівалентного коду Groovy, оскільки це власне абстрактне дерево синтаксису, яким маніпулюють в пам'яті.


3

Якщо ви хочете дізнатися більше про це, перевірте функцію transformVariableExpression у вихідному коді gradle у 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 і додає лапки навколо ідентифікатора (назви завдання), щоб groovy міг скомпілювати його без проблем.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.