Cannot Cast PsiElement to KtClass

已回答

I'm learning to create a plugin for IntelliJ but I'm stuck at PsiElement. I can't cast PsiElement to KtClass even though it also a KtClass.

Here's the error log

java.lang.ClassCastException: org.jetbrains.kotlin.psi.KtClass cannot be cast to org.jetbrains.kotlin.psi.KtClass
at action.MyAction.getPsiClassFromEvent(MyAction.kt:32)
at action.MyAction.actionPerformed(MyAction.kt:21)
at com.intellij.openapi.actionSystem.ex.ActionUtil$1.run(ActionUtil.java:261)
at com.intellij.openapi.actionSystem.ex.ActionUtil.performActionDumbAware(ActionUtil.java:278)
at com.intellij.openapi.actionSystem.ex.ActionUtil.performActionDumbAwareWithCallbacks(ActionUtil.java:252)
at com.intellij.ui.popup.ActionPopupStep.performAction(ActionPopupStep.java:200)
at com.intellij.ui.popup.ActionPopupStep.performAction(ActionPopupStep.java:190)
at com.intellij.ui.popup.ActionPopupStep.lambda$onChosen$2(ActionPopupStep.java:184)
at com.intellij.openapi.application.TransactionGuardImpl.performUserActivity(TransactionGuardImpl.java:195)
at com.intellij.ui.popup.AbstractPopup.lambda$dispose$13(AbstractPopup.java:1416)
at com.intellij.util.ui.UIUtil.invokeLaterIfNeeded(UIUtil.java:3082)
at com.intellij.ide.IdeEventQueue.ifFocusEventsInTheQueue(IdeEventQueue.java:160)
at com.intellij.ide.IdeEventQueue.executeWhenAllFocusEventsLeftTheQueue(IdeEventQueue.java:112)
at com.intellij.openapi.wm.impl.FocusManagerImpl.doWhenFocusSettlesDown(FocusManagerImpl.java:179)
at com.intellij.openapi.wm.impl.IdeFocusManagerImpl.doWhenFocusSettlesDown(IdeFocusManagerImpl.java:58)
at com.intellij.ui.popup.AbstractPopup.dispose(AbstractPopup.java:1412)
at com.intellij.ui.popup.WizardPopup.dispose(WizardPopup.java:160)
at com.intellij.ui.popup.list.ListPopupImpl.dispose(ListPopupImpl.java:306)
at com.intellij.ui.popup.PopupFactoryImpl$ActionGroupPopup.dispose(PopupFactoryImpl.java:279)
at com.intellij.openapi.util.Disposer$1.execute(Disposer.java:48)
at com.intellij.openapi.util.Disposer$1.execute(Disposer.java:44)
at com.intellij.openapi.util.objectTree.ObjectNode$1.execute(ObjectNode.java:136)
at com.intellij.openapi.util.objectTree.ObjectNode$1.execute(ObjectNode.java:105)
at com.intellij.openapi.util.objectTree.ObjectTree.executeActionWithRecursiveGuard(ObjectTree.java:214)
at com.intellij.openapi.util.objectTree.ObjectNode.execute(ObjectNode.java:105)
at com.intellij.openapi.util.objectTree.ObjectTree.executeAll(ObjectTree.java:162)
at com.intellij.openapi.util.Disposer.dispose(Disposer.java:129)
at com.intellij.openapi.util.Disposer.dispose(Disposer.java:125)
at com.intellij.ui.popup.WizardPopup.disposeAllParents(WizardPopup.java:263)
at com.intellij.ui.popup.list.ListPopupImpl.handleNextStep(ListPopupImpl.java:442)
at com.intellij.ui.popup.list.ListPopupImpl._handleSelect(ListPopupImpl.java:395)
at com.intellij.ui.popup.list.ListPopupImpl.handleSelect(ListPopupImpl.java:336)
at com.intellij.ui.popup.list.ListPopupImpl$1.actionPerformed(ListPopupImpl.java:249)
at com.intellij.ui.popup.WizardPopup.proceedKeyEvent(WizardPopup.java:378)
at com.intellij.ui.popup.WizardPopup.dispatch(WizardPopup.java:358)
at com.intellij.ui.popup.PopupDispatcher.dispatchKeyEvent(PopupDispatcher.java:114)
at com.intellij.ui.popup.PopupDispatcher.dispatch(PopupDispatcher.java:150)
at com.intellij.ide.IdePopupManager.dispatch(IdePopupManager.java:86)
at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:657)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:375)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)



Here's my function

private fun getPsiClassFromEvent(e: AnActionEvent): KtClass? {
val psiElement = e.getData(
LangDataKeys.PSI_ELEMENT
) ?: return null

return psiElement as KtClass
}

here's my gradle:

plugins {
id 'org.jetbrains.intellij' version '0.4.15'
id 'org.jetbrains.kotlin.jvm' version '1.3.61'
}

group 'intellijtemplate.djaka.id'
version '1.0-SNAPSHOT'

repositories {
mavenCentral()
}

apply plugin: 'org.jetbrains.intellij'
apply plugin: 'kotlin'

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61"
}

// See https://github.com/JetBrains/gradle-intellij-plugin/
intellij {
version '2019.1.4'
plugins 'org.jetbrains.kotlin:1.3.11-release-IJ2018.3-1'
}

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>"""
}
0

I found the following problems:

1) using "import org.jetbrains.kotlin.com.intellij.psi.PsiElement" from Kotlin Plugin instead of "com.intellij.psi.PsiElement" in KtClassHelper

2) in build.gradle, "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61" was included into project's instead of buildscript classpath

Please fix (1) and change your build.gradle file to the version posted below. Please see http://www.jetbrains.org/intellij/sdk/docs/tutorials/kotlin.html in SDK Docs as reference.

 

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61"
}
}

plugins {
id 'org.jetbrains.intellij' version '0.4.15'
id 'org.jetbrains.kotlin.jvm' version '1.3.61'
}

group 'intellijtemplate.djaka.id'
version '1.0-SNAPSHOT'

repositories {
mavenCentral()
}

apply plugin: 'org.jetbrains.intellij'
apply plugin: 'kotlin'

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
}

// See https://github.com/JetBrains/gradle-intellij-plugin/
intellij {
version '2019.1.4'
plugins 'Kotlin'
}

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>"""
}
1

There is no dedicated tutorial for Kotlin's PSI.

You can find plugins targeting Kotlin in some way with sources available here https://plugins.jetbrains.com/search?search=kotlin&shouldHaveSource=true

Also, make use of https://plugins.jetbrains.com/plugin/227-psiviewer to understand the PSI

1

Hello, can you help me find what am I doing wrong? I'm getting the following error:

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 @6bf6bf87; org.jetbrains.kotlin.psi.KtFile is in unnamed module of loader com.intellij.ide.plugins.cl.PluginClassLoader @62ccc687) at com.ordinarythinker.jcat.ProcessKtFileAction.actionPerformed(ProcessKtFileAction.kt:24)

here is my build.gradle.kts:

plugins {
   id("org.jetbrains.intellij") version "1.16.0"
   id("org.jetbrains.kotlin.jvm") version "1.9.21"
}
group = "com.ordinarythinker"
version = "1.0-SNAPSHOT"
repositories {
   mavenCentral()
}
dependencies {
   implementation(kotlin("compiler-embeddable", "1.9.21"))
   implementation(kotlin("reflect"))
}
apply(plugin = "org.jetbrains.intellij")
apply(plugin = "kotlin")
intellij {
   version.set("2022.3.1")
   type.set("IC")
   plugins.set(listOf("android", "Kotlin"))
}
tasks {
   withType<JavaCompile> {
       sourceCompatibility = "17"
       targetCompatibility = "17"
   }
   withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
       kotlinOptions.jvmTarget = "17"
   }
   runIde {
       ideDir.set(file("C:\\Program Files\\Android\\Android Studio2"))
   }
   patchPluginXml {
       sinceBuild.set("223")
       untilBuild.set("241.*")
   }
   signPlugin {
       certificateChain.set(System.getenv("CERTIFICATE_CHAIN"))
       privateKey.set(System.getenv("PRIVATE_KEY"))
       password.set(System.getenv("PRIVATE_KEY_PASSWORD"))
   }
   publishPlugin {
       token.set(System.getenv("PUBLISH_TOKEN"))
   }
}
1

here is my custom action code:

package com.ordinarythinker.jcat
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedFunction

class ProcessKtFileAction : AnAction() {
    override fun actionPerformed(e: AnActionEvent) {
        val project: Project = e.project ?: return
        val file: VirtualFile? = e.getData(CommonDataKeys.VIRTUAL_FILE)

        if (file != null && file.isValid) {
            val psiFile: PsiFile? = e.getData(CommonDataKeys.PSI_FILE)

            try {
                val ktFile = psiFile as KtFile
            } catch (e: Exception) {
                e.printStackTrace()
            }

            if (psiFile != null && psiFile is KtFile) {
                if (containsComposableFunctions(psiFile)) {
                    try {
                        runPluginTask(project, file)
                    } catch (ex: Exception) {
                        ex.printStackTrace()
                    }
                }
            }
        }
    }
    // some other code
}
1

and here is my plugin.xml:
 


<idea-plugin>
    <id>com.ordinarythinker.jCat</id>

    <name>jCat</name>

    <vendor email="" url="https://github.com/ordinarythinker">Andrii D.</vendor>

    <description><![CDATA[
    JCat is a plugin for automated tests generation for Composable functions<br>
    <em>Currently is underway the development</em>
  ]]></description>

    <depends>com.intellij.modules.platform</depends>

    <extensions defaultExtensionNs="com.intellij">
    </extensions>

    <actions>
        <action
                id="ProcessKtFileAction"
                class="com.ordinarythinker.jcat.ProcessKtFileAction"
                text="Generate Test"
                description="Generate test">
            <add-to-group group-id="EditorPopupMenu" anchor="last"/>
        </action>
    </actions>

    <depends>org.jetbrains.kotlin</depends>
</idea-plugin>
1

could you help me identify my mistake?

if it's necessary, here is my repository to reproduce:
https://github.com/ordinarythinker/jCat

1

ordinarythinker Please keep one report in one message

1) plugin.xml is missing declaration on Kotlin plugin via <depends>

2) Gradle build file has wrong ID for plugin dependency on Kotlin plugin, see https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html (must be org.jetbrains.kotlin)

3) Please remove this dependency from your Gradle build file. 

   implementation(kotlin("compiler-embeddable", "1.9.21"))
  
1

Hello,
I'm receiving a similar error when testing a Kotlin plugin I'm working on. 
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 @43bfa47d; org.jetbrains.kotlin.psi.KtFile is in unnamed module of loader com.intellij.ide.plugins.cl.PluginClassLoader @12b3e104)
    at com.github.jmechamfd.kotlinannotationfolding.KotlinAnnotationFoldingBuilder.buildFoldRegions(KotlinAnnoationFoldingBuilder.kt:20)


I was wondering if you could help me determine what in my config is causing this issue. I've used the plugin template that JetBrains provides. I've also followed the instructions to Configure Kotlin Support.

Here is the repo I'm workin on : https://github.com/jmechamFD/Kotlin-Annotation-Folding

Here are some quick links to some of the relevant files:
build.gradle.kts
plugin.xml
KotlinAnnotationFoldingBuilder.kt (The file throwing the error)

1

I did, here's my plugin.xml

 

<idea-plugin>
<id>intellijtemplate.djaka.id.intellijtemplate</id>
<name>Intelij Template</name>
<vendor email="test@gmail.com" url="http://www.djaka.id">Djaka Pradana</vendor>

<description>It's just a little short experiment hehehe</description>

<!--depend on kotlin plugin-->
<depends>org.jetbrains.kotlin</depends>

<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
on how to target different products -->
<!-- uncomment to enable plugin in all products
<depends>com.intellij.modules.lang</depends>
-->

<extensions defaultExtensionNs="com.intellij">
<!-- Add your extensions here -->
</extensions>

<actions>
<action id="MyAction" class="action.MyAction" text="MyAction"
description="MyAction">
<add-to-group group-id="GenerateGroup" anchor="last"/>
</action>
</actions>
</idea-plugin>
0

You are referring to a different Kotlin plugin version than the one bundled with 2019.1.4, this will not work.

Please try replacing in build.gradle

plugins 'Kotlin'

instead of

 plugins 'org.jetbrains.kotlin:1.3.11-release-IJ2018.3-1'
0

I've replaced it to this one, but unfortunately still getting the same error

intellij {
version '2019.1.4'
plugins 'Kotlin'
}
0

Please provide complete project sources

0

Thank youu, it works like a charm. I've been stuck in this problem for days.

0

Hello Mr Yann Cebron I cannot find

import org.jetbrains.kotlin.com.intellij.psi.PsiElement;

This is my build.gradel

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.11"
}
}
plugins {
id 'java'
id 'org.jetbrains.intellij' version '0.4.21'
id 'org.jetbrains.kotlin.jvm' version '1.3.11'
}

apply plugin: "kotlin"
apply plugin: 'org.jetbrains.intellij'

group 'com.test.plugin'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
intellij {
plugins "Kotlin"
version '2018.3.6'
alternativeIdePath 'C:\\Program Files\\Android\\Android Studio'
updateSinceUntilBuild false
}
patchPluginXml {
changeNotes """
Add change notes here.<br>
<em>most HTML tags may be used</em>"""
}
0

Nvh Haui,

You have to add a Java dependency in your Gradle:

intellij {
// ...
plugins = ['java', 'Kotlin']
}

and in plugin.xml:

<depends>com.intellij.modules.java</depends>

Check the Compatibility with Multiple Products section in our docs for more details.

0

after I add

plugins = ['java', 'Kotlin'] 
I got error Cannot find builtin plugin java for IDE: C:\Users\hung.nv14\.gradle\caches\modules-2\files-2.1\com.jetbrains.intellij.idea\ideaIC\2018.3.6\be4a083c7dca1159d340fd6dcacc4a78646acfb4\ideaIC-2018.3.6

Should I add plugin in setting -> plugins -> Java ?
I don't know exactly plugin i have to install. Please help me fix it Thank 

0

Update
in plugin.xml I added

<depends>org.jetbrains.kotlin</depends>
<depends>com.intellij.modules.java</depends>

in build.grable
I added 

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib"
implementation "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.11"
testCompile group: 'junit', name: 'junit', version: '4.12'
}

// See https://github.com/JetBrains/gradle-intellij-plugin/
intellij {
version '2020.2'
plugins = ['java', 'Kotlin']
alternativeIdePath 'C:\\Program Files\\Android\\Android Studio'
updateSinceUntilBuild false
}

my language is Java and i can't import import org.jetbrains.kotlin.com.intellij.psi.PsiElement 

0

Nvh haui, please follow guide from https://jetbrains.org/intellij/sdk/docs/products/android_studio.html

you should ideally not use "alternativeIdePath" and it cannot be mixed with "version" at the same time anyway.

0

I think it's not relate my problem. current i can not get kt class from PsiElement. This is my code

public static KtClass getKtClassForElement(@NotNull PsiElement psiElement) {
System.out.println("getKtClassForElement" + "name : " + psiElement.toString());
if (psiElement instanceof KtLightElement) {
System.out.println("psiElement instanceof KtLightElement");
PsiElement origin = ((KtLightElement) psiElement).getKotlinOrigin();
if (origin != null) {
return getKtClassForElement(origin);
} else {
return null;
}

} else if (psiElement instanceof KtClass && !((KtClass) psiElement).isEnum() &&
!((KtClass) psiElement).isInterface() &&
!((KtClass) psiElement).isAnnotation() &&
!((KtClass) psiElement).isSealed()) {
System.out.println("psiElement instanceof KtClass ");
return (KtClass) psiElement;

} else {
System.out.println("Else");
PsiElement parent = psiElement.getParent();
if (parent == null) {
return null;
} else {
return getKtClassForElement(parent);
}
}
}

It's always run in System.out.println("Else") and return null.
Should I using "import org.jetbrains.kotlin.com.intellij.psi.PsiElement" from Kotlin Plugin instead of "com.intellij.psi.PsiElement" in KtClassHelper ?

 

0

Please link your full plugin sources, it's impossible to guess from snippets what is happening.

0


In my company I can not upload source. Do you have any repository and tutorial about KtClass.

I want to create a plugin which can create test for kotlin file. I want to deep search in KtClass but I can not find some tutorial for it.
Could you give me some guide or tutorial ?


Thank you in advance

0

Thanks a lot, it worked!

0

Jmecham  Sorry for delay.

Your plugin misses correct setup of Kotlin plugin in Gradle script https://github.com/jmechamFD/Kotlin-Annotation-Folding/blob/main/gradle.properties#L19 

0

Is there a way to build for both Java and Kotlin, my code runs perfect for Java Classes, but I am having problems with Kotlin Classes

Tried this in build gradle:

```
plugins {
  id("java")
  id("org.jetbrains.kotlin.jvm") version "1.9.23"
  id("org.jetbrains.intellij") version "1.17.2"
}

group = "com.utkarshgupta"
version = "1.0-SNAPSHOT"

repositories {
  mavenCentral()
}

dependencies {
  implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
  implementation("org.jetbrains.kotlin:kotlin-reflect")
  implementation("org.jetbrains.kotlin:kotlin-gradle-plugin")
}

apply(plugin = "org.jetbrains.intellij")
apply(plugin = "org.jetbrains.kotlin.jvm")

// Configure Gradle IntelliJ Plugin
// Read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html
intellij {
  version.set("2023.2.5")
  type.set("IC") // Target IDE Platform

  plugins.set(listOf("android", "Kotlin", "java"))
}

tasks {
  // Set the JVM compatibility versions
  withType<JavaCompile> {
    sourceCompatibility = "1.8"
    targetCompatibility = "1.8"
  }
  withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    kotlinOptions.jvmTarget = "1.8"
  }

  patchPluginXml {
    sinceBuild.set("231")
    untilBuild.set("242.*")
  }

  signPlugin {
    certificateChain.set(System.getenv("CERTIFICATE_CHAIN"))
    privateKey.set(System.getenv("PRIVATE_KEY"))
    password.set(System.getenv("PRIVATE_KEY_PASSWORD"))
  }

  publishPlugin {
    token.set(System.getenv("PUBLISH_TOKEN"))
  }
}
```

And my xml:

```
<!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html -->
<idea-plugin>
  <!-- Unique identifier of the plugin. It should be FQN. It cannot be changed between the plugin versions. -->
  <id>com.utkarshgupta.class_diagram_generator</id>

  <!-- Public plugin name should be written in Title Case.
       Guidelines: https://plugins.jetbrains.com/docs/marketplace/plugin-overview-page.html#plugin-name -->
  <name>Class Diagram Generator</name>

  <idea-version since-build="202"/>

  <!-- A displayed Vendor name or Organization ID displayed on the Plugins Page. -->
  <vendor>Utkarsh Gupta</vendor>

  <!-- Description of the plugin displayed on the Plugin Page and IDE Plugin Manager.
       Simple HTML elements (text formatting, paragraphs, and lists) can be added inside of <![CDATA[ ]]> tag.
       Guidelines: https://plugins.jetbrains.com/docs/marketplace/plugin-overview-page.html#plugin-description -->
  <description><![CDATA[
    Generates a class diagram in UML format, with configurable settings.
  ]]></description>

  <!-- Product and plugin compatibility requirements.
       Read more: https://plugins.jetbrains.com/docs/intellij/plugin-compatibility.html -->
  <depends>com.intellij.modules.platform</depends>
  <depends>com.intellij.modules.java</depends>
  <depends>com.intellij.java</depends>
  <depends>org.jetbrains.kotlin</depends>

  <!-- Extension points defined by the plugin.
       Read more: https://plugins.jetbrains.com/docs/intellij/plugin-extension-points.html -->
  <extensions defaultExtensionNs="com.intellij">

  </extensions>

  <actions>
    <action id="GenerateClassDiagramAction" class="com.utkarshgupta.class_diagram_generator.actions.GenerateClassDiagramAction" text="Generate Class Diagram" description="Generate UML class diagram from selected class">
      <add-to-group group-id="EditorPopupMenu" anchor="first"/>
    </action>
  </actions>
</idea-plugin>
```

Not able to import `import org.jetbrains.kotlin.com.intellij.psi.PsiElement as KotlinPsiElement`

It says intellij is an unresolved reference

0

Utkarshgupta2504 Why not use UAST? It is the default solution when adressing Java/Kotlin/Scala… JVM languages with one API interface https://plugins.jetbrains.com/docs/intellij/uast.html

0

Yann Cebron , checked out the docs, looks promising, will try and update this comment as my progress goes, thank you! 

0

请先登录再写评论。