Package tree.utils

Source Code of tree.utils.ReferencesListBuilder

package tree.utils;

import java.util.HashMap;

import tree.ErrorNode;
import tree.Function;
import tree.HaxeTree;
import tree.IPackageInfo;
import tree.Module;
import tree.expression.Array;
import tree.expression.Assignment;
import tree.expression.Binary;
import tree.expression.Constant;
import tree.expression.Declaration;
import tree.expression.MethodCall;
import tree.expression.NewNode;
import tree.expression.Slice;
import tree.expression.Unary;
import tree.expression.Usage;
import tree.statement.BlockScope;
import tree.statement.For;
import tree.statement.IfNode;
import tree.statement.Return;
import tree.statement.While;
import tree.type.Class;
import tree.type.Enum;
import tree.type.HaxeType;
import workspace.Activator;
import workspace.HashMapForLists;
import workspace.NodeLink;
import workspace.ProjectManager;
import workspace.elements.CodeFile;
import workspace.elements.HaxeProject;

/**
* Makes a list of usages and calls for the node passed to
* that class in the project to which currently active file
* belongs.
* @author Savenko Maria
*/
public class ReferencesListBuilder extends AbstractHaxeTreeVisitor
{
    // a VarDeclaration\Function\Class\Enum
    private HaxeTree searchObject = null;
    // filepackage - list of found nodes in this' file ast
    private HashMapForLists<NodeLink> foundResult = null;
    private HaxeProject project = null;
    private CodeFile currFile = null;
   
    /**
     * Starts the analysis of references to sertain object in the project.
     * The object to searche references to should be one of the following:
     * Function, Class, Enum, Variable Declaration (later the list of
     * types can be extended)
     *
     * Use Utils to get the object that this class can analyze.
     */
    public void visit(final HaxeTree searchFor)
    {
        ProjectManager prManager = Activator.getProjectManager();
       
        foundResult = new HashMapForLists<NodeLink>();
        project = prManager.getCurrentHaxeProject();
       
        HashMap<String, CodeFile> fullList = project.getFiles();
       
        currFile = prManager.getCurrentFile();
        analyseSearchedObject(searchFor);
       
        for (CodeFile file : fullList.values())
        {
            currFile = file;
            visit(file.getAst(), null);
        }
    }
   
    /**
     * For testing perposes only - when we have no prebuilt project
     * structure.
     * @param searchFor - object to search for
     * @param ast - for current parsed part of test
     */
    public void testVisit(final HaxeTree searchFor, final HaxeTree ast)
    {
        searchObject = searchFor;
        foundResult = new HashMapForLists<NodeLink>();
       
        currFile = new CodeFile("some file", ast);
        visit(ast, null);
    }
   
    /**
     * List of usages\calls for object with the package
     * for file where they we found.
     * @return List of pairs of usages\calls or empty list of pairs.
     */
    public HashMapForLists<NodeLink> getResult()
    {
        return foundResult;
    }
   
    /**
     * This function will analyse the class of the searched object
     * and will extract the real object we should search for.
     * After running that function the previously null 'searchObject'
     * will have the value if the object for searching was valid.
     * @param searchFor
     */
    private void analyseSearchedObject(final HaxeTree searchFor)
    {
        if (searchFor instanceof Declaration)
        {
            addToResults(searchFor);
            searchObject = searchFor;
        }
        else if (searchFor instanceof Class)
        {
            searchObject = searchFor;
            /*
            // TODO actually we can only have one constructor in the class but we
            // can have regular Function named 'new' as well and thus I don't know
            // how to destinguish them so for now I will just make a list and search
            // usages for the first from that list
            List<HaxeTree> constructors = new ArrayList<HaxeTree>();
            ClassNode classN = (ClassNode)searchFor;
            while (constructors.isEmpty())
            {
                BlockScopeNode block = classN.getBlockScope();
                for (HaxeTree subNode : block.getChildren())
                {
                    if (subNode instanceof FunctionNode &&
                            subNode.getText().equals("new"))
                    {
                        constructors.add(subNode);
                    }
                }
                HaxeTree parent = classN.getParentToExtend();
                if (parent == null)
                {
                    break;
                }
                // if the list is empry we will search for superclasses constructors
                classN = (ClassNode)parent;
            }
            // this is just for now as was explained earlier
            if (!constructors.isEmpty())
            {
                searchObject = constructors.get(0);
            }*/
        }
        else if (searchFor instanceof Enum)
        {
            // not implemented yet
        }
        else if (searchFor instanceof Function)
        {
            // if (searchFor.getText().equals("new"))
            // TODO actually we can only have one constructor in the class but we
            // can have regular Function named 'new' as well and thus I don't know
            // how to destinguish them
            searchObject = searchFor;
            addToResults(searchObject);
        }
    }
   
    private void addToResults(final HaxeTree foundNode)
    {
        if (currFile == null)
        {
            return;
        }
        if (foundNode instanceof IPackageInfo)
        {
            String pack = ((IPackageInfo)foundNode).getPackage();
            CodeFile file = project.getFile(pack);
            addToResults(foundNode, file);
        }
        else
        {
            addToResults(foundNode, currFile);
        }
    }
   
    private void addToResults(final HaxeTree foundNode, final CodeFile file)
    {
        NodeLink info = new NodeLink(file.getRealFile(), foundNode);
        foundResult.put(file.getPackage(), info);
    }

    @Override
    protected void visit(final Module node, Object data)
    {
        visitAllChildren(node, data);
    }

    @Override
    protected void visit(final Class node, Object data)
    {
        BlockScope block = node.getBlockScope();       
        if (block == null)
        {
            return;
        }
        visitAllChildren(block, data);       
    }

    @Override
    protected void visit(final Function node, Object data)
    {
        for (HaxeTree param : node.getParametersAsDeclarations())
        {
            visit(param, data);
        }
       
        BlockScope block = node.getBlockScope();     
        if (block == null)
        {
            return;
        }
        visitAllChildren(block, data);
    }

    @Override
    protected void visit(final Declaration node, Object data)
    {
        HaxeType nodeType = node.getHaxeType();
        if ((searchObject instanceof Class || searchObject instanceof Enum)
                && nodeType != null
                && searchObject.getHaxeType().getShortTypeName().equals(nodeType.getShortTypeName()))
        {
            addToResults(node);
        }
        HaxeTree init = node.getInitializationNode();
        if (init == null)
        {
            return;
        }
        visit (init, data);
    }

    @Override
    protected void visit(final NewNode node, Object data)
    {
        HaxeTree declaration = node.getDeclarationNode();
        if (declaration != null
                && searchObject instanceof Class
                // TODO check parameter types and so
                && declaration.getText().equals(searchObject.getText()))
        {
            addToResults(node);
        }
       
        // now visit the params if there are any
        for (HaxeTree child : node.getChildren())
        {
            if (child.getChildIndex() == 0)
            {
                continue;
            }
            visit(child, data);
        }
    }

    @Override
    protected void visit(final MethodCall node, Object data)
    {
        HaxeTree parent = node.getParent();
        HaxeTree decl = node.getDeclarationNode();
        if ((searchObject instanceof Function
                || parent instanceof NewNode) // for constructors
                && decl != null
                && decl.equals(searchObject))
        {
            addToResults(node);
        }
       
        for (HaxeTree param : node.getParameters())
        {
            visit(param, data);
        }
   
        if (node.isFieldUse())
        {
            visit(node.getChild(node.getChildCount() - 1), data);
        }
    }

    @Override
    protected void visit(final Slice node, Object data)
    {
        visitAllChildren(node, data);
    }

    @Override
    protected void visit(final Usage node, Object data)
    {
        String searchName = searchObject.getText();
        String nodeName = node.getText();
        if (node.getDeclarationNode() == null)
        {
            return;
        }
        if (nodeName.equals(searchName)
                && node.getDeclarationNode().equals(searchObject)
                && (searchObject instanceof Declaration
                        || searchObject instanceof Class // for static classes
                        || searchObject instanceof Enum))
        {
            addToResults(node);
        }
        if (node.isFieldUse())
        {
            HaxeTree child = node.getChild(0).getChild(0);
            visit(child, data);
        }
    }

    @Override
    protected void visit(final Assignment node, Object data)
    {
        visitAllChildren(node, data);
    }

    @Override
    protected void visit(final Array node, Object data)
    {
        visitAllChildren(node, data);
    }

    @Override
    protected void visit(final Constant node, Object data)
    {
        // skip
    }

    @Override
    protected void visit(final Return node, Object data)
    {
        visitAllChildren(node, data);
    }

    @Override
    protected void visit(final Binary node, Object data)
    {
        visitAllChildren(node, data);
    }
   
    protected void visit(final Unary node, Object data)
    {
        visitAllChildren(node, data);
    }

    @Override
    protected void visit(final BlockScope node, Object data)
    {
        visitAllChildren(node, data);
    }

    @Override
    protected void visit(final ErrorNode node, Object data)
    {
        // skip
    }

    @Override
    protected void visit(final IfNode node, Object data)
    {
        visitAllChildren(node, data);
    }

    @Override
    protected void visit(final For node, Object data)
    {
        visitAllChildren(node, data);
    }

    @Override
    protected void visit(final While node, Object data)
    {
        visitAllChildren(node, data);
    }

    @Override
    protected void visitUnknown(final HaxeTree node, Object data)
    {
        visitAllChildren(node, data);
    }

}
TOP

Related Classes of tree.utils.ReferencesListBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.