问题
I am trying to write a plugin to add mock data to a Kotlin project. The first part involves finding all the Kotlin classes in the current project that inherits from a specific base class. 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. To get access to KtFile, KtClass etc I added a dependency to "org.jetbrains.kotlin:kotlin-compiler-embeddable" in my build-gradle file. This seems to be OK until I try to run the plugin. I never get a match when using e.g. 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:
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. Tried to use different versions of the kotlin plugins (1.3.31 and 1.3.41). Running on 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)
}
}
I assume I set up gradle incorrectly. I have looked for a proper setup extensively, but failed to find a working solution. Can anyone guide me to the proper gradle setup?
回答1:
Did you check by adding plugins to IntelliJ task
intellij {
version '2020.1'
plugins = ['java','Kotlin']
intellij.type = 'IC'
}
Please check and update
来源:https://stackoverflow.com/questions/58803103/how-to-include-kotlin-psi-classes-e-g-ktclass-in-intellij-idea-gradle-plugin