简体   繁体   English

如何在用 Kotlin 编写的 Intellij IDEA Gradle 插件项目中包含 Kotlin PSI 类(例如 KtClass)?

[英]How to include Kotlin PSI classes (e.g. KtClass) in Intellij IDEA Gradle plugin project written in Kotlin?

I am trying to write a plugin to add mock data to a Kotlin project.我正在尝试编写一个插件来将模拟数据添加到 Kotlin 项目中。 The first part involves finding all the Kotlin classes in the current project that inherits from a specific base class.第一部分涉及查找当前项目中继承自特定基础 class 的所有 Kotlin 类。 I want to be able to parse these classes to read the value of an annotation and to get the structure of the constructor.我希望能够解析这些类以读取注释的值并获取构造函数的结构。 This information will then be used to add code to the project adding instances of selected classes to a mock database instance.然后,此信息将用于向项目添加代码,将选定类的实例添加到模拟数据库实例。

I have been using the PsiViewer plugin to inspect the PSI tree in the Kotlin class files.我一直在使用 PsiViewer 插件来检查 Kotlin class 文件中的 PSI 树。 To get access to KtFile, KtClass etc I added a dependency to "org.jetbrains.kotlin:kotlin-compiler-embeddable" in my build-gradle file.为了访问 KtFile、KtClass 等,我在 build-gradle 文件中添加了对“org.jetbrains.kotlin:kotlin-compiler-embeddable”的依赖项。 This seems to be OK until I try to run the plugin.在我尝试运行插件之前,这似乎没问题。 I never get a match when using eg psiFile is KtFile .使用例如psiFile is KtFile时,我从来没有得到匹配。 I still manage to get hold of the correct PsiFile instances by simple parsing of the text field, but when I try to cast a PsiFile instance I get the following exception:我仍然设法通过简单地解析text字段来获取正确的PsiFile实例,但是当我尝试PsiFile实例时,我得到以下异常:

java.lang.ClassCastException: class org.jetbrains.kotlin.psi.KtFile cannot be cast to class org.jetbrains.kotlin.psi.KtFile (org.jetbrains.kotlin.psi.KtFile is in unnamed module of loader com.intellij.ide.plugins.cl.PluginClassLoader @2ed18f3d; org.jetbrains.kotlin.psi.KtFile is in unnamed module of loader com.intellij.ide.plugins.cl.PluginClassLoader @4308c14c)

I am using IntelliJ IDEA 2019.2.3 at the moment.我目前正在使用 IntelliJ IDEA 2019.2.3。 Tried to use different versions of the kotlin plugins (1.3.31 and 1.3.41).尝试使用不同版本的 kotlin 插件(1.3.31 和 1.3.41)。 Running on Windows 10.在 Windows 10 上运行。

build.gradle build.gradle

plugins {
    id 'java'
    id 'org.jetbrains.intellij' version '0.4.11'
    id 'org.jetbrains.kotlin.jvm' version '1.3.31'
}

group 'se.winassist'
version '1.0'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    implementation "org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.31"
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

// See https://github.com/JetBrains/gradle-intellij-plugin/
intellij {
    version '2019.2.3'
}
compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
patchPluginXml {
    changeNotes """
      Add change notes here.<br>
      <em>most HTML tags may be used</em>"""
}

CreateMockdataFromPostgreSQLClass.kt: CreateMockdataFromPostgreSQLClass.kt:

import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.ui.Messages
import org.jetbrains.kotlin.psi.KtFile

class CreateMockdataFromPostgreSQLClass: AnAction() {
    override fun actionPerformed(e: AnActionEvent) {
        val project = e.getRequiredData(CommonDataKeys.PROJECT)
        val kotlinFileHandler = KotlinFileHandler(project)
        val dbClasses = kotlinFileHandler.getAllKotlinDbClasses()
        val classNames = dbClasses.map {
            val ktFile = it as KtFile
            ktFile.name
        }.joinToString(separator = "\n")
        Messages.showInfoMessage(classNames, "Test")
    }
}

KotlinFileHandler.kt : KotlinFileHandler.kt

import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.psi.PsiDirectory
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager

data class KotlinFileHandler(val aProject: Project) {

    fun getAllKotlinDbClasses(): List<PsiFile> {
        val roots = ProjectRootManager.getInstance(aProject).contentSourceRoots
        val dirs = roots.map { PsiManager.getInstance(aProject).findDirectory(it) }
        val result = mutableListOf<PsiFile>()
        getKotlinDbClassesInPsiDir(result, dirs)
        return result.toList()
    }

    private tailrec fun getKotlinDbClassesInPsiDir(aResult: MutableList<PsiFile>, aPsiDirectoryList: List<PsiDirectory?>) {
        if (aPsiDirectoryList.isEmpty()) return

        val subDirectories = mutableListOf<PsiDirectory>()
        aPsiDirectoryList.filter { it != null }.forEach {
            val children = it!!.children
            val files = children.filter {
                it is PsiFile && it.language.toString().toLowerCase() == "language: kotlin"
            }.map { it as PsiFile }
            subDirectories += children.filter { it is PsiDirectory }.map { it as PsiDirectory }
            aResult += files.filter {
                hasBasePersistenceSuperclass(it) && hasTableNameAnnotation(it)
            }.toList()
        }
        getKotlinDbClassesInPsiDir(aResult, subDirectories)
    }
}

I assume I set up gradle incorrectly.我假设我错误地设置了 gradle。 I have looked for a proper setup extensively, but failed to find a working solution.我已经广泛寻找合适的设置,但未能找到有效的解决方案。 Can anyone guide me to the proper gradle setup?谁能指导我正确的 gradle 设置?

Did you check by adding plugins to IntelliJ task您是否通过将插件添加到 IntelliJ 任务来检查

intellij {
  version '2020.1'
  plugins = ['java','Kotlin']
  intellij.type = 'IC'
}

Please check and update请检查并更新

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使Gradle中的Idea插件为Kotlin生成正确的项目配置? - How to make idea plugin in gradle generate proper project configuration for Kotlin? 如何在IntelliJ IDEA插件项目中使用Gradle? - How to use gradle in intellij idea plugin project? 如何在 IntelliJ IDEA/Gradle 项目中使用 Java `package-info.java` 记录 Kotlin 包? - How do I document a Kotlin package like with the Java `package-info.java` in an IntelliJ IDEA/Gradle project? 如何在 Intellij IDEA 中使用 Gradle 创建 Kotlin 控制台应用程序 - How to create a Kotlin console application with Gradle in Intellij IDEA IntelliJ IDEA 存在 Kotlin Gradle 依赖问题 - IntelliJ IDEA having problem with Kotlin Gradle dependency 获取IntelliJ Kotlin插件和gradle进行配对 - Get IntelliJ Kotlin plugin and gradle to match up 如何使用 Gradle 和 IntelliJ 在 Kotlin 多平台项目中配置 JUnit 5? - How to configure JUnit 5 in a Kotlin multiplatform project using Gradle and IntelliJ? 如何从用 Kotlin/Java 编写的 gradle 插件设置 gradle 插件版本? - How to set gradle plugin version from gradle plugin written in Kotlin/Java? 在 Intellij IDEA 生成的 kotlin 原生项目中放置 gradle 依赖项块的位置? - Where to put gradle dependencies block in kotlin native project generated by Intellij IDEA? 在新安装的 IntelliJ IDEA 中使用默认设置创建新 Kotlin 项目时,Gradle 同步失败 - Gradle sync fails when creating a new Kotlin project with default settings in freshly installed IntelliJ IDEA
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM