pojo2json icon indicating copy to clipboard operation
pojo2json copied to clipboard

无法识别 Kotlin multiplatform 中非JVM平台源码集中的类

Open ForteScarlet opened this issue 1 year ago • 8 comments

Kotlin多平台项目中无法识别 commonMain 中定义的类型,例如 commonMain 中写的某个数据类。如果点击 Copy JSON 会在粘贴板中得到 null 。 会考虑支持Kotlin多平台吗?

ForteScarlet avatar Jun 08 '24 19:06 ForteScarlet

我不太了解你说的 Kotlin多平台, 我搜索的信息认为它是一种移动端跨平台的框架, 所以我没明白你的问题, 你应该用代码展示一个例子,, 让我知道你的想法 .. 另外我也不知道你说的 commonMain 是什么? 如果它是一个标准的 Kotlin class 那么应该是支持的.. 插件会检查带有 "class"字段的 Kotlin 文件, 如果你说的 commonMain 可以被定义为一个 Kotlin class 那应该是支持的..

organics2016 avatar Jun 09 '24 16:06 organics2016

我创建了一个简单的 Kotlin 多平台项目,也许可以用作参考: kt-multiplatform-example.zip

Kotlin 多平台的源码集大概类似于:

root
   \- src
        \- commonMain  ---> 共享的源码集
        |      \- kotlin 
        |            \- DataCommon.kt
        \- jvmMain  -------> 专供 JVM 平台的源码集
        |      \- kotlin
        |            \--- DataJvm.kt
        \- jsMain  ---------> 专供 JS 平台的源码集
              

其中,commonMain 就是对所有平台都共享的源码集,可以在其他平台中访问、并被编译进对应的平台产物中(比如编译成class文件) jvmMain 是 JVM 平台的源码集,可以使用 commonMain 中的东西,但是不能使用其他平台的(比如 JS 平台 jsMain 中的类型)

遇到的问题: 在我上面提供的那个简单的项目中,有两个类,分别是定义在 commonMain 中的 DataCommon.ktjvmMain 中的 DataJvm.kt,而对 DataCommon.kt 使用 Copy JSON 只会在粘贴板中得到 nullDataJvm.kt 则是正常的。

这似乎是因为在 commonMain 中的时候, https://github.com/organics2016/pojo2json/blob/fcf403b2ef1f0ad7bced5e1bbbb8d375568cabea/src/main/java/ink/organics/pojo2json/POJO2JSONAction.java#L33-L77

POJO2JSONAction.pojo2jsonAction 里准备 uElement 的条件逻辑都没有生效,导致最终 uElement 的值为 null,因此toJson得到了值为 nulljson 并且提示了成功。

https://github.com/organics2016/pojo2json/blob/fcf403b2ef1f0ad7bced5e1bbbb8d375568cabea/src/main/java/ink/organics/pojo2json/POJO2JSONAction.java#L67

逻辑中定位到的 elementAt (例如 PsiElement elementAt = psiFile.findElementAt(offset);)是有值的,但是它们似乎无法被解析为UClass 之类的类型 🤔。

我不太了解插件开发,因此想要尝试自行修复但是没有成功,也无法定位到更根本的原因,还望见谅😢

ForteScarlet avatar Jun 09 '24 16:06 ForteScarlet

收到你的回复,,我已经成功复现, 我需要一些时间解决这个BUG

organics2016 avatar Jun 10 '24 05:06 organics2016

感谢你的回复, 可以确定这是一个BUG, 但遗憾的是短时间无法修复. https://github.com/organics2016/pojo2json/blob/fcf403b2ef1f0ad7bced5e1bbbb8d375568cabea/src/main/java/ink/organics/pojo2json/POJO2JSONAction.java#L63 问题在这里, 这可能是 jetbrains plugins SDK 的问题, DataCommon.ktDataJvm.kt 格式上没有任何区别, 但却返回两种不同的结果. 准确的说 commonMain 文件夹下的 kt 文件都无法被正确的解析为 UElement 我对此也很懵逼. JB SDK 的抽象语法引擎实现就是一坨....

https://github.com/organics2016/pojo2json/blob/fcf403b2ef1f0ad7bced5e1bbbb8d375568cabea/src/main/java/ink/organics/pojo2json/POJO2JSONAction.java#L55-L64 这段代码逻辑是: 当用户光标在文件没有元素的区域进行 Copy JSON 时, 会自动查找这个文件中 class 关键字 并将这个关键字所在的元素解析为 抽象语法树中的 UElement . 但是对于 commonMain 文件夹下的所有 kt 文件解析结果却是 null.

这个问题我的去 jetbrains plugins SDK 提Issue.. 短时间内应该无法解决.

organics2016 avatar Jun 10 '24 09:06 organics2016

👌🏻已了解

不知道会不会有别的不用 UElement 的实现方法呢?🤔

这方面不太了解,只是随口说说 , 总而言之辛苦排查了,期待修复的那一天~

ForteScarlet avatar Jun 10 '24 10:06 ForteScarlet

目前最有可能的解释是 IDEA 为 commonMainjvmMain 两个文件夹 加载了两种不同的包环境 , 因为环境中的lib不一样 , 导致语法树引擎认为它们不一样... 之前也有类似的情况. 我已经尝试将 UElement 当作原始的 PsiElement 进行处理,结果所有 kt 文件都会失效....情况比现在更差..我暂时也没什么好办法了..

organics2016 avatar Jun 10 '24 10:06 organics2016

好吧,看来需要等待JB对Issue的答复了

ForteScarlet avatar Jun 10 '24 10:06 ForteScarlet

https://intellij-support.jetbrains.com/hc/en-us/community/posts/19466336231186--BUG-org-jetbrains-uast-UastUtils-findContaining-Unable-to-recognize-Kotlin-class-in-Kotlin-multiplatform

organics2016 avatar Jun 11 '24 04:06 organics2016