Package actions

Source Code of actions.ShowFlowAction

package actions;

import com.intellij.find.FindManager;
import com.intellij.find.findUsages.FindUsagesHandler;
import com.intellij.find.findUsages.FindUsagesManager;
import com.intellij.find.findUsages.FindUsagesOptions;
import com.intellij.find.impl.FindManagerImpl;
import com.intellij.lang.javascript.JSTokenTypes;
import com.intellij.lang.javascript.psi.JSFile;
import com.intellij.lang.javascript.psi.JSFunction;
import com.intellij.lang.javascript.psi.ecmal4.JSClass;
import com.intellij.lang.javascript.psi.resolve.JSResolveUtil;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.usages.Usage;
import com.intellij.usages.UsageInfo2UsageAdapter;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;

import java.util.*;

/**
* User: John Lindquist
* Date: 6/16/11
* Time: 10:26 AM
*/
public class ShowFlowAction extends AnAction
{

    public void actionPerformed(AnActionEvent e)
    {
        Project project = e.getData(LangDataKeys.PROJECT);
        buildMappingData(project, "IMediatorMap", "mapView");

//        Collection<JSClass> contextSubclasses = JSInheritanceUtil.findDirectSubClasses(jsClass, false);
//        JSClass next = contextSubclasses.iterator().next();
//        Collection<JSClass> declaringClasses = JSInheritanceUtil.findDeclaringClasses(mediatorMap);//finds a class that declares mediatorMape
//        FindUsagesHandler usagesOfPsiElement = findUsagesOfPsiElement(mapView, project);
//        PsiElement[] primaryElements = usagesOfPsiElement.getPrimaryElements();
//        JSQualifiedNamedElement next = JSResolveUtil.findElementsByName("Context", project, GlobalSearchScope.allScope(project)).iterator().next();
//        JSChangeUtil.createJSTreeFromText(project, "")
//        JSResolveUtil.getClassOfContext() //this should be useful to find the commands that reference mediatorMap

//        FindUsagesHandler findUsagesHandler = findUsagesOfPsiElement(psiElement, project);
//        ((UsageInfo2UsageAdapter)usage).getElement().getContext().getChildren()[1] //getting args list of a mapView call
//        ((UsageInfo2UsageAdapter)usage).getElement().getContext().getChildren()[1].getChildren()[0] //first arg
//        ((UsageInfo2UsageAdapter)usage).getElement().getContext().getChildren()[1].getChildren()[1] //second arg
//        ((UsageInfo2UsageAdapter)usage).getElement().getContext().getChildren()[1].getChildren()[0].resolve() //the class of the first arg

//        PsiElement[] psiElements = findUsagesHandler.getPrimaryElements();
    }

    private void buildMappingData(Project project, String className, String functionName)
    {
        PsiDocumentManager.getInstance(project).commitAllDocuments();

        //What's a better way to find a JSClass from a String? I want to find: org.robotlegs.core.IMediatorMap
        JSClass jsClass = (JSClass) JSResolveUtil.findElementsByName(className, project, GlobalSearchScope.allScope(project)).iterator().next();

        //Find the "mapView" function on IMediatorMap so we can find where it's used throughout the app
        JSFunction mapView = jsClass.findFunctionByName(functionName);

        //Find all the usages of "mapView" and return then as UsageInfo
        List<UsageInfo2UsageAdapter> mapViewUsages = findUsagesOfPsiElement(mapView, project);

        //Create a map of the first param (the "view") to the second param (the "mediator")
        HashMap<JSFile, HashMap<JSClass, JSClass>> fileWithViewToMediatorMap = getMappedElementsFromUsage(mapViewUsages);

        Set<JSFile> keys = fileWithViewToMediatorMap.keySet();

        for (JSFile key : keys)
        {
            System.out.print(key.getName() " has mappings: \n");
            List<HashMap<JSClass, JSClass>> listOfMappings = (List<HashMap<JSClass, JSClass>>) fileWithViewToMediatorMap.get(key);
            for (HashMap<JSClass, JSClass> mapping : listOfMappings)
            {
                Set<JSClass> viewClasses = mapping.keySet();
                for (JSClass viewClass : viewClasses)
                {
                    System.out.print("\t" + viewClass.getName() + " to " + mapping.get(viewClass).getName() "\n");
                }
            }
        }
    }

    private HashMap<JSFile, HashMap<JSClass, JSClass>> getMappedElementsFromUsage(List<UsageInfo2UsageAdapter> mapViewUsages)
    {
        HashMap fileToViewMediatorMapList = new HashMap<JSFile, List<HashMap < JSClass, JSClass >>>();

        for (UsageInfo2UsageAdapter mapViewUsage:mapViewUsages)
        {
            PsiFile containingFile = mapViewUsage.getElement().getContainingFile();

            List<HashMap<JSClass, JSClass>> viewMediatorMapList = (List<HashMap<JSClass, JSClass>>) fileToViewMediatorMapList.get(containingFile);

            if (viewMediatorMapList == null)
            {
                viewMediatorMapList = new ArrayList<HashMap<JSClass, JSClass>>();
                fileToViewMediatorMapList.put(containingFile, viewMediatorMapList);
            }

            //move "up" once: mediatorMap.mapView -> mediatorMap.mapView(View, Mediator)
            PsiElement context = mapViewUsage.getElement().getContext();

            //move to args: mediatorMap.mapView(View, Mediator) -> (View, Mediator)
            PsiElement[] children = context.getChildren()[1].getChildren();

            JSClass view = (JSClass) ((PsiReference) children[0]).resolve();
            JSClass mediator = (JSClass) ((PsiReference) children[1]).resolve();

            //map the view to the mediator
            HashMap<JSClass, JSClass> viewToMediatorMap = new HashMap<JSClass, JSClass>();
            viewToMediatorMap.put(view, mediator);
            viewMediatorMapList.add(viewToMediatorMap);
        }
        return fileToViewMediatorMapList;
    }

    public static List<UsageInfo2UsageAdapter> findUsagesOfPsiElement(PsiElement psiElement, Project project)
    {
        final List<UsageInfo2UsageAdapter> usages = new ArrayList<UsageInfo2UsageAdapter>();
        Processor<Usage> collect = new Processor<Usage>()
        {
            public boolean process(@NotNull Usage usage)
            {
                synchronized (usages)
                {
                    usages.add(((UsageInfo2UsageAdapter) usage));
                }
                return true;
            }
        };

        FindUsagesManager findUsagesManager = ((FindManagerImpl) FindManager.getInstance(project)).getFindUsagesManager();
        FindUsagesHandler findUsagesHandler = findUsagesManager.getFindUsagesHandler(psiElement, false);
        FindUsagesOptions findUsagesOptions = findUsagesHandler.getFindUsagesOptions();
        findUsagesManager.processUsages(findUsagesHandler, collect, findUsagesOptions);
        return usages;
    }

    private static void checkCallIdentifier(PsiElement element, String identifierString)
    {
        PsiElement identifier = (PsiElement) element.getContext().getContext().getChildren()[0].getNode().findChildByType(JSTokenTypes.IDENTIFIER);
        if (identifier != null)
        {
            String listenerText = element.getContext().getContext().getText();
            PsiFile containingFile = element.getContainingFile();
            if (identifier.getText().equals("mapListener"))
            {
                System.out.print("You found a robotlegs mapListener reference at " + containingFile.getText() + listenerText + "\n");
            }
            if (identifier.getText().equals(identifierString))
            {
                System.out.print("You found an addEventListener reference" + containingFile.getText() + listenerText + "\n");
            }
        }
    }
}

TOP

Related Classes of actions.ShowFlowAction

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.