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

4

我正在尝试编写一个插件,以向Kotlin项目添加模拟数据。第一部分涉及查找当前项目中所有继承特定基类的Kotlin类。我希望能够解析这些类以读取注释的值并获取构造函数的结构。然后使用这些信息将代码添加到项目中,向模拟数据库实例添加所选类的实例。

我一直在使用PsiViewer插件来检查Kotlin类文件中的PSI树。为了访问KtFile、KtClass等,我在我的build-gradle文件中添加了对"org.jetbrains.kotlin:kotlin-compiler-embeddable"的依赖。这似乎很好,直到我尝试运行插件时。例如,当我使用psiFile is KtFile时,我永远无法匹配。我仍然通过简单解析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)

我目前正在使用的是 IntelliJ IDEA 2019.2.3。尝试使用了不同版本的 Kotlin 插件(1.3.31 和 1.3.41)。运行在 Windows 10 上。

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:

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:

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)
    }
}

我认为我没有正确设置Gradle。我已经广泛寻找了适当的设置,但未能找到可行的解决方案。有人可以指导我正确设置Gradle吗?


也许这个线程相关?https://stackoverflow.com/questions/50183198/how-to-add-kotlin-psi-source-files-to-idea-plugin-project-configuration - dasfima
1个回答

1

你是否通过在IntelliJ任务中添加插件来进行检查?

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

请检查并更新。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接