Fix local anonymous class name error in K2MetadataCompiler
Extract the logic of approximating to denotable class supertype from JS/KLIB and use it in metadata compiler. ^KT-20996 In Progress
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.cli.metadata
|
||||
|
||||
import org.jetbrains.kotlin.metadata.builtins.BuiltInsBinaryVersion
|
||||
import org.jetbrains.kotlin.serialization.ApproximatingStringTable
|
||||
import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase
|
||||
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
|
||||
|
||||
@@ -24,4 +25,5 @@ class MetadataSerializerExtension(
|
||||
override val metadataVersion: BuiltInsBinaryVersion
|
||||
) : KotlinSerializerExtensionBase(BuiltInSerializerProtocol) {
|
||||
override fun shouldUseTypeTable(): Boolean = true
|
||||
override val stringTable = ApproximatingStringTable()
|
||||
}
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.serialization
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
|
||||
|
||||
open class ApproximatingStringTable : StringTableImpl() {
|
||||
override fun getLocalClassIdReplacement(descriptor: ClassifierDescriptorWithTypeParameters): ClassId? {
|
||||
return if (descriptor.containingDeclaration is CallableMemberDescriptor) {
|
||||
val superClassifiers = descriptor.getAllSuperClassifiers()
|
||||
.mapNotNull { it as ClassifierDescriptorWithTypeParameters }
|
||||
.filter { it != descriptor }
|
||||
.toList()
|
||||
if (superClassifiers.size == 1) {
|
||||
superClassifiers[0].classId
|
||||
} else {
|
||||
val superClass = superClassifiers.find { !DescriptorUtils.isInterface(it) }
|
||||
superClass?.classId ?: ClassId.topLevel(StandardNames.FqNames.any.toSafe())
|
||||
}
|
||||
} else {
|
||||
super.getLocalClassIdReplacement(descriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-62
@@ -1,62 +1 @@
|
||||
exception: java.lang.IllegalStateException: Cannot get FQ name of local class: class <no name provided> defined in private val pVal: <no name provided> defined in root package in file anonymousObjectType.kt
|
||||
at org.jetbrains.kotlin.serialization.DescriptorAwareStringTable$DefaultImpls.getFqNameIndex(DescriptorAwareStringTable.kt:26)
|
||||
at org.jetbrains.kotlin.serialization.StringTableImpl.getFqNameIndex(StringTableImpl.kt:25)
|
||||
at org.jetbrains.kotlin.serialization.DescriptorSerializer.getClassifierId(DescriptorSerializer.kt:741)
|
||||
at org.jetbrains.kotlin.serialization.DescriptorSerializer.fillFromPossiblyInnerType(DescriptorSerializer.kt:613)
|
||||
at org.jetbrains.kotlin.serialization.DescriptorSerializer.type$serialization(DescriptorSerializer.kt:580)
|
||||
at org.jetbrains.kotlin.serialization.DescriptorSerializer.typeId(DescriptorSerializer.kt:547)
|
||||
at org.jetbrains.kotlin.serialization.DescriptorSerializer.propertyProto(DescriptorSerializer.kt:255)
|
||||
at org.jetbrains.kotlin.serialization.DescriptorSerializer.packagePartProto(DescriptorSerializer.kt:661)
|
||||
at org.jetbrains.kotlin.cli.metadata.MetadataSerializer$PackageSerializer.serializeMembers(MetadataSerializer.kt:157)
|
||||
at org.jetbrains.kotlin.cli.metadata.MetadataSerializer$PackageSerializer.run(MetadataSerializer.kt:136)
|
||||
at org.jetbrains.kotlin.cli.metadata.MetadataSerializer.performSerialization(MetadataSerializer.kt:94)
|
||||
at org.jetbrains.kotlin.cli.metadata.MetadataSerializer.serialize(MetadataSerializer.kt:49)
|
||||
at org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler.doExecute(K2MetadataCompiler.kt:111)
|
||||
at org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler.doExecute(K2MetadataCompiler.kt:40)
|
||||
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:88)
|
||||
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:44)
|
||||
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:98)
|
||||
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:76)
|
||||
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:45)
|
||||
at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMainNoExit(CLITool.kt:227)
|
||||
at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMainNoExit$default(CLITool.kt:222)
|
||||
at org.jetbrains.kotlin.test.CompilerTestUtil.executeCompiler(CompilerTestUtil.kt:41)
|
||||
at org.jetbrains.kotlin.cli.AbstractCliTest.executeCompilerGrabOutput(AbstractCliTest.java:73)
|
||||
at org.jetbrains.kotlin.cli.AbstractCliTest.doTest(AbstractCliTest.java:105)
|
||||
at org.jetbrains.kotlin.cli.AbstractCliTest.doMetadataTest(AbstractCliTest.java:285)
|
||||
at org.jetbrains.kotlin.test.KotlinTestUtils.lambda$testWithCustomIgnoreDirective$5(KotlinTestUtils.java:572)
|
||||
at org.jetbrains.kotlin.test.KotlinTestUtils.runTestImpl(KotlinTestUtils.java:542)
|
||||
at org.jetbrains.kotlin.test.KotlinTestUtils.runTest(KotlinTestUtils.java:485)
|
||||
at org.jetbrains.kotlin.cli.CliTestGenerated$Metadata.runTest(CliTestGenerated.java:1176)
|
||||
at org.jetbrains.kotlin.cli.CliTestGenerated$Metadata.testAnonymousObjectType(CliTestGenerated.java:1185)
|
||||
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
|
||||
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
||||
at java.lang.reflect.Method.invoke(Method.java:498)
|
||||
at junit.framework.TestCase.runTest(TestCase.java:176)
|
||||
at org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase.lambda$runTest$9(KtUsefulTestCase.java:374)
|
||||
at org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase.lambda$invokeTestRunnable$10(KtUsefulTestCase.java:407)
|
||||
at com.intellij.testFramework.EdtTestUtilKt.runInEdtAndWait(EdtTestUtil.kt:63)
|
||||
at org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase.invokeTestRunnable(KtUsefulTestCase.java:406)
|
||||
at org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase.runTest(KtUsefulTestCase.java:393)
|
||||
at org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase.defaultRunBare(KtUsefulTestCase.java:424)
|
||||
at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait$1.invoke(EdtTestUtil.kt:18)
|
||||
at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait$1.invoke(EdtTestUtil.kt:13)
|
||||
at com.intellij.testFramework.EdtTestUtilKt$runInEdtAndWait$3.run(EdtTestUtil.kt:67)
|
||||
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:301)
|
||||
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
|
||||
at java.awt.EventQueue.access$500(EventQueue.java:97)
|
||||
at java.awt.EventQueue$3.run(EventQueue.java:709)
|
||||
at java.awt.EventQueue$3.run(EventQueue.java:703)
|
||||
at java.security.AccessController.doPrivileged(Native Method)
|
||||
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
|
||||
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
|
||||
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:419)
|
||||
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)
|
||||
|
||||
INTERNAL_ERROR
|
||||
OK
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package test
|
||||
|
||||
import lib.*
|
||||
|
||||
val w = W()
|
||||
val v1 = fn()
|
||||
val v2 = O.o()
|
||||
val v3 = w.w()
|
||||
|
||||
// private
|
||||
val e1 = o3
|
||||
val e2 = w.o7
|
||||
val e3 = O.o10
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
package lib
|
||||
|
||||
interface I1 {
|
||||
fun i1() {}
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
fun i2() {}
|
||||
}
|
||||
|
||||
interface I3 : I2, I1
|
||||
|
||||
open class C {
|
||||
fun c() {}
|
||||
}
|
||||
|
||||
open class G<T> {
|
||||
fun g() {}
|
||||
}
|
||||
|
||||
private val o1 = object { fun foo() {} }
|
||||
private val o2 = object : I1 {}
|
||||
private val o3 = object : I1, I2 {}
|
||||
private val o4 = object : I3 {}
|
||||
private val o5 = object : C() {}
|
||||
private val o6 = object : C(), I1, I2 {}
|
||||
private val o7 = object : C(), I3 {}
|
||||
private val o8 = object : G<Int>() {}
|
||||
private val o9 = object : G<Int>(), I1, I2 {}
|
||||
private val o10 = object : G<Int>(), I3 {}
|
||||
|
||||
fun fn() {
|
||||
o1.foo()
|
||||
o2.i1()
|
||||
o3.i1()
|
||||
o3.i2()
|
||||
o4.i1()
|
||||
o4.i2()
|
||||
o5.c()
|
||||
o6.c()
|
||||
o6.i1()
|
||||
o6.i2()
|
||||
o7.c()
|
||||
o7.i1()
|
||||
o7.i2()
|
||||
o8.g()
|
||||
o9.g()
|
||||
o9.i1()
|
||||
o9.i2()
|
||||
o10.g()
|
||||
o10.i1()
|
||||
o10.i2()
|
||||
}
|
||||
|
||||
class W {
|
||||
private val o1 = object { fun foo() {} }
|
||||
private val o2 = object : I1 {}
|
||||
private val o3 = object : I1, I2 {}
|
||||
private val o4 = object : I3 {}
|
||||
private val o5 = object : C() {}
|
||||
private val o6 = object : C(), I1, I2 {}
|
||||
private val o7 = object : C(), I3 {}
|
||||
private val o8 = object : G<Int>() {}
|
||||
private val o9 = object : G<Int>(), I1, I2 {}
|
||||
private val o10 = object : G<Int>(), I3 {}
|
||||
|
||||
fun w() {
|
||||
o1.foo()
|
||||
o2.i1()
|
||||
o3.i1()
|
||||
o3.i2()
|
||||
o4.i1()
|
||||
o4.i2()
|
||||
o5.c()
|
||||
o6.c()
|
||||
o6.i1()
|
||||
o6.i2()
|
||||
o7.c()
|
||||
o7.i1()
|
||||
o7.i2()
|
||||
o8.g()
|
||||
o9.g()
|
||||
o9.i1()
|
||||
o9.i2()
|
||||
o10.g()
|
||||
o10.i1()
|
||||
o10.i2()
|
||||
}
|
||||
}
|
||||
|
||||
object O {
|
||||
private val o1 = object { fun foo() {} }
|
||||
private val o2 = object : I1 {}
|
||||
private val o3 = object : I1, I2 {}
|
||||
private val o4 = object : I3 {}
|
||||
private val o5 = object : C() {}
|
||||
private val o6 = object : C(), I1, I2 {}
|
||||
private val o7 = object : C(), I3 {}
|
||||
private val o8 = object : G<Int>() {}
|
||||
private val o9 = object : G<Int>(), I1, I2 {}
|
||||
private val o10 = object : G<Int>(), I3 {}
|
||||
|
||||
fun o() {
|
||||
o1.foo()
|
||||
o2.i1()
|
||||
o3.i1()
|
||||
o3.i2()
|
||||
o4.i1()
|
||||
o4.i2()
|
||||
o5.c()
|
||||
o6.c()
|
||||
o6.i1()
|
||||
o6.i2()
|
||||
o7.c()
|
||||
o7.i1()
|
||||
o7.i2()
|
||||
o8.g()
|
||||
o9.g()
|
||||
o9.i1()
|
||||
o9.i2()
|
||||
o10.g()
|
||||
o10.i1()
|
||||
o10.i2()
|
||||
}
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/anonymousObjectTypeMetadata/anonymousObjectTypeMetadata.kt:11:10: error: cannot access 'o3': it is private in file
|
||||
val e1 = o3
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/anonymousObjectTypeMetadata/anonymousObjectTypeMetadata.kt:12:12: error: cannot access 'o7': it is private in 'W'
|
||||
val e2 = w.o7
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/anonymousObjectTypeMetadata/anonymousObjectTypeMetadata.kt:13:12: error: cannot access 'o10': it is private in 'O'
|
||||
val e3 = O.o10
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
+12
@@ -725,6 +725,18 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
|
||||
loadClassFile("SourceKt", tmpdir, library)
|
||||
}
|
||||
|
||||
fun testAnonymousObjectTypeMetadata() {
|
||||
val library = compileCommonLibrary(
|
||||
libraryName = "library",
|
||||
)
|
||||
compileKotlin(
|
||||
"anonymousObjectTypeMetadata.kt",
|
||||
tmpdir,
|
||||
listOf(library),
|
||||
K2MetadataCompiler(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun loadClassFile(className: String, dir: File, library: File) {
|
||||
val classLoader = URLClassLoader(arrayOf(dir.toURI().toURL(), library.toURI().toURL()))
|
||||
val mainClass = classLoader.loadClass(className)
|
||||
|
||||
+2
-26
@@ -5,30 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.serialization.metadata
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
|
||||
import org.jetbrains.kotlin.serialization.StringTableImpl
|
||||
import org.jetbrains.kotlin.serialization.ApproximatingStringTable
|
||||
|
||||
class KlibMetadataStringTable : StringTableImpl() {
|
||||
override fun getLocalClassIdReplacement(descriptor: ClassifierDescriptorWithTypeParameters): ClassId? {
|
||||
return if (descriptor.containingDeclaration is CallableMemberDescriptor) {
|
||||
val superClassifiers = descriptor.getAllSuperClassifiers()
|
||||
.mapNotNull { it as ClassifierDescriptorWithTypeParameters }
|
||||
.filter { it != descriptor }
|
||||
.toList()
|
||||
if (superClassifiers.size == 1) {
|
||||
superClassifiers[0].classId
|
||||
} else {
|
||||
val superClass = superClassifiers.find { !DescriptorUtils.isInterface(it) }
|
||||
superClass?.classId ?: ClassId.topLevel(StandardNames.FqNames.any.toSafe())
|
||||
}
|
||||
} else {
|
||||
super.getLocalClassIdReplacement(descriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
typealias KlibMetadataStringTable = ApproximatingStringTable
|
||||
|
||||
+2
-26
@@ -16,30 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.serialization.js
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
|
||||
import org.jetbrains.kotlin.serialization.StringTableImpl
|
||||
import org.jetbrains.kotlin.serialization.ApproximatingStringTable
|
||||
|
||||
class JavaScriptStringTable : StringTableImpl() {
|
||||
override fun getLocalClassIdReplacement(descriptor: ClassifierDescriptorWithTypeParameters): ClassId? {
|
||||
return if (descriptor.containingDeclaration is CallableMemberDescriptor) {
|
||||
val superClassifiers = descriptor.getAllSuperClassifiers()
|
||||
.mapNotNull { it as ClassifierDescriptorWithTypeParameters }
|
||||
.filter { it != descriptor }
|
||||
.toList()
|
||||
if (superClassifiers.size == 1) {
|
||||
superClassifiers[0].classId
|
||||
} else {
|
||||
val superClass = superClassifiers.find { !DescriptorUtils.isInterface(it) }
|
||||
superClass?.classId ?: ClassId.topLevel(StandardNames.FqNames.any.toSafe())
|
||||
}
|
||||
} else {
|
||||
super.getLocalClassIdReplacement(descriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
typealias JavaScriptStringTable = ApproximatingStringTable
|
||||
|
||||
Reference in New Issue
Block a user