<commit_before>package asteroid.internal;

import static org.codehaus.groovy.runtime.DefaultGroovyMethods.first;
import static org.codehaus.groovy.runtime.DefaultGroovyMethods.last;

import groovy.transform.InheritConstructors;
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotatedNode;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.ConstructorNode;
import org.codehaus.groovy.ast.GenericsType;
import org.codehaus.groovy.ast.expr.PropertyExpression;
import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.transform.AbstractASTTransformation;
import org.codehaus.groovy.transform.GroovyASTTransformation;

import java.util.List;
import java.util.Arrays;

import asteroid.A;
import asteroid.A.PHASE_LOCAL;

/**
 * This transformation makes easier to declare a given local transformation. It narrows the available
 * compilation phases to those only capable of being used in a local transformation. The way of declaring
 * the transformation makes clearer the fact that it is a local transformation.
 *
 * @since 0.1.0
 */
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
public class LocalTransformationTransformation extends AbstractASTTransformation {

    /**
     * {@inheritDoc}
     *
     * @since 0.1.0
     */
    @Override
    public void visit(final ASTNode[] nodes, final SourceUnit source) {
        if (nodes == null) return;
        if (nodes.length != 2) return;
        if (!(nodes[0] instanceof AnnotationNode)) return;
        if (!(nodes[1] instanceof AnnotatedNode)) return;

        this.sourceUnit = source;

        AnnotationNode annotationNode = A.UTIL.MISC.getFirstNodeAs(nodes, AnnotationNode.class);
        ClassNode      annotatedNode  = A.UTIL.MISC.getLastNodeAs(nodes, ClassNode.class);

        addAnnotationsFromTo(annotationNode, annotatedNode);
        addClassConstructor(annotatedNode);

        // tag::addCheckTo[]
        A.UTIL.CHECK.addCheckTo(A.UTIL.CLASS.findMethodByName(annotatedNode, "doVisit"));
        // end::addCheckTo[]
    }

    private void addClassConstructor(final ClassNode annotatedNode) {
        List<GenericsType> generics = Arrays.asList(annotatedNode.getSuperClass().getGenericsTypes());
        ClassNode annotationType    = first(generics).getType();

        Statement callSuper = A.STMT
            .ctorSuperS(A.EXPR.classX(annotationType));

        ConstructorNode constructorNode = A.NODES
            .constructor(A.ACC.ACC_PUBLIC)
            .code(callSuper)
            .build();<commit_msg>Make LocalTransformationT... to use abstractions<commit_after>package asteroid.internal;

import static org.codehaus.groovy.runtime.DefaultGroovyMethods.first;
import static org.codehaus.groovy.runtime.DefaultGroovyMethods.last;

import groovy.transform.InheritConstructors;
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotatedNode;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.ConstructorNode;
import org.codehaus.groovy.ast.GenericsType;
import org.codehaus.groovy.ast.expr.PropertyExpression;
import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.transform.AbstractASTTransformation;
import org.codehaus.groovy.transform.GroovyASTTransformation;

import java.util.List;
import java.util.Arrays;

import asteroid.A;
import asteroid.A.PHASE_LOCAL;
import asteroid.local.LocalTransformation;
import asteroid.local.LocalTransformationImpl;

/**
 * This transformation makes easier to declare a given local transformation. It narrows the available
 * compilation phases to those only capable of being used in a local transformation. The way of declaring
 * the transformation makes clearer the fact that it is a local transformation.
 *
 * @since 0.1.0
 */
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
public class LocalTransformationTransformation extends LocalTransformationImpl<LocalTransformation,ClassNode> {


    /**
     * Constructor using abstraction {@link LocalTransformationImpl}
     *
     * @since 0.1.6
     */
    public LocalTransformationTransformation() {
        super(LocalTransformation.class);
    }

    /**
     * {@inheritDoc}
     *
     * @since 0.1.6
     */
    @Override
    public void doVisit(final AnnotationNode annotationNode, final ClassNode annotatedNode, final SourceUnit source) {
        addAnnotationsFromTo(annotationNode, annotatedNode);
        addClassConstructor(annotatedNode);

        // tag::addCheckTo[]
        A.UTIL.CHECK.addCheckTo(A.UTIL.CLASS.findMethodByName(annotatedNode, "doVisit"));
        // end::addCheckTo[]
    }

    private void addClassConstructor(final ClassNode annotatedNode) {
        List<GenericsType> generics = Arrays.asList(annotatedNode.getSuperClass().getGenericsTypes());
        ClassNode annotationType    = first(generics).getType();

        Statement callSuper = A.STMT
            .ctorSuperS(A.EXPR.classX(annotationType));

        ConstructorNode constructorNode = A.NODES
            .constructor(A.ACC.ACC_PUBLIC)
            .code(callSuper)
            .build();
{'fraction_non_alphanumeric': 0.09540570581696925, 'fraction_numerical': 0.0033345683586513525, 'mean_word_length': 4.031686859273067, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7593752', 'n_tokens_mistral': 1639, 'n_tokens_neox': 1531, 'n_words': 316}