Package fr.adrienbrault.idea.symfony2plugin.templating

Source Code of fr.adrienbrault.idea.symfony2plugin.templating.TwigTemplateGoToDeclarationHandler

package fr.adrienbrault.idea.symfony2plugin.templating;

import com.intellij.codeInsight.navigation.actions.GotoDeclarationHandler;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.jetbrains.twig.TwigFile;
import com.jetbrains.twig.TwigLanguage;
import com.jetbrains.twig.TwigTokenTypes;
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
import fr.adrienbrault.idea.symfony2plugin.TwigHelper;
import fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper;
import fr.adrienbrault.idea.symfony2plugin.templating.dict.TwigBlock;
import fr.adrienbrault.idea.symfony2plugin.templating.dict.TwigBlockParser;
import fr.adrienbrault.idea.symfony2plugin.templating.dict.TwigExtension;
import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigExtensionParser;
import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigUtil;
import fr.adrienbrault.idea.symfony2plugin.translation.dict.TranslationUtil;
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils;
import fr.adrienbrault.idea.symfony2plugin.util.controller.ControllerIndex;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.Nullable;

import java.util.*;

/**
* @author Adrien Brault <adrien.brault@gmail.com>
*/
public class TwigTemplateGoToDeclarationHandler implements GotoDeclarationHandler {

    @Nullable
    @Override
    public PsiElement[] getGotoDeclarationTargets(PsiElement psiElement, int i, Editor editor) {

        if(!Symfony2ProjectComponent.isEnabled(psiElement) || !PlatformPatterns.psiElement().withLanguage(TwigLanguage.INSTANCE).accepts(psiElement)) {
            return null;
        }

        if (TwigHelper.getBlockTagPattern().accepts(psiElement)) {
            return getBlockGoTo(psiElement);
        }

        if (TwigHelper.getPathAfterLeafPattern().accepts(psiElement)) {
            PsiElement[] psiElements = this.getRouteParameterGoTo(psiElement);
            if(psiElements.length > 0) {
                return psiElements;
            }
        }

        // support: {% include() %}, {{ include() }}
        if(TwigHelper.getTemplateFileReferenceTagPattern().accepts(psiElement) || TwigHelper.getPrintBlockFunctionPattern("include", "source").accepts(psiElement)) {
            return this.getTwigFiles(psiElement);
        }

        if(TwigHelper.getAutocompletableRoutePattern().accepts(psiElement)) {
            return this.getRouteGoTo(psiElement);
        }

        // find trans('', {}, '|')
        // tricky way to get the function string trans(...)
        if (TwigHelper.getTransDomainPattern().accepts(psiElement)) {
            PsiElement psiElementTrans = PsiElementUtils.getPrevSiblingOfType(psiElement, PlatformPatterns.psiElement(TwigTokenTypes.IDENTIFIER).withText(PlatformPatterns.string().oneOf("trans", "transchoice")));
            if(psiElementTrans != null && TwigHelper.getTwigMethodString(psiElementTrans) != null) {
                List<PsiFile> domainPsiFiles = TranslationUtil.getDomainPsiFiles(psiElement.getProject(), psiElement.getText());
                return domainPsiFiles.toArray(new PsiElement[domainPsiFiles.size()]);
            }
        }

        if (TwigHelper.getTranslationPattern("trans", "transchoice").accepts(psiElement)) {
            return getTranslationKeyGoTo(psiElement);
        }

        // provide global twig file resolving
        if (PlatformPatterns.psiElement(TwigTokenTypes.STRING_TEXT)
            .withText(PlatformPatterns.string().endsWith(".twig")).accepts(psiElement)) {

            return this.getTwigFiles(psiElement);
        }

        if(TwigHelper.getPrintBlockFunctionPattern("controller").accepts(psiElement)) {
            PsiElement controllerMethod = this.getControllerGoTo(psiElement);
            if(controllerMethod != null) {
                return new PsiElement[] { controllerMethod };
            }
        }

        if(TwigHelper.getTransDefaultDomain().accepts(psiElement)) {
            List<PsiFile> domainPsiFiles = TranslationUtil.getDomainPsiFiles(psiElement.getProject(), psiElement.getText());
            return domainPsiFiles.toArray(new PsiElement[domainPsiFiles.size()]);
        }

        if(TwigHelper.getAutocompletableFilterPattern().accepts(psiElement)) {
            return getFilterGoTo(psiElement);
        }

        return null;
    }

    private PsiElement[] getRouteParameterGoTo(PsiElement psiElement) {

        String routeName = TwigHelper.getMatchingRouteNameOnParameter(psiElement);
        if(routeName == null) {
            return new PsiElement[0];
        }

        return RouteHelper.getRouteParameterPsiElements(psiElement.getProject(), routeName, psiElement.getText());
    }

    private PsiElement getControllerGoTo(PsiElement psiElement) {
        String text = PsiElementUtils.trimQuote(psiElement.getText());
        return ControllerIndex.getControllerMethod(psiElement.getProject(), text);
    }

    @Nullable
    private PsiElement[] getTwigFiles(PsiElement psiElement) {

        String templateName = psiElement.getText();
        PsiElement[] psiElements = TwigHelper.getTemplatePsiElements(psiElement.getProject(), templateName);

        if(psiElements.length == 0) {
            return null;
        }

        return psiElements;
    }

    private PsiElement[] getFilterGoTo(PsiElement psiElement) {
        HashMap<String, TwigExtension> filters = new TwigExtensionParser(psiElement.getProject()).getFilters();
        if(!filters.containsKey(psiElement.getText())) {
            return new PsiElement[0];
        }

        String signature = filters.get(psiElement.getText()).getSignature();
        if(signature == null) {
            return new PsiElement[0];
        }

        return PhpElementsUtil.getPsiElementsBySignature(psiElement.getProject(), signature);
    }

    public static PsiElement[] getBlockGoTo(PsiElement psiElement) {

        PsiFile containingFile = psiElement.getContainingFile();
        if(containingFile == null) {
            return new PsiElement[0];
        }

        String blockName = psiElement.getText();
        return getBlockNameGoTo(containingFile, blockName);
    }

    public static PsiElement[] getBlockNameGoTo(PsiFile psiFile, String blockName) {
        return getBlockNameGoTo(psiFile, blockName, false);
    }

    public static PsiElement[] getBlockNameGoTo(PsiFile psiFile, String blockName, boolean withSelfBlocks) {
        Map<String, VirtualFile> twigFilesByName = TwigHelper.getTwigFilesByName(psiFile.getProject());
        List<TwigBlock> blocks = new TwigBlockParser(twigFilesByName).withSelfBlocks(withSelfBlocks).walk(psiFile);
        List<PsiElement> psiElements = new ArrayList<PsiElement>();
        for (TwigBlock block : blocks) {
            if(block.getName().equals(blockName)) {
                Collections.addAll(psiElements, block.getBlock());
            }
        }

        return psiElements.toArray(new PsiElement[psiElements.size()]);
    }

    private PsiElement[] getRouteGoTo(PsiElement psiElement) {

        String text = PsiElementUtils.getText(psiElement);

        if(StringUtils.isBlank(text)) {
            return new PsiElement[0];
        }

        PsiElement[] methods = RouteHelper.getMethods(psiElement.getProject(), text);
        if(methods.length > 0) {
            return methods;
        }

        List<PsiElement> psiElementList = RouteHelper.getRouteDefinitionTargets(psiElement.getProject(), text);
        return psiElementList.toArray(new PsiElement[psiElementList.size()]);
    }

    private PsiElement[] getTranslationKeyGoTo(PsiElement psiElement) {
        String translationKey = psiElement.getText();
        return TranslationUtil.getTranslationPsiElements(psiElement.getProject(), translationKey, TwigUtil.getPsiElementTranslationDomain(psiElement));
    }

    @Nullable
    @Override
    public String getActionText(DataContext dataContext) {
        return null;
    }
}
TOP

Related Classes of fr.adrienbrault.idea.symfony2plugin.templating.TwigTemplateGoToDeclarationHandler

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.