簡體   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?

我正在嘗試編寫一個插件來將模擬數據添加到 Kotlin 項目中。 第一部分涉及查找當前項目中繼承自特定基礎 class 的所有 Kotlin 類。 我希望能夠解析這些類以讀取注釋的值並獲取構造函數的結構。 然后,此信息將用於向項目添加代碼,將選定類的實例添加到模擬數據庫實例。

我一直在使用 PsiViewer 插件來檢查 Kotlin class 文件中的 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 設置?

您是否通過將插件添加到 IntelliJ 任務來檢查

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

請檢查並更新

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM