Я пытаюсь написать плагин для добавления фиктивных данных в проект Kotlin. Первая часть включает в себя поиск всех классов Kotlin в текущем проекте, которые наследуются от определенного базового класса. Я хочу иметь возможность анализировать эти классы, чтобы прочитать значение аннотации и получить структуру конструктора. Затем эта информация будет использоваться для добавления кода в проект и добавления экземпляров выбранных классов в экземпляр фиктивной базы данных.
Я использовал плагин PsiViewer для проверки дерева PSI в файлах классов Kotlin. Чтобы получить доступ к KtFile, KtClass и т. Д., Я добавил в файл build-gradle зависимость от «org.jetbrains.kotlin: kotlin-compiler-embeddable». Кажется, это нормально, пока я не попытаюсь запустить плагин. Я никогда не получаю совпадение при использовании, например, psiFile is KtFile
. Мне все еще удается получить правильные PsiFile
экземпляры простым анализом поля text
, но когда я пытаюсь привести экземпляр 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Я использую 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?