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

de.hunsicker.jalopy.language.antlr.JavaNodeFactory Maven / Gradle / Ivy

Go to download

A source code formatter/beautifier/pretty printer for the Java programming language.

The newest version!
/*
 * Copyright (c) 2001-2002, Marco Hunsicker. All rights reserved.
 *
 * This software is distributable under the BSD license. See the terms of the
 * BSD license in the documentation provided with this software.
 */
package de.hunsicker.jalopy.language.antlr;

import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;

import antlr.ASTFactory;
import antlr.ASTPair;
import antlr.Token;
import antlr.collections.AST;
import de.hunsicker.jalopy.language.CompositeFactory;
import de.hunsicker.jalopy.language.antlr.JavaTokenTypes;
import de.hunsicker.jalopy.storage.Loggers;


/**
 * Central facility to create the nodes for Java parse trees.
 *
 * @author Marco Hunsicker
 * @version $Revision: 1.2 $
 */
public class JavaNodeFactory
    extends ASTFactory
{
    //~ Static variables/initializers ----------------------------------------------------

    private static final String EMPTY_STRING = "" /* NOI18N */.intern();
    private final CompositeFactory _compositeFactory;
    
    private class JavaNodeImpl extends JavaNode {

        public JavaNodeImpl() {
            super();
        }
        
    }

    //~ Constructors ---------------------------------------------------------------------

    /**
     * Creates a new JavaNodeFactory object.
     */
    public JavaNodeFactory(CompositeFactory compositeFactory)
    {
        this._compositeFactory = compositeFactory;
        this.theASTNodeType = "JavaNode" /* NOI18N */;
        this.theASTNodeTypeClass = JavaNode.class;
    }

    //~ Methods --------------------------------------------------------------------------

    /**
     * Add the given node as a child to the given root.
     *
     * @param currentAST root pair.
     * @param child new child to add.
     * TODO Examine what this does ?
     */
    
    public void addASTChild(
        ASTPair currentAST,
        AST     child)
    {
        if (child != null)
        {
            JavaNode newChild = (JavaNode) child;

            if (currentAST.root == null)
            {
                // make new child the current root
                currentAST.root = newChild;
            }
            else
            {
                JavaNode root = (JavaNode) currentAST.root;

                if (
                    (root.getType() == JavaTokenTypes.EXPR)
                    && (newChild.getType() == JavaTokenTypes.EXPR))
                {
                    ;
                }
                else if (newChild.isPositionKnown())
                {
                    root.endLine = newChild.endLine;
                    root.endColumn = newChild.endColumn;
                }

                // add new child to current root
                if (currentAST.child == null)
                {
                    currentAST.root.setFirstChild(newChild);
                    newChild.parent = root;
                    newChild.prevSibling = root;
                }
                else
                {
                    currentAST.child.setNextSibling(newChild);
                    newChild.parent = root;
                    newChild.prevSibling = (JavaNode) currentAST.child;
                }

                // update the parent link for all siblings
                for (
                    JavaNode sibling = (JavaNode) newChild.getNextSibling();
                    sibling != null; sibling = (JavaNode) sibling.getNextSibling())
                {
                    sibling.parent = root;
                }
            }

            currentAST.child = child;
            currentAST.advanceChildToEnd();
        }
    }
    /**
     * Creates a new JavaNode node.
     *
     * @param type information to setup the node with.
     *
     * @return newly created Node.
     */
    public AST create(int type)
    {
        JavaNode node = (JavaNode) _compositeFactory.getCached(JavaNodeFactory.class);
        if (node==null) {
            node = new JavaNodeImpl();
            _compositeFactory.addCached(JavaNodeFactory.class,node);
        }
        node.initialize(type, EMPTY_STRING);

        return node;
    }


    /**
     * Creates a new JavaNode node.
     *
     * @param node node to setup the new node with.
     *
     * @return newly created Node.
     */
    public AST create(AST node)
    {
        if (node == null)
        {
            return null;
        }

        JavaNode result = (JavaNode) create();
        result.initialize(node);

        return result;
    }


    /**
     * Creates a new JavaNode node.
     *
     * @param token token to setup the new node with.
     *
     * @return newly created Node.
     */
    public AST create(Token token)
    {
        if (token == null)
        {
            return null;
        }

        JavaNode result = (JavaNode) create();
        result.initialize(token);

        return result;
    }


    /**
     * Creates a new JavaNode node.
     *
     * @param type type information to setup the node with.
     * @param text text to setup the node with.
     *
     * @return newly created Node.
     */
    public AST create(
        int    type,
        String text)
    {
        JavaNode result = (JavaNode) create();
        result.initialize(type, text);

        return result;
    }


    /**
     * Duplicate the given tree (including all siblings of root).
     *
     * @param t the root node of the tree (or tree portion)
     *
     * @return the copy of the tree.
     */
    public AST dupList(AST t)
    {
        JavaNode result = (JavaNode) dupTree(t); // if t == null, then result==null

        if (result != null)
        {
            JavaNode node = (JavaNode) t;
            result.parent = node.parent;
            result.prevSibling = node.parent;
        }

        JavaNode nt = result;

        while (t != null) // for each sibling of the root
        {
            t = t.getNextSibling();

            JavaNode next = (JavaNode) dupTree(t);
            nt.setNextSibling(next); // dup each subtree, building new tree

            if (next != null)
            {
                next.prevSibling = nt;
                next.parent = result.parent;
            }

            nt = (JavaNode) nt.getNextSibling();
        }

        return result;
    }
    
    /** Copy a single node with same Java AST objec type.
     *  Ignore the tokenType->Class mapping since you know
     *  the type of the node, t.getClass(), and doing a dup.
     *
     *  clone() is not used because we want all AST creation
     *  to go thru the factory so creation can be
     *  tracked.  Returns null if t is null.
     */
    public AST dup(AST t) {
        if ( t==null ) {
            return null;
        }
        AST dup_t = create();
        dup_t.initialize(t);
        return dup_t;
    }


    /**
     * Duplicate a tree, assuming this is a root node of a tree -- duplicates that node
     * and what's below; ignore siblings of root node.
     *
     * @param t the root node of the tree (or tree portion)
     *
     * @return the copy of the tree.
     */
    public AST dupTree(AST t)
    {
        
        JavaNode result = (JavaNode) dup(t); // make copy of root

        // copy all children of root.
        if (t != null)
        {
            JavaNode child = (JavaNode) t.getFirstChild();

            if (child != null)
            {
                child.parent = result;
                child.prevSibling = result;
                result.setFirstChild(dupList(child));
            }
        }

        return result;
    }


    /**
     * Logs the given error message.
     *
     * @param message an error message.
     */
    public void error(String message)
    {
        Loggers.PARSER.error(message);
    }


    /**
     * Makes a tree from a list of nodes. The first element in the array is the root. If
     * the root is null, then the tree is actually a simple list not a
     * tree. Handles null children nodes correctly. For example,
     * build(a, b,  null, c) yields tree (a b c).
     * build(null,a,b) yields tree (nil a b).
     * 
     * 

* Sets also the line/column info of the root node. *

* * @param nodes the nodes to create the tree with. * TODO Examine what this does * @return the generated tree. */ public AST make(AST[] nodes) { if ((nodes == null) || (nodes.length == 0)) { return null; } JavaNode root = (JavaNode) nodes[0]; if (root != null) { // don't leave any old pointers set root.setFirstChild(null); } // was the position info set boolean set = root.isPositionKnown(); JavaNode tail = null; // link in children for (int i = 1; i < nodes.length; i++) { if (nodes[i] == null) { continue; } JavaNode first = (JavaNode) nodes[i]; if (root == null) { // set the root and set it up for a flat list root = tail = (JavaNode) nodes[i]; } else if (tail == null) { root.setFirstChild(nodes[i]); tail = first; tail.parent = root; tail.prevSibling = root; } else { tail.setNextSibling(nodes[i]); JavaNode tmp = tail; tail = first; tail.parent = root; tail.prevSibling = tmp; } // set the root position from the first child were the position // is known if (!set && first.isPositionKnown()) { // make sure the first node holds the first token first = getFirstNode(first); root.startLine = first.startLine; root.startColumn = first.startColumn; root.endLine = first.endLine; root.endColumn = first.endColumn; set = true; } // chase tail to last sibling while (tail.getNextSibling() != null) { JavaNode prevSibling = tail; tail = (JavaNode) tail.getNextSibling(); tail.parent = root; tail.prevSibling = prevSibling; } } if (root.isPositionKnown() && tail!=null) { if (tail.isPositionKnown()) { root.endLine = tail.endLine; root.endColumn = tail.endColumn; } else { tail.startLine = root.startLine; tail.startColumn = root.startColumn + 1; tail.endLine = root.endLine; tail.endColumn = root.endColumn - 1; } } return root; } /** * DOCUMENT ME! * * @param currentAST DOCUMENT ME! * @param root DOCUMENT ME! */ public void makeASTRoot( ASTPair currentAST, AST root) { if (root != null) { // Add the current root as a child of new root root.addChild(currentAST.root); // The new current child is the last sibling of the old root currentAST.child = currentAST.root; currentAST.advanceChildToEnd(); // update the parent link for all siblings for ( JavaNode sibling = (JavaNode) currentAST.root; sibling != null; sibling = (JavaNode) sibling.getNextSibling()) { sibling.parent = (JavaNode) root; } // Set the new root currentAST.root = root; } } /** * Returns the node which holds the actual first token (as found in the input * source). For dotted AST portions that means we have to link into the children to * find the correct one (which is the last in the AST portion). * * @param node node to search for the actual first node. * * @return the actual first node (normally node is returned). */ private JavaNode getFirstNode(AST node) { switch (node.getType()) { case JavaTokenTypes.DOT : case JavaTokenTypes.METHOD_CALL : return getFirstNode(node.getFirstChild()); } return (JavaNode) node; } public JavaNode create( int startLine, int startColumn, int endLine, int endColumn) { JavaNode node = (JavaNode)create(); node.startLine=startLine; node.startColumn=startColumn; node.endLine=endLine; node.endColumn=endColumn; return node; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy