From 90b6a12a5ce28b7c2dd6763a8c6c752b5ddf1b9b Mon Sep 17 00:00:00 2001 From: KonstantinAnisimov Date: Wed, 30 Nov 2016 16:19:28 +0300 Subject: [PATCH] Canonical name (#99) * TEST: enabled testRetainAll * Method resolution spared of annotations and generics * TEST: test for canonical names "interface+generic" added * Methods' canonical names support: - Recursive iteration of method argument types - Arguments in question are delivered from topmost overriden ancestor of this method --- .../kotlin/backend/konan/llvm/NameUtils.kt | 25 ++++++++++++-- backend.native/tests/build.gradle | 4 +++ .../tests/codegen/basics/canonical_name.kt | 33 +++++++++++++++++++ .../tests/runtime/collections/array_list1.kt | 9 +++-- 4 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 backend.native/tests/codegen/basics/canonical_name.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/NameUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/NameUtils.kt index 95271c053dc..c16ab585969 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/NameUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/NameUtils.kt @@ -7,16 +7,35 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.constants.StringValue import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.resolve.findOriginalTopMostOverriddenDescriptors +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeUtils + private val symbolNameAnnotation = FqName("kotlin.SymbolName") +fun typeToHashString(type: KotlinType): String { + if (TypeUtils.isTypeParameter(type)) return "GENERIC" + + var hashString = type.constructor.toString() + if (!type.arguments.isEmpty()) { + hashString += "<${type.arguments.map { + typeToHashString(it.type) + }.joinToString(",")}>" + } + + if (type.isMarkedNullable) hashString += "?" + return hashString +} + private val FunctionDescriptor.signature: String get() { - // TODO: KotlinType.toString seems to use unqualified names - val extensionReceiverPart = this.extensionReceiverParameter?.let { "${it.type}." } ?: "" + val actualDescriptor = this.findOriginalTopMostOverriddenDescriptors().firstOrNull() ?: this - val argsPart = this.valueParameters.map { it.type }.joinToString(";") + val argsPart = actualDescriptor.valueParameters.map { + typeToHashString(it.type) + }.joinToString(";") // TODO: add return type // (it is not simple because return type can be changed when overriding) diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index e5ad093797a..e88cbfbea4e 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -268,6 +268,10 @@ task local_variable(type: UnitKonanTest) { source = "codegen/basics/local_variable.kt" } +task canonical_name(type: RunKonanTest) { + goldValue = "A:foo\nA:qux\n" + source = "codegen/basics/canonical_name.kt" +} task cast_simple(type: UnitKonanTest) { source = "codegen/basics/cast_simple.kt" diff --git a/backend.native/tests/codegen/basics/canonical_name.kt b/backend.native/tests/codegen/basics/canonical_name.kt new file mode 100644 index 00000000000..95afe1d11b3 --- /dev/null +++ b/backend.native/tests/codegen/basics/canonical_name.kt @@ -0,0 +1,33 @@ +interface I { + fun foo(a: U): T + fun qux(a: T): U +} + +//-----------------------------------------------------------------------------// + +class A1 +class A2 + +//-----------------------------------------------------------------------------// + +class A : I { + override fun foo(a: A1): A2 { println("A:foo"); return A2() } + override fun qux(a: A2): A1 { println("A:qux"); return A1() } +} + +//-----------------------------------------------------------------------------// + +fun baz(i: I, u: U, v:V) { + i.foo(u) + i.qux(v) +} + +//-----------------------------------------------------------------------------// + +fun main(args: Array) { + baz(A(), A1(), A2()) +} + + + + diff --git a/backend.native/tests/runtime/collections/array_list1.kt b/backend.native/tests/runtime/collections/array_list1.kt index ffc53ddb329..b05582121a3 100644 --- a/backend.native/tests/runtime/collections/array_list1.kt +++ b/backend.native/tests/runtime/collections/array_list1.kt @@ -266,6 +266,7 @@ fun testIteratorRemove() { } it.next() } + assertEquals(makeList135(), a) } @@ -288,8 +289,7 @@ fun main(args : Array) { testIterator() testRemove() testRemoveAll() - // Fails due to unknown virtual method call! - // testRetainAll() + testRetainAll() testEquals() testHashCode() testToString() @@ -299,8 +299,7 @@ fun main(args : Array) { testSubListContains() testSubListIndexOf() testSubListLastIndexOf() - // Fails due to unknown virtual method call! - // testIteratorAdd() - // testIteratorRemove() +// testIteratorAdd() runtime assert: Throwing is unsupported +// testIteratorRemove() assertEquals fails println("OK") } \ No newline at end of file