kotlin编译失败_聊两个 Kotlin 编译器的 bug
歡迎大家支持原文。
最近在使用 Kotlin 開發(fā)一個 IDE 插件,遇到了一些 Kotlin 編譯器的 bug ,就在博客里分享一下。
Java 交互問題
首先, Kotlin 編譯器在遇到接口自帶實現(xiàn)的情況時,會生成一個 DefaultImpls ,大概長這樣:
@Metadata(
mv = {1, 1, 9},
bv = {1, 0, 2},
k = 3
)
public static final class DefaultImpls {
@NotNull
public static FShapeQuad getDefaultActiveArea(final FriceGame $this) {
return (FShapeQuad)(new FShapeQuad() { // ... });
}
@NotNull
public static FShapeQuad getBox(FriceGame $this) {
FShapeQuad var10000 = $this.getActiveArea();
if (var10000 == null) {
var10000 = $this.getDefaultActiveArea();
}
return var10000;
}
// ...
然后生成的子類中還是會有這些抽象方法的實現(xiàn), 只是實現(xiàn)都會調(diào)用這個 DefaultImpls 里的方法(也就是說, 它對 Java8 的 default 一無所知
)。
因此,如果有一個 Java 的子類實現(xiàn)這個接口, 那么這些在 Kotlin 里有默認(rèn)實現(xiàn)的方法其實都還是抽象的, 只是你可以直接在里面寫 return DefaultImpls.xxx() 而已。
我遇到這個問題的 case ,是有這樣的代碼的繼承關(guān)系:
interface IJuliaSymbol : PsiElement { fun rua() = 233 }
abstract class JuliaSymbolMixin : JuliaSymbol
interface JuliaSymbol extends IJuliaSymbol { }
class JuliaSymbolImpl extends JuliaSymbolMixin { }
我以為 rua 的實現(xiàn)會在 JuliaSymbolMixin 中被自動插入, 于是 JuliaSymbolImpl 就可以使用了。
結(jié)果我太年輕,編譯器直接拋異常。
錯誤信息:
Error:Kotlin: [Internal Error] java.lang.AssertionError: Could not generate LightClass for org.ice1000.julia.lang.psi.impl declared in
System: Linux 4.13.0-32-generic Java Runtime: 1.8.0_151-8u151-b12-0ubuntu0.16.04.2-b12
元數(shù)據(jù)和實際代碼不符的問題
一開始我遇到這個問題是懵逼的,因為我只是調(diào)用了一個 inline reified 的方法而已,我犯了什么錯呢。
get() = parentOfType() ?: parent
實際上是這樣的, Kotlin 在查找方法之類的東西的定義的時候, 是進(jìn)入類文件的元數(shù)據(jù)進(jìn)行查找的, 因此如果元數(shù)據(jù)和方法本身不匹配的話就可以崩掉編譯器。
而這里就是一個道理,生成的類被混淆了,而元數(shù)據(jù)保持不變, 于是編譯器找到的合法定義變得不存在了,就拋異常。
這也是一開始 Alex 沒有成功復(fù)現(xiàn)這個 bug 的原因,因為在他的電腦里, gradle 是通過下載 IntelliJ Community 的最新版來解決的依賴問題, 而這個就沒有被混淆,所以編譯正常通過。
錯誤信息:
e: org.jetbrains.kotlin.codegen.CompilationException: Back-end (JVM) Internal error: Couldn't inline method call 'parentOfType' into
public open val startPoint: com.intellij.psi.PsiElement defined in org.ice1000.julia.lang.psi.impl.JuliaDeclaration
open val startPoint: PsiElement get() = parentOfType() ?: parent
Cause: Not generated
Cause: Couldn't obtain compiled function body for public inline fun com.intellij.psi.PsiElement.parentOfType(): T? defined in com.intellij.psi.util[DeserializedSimpleFunctionDescriptor@676ab4f3]
File being compiled and position: (29,42) in /home/ice1000/git-repos/julia-intellij/src/org/ice1000/julia/lang/psi/impl/julia-psi-mixin.kt
The root cause was thrown at: InlineCodegen.kt:529
希望這些 bug 都早日得到修復(fù)。
最后再唾棄一次:
第二次用 Emacs 寫這么多中文,感覺好不習(xí)慣【x
總結(jié)
以上是生活随笔為你收集整理的kotlin编译失败_聊两个 Kotlin 编译器的 bug的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Spring3+Quartz实现定时
- 下一篇: B端产品如何寻找竞品?