[groovy] Gradle 작업 정의에서 그루비 구문 이해

저는 Gradle과 Groovy를 처음 접했고 gradle 작업이 정의 될 때 그루비 수준에서 무슨 일이 일어나고 있는지 이해하려고 노력하고 있습니다.

task hello  {
   println "configuring task hello"
   doLast {
     println "hello there"
   }
}

“Gradle In Action”책을 읽음으로써 나는 이것이 task hello {}정말 task()그루비 Project인터페이스 의 메소드에 대한 호출 이라는 것을 알고 있습니다. 77 페이지에서는 Project인터페이스에 task라는 4 개의 메소드가 있음을 보여줍니다.

task(args: Map<String,?>, name:String)
task(args: Map<String,?>, name:String, c:Closure)
task(name: String)
task(name: String, c:Closure)

나는 그것이 {}폐쇄 본문 이라는 것을 이해합니다 .

내가 이해하지 못하는 것은 해석 당연하지 어떻게 hellotask hello { }에 따라 https://stackoverflow.com/a/25592665/438319 가 그루비 컴파일러 플러그인이 변환 task hello { }task('hello', { })

내 질문 :

  • 변환을 수행하는 Gradle Groovy 컴파일러 플러그인에 대한 정보는 어디에서 찾을 수 있습니까?

  • Gradle이 Groovy 프로그래밍 언어를 확장하기 때문에 Gradle 스크립트가 기술적으로 잘못된 프로그램이라는 주장이 있습니까?

  • gradle컴파일러 플러그인이 실행 된 후 생성되는 기본 그루비 코드를 인쇄 하는 명령 을 얻는 방법이 있습니까?



답변

Gradle은 AST 변환 을 사용하여 Groovy 구문을 확장합니다. 언급 한 작업 정의 구문은 Gradle이 적용하는 변환 중 하나 일뿐입니다. 여기 에서 해당 변환에 대한 구현을 찾을 수 있습니다 . 구체적인 질문에 답하려면 :

  • Gradle이 적용하는 개별 변환은 내가 아는 곳에서 구체적으로 문서화되지 않았습니다. 그러나 위 링크의 동일한 패키지에서 다른 클래스를 볼 수 있습니다.

  • Gradle 스크립트는 Groovy 구문의 상위 집합을 지원합니다. 유효한 Groovy는 Gradle 스크립트에서도 유효하지만 Gradle 스크립트는 반드시 유효한 “기본”Groovy는 아닙니다 (일반적으로 아님).

  • 메모리에서 조작되는 실제 추상 구문 트리이기 때문에 동등한 Groovy 코드의 출력을 얻을 수있는 방법이 없습니다.


답변

그것에 대해 더 알고 싶다면 클래스 의 gradle 소스 코드에서 transformVariableExpression 함수 를 확인하십시오.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 및 추가 따옴표로 작업 정의를 발견 그루비는 문제없이 컴파일 할 수 있습니다.


답변