小鸭子的学习笔记duck

Duck Blog

唐如飞

( ^∀^)/欢迎\( ^∀^)

79 文章数
14 评论数

IDEA-行标记导航程序

tangrufei
2023-08-23 / 1 评论 / 388 阅读 / 0 点赞

示例代码

XML文件跳转至Java文件

class MyBatisJavaNavigationProvider : RelatedItemLineMarkerProvider()
{
    override fun collectNavigationMarkers(
        element: PsiElement, result: MutableCollection<in RelatedItemLineMarkerInfo<*>>
                                         )
    {
        if (element is PsiClass)
        {
            val psiClass: PsiClass = element
            println(psiClass.qualifiedName)
            val allMethods = element.allMethods
            if (psiClass.containingFile.virtualFile == null)
            {
                return
            }
            val targets: ArrayList<PsiElement> = ArrayList()

            // 1. 查找与 class 类名同名的 xml 文件, 并追加到结果集合
            val xmlFiles = FilenameIndex.getFilesByName(
                psiClass.project, psiClass.name + ".xml", GlobalSearchScope.projectScope(psiClass.project)
                                                       ).toList()
            for (xmlFile in xmlFiles)
            {
                if(xmlFile is XmlFile)
                {
                    var xml:XmlFile=xmlFile
                    println(xml.name)
                    val tag = xml.rootTag
                    if (tag != null)
                    {
                        println(tag.namespace)
                        if(tag.getAttributeValue("namespace") == psiClass.qualifiedName)
                        {
                            targets.add(tag)
                        }
                    }
                }
            }
            if (targets.isEmpty())
            {
                println("结果为空")
                return
            } // 构建导航样式
            val builder: NavigationGutterIconBuilder<PsiElement> =
                NavigationGutterIconBuilder.create(AllIcons.FileTypes.Xml).setTargets(targets)
                    .setTooltipText("Navigate to Xml resource").setAlignment(GutterIconRenderer.Alignment.RIGHT)
                    .setCellRenderer(MyMapperCellRenderer())
            if (null != psiClass.nameIdentifier)
            {
                result.add(builder.createLineMarkerInfo(psiClass.nameIdentifier!!))
            }
            if(!targets.isNullOrEmpty())
            {

                for (method in allMethods)
                {
                    val methodTargets: ArrayList<PsiElement> = ArrayList()
                    val psiElement = targets.get(0)
                    if( psiElement is XmlTag)
                    {
                       var xmlFile:XmlTag= psiElement
                        val findXmlTagById = findXmlTagById(xmlFile, method.name)

                        if (findXmlTagById != null)
                        {
                            methodTargets.add(findXmlTagById)
                            val methodBuilder =
                                NavigationGutterIconBuilder.create(AllIcons.FileTypes.Xml).setTargets(methodTargets)
                                    .setTooltipText("Navigate to Xml resource").setAlignment(GutterIconRenderer.Alignment.RIGHT)
                                    .setCellRenderer(MyMapperCellRenderer())
                            result.add(methodBuilder.createLineMarkerInfo(method.nameIdentifier!!))
                        }
                    }

                }
            }
        }



    }
    fun findXmlTagById(xmlTag: XmlTag, tagId: String): XmlTag? {
        // 查找当前标签的 ID 属性
        val idAttribute = xmlTag.getAttribute("id")
        if (idAttribute != null && idAttribute.value == tagId) {
            return xmlTag
        }

        // 递归查找子标签
        for (childTag in xmlTag.subTags) {
            val foundTag = findXmlTagById(childTag, tagId)
            if (foundTag != null) {
                return foundTag
            }
        }

        return null
    }
    class MyMapperCellRenderer : DefaultPsiElementCellRenderer()
    {
        override fun getElementText(element: PsiElement): String
        {
            val prefix = StringBuilder()
            if (element is JsonProperty)
            {
                prefix.append("Found XML! ")
            }
            return prefix.append(super.getElementText(element)).toString()
        }

        override fun getIcon(element: PsiElement): Icon
        {
            return AllIcons.FileTypes.Xml
        }
    }
}

Java文件跳转至XML文件

package com.atelier.plugin.provider

import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder
import com.intellij.icons.AllIcons
import com.intellij.ide.util.DefaultPsiElementCellRenderer
import com.intellij.json.psi.JsonProperty
import com.intellij.openapi.editor.markup.GutterIconRenderer
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.search.FilenameIndex
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.xml.XmlFile
import com.intellij.sql.formatter.findSubSequence
import javax.swing.Icon

class MyBatisXMLNavigationProvider: RelatedItemLineMarkerProvider()
{
    override fun collectNavigationMarkers(
        element: PsiElement, result: MutableCollection<in RelatedItemLineMarkerInfo<*>>
                                         )
    {
        if (element !is XmlFile) {
            return
        }
        val xmlfile: XmlFile = element
        val tag = xmlfile.rootTag
        val xmlFileName = xmlfile.name
        val className = xmlFileName.substringBeforeLast(".xml")
        if (xmlfile.containingFile.virtualFile == null) {
            return
        }
        val targets: ArrayList<PsiElement> = ArrayList()
        // 1. 查找与 class 类名同名的 java 文件, 并追加到结果集合
        val psiClasses = FilenameIndex.getFilesByName(
            xmlfile.project, "$className.java", GlobalSearchScope.projectScope(xmlfile.project)
                                                   ).toList()
        JavaPsiFacade.getInstance(xmlfile.project).findClass("com.hyway.entity.Shop", element.resolveScope)
        /** 构建样式 */
        val builder: NavigationGutterIconBuilder<PsiElement> =
            NavigationGutterIconBuilder.create(AllIcons.FileTypes.Java).setTargets(targets)
                .setTooltipText("Navigate to Java resource").setAlignment(GutterIconRenderer.Alignment.RIGHT)
                .setCellRenderer(MyJAVACellRenderer())
        //构建根标签
        for (psiClass in psiClasses)
        {
            if (psiClass is PsiJavaFile){
                var javaFile: PsiJavaFile=psiClass
                val javaClasses = javaFile.classes
                val javaClass = javaClasses[0]
                if (javaClass.qualifiedName!! == tag!!.getAttributeValue("namespace"))
                {
                    targets.add(javaClass)
                    result.add(builder.createLineMarkerInfo(tag))
                }
            }
        }
        val subTags = tag!!.subTags

        if (targets.isEmpty()){
            println("未匹配到对应Java实体类")
            return
        }
        for (subTag in subTags)
        {
                val methodTargets: ArrayList<PsiElement> = ArrayList()
                val psiElement = targets[0]
                if (psiElement is PsiClass)
                {
                var psiClass: PsiClass = psiElement
                    val idAttribute = subTag.getAttributeValue("id")
                    val methods = psiClass.findMethodsByName(idAttribute,false)
                    for (method in methods)
                    {
                        methodTargets.add(method)
                    }
                    if(!methods.isEmpty())
                    {
                        val tagBuilder: NavigationGutterIconBuilder<PsiElement> =
                            NavigationGutterIconBuilder.create(AllIcons.FileTypes.Java).setTargets(methodTargets)
                                .setTooltipText("Navigate to Java resource")
                                .setAlignment(GutterIconRenderer.Alignment.RIGHT).setCellRenderer(MyJAVACellRenderer())
                        result.add(tagBuilder.createLineMarkerInfo(subTag!!))
                    }
                }
            }

    }
    class MyJAVACellRenderer : DefaultPsiElementCellRenderer()
    {
        override fun getElementText(element: PsiElement): String
        {
            val prefix = StringBuilder()
            if (element is JsonProperty)
            {
                prefix.append("Found Java! ")
            }
            return prefix.append(super.getElementText(element)).toString()
        }

        override fun getIcon(element: PsiElement): Icon
        {
            return AllIcons.FileTypes.Java
        }
    }
}
文章不错,扫码支持一下吧~
上一篇 下一篇
评论
来首音乐
光阴似箭
今日已经过去小时
这周已经过去
本月已经过去
今年已经过去个月