diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index 9d7f73a24c3..f529b4833b3 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -107,6 +107,7 @@ class JvmBackendContext( internal val collectionStubComputer = CollectionStubComputer(this) internal val bridgeLoweringCache = BridgeLowering.BridgeLoweringCache(this) + internal val functionsWithSpecialBridges: MutableSet = HashSet() override var inVerbosePhase: Boolean = false diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt index a9c36b9988b..d8dce86526d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt @@ -260,7 +260,9 @@ class MethodSignatureMapper(private val context: JvmBackendContext) { val specialSignatureInfo = with(BuiltinMethodsWithSpecialGenericSignature) { function.toIrBasedDescriptor().getSpecialSignatureInfo() } - if (specialSignatureInfo != null) { + // Old back-end doesn't patch generic signatures if corresponding function had special bridges. + // See org.jetbrains.kotlin.codegen.FunctionCodegen#hasSpecialBridgeMethod and its usage. + if (specialSignatureInfo != null && function !in context.functionsWithSpecialBridges) { val newGenericSignature = specialSignatureInfo.replaceValueParametersIn(signature.genericsSignature) return JvmMethodGenericSignature(signature.asmMethod, signature.valueParameters, newGenericSignature) } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt index d2d4b2d28df..5f458a4a012 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt @@ -424,6 +424,8 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass name = Name.identifier(specialBridge.signature.name) returnType = specialBridge.substitutedReturnType ?: specialBridge.overridden.returnType.eraseTypeParameters() }.apply { + context.functionsWithSpecialBridges.add(target) + copyParametersWithErasure(this@addSpecialBridge, specialBridge.overridden, specialBridge.substitutedParameterTypes) body = context.createIrBuilder(symbol, startOffset, endOffset).irBlockBody { diff --git a/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsJavaMap.kt b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsJavaMap.kt new file mode 100644 index 00000000000..5f9b0e778d1 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsJavaMap.kt @@ -0,0 +1,21 @@ +// WITH_SIGNATURES +// FILE: implementsJavaMap.kt +import java.util.* + +abstract class JMapImpl : JMap { + override fun containsKey(key: A): Boolean = false +} + +abstract class JMapNImpl : JMapN { + override fun containsKey(key: A): Boolean = false +} + +// FILE: JMap.java +import java.util.*; + +public interface JMap extends Map {} + +// FILE: JMapN.java +import java.util.*; + +public interface JMapN extends Map {} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsJavaMap.txt b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsJavaMap.txt new file mode 100644 index 00000000000..47e07eaf004 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsJavaMap.txt @@ -0,0 +1,38 @@ +@kotlin.Metadata +public abstract class<Ljava/lang/Object;LJMap;> JMapImpl { + // source: 'implementsJavaMap.kt' + public bridge final <()Ljava/util/Collection;> method values(): java.util.Collection + public bridge final <()Ljava/util/Set;>;> method entrySet(): java.util.Set + public bridge final <()Ljava/util/Set;> method keySet(): java.util.Set + public method (): void + public method containsKey(p0: java.lang.Object): boolean + public abstract method containsValue(p0: java.lang.Object): boolean + public abstract method get(p0: java.lang.Object): java.lang.Object + public abstract method getEntries(): java.util.Set + public abstract method getKeys(): java.util.Set + public abstract method getSize(): int + public abstract method getValues(): java.util.Collection + public abstract method remove(p0: java.lang.Object): java.lang.Object + public bridge final method size(): int +} + +@kotlin.Metadata +public abstract class<Ljava/lang/Object;LJMapN;> JMapNImpl { + // source: 'implementsJavaMap.kt' + public bridge final <()Ljava/util/Collection;> method values(): java.util.Collection + public bridge final <()Ljava/util/Set;>;> method entrySet(): java.util.Set + public bridge final <()Ljava/util/Set;> method keySet(): java.util.Set + public bridge final <(Ljava/lang/Object;)TB;> method get(p0: java.lang.Object): java.lang.Object + public bridge final <(Ljava/lang/Object;)TB;> method remove(p0: java.lang.Object): java.lang.Object + public <(TA;)Z> method containsKey(@org.jetbrains.annotations.NotNull p0: java.lang.Number): boolean + public method (): void + public bridge final method containsKey(p0: java.lang.Object): boolean + public abstract method containsValue(p0: java.lang.Object): boolean + public abstract method get(p0: java.lang.Number): java.lang.Object + public abstract method getEntries(): java.util.Set + public abstract method getKeys(): java.util.Set + public abstract method getSize(): int + public abstract method getValues(): java.util.Collection + public abstract method remove(p0: java.lang.Number): java.lang.Object + public bridge final method size(): int +} diff --git a/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsJavaMap_ir.txt b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsJavaMap_ir.txt new file mode 100644 index 00000000000..14519ef19c8 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsJavaMap_ir.txt @@ -0,0 +1,34 @@ +@kotlin.Metadata +public abstract class<Ljava/lang/Object;LJMap;> JMapImpl { + // source: 'implementsJavaMap.kt' + public abstract <()Ljava/util/Collection;> method getValues(): java.util.Collection + public bridge final <()Ljava/util/Collection;> method values(): java.util.Collection + public bridge final <()Ljava/util/Set;>;> method entrySet(): java.util.Set + public abstract <()Ljava/util/Set;>;> method getEntries(): java.util.Set + public abstract <()Ljava/util/Set;> method getKeys(): java.util.Set + public bridge final <()Ljava/util/Set;> method keySet(): java.util.Set + public method (): void + public method containsKey(p0: java.lang.Object): boolean + public abstract method getSize(): int + public bridge final method size(): int +} + +@kotlin.Metadata +public abstract class<Ljava/lang/Object;LJMapN;> JMapNImpl { + // source: 'implementsJavaMap.kt' + public abstract <()Ljava/util/Collection;> method getValues(): java.util.Collection + public bridge final <()Ljava/util/Collection;> method values(): java.util.Collection + public bridge final <()Ljava/util/Set;>;> method entrySet(): java.util.Set + public abstract <()Ljava/util/Set;>;> method getEntries(): java.util.Set + public abstract <()Ljava/util/Set;> method getKeys(): java.util.Set + public bridge final <()Ljava/util/Set;> method keySet(): java.util.Set + public bridge final <(Ljava/lang/Object;)TB;> method get(p0: java.lang.Object): java.lang.Object + public bridge final <(Ljava/lang/Object;)TB;> method remove(p0: java.lang.Object): java.lang.Object + public abstract <(TA;)TB;> method get(p0: java.lang.Number): java.lang.Object + public abstract <(TA;)TB;> method remove(p0: java.lang.Number): java.lang.Object + public <(TA;)Z> method containsKey(@org.jetbrains.annotations.NotNull p0: java.lang.Number): boolean + public method (): void + public bridge final method containsKey(p0: java.lang.Object): boolean + public abstract method getSize(): int + public bridge final method size(): int +} diff --git a/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsMap.kt b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsMap.kt new file mode 100644 index 00000000000..42f1cc16ef7 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsMap.kt @@ -0,0 +1,15 @@ +// WITH_SIGNATURES + +interface MapN : Map + +abstract class MapImpl : Map { + override fun containsKey(key: A): Boolean = false +} + +abstract class MapSImpl : Map { + override fun containsKey(key: String): Boolean = false +} + +abstract class MapNImpl : MapN { + override fun containsKey(key: A): Boolean = false +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsMap.txt b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsMap.txt new file mode 100644 index 00000000000..c33fa923b05 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsMap.txt @@ -0,0 +1,73 @@ +@kotlin.Metadata +public abstract class<Ljava/lang/Object;Ljava/util/Map;Lkotlin/jvm/internal/markers/KMappedMarker;> MapImpl { + // source: 'implementsMap.kt' + public bridge final <()Ljava/util/Collection;> method values(): java.util.Collection + public bridge final <()Ljava/util/Set;>;> method entrySet(): java.util.Set + public bridge final <()Ljava/util/Set;> method keySet(): java.util.Set + public <(Ljava/lang/Object;)TB;> method remove(p0: java.lang.Object): java.lang.Object + public <(Ljava/util/Map<+TA;+TB;>;)V> method putAll(p0: java.util.Map): void + public <(TA;TB;)TB;> method put(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object + public method (): void + public method clear(): void + public method containsKey(p0: java.lang.Object): boolean + public abstract method containsValue(p0: java.lang.Object): boolean + public abstract method get(p0: java.lang.Object): java.lang.Object + public abstract method getEntries(): java.util.Set + public abstract method getKeys(): java.util.Set + public abstract method getSize(): int + public abstract method getValues(): java.util.Collection + public bridge final method size(): int +} + +@kotlin.Metadata +public interface<Ljava/lang/Object;Ljava/util/Map;Lkotlin/jvm/internal/markers/KMappedMarker;> MapN { + // source: 'implementsMap.kt' +} + +@kotlin.Metadata +public abstract class<Ljava/lang/Object;LMapN;> MapNImpl { + // source: 'implementsMap.kt' + public bridge final <()Ljava/util/Collection;> method values(): java.util.Collection + public bridge final <()Ljava/util/Set;>;> method entrySet(): java.util.Set + public bridge final <()Ljava/util/Set;> method keySet(): java.util.Set + public bridge final <(Ljava/lang/Object;)TB;> method get(p0: java.lang.Object): java.lang.Object + public <(Ljava/lang/Object;)TB;> method remove(p0: java.lang.Object): java.lang.Object + public <(Ljava/util/Map<+TA;+TB;>;)V> method putAll(p0: java.util.Map): void + public <(TA;)Z> method containsKey(@org.jetbrains.annotations.NotNull p0: java.lang.Number): boolean + public <(TA;TB;)TB;> method put(p0: java.lang.Number, p1: java.lang.Object): java.lang.Object + public method (): void + public method clear(): void + public bridge final method containsKey(p0: java.lang.Object): boolean + public abstract method containsValue(p0: java.lang.Object): boolean + public abstract method get(p0: java.lang.Number): java.lang.Object + public abstract method getEntries(): java.util.Set + public abstract method getKeys(): java.util.Set + public abstract method getSize(): int + public abstract method getValues(): java.util.Collection + public synthetic method put(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object + public bridge final method size(): int +} + +@kotlin.Metadata +public abstract class<Ljava/lang/Object;Ljava/util/Map;Lkotlin/jvm/internal/markers/KMappedMarker;> MapSImpl { + // source: 'implementsMap.kt' + public bridge final <()Ljava/util/Collection;> method values(): java.util.Collection + public bridge final <()Ljava/util/Set;> method keySet(): java.util.Set + public bridge final <()Ljava/util/Set;>;> method entrySet(): java.util.Set + public bridge final <(Ljava/lang/Object;)TB;> method get(p0: java.lang.Object): java.lang.Object + public <(Ljava/lang/Object;)TB;> method remove(p0: java.lang.Object): java.lang.Object + public <(Ljava/lang/String;TB;)TB;> method put(p0: java.lang.String, p1: java.lang.Object): java.lang.Object + public <(Ljava/util/Map<+Ljava/lang/String;+TB;>;)V> method putAll(p0: java.util.Map): void + public method (): void + public method clear(): void + public method containsKey(@org.jetbrains.annotations.NotNull p0: java.lang.String): boolean + public bridge final method containsKey(p0: java.lang.Object): boolean + public abstract method containsValue(p0: java.lang.Object): boolean + public abstract method get(p0: java.lang.String): java.lang.Object + public abstract method getEntries(): java.util.Set + public abstract method getKeys(): java.util.Set + public abstract method getSize(): int + public abstract method getValues(): java.util.Collection + public synthetic method put(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object + public bridge final method size(): int +} diff --git a/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsMap_ir.txt b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsMap_ir.txt new file mode 100644 index 00000000000..38cc2a22ad8 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsMap_ir.txt @@ -0,0 +1,69 @@ +@kotlin.Metadata +public abstract class<Ljava/lang/Object;Ljava/util/Map;Lkotlin/jvm/internal/markers/KMappedMarker;> MapImpl { + // source: 'implementsMap.kt' + public abstract <()Ljava/util/Collection;> method getValues(): java.util.Collection + public bridge final <()Ljava/util/Collection;> method values(): java.util.Collection + public bridge final <()Ljava/util/Set;>;> method entrySet(): java.util.Set + public abstract <()Ljava/util/Set;>;> method getEntries(): java.util.Set + public abstract <()Ljava/util/Set;> method getKeys(): java.util.Set + public bridge final <()Ljava/util/Set;> method keySet(): java.util.Set + public <(Ljava/lang/Object;)TB;> method remove(p0: java.lang.Object): java.lang.Object + public <(Ljava/util/Map<+TA;+TB;>;)V> method putAll(p0: java.util.Map): void + public <(TA;TB;)TB;> method put(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object + public method (): void + public method clear(): void + public method containsKey(p0: java.lang.Object): boolean + public abstract method getSize(): int + public bridge final method size(): int +} + +@kotlin.Metadata +public interface<Ljava/lang/Object;Ljava/util/Map;Lkotlin/jvm/internal/markers/KMappedMarker;> MapN { + // source: 'implementsMap.kt' +} + +@kotlin.Metadata +public abstract class<Ljava/lang/Object;LMapN;> MapNImpl { + // source: 'implementsMap.kt' + public abstract <()Ljava/util/Collection;> method getValues(): java.util.Collection + public bridge final <()Ljava/util/Collection;> method values(): java.util.Collection + public bridge final <()Ljava/util/Set;>;> method entrySet(): java.util.Set + public abstract <()Ljava/util/Set;>;> method getEntries(): java.util.Set + public abstract <()Ljava/util/Set;> method getKeys(): java.util.Set + public bridge final <()Ljava/util/Set;> method keySet(): java.util.Set + public bridge final <(Ljava/lang/Object;)TB;> method get(p0: java.lang.Object): java.lang.Object + public <(Ljava/lang/Object;)TB;> method remove(p0: java.lang.Object): java.lang.Object + public <(Ljava/util/Map<+TA;+TB;>;)V> method putAll(p0: java.util.Map): void + public abstract <(TA;)TB;> method get(p0: java.lang.Number): java.lang.Object + public <(TA;)Z> method containsKey(@org.jetbrains.annotations.NotNull p0: java.lang.Number): boolean + public <(TA;TB;)TB;> method put(p0: java.lang.Number, p1: java.lang.Object): java.lang.Object + public method (): void + public method clear(): void + public bridge final method containsKey(p0: java.lang.Object): boolean + public abstract method getSize(): int + public synthetic bridge method put(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object + public bridge final method size(): int +} + +@kotlin.Metadata +public abstract class<Ljava/lang/Object;Ljava/util/Map;Lkotlin/jvm/internal/markers/KMappedMarker;> MapSImpl { + // source: 'implementsMap.kt' + public abstract <()Ljava/util/Collection;> method getValues(): java.util.Collection + public bridge final <()Ljava/util/Collection;> method values(): java.util.Collection + public abstract <()Ljava/util/Set;> method getKeys(): java.util.Set + public bridge final <()Ljava/util/Set;> method keySet(): java.util.Set + public bridge final <()Ljava/util/Set;>;> method entrySet(): java.util.Set + public abstract <()Ljava/util/Set;>;> method getEntries(): java.util.Set + public bridge final <(Ljava/lang/Object;)TB;> method get(p0: java.lang.Object): java.lang.Object + public <(Ljava/lang/Object;)TB;> method remove(p0: java.lang.Object): java.lang.Object + public abstract <(Ljava/lang/String;)TB;> method get(p0: java.lang.String): java.lang.Object + public <(Ljava/lang/String;TB;)TB;> method put(p0: java.lang.String, p1: java.lang.Object): java.lang.Object + public <(Ljava/util/Map<+Ljava/lang/String;+TB;>;)V> method putAll(p0: java.util.Map): void + public method (): void + public method clear(): void + public method containsKey(@org.jetbrains.annotations.NotNull p0: java.lang.String): boolean + public bridge final method containsKey(p0: java.lang.Object): boolean + public abstract method getSize(): int + public synthetic bridge method put(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object + public bridge final method size(): int +} diff --git a/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsSortedMap.kt b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsSortedMap.kt new file mode 100644 index 00000000000..1e3dc42c19d --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsSortedMap.kt @@ -0,0 +1,25 @@ +// WITH_RUNTIME +// WITH_SIGNATURES + +import java.util.* + +class SortedMapImpl, B>(private val map: SortedMap) : SortedMap { + override fun containsKey(key: A): Boolean = map.containsKey(key) + override fun containsValue(value: B): Boolean = map.containsValue(value) + override fun get(key: A): B? = map.get(key) + override fun isEmpty(): Boolean = map.isEmpty() + override fun clear() = map.clear() + override fun put(key: A, value: B): B? = map.put(key, value) + override fun putAll(from: Map) = map.putAll(from) + override fun remove(key: A): B? = map.remove(key) + override fun comparator(): Comparator = map.comparator() + override fun subMap(fromKey: A, toKey: A): SortedMap = map.subMap(fromKey, toKey) + override fun headMap(toKey: A): SortedMap = map.headMap(toKey) + override fun tailMap(fromKey: A): SortedMap = map.tailMap(fromKey) + override fun firstKey(): A = map.firstKey() + override fun lastKey(): A = map.lastKey() + override val entries: MutableSet> get() = map.entries + override val keys: MutableSet get() = map.keys + override val values: MutableCollection get() = map.values + override val size: Int get() = map.size +} diff --git a/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsSortedMap.txt b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsSortedMap.txt new file mode 100644 index 00000000000..d340ebc7bf2 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsSortedMap.txt @@ -0,0 +1,37 @@ +@kotlin.Metadata +public final class<;B:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/SortedMap;> SortedMapImpl { + // source: 'implementsSortedMap.kt' + public @org.jetbrains.annotations.NotNull <()Ljava/util/Collection;> method getValues(): java.util.Collection + public bridge final <()Ljava/util/Collection;> method values(): java.util.Collection + public @org.jetbrains.annotations.NotNull <()Ljava/util/Comparator<-TA;>;> method comparator(): java.util.Comparator + public bridge final <()Ljava/util/Set;>;> method entrySet(): java.util.Set + public @org.jetbrains.annotations.NotNull <()Ljava/util/Set;>;> method getEntries(): java.util.Set + public @org.jetbrains.annotations.NotNull <()Ljava/util/Set;> method getKeys(): java.util.Set + public bridge final <()Ljava/util/Set;> method keySet(): java.util.Set + public @org.jetbrains.annotations.NotNull <()TA;> method firstKey(): java.lang.Comparable + public @org.jetbrains.annotations.NotNull <()TA;> method lastKey(): java.lang.Comparable + public bridge final <(Ljava/lang/Object;)TB;> method get(p0: java.lang.Object): java.lang.Object + public bridge final <(Ljava/lang/Object;)TB;> method remove(p0: java.lang.Object): java.lang.Object + public <(Ljava/util/Map<+TA;+TB;>;)V> method putAll(@org.jetbrains.annotations.NotNull p0: java.util.Map): void + public <(Ljava/util/SortedMap;)V> method (@org.jetbrains.annotations.NotNull p0: java.util.SortedMap): void + public @org.jetbrains.annotations.NotNull <(TA;)Ljava/util/SortedMap;> method headMap(@org.jetbrains.annotations.NotNull p0: java.lang.Comparable): java.util.SortedMap + public @org.jetbrains.annotations.NotNull <(TA;)Ljava/util/SortedMap;> method tailMap(@org.jetbrains.annotations.NotNull p0: java.lang.Comparable): java.util.SortedMap + public @org.jetbrains.annotations.Nullable <(TA;)TB;> method get(@org.jetbrains.annotations.NotNull p0: java.lang.Comparable): java.lang.Object + public @org.jetbrains.annotations.Nullable <(TA;)TB;> method remove(@org.jetbrains.annotations.NotNull p0: java.lang.Comparable): java.lang.Object + public <(TA;)Z> method containsKey(@org.jetbrains.annotations.NotNull p0: java.lang.Comparable): boolean + public @org.jetbrains.annotations.NotNull <(TA;TA;)Ljava/util/SortedMap;> method subMap(@org.jetbrains.annotations.NotNull p0: java.lang.Comparable, @org.jetbrains.annotations.NotNull p1: java.lang.Comparable): java.util.SortedMap + public @org.jetbrains.annotations.Nullable <(TA;TB;)TB;> method put(@org.jetbrains.annotations.NotNull p0: java.lang.Comparable, p1: java.lang.Object): java.lang.Object + public method clear(): void + public bridge final method containsKey(p0: java.lang.Object): boolean + public method containsValue(p0: java.lang.Object): boolean + public synthetic bridge method firstKey(): java.lang.Object + public method getSize(): int + public synthetic bridge method headMap(p0: java.lang.Object): java.util.SortedMap + public method isEmpty(): boolean + public synthetic bridge method lastKey(): java.lang.Object + public synthetic bridge method put(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object + public bridge final method size(): int + public synthetic bridge method subMap(p0: java.lang.Object, p1: java.lang.Object): java.util.SortedMap + public synthetic bridge method tailMap(p0: java.lang.Object): java.util.SortedMap + private final field ;> map: java.util.SortedMap +} diff --git a/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsSortedMap_ir.txt b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsSortedMap_ir.txt new file mode 100644 index 00000000000..1c3a98fd1d2 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsSortedMap_ir.txt @@ -0,0 +1,37 @@ +@kotlin.Metadata +public final class<;B:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/SortedMap;> SortedMapImpl { + // source: 'implementsSortedMap.kt' + public @org.jetbrains.annotations.NotNull <()Ljava/util/Collection;> method getValues(): java.util.Collection + public bridge final <()Ljava/util/Collection;> method values(): java.util.Collection + public @org.jetbrains.annotations.NotNull <()Ljava/util/Comparator<-TA;>;> method comparator(): java.util.Comparator + public bridge final <()Ljava/util/Set;>;> method entrySet(): java.util.Set + public @org.jetbrains.annotations.NotNull <()Ljava/util/Set;>;> method getEntries(): java.util.Set + public @org.jetbrains.annotations.NotNull <()Ljava/util/Set;> method getKeys(): java.util.Set + public bridge final <()Ljava/util/Set;> method keySet(): java.util.Set + public @org.jetbrains.annotations.NotNull <()TA;> method firstKey(): java.lang.Comparable + public @org.jetbrains.annotations.NotNull <()TA;> method lastKey(): java.lang.Comparable + public bridge final <(Ljava/lang/Object;)TB;> method get(p0: java.lang.Object): java.lang.Object + public bridge final <(Ljava/lang/Object;)TB;> method remove(p0: java.lang.Object): java.lang.Object + public <(Ljava/util/Map<+TA;+TB;>;)V> method putAll(@org.jetbrains.annotations.NotNull p0: java.util.Map): void + public <(Ljava/util/SortedMap;)V> method (@org.jetbrains.annotations.NotNull p0: java.util.SortedMap): void + public @org.jetbrains.annotations.NotNull <(TA;)Ljava/util/SortedMap;> method headMap(@org.jetbrains.annotations.NotNull p0: java.lang.Comparable): java.util.SortedMap + public @org.jetbrains.annotations.NotNull <(TA;)Ljava/util/SortedMap;> method tailMap(@org.jetbrains.annotations.NotNull p0: java.lang.Comparable): java.util.SortedMap + public @org.jetbrains.annotations.Nullable <(TA;)TB;> method get(@org.jetbrains.annotations.NotNull p0: java.lang.Comparable): java.lang.Object + public @org.jetbrains.annotations.Nullable <(TA;)TB;> method remove(@org.jetbrains.annotations.NotNull p0: java.lang.Comparable): java.lang.Object + public <(TA;)Z> method containsKey(@org.jetbrains.annotations.NotNull p0: java.lang.Comparable): boolean + public @org.jetbrains.annotations.NotNull <(TA;TA;)Ljava/util/SortedMap;> method subMap(@org.jetbrains.annotations.NotNull p0: java.lang.Comparable, @org.jetbrains.annotations.NotNull p1: java.lang.Comparable): java.util.SortedMap + public @org.jetbrains.annotations.Nullable <(TA;TB;)TB;> method put(@org.jetbrains.annotations.NotNull p0: java.lang.Comparable, p1: java.lang.Object): java.lang.Object + public method clear(): void + public bridge final method containsKey(p0: java.lang.Object): boolean + public method containsValue(p0: java.lang.Object): boolean + public synthetic bridge method firstKey(): java.lang.Object + public method getSize(): int + public synthetic bridge method headMap(p0: java.lang.Object): java.util.SortedMap + public method isEmpty(): boolean + public synthetic bridge method lastKey(): java.lang.Object + public synthetic bridge method put(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object + public bridge final method size(): int + public synthetic bridge method subMap(p0: java.lang.Object, p1: java.lang.Object): java.util.SortedMap + public synthetic bridge method tailMap(p0: java.lang.Object): java.util.SortedMap + private final @org.jetbrains.annotations.NotNull field ;> map: java.util.SortedMap +} diff --git a/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/partiallySpecializedClass_ir.txt b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/partiallySpecializedClass_ir.txt index 26f62199369..3ba4d9e5aec 100644 --- a/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/partiallySpecializedClass_ir.txt +++ b/compiler/testData/codegen/bytecodeListing/specialBridges/signatures/partiallySpecializedClass_ir.txt @@ -7,10 +7,10 @@ public abstract class<Ljava/lang/Object;Ljava/util/Map;> method keySet(): java.util.Set public bridge final <()Ljava/util/Set;>;> method entrySet(): java.util.Set public @org.jetbrains.annotations.NotNull <()Ljava/util/Set;>;> method getEntries(): java.util.Set - public @org.jetbrains.annotations.Nullable <(Ljava/lang/Object;)TV;> method get(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.Object public bridge final <(Ljava/lang/Object;)TV;> method get(p0: java.lang.Object): java.lang.Object - public @org.jetbrains.annotations.Nullable <(Ljava/lang/Object;)TV;> method remove(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.Object public bridge final <(Ljava/lang/Object;)TV;> method remove(p0: java.lang.Object): java.lang.Object + public @org.jetbrains.annotations.Nullable <(Ljava/lang/String;)TV;> method get(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.Object + public @org.jetbrains.annotations.Nullable <(Ljava/lang/String;)TV;> method remove(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.Object public @org.jetbrains.annotations.Nullable <(Ljava/lang/String;TV;)TV;> method put(@org.jetbrains.annotations.NotNull p0: java.lang.String, p1: java.lang.Object): java.lang.Object public <(Ljava/util/Map<+Ljava/lang/String;+TV;>;)V> method putAll(@org.jetbrains.annotations.NotNull p0: java.util.Map): void public method (): void @@ -34,10 +34,10 @@ public final class<Ljava/lang/Object;Ljava/util/Map;> method keySet(): java.util.Set public bridge final <()Ljava/util/Set;>;> method entrySet(): java.util.Set public @org.jetbrains.annotations.NotNull <()Ljava/util/Set;>;> method getEntries(): java.util.Set - public @org.jetbrains.annotations.Nullable <(Ljava/lang/Object;)TV;> method get(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.Object public bridge final <(Ljava/lang/Object;)TV;> method get(p0: java.lang.Object): java.lang.Object - public @org.jetbrains.annotations.Nullable <(Ljava/lang/Object;)TV;> method remove(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.Object public bridge final <(Ljava/lang/Object;)TV;> method remove(p0: java.lang.Object): java.lang.Object + public @org.jetbrains.annotations.Nullable <(Ljava/lang/String;)TV;> method get(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.Object + public @org.jetbrains.annotations.Nullable <(Ljava/lang/String;)TV;> method remove(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.Object public @org.jetbrains.annotations.Nullable <(Ljava/lang/String;TV;)TV;> method put(@org.jetbrains.annotations.NotNull p0: java.lang.String, p1: java.lang.Object): java.lang.Object public <(Ljava/util/Map<+Ljava/lang/String;+TV;>;)V> method putAll(@org.jetbrains.annotations.NotNull p0: java.util.Map): void public method (): void diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index 54970740027..262cfaf0df3 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -1196,6 +1196,21 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { runTest("compiler/testData/codegen/bytecodeListing/specialBridges/signatures/genericClass.kt"); } + @TestMetadata("implementsJavaMap.kt") + public void testImplementsJavaMap() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsJavaMap.kt"); + } + + @TestMetadata("implementsMap.kt") + public void testImplementsMap() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsMap.kt"); + } + + @TestMetadata("implementsSortedMap.kt") + public void testImplementsSortedMap() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsSortedMap.kt"); + } + @TestMetadata("nonGenericClass.kt") public void testNonGenericClass() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/specialBridges/signatures/nonGenericClass.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java index 4943d6c258f..085531b051e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java @@ -1166,6 +1166,21 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes runTest("compiler/testData/codegen/bytecodeListing/specialBridges/signatures/genericClass.kt"); } + @TestMetadata("implementsJavaMap.kt") + public void testImplementsJavaMap() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsJavaMap.kt"); + } + + @TestMetadata("implementsMap.kt") + public void testImplementsMap() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsMap.kt"); + } + + @TestMetadata("implementsSortedMap.kt") + public void testImplementsSortedMap() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/specialBridges/signatures/implementsSortedMap.kt"); + } + @TestMetadata("nonGenericClass.kt") public void testNonGenericClass() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/specialBridges/signatures/nonGenericClass.kt"); diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/specialBuiltinMembers.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/specialBuiltinMembers.kt index 911c8905d6e..3a5fe973253 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/specialBuiltinMembers.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/specialBuiltinMembers.kt @@ -126,7 +126,7 @@ object BuiltinMethodsWithSpecialGenericSignature { } val Name.sameAsBuiltinMethodWithErasedValueParameters: Boolean - get () = this in ERASED_VALUE_PARAMETERS_SHORT_NAMES + get() = this in ERASED_VALUE_PARAMETERS_SHORT_NAMES enum class SpecialSignatureInfo(val valueParametersSignature: String?, val isObjectReplacedWithTypeParameter: Boolean) { ONE_COLLECTION_PARAMETER("Ljava/util/Collection<+Ljava/lang/Object;>;", false), @@ -150,10 +150,10 @@ object BuiltinMethodsWithSpecialGenericSignature { val defaultValue = SIGNATURE_TO_DEFAULT_VALUES_MAP.getValue(builtinSignature) - return if (defaultValue == TypeSafeBarrierDescription.NULL) + return if (defaultValue == TypeSafeBarrierDescription.NULL) { // return type is some generic type as 'Map.get' SpecialSignatureInfo.OBJECT_PARAMETER_GENERIC - else + } else SpecialSignatureInfo.OBJECT_PARAMETER_NON_GENERIC } }