Добавление поля с Groovy AST не генерирует геттер и сеттер - PullRequest
0 голосов
/ 04 декабря 2018

Итак, я пишу преобразование AST, которое добавляет поле с аннотацией @Delegate к классу

@SimpleAST
class PersonBuilder{
}

Должно выдать

class PersonBuilder{
        @Delegate
        Person target = new Person
    }

Мой интерфейс:

@Retention(RetentionPolicy.RUNTIME)
@Target([ElementType.TYPE])
@GroovyASTTransformationClass("poc.SimpleASTTransformation")
public @interface SimpleAST {

    /**
     * A class for which builder methods should be created. It will be an error to leave
     * this attribute with its default value for some strategies.
     */

    Class value()

}

Мое преобразование:

@CompileStatic
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
class SimpleASTTransformation implements ASTTransformation {

    @Override
    void visit(ASTNode[] astNodes, SourceUnit source) {

        ClassNode classNode = (ClassNode) astNodes[1]

        if (!astNodes) return
        if (!astNodes[0]) return
        if (!astNodes[1]) return
        if (!(astNodes[0] instanceof AnnotationNode)) return
        if (!(astNodes[1] instanceof ClassNode)) return

        println "Running AST Transformation for ${classNode.getNameWithoutPackage()}..."

        AnnotationNode annotationNode = (AnnotationNode) astNodes[0]
        ClassExpression classExpression = (ClassExpression) annotationNode.getMember("value")
        String packageName = classNode.getPackageName()
        String builderClassNameWithoutPackage = classNode.getNameWithoutPackage()
        String originalClassNameWithPackage = classExpression.getText()
        originalClassNameWithPackage = Validate.checkOriginalClassName(originalClassNameWithPackage)
        Class<?> originalClass = Class.forName(originalClassNameWithPackage)
        ClassNode originalClassNode = new ClassNode(originalClass)
        String originalClassNameWithoutPackage = originalClassNode.getNameWithoutPackage()

        println "Generating methods for $originalClassNameWithoutPackage..."

        generateTargetField(classNode,originalClass)

        println "Transformation applied!"

    }

   static void generateTargetField(ClassNode classNode, Class originalClass){
        ClassNode originalClassNode = new ClassNode(originalClass)
        ConstructorCallExpression constructorCallExpression = new ConstructorCallExpression(originalClassNode,new ArgumentListExpression())
        FieldNode fieldNode = new FieldNode("target",
                2,
                originalClassNode,
                classNode,
                constructorCallExpression)

        ArrayList<AnnotationNode> annotationNodes = new ArrayList<>()
        annotationNodes.add(new AnnotationNode(new ClassNode(Delegate)))
        fieldNode.addAnnotations(annotationNodes)
        classNode.addField(fieldNode)
    }
}

Когда я проверяю байт-код, в полях класса Person нет методов получения / установки (я использовал @Delegate для целевого поля)

Однако, если я просто добавлю поле вручную и скомпилирую код, я получу методы получения и установки для полей в классе Person.

У Person есть 2 поля: firstName, lastName и Strings.

...