All Downloads are FREE. Search and download functionalities are using the official Maven repository.

kendal.api.impl.AstHelperImpl Maven / Gradle / Ivy

There is a newer version: 0.6
Show newest version
package kendal.api.impl;

import static kendal.utils.Utils.with;

import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import javax.lang.model.element.Name;

import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;

import kendal.api.AstHelper;
import kendal.api.AstNodeBuilder;
import kendal.api.AstUtils;
import kendal.api.AstValidator;
import kendal.api.exceptions.ImproperNodeTypeException;
import kendal.model.Node;

public class AstHelperImpl implements AstHelper {
    private final Context context;
    private final AstUtils astUtils;
    private final AstValidator astValidator;
    private final AstNodeBuilder astNodeBuilder;

    public AstHelperImpl(Context context) {
        this.context = context;
        astUtils = new AstUtilsImpl(context);
        astValidator = new AstValidatorImpl(astUtils);
        astNodeBuilder = new AstNodeBuilderImpl(context, astValidator);
    }

    @Override
    public  void addElementToClass(Node clazz, Node element, Mode mode) throws ImproperNodeTypeException {
        if (!astValidator.isClass(clazz)) {
            throw new ImproperNodeTypeException();
        }
        // Update Kendal AST:
        if (mode == Mode.APPEND) clazz.addChild(element);
        else clazz.addChild(0, element);

        // Update javac AST:
        JCClassDecl classDecl = clazz.getObject();
        JCTree elementDecl = element.getObject();
        if (mode == Mode.APPEND) classDecl.defs = append(classDecl.defs, elementDecl);
        else classDecl.defs = prepend(classDecl.defs, elementDecl);
    }

    @Override
    public  void addExpressionStatementToMethod(Node method, Node expressionStatement, Mode mode) {
        // Update Kendal AST:
        if (mode == Mode.APPEND) method.addChild(expressionStatement);
        else method.addChild(0, expressionStatement);

        // Update javac AST:
        JCMethodDecl methodDecl = method.getObject();
        with(methodDecl.body, b -> {
            if (mode == Mode.APPEND) b.stats = append(b.stats, expressionStatement.getObject());
            else b.stats = prepend(b.stats, expressionStatement.getObject());
        });
    }

    @Override
    public Node findFieldByName(Node classDeclNode, Name name) {
        return classDeclNode.getChildren().stream()
                .filter(node -> node.getObject() instanceof JCVariableDecl && ((JCVariableDecl) node.getObject()).name.equals(name))
                .findAny().orElse(null);
    }

    @Override
    public AstNodeBuilder getAstNodeBuilder() {
        return astNodeBuilder;
    }

    @Override
    public AstValidator getAstValidator() {
        return astValidator;
    }

    @Override
    public AstUtils getAstUtils() {
        return astUtils;
    }

    private  List append(List defs, T element) {
        return add(defs.size(), defs, element);
    }

    private  List prepend(List defs, T element) {
        return add(0, defs, element);
    }

    private  List add(int index, List defs, T element) {
        java.util.List list = StreamSupport.stream(defs.spliterator(), false).collect(Collectors.toList());
        list.add(index, element);
        return List.from(list);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy