[英]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.