JVM_IR merge annotations when substituting types
Otherwise special annotations such as @EnhancedNullability are lost, which affects JVM signatures. KT-42330
This commit is contained in:
@@ -82,8 +82,16 @@ fun IrType.substitute(params: List<IrTypeParameter>, arguments: List<IrType>): I
|
||||
fun IrType.substitute(substitutionMap: Map<IrTypeParameterSymbol, IrType>): IrType {
|
||||
if (this !is IrSimpleType) return this
|
||||
|
||||
substitutionMap[classifier]?.let {
|
||||
return it.withHasQuestionMark(hasQuestionMark || it is IrSimpleType && it.hasQuestionMark)
|
||||
val newAnnotations = annotations.map { it.deepCopyWithSymbols() }
|
||||
|
||||
substitutionMap[classifier]?.let { substitutedType ->
|
||||
// Add nullability and annotations from original type
|
||||
return substitutedType
|
||||
.withHasQuestionMark(
|
||||
hasQuestionMark ||
|
||||
substitutedType is IrSimpleType && substitutedType.hasQuestionMark
|
||||
)
|
||||
.addAnnotations(newAnnotations)
|
||||
}
|
||||
|
||||
val newArguments = arguments.map {
|
||||
@@ -94,7 +102,6 @@ fun IrType.substitute(substitutionMap: Map<IrTypeParameterSymbol, IrType>): IrTy
|
||||
}
|
||||
}
|
||||
|
||||
val newAnnotations = annotations.map { it.deepCopyWithSymbols() }
|
||||
return IrSimpleTypeImpl(
|
||||
classifier,
|
||||
hasQuestionMark,
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
@@ -35,6 +36,20 @@ fun IrType.withHasQuestionMark(newHasQuestionMark: Boolean): IrType =
|
||||
else -> this
|
||||
}
|
||||
|
||||
fun IrType.addAnnotations(newAnnotations: List<IrConstructorCall>): IrType =
|
||||
if (newAnnotations.isEmpty())
|
||||
this
|
||||
else when (this) {
|
||||
is IrSimpleType ->
|
||||
toBuilder().apply {
|
||||
annotations = annotations + newAnnotations
|
||||
}.buildSimpleType()
|
||||
is IrDynamicType ->
|
||||
IrDynamicTypeImpl(null, annotations + newAnnotations, Variance.INVARIANT)
|
||||
else ->
|
||||
this
|
||||
}
|
||||
|
||||
val IrType.classifierOrFail: IrClassifierSymbol
|
||||
get() = cast<IrSimpleType>().classifier
|
||||
|
||||
|
||||
Vendored
+7
-7
@@ -156,11 +156,11 @@ public final class DIntMap {
|
||||
private synthetic final field $$delegate_0: java.util.Map
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: java.util.Map): void
|
||||
public method clear(): void
|
||||
public method compute(p0: int, p1: java.util.function.BiFunction): java.lang.Double
|
||||
public method compute(p0: java.lang.Integer, p1: java.util.function.BiFunction): java.lang.Double
|
||||
public synthetic bridge method compute(p0: java.lang.Object, p1: java.util.function.BiFunction): java.lang.Object
|
||||
public method computeIfAbsent(p0: int, p1: java.util.function.Function): java.lang.Double
|
||||
public method computeIfAbsent(p0: java.lang.Integer, p1: java.util.function.Function): java.lang.Double
|
||||
public synthetic bridge method computeIfAbsent(p0: java.lang.Object, p1: java.util.function.Function): java.lang.Object
|
||||
public method computeIfPresent(p0: int, p1: java.util.function.BiFunction): java.lang.Double
|
||||
public method computeIfPresent(p0: java.lang.Integer, p1: java.util.function.BiFunction): java.lang.Double
|
||||
public synthetic bridge method computeIfPresent(p0: java.lang.Object, p1: java.util.function.BiFunction): java.lang.Object
|
||||
public method containsKey(p0: int): boolean
|
||||
public bridge final method containsKey(p0: java.lang.Object): boolean
|
||||
@@ -176,18 +176,18 @@ public final class DIntMap {
|
||||
public @org.jetbrains.annotations.NotNull method getValues(): java.util.Collection
|
||||
public method isEmpty(): boolean
|
||||
public bridge final method keySet(): java.util.Set
|
||||
public method merge(p0: int, p1: double, p2: java.util.function.BiFunction): java.lang.Double
|
||||
public method merge(p0: java.lang.Integer, p1: java.lang.Double, p2: java.util.function.BiFunction): java.lang.Double
|
||||
public synthetic bridge method merge(p0: java.lang.Object, p1: java.lang.Object, p2: java.util.function.BiFunction): java.lang.Object
|
||||
public method put(p0: int, p1: double): java.lang.Double
|
||||
public synthetic bridge method put(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||
public method putAll(p0: java.util.Map): void
|
||||
public method putIfAbsent(p0: int, p1: double): java.lang.Double
|
||||
public method putIfAbsent(p0: java.lang.Integer, p1: java.lang.Double): java.lang.Double
|
||||
public synthetic bridge method putIfAbsent(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||
public method remove(p0: java.lang.Object): java.lang.Double
|
||||
public synthetic bridge method remove(p0: java.lang.Object): java.lang.Object
|
||||
public method remove(p0: java.lang.Object, p1: java.lang.Object): boolean
|
||||
public method replace(p0: int, p1: double): java.lang.Double
|
||||
public method replace(p0: int, p1: double, p2: double): boolean
|
||||
public method replace(p0: java.lang.Integer, p1: java.lang.Double): java.lang.Double
|
||||
public method replace(p0: java.lang.Integer, p1: java.lang.Double, p2: java.lang.Double): boolean
|
||||
public synthetic bridge method replace(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||
public synthetic bridge method replace(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object): boolean
|
||||
public method replaceAll(p0: java.util.function.BiFunction): void
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
// FULL_JDK
|
||||
|
||||
abstract class IntIntMap : Map<Int, Int>
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
@kotlin.Metadata
|
||||
public abstract class IntIntMap {
|
||||
// source: 'mapOfPrimitivesFullJdk.kt'
|
||||
public method <init>(): void
|
||||
public method clear(): void
|
||||
public method compute(p0: java.lang.Integer, p1: java.util.function.BiFunction): java.lang.Integer
|
||||
public synthetic method compute(p0: java.lang.Object, p1: java.util.function.BiFunction): java.lang.Object
|
||||
public method computeIfAbsent(p0: java.lang.Integer, p1: java.util.function.Function): java.lang.Integer
|
||||
public synthetic method computeIfAbsent(p0: java.lang.Object, p1: java.util.function.Function): java.lang.Object
|
||||
public method computeIfPresent(p0: java.lang.Integer, p1: java.util.function.BiFunction): java.lang.Integer
|
||||
public synthetic method computeIfPresent(p0: java.lang.Object, p1: java.util.function.BiFunction): java.lang.Object
|
||||
public abstract method containsKey(p0: int): boolean
|
||||
public bridge final method containsKey(p0: java.lang.Object): boolean
|
||||
public abstract method containsValue(p0: int): boolean
|
||||
public bridge final method containsValue(p0: java.lang.Object): boolean
|
||||
public bridge final method entrySet(): java.util.Set
|
||||
public abstract method get(p0: int): java.lang.Integer
|
||||
public bridge final 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 keySet(): java.util.Set
|
||||
public method merge(p0: java.lang.Integer, p1: java.lang.Integer, p2: java.util.function.BiFunction): java.lang.Integer
|
||||
public synthetic method merge(p0: java.lang.Object, p1: java.lang.Object, p2: java.util.function.BiFunction): java.lang.Object
|
||||
public method put(p0: int, p1: int): java.lang.Integer
|
||||
public synthetic method put(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||
public method putAll(p0: java.util.Map): void
|
||||
public method putIfAbsent(p0: java.lang.Integer, p1: java.lang.Integer): java.lang.Integer
|
||||
public synthetic method putIfAbsent(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||
public method remove(p0: java.lang.Object): java.lang.Object
|
||||
public method remove(p0: java.lang.Object, p1: java.lang.Object): boolean
|
||||
public method replace(p0: java.lang.Integer, p1: java.lang.Integer): java.lang.Integer
|
||||
public method replace(p0: java.lang.Integer, p1: java.lang.Integer, p2: java.lang.Integer): boolean
|
||||
public synthetic method replace(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||
public synthetic method replace(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object): boolean
|
||||
public method replaceAll(p0: java.util.function.BiFunction): void
|
||||
public bridge final method size(): int
|
||||
public bridge final method values(): java.util.Collection
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
@kotlin.Metadata
|
||||
public abstract class IntIntMap {
|
||||
// source: 'mapOfPrimitivesFullJdk.kt'
|
||||
public method <init>(): void
|
||||
public method clear(): void
|
||||
public method compute(p0: java.lang.Integer, p1: java.util.function.BiFunction): java.lang.Integer
|
||||
public synthetic bridge method compute(p0: java.lang.Object, p1: java.util.function.BiFunction): java.lang.Object
|
||||
public method computeIfAbsent(p0: java.lang.Integer, p1: java.util.function.Function): java.lang.Integer
|
||||
public synthetic bridge method computeIfAbsent(p0: java.lang.Object, p1: java.util.function.Function): java.lang.Object
|
||||
public method computeIfPresent(p0: java.lang.Integer, p1: java.util.function.BiFunction): java.lang.Integer
|
||||
public synthetic bridge method computeIfPresent(p0: java.lang.Object, p1: java.util.function.BiFunction): java.lang.Object
|
||||
public abstract method containsKey(p0: int): boolean
|
||||
public bridge final method containsKey(p0: java.lang.Object): boolean
|
||||
public abstract method containsValue(p0: int): boolean
|
||||
public bridge final method containsValue(p0: java.lang.Object): boolean
|
||||
public bridge final method entrySet(): java.util.Set
|
||||
public abstract method get(p0: int): java.lang.Integer
|
||||
public bridge final method get(p0: java.lang.Object): java.lang.Integer
|
||||
public synthetic bridge 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 keySet(): java.util.Set
|
||||
public method merge(p0: java.lang.Integer, p1: java.lang.Integer, p2: java.util.function.BiFunction): java.lang.Integer
|
||||
public synthetic bridge method merge(p0: java.lang.Object, p1: java.lang.Object, p2: java.util.function.BiFunction): java.lang.Object
|
||||
public method put(p0: int, p1: int): java.lang.Integer
|
||||
public synthetic bridge method put(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||
public method putAll(p0: java.util.Map): void
|
||||
public method putIfAbsent(p0: java.lang.Integer, p1: java.lang.Integer): java.lang.Integer
|
||||
public synthetic bridge method putIfAbsent(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||
public method remove(p0: java.lang.Object): java.lang.Integer
|
||||
public synthetic bridge method remove(p0: java.lang.Object): java.lang.Object
|
||||
public method remove(p0: java.lang.Object, p1: java.lang.Object): boolean
|
||||
public method replace(p0: java.lang.Integer, p1: java.lang.Integer): java.lang.Integer
|
||||
public method replace(p0: java.lang.Integer, p1: java.lang.Integer, p2: java.lang.Integer): boolean
|
||||
public synthetic bridge method replace(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||
public synthetic bridge method replace(p0: java.lang.Object, p1: java.lang.Object, p2: java.lang.Object): boolean
|
||||
public method replaceAll(p0: java.util.function.BiFunction): void
|
||||
public bridge final method size(): int
|
||||
public bridge final method values(): java.util.Collection
|
||||
}
|
||||
+5
@@ -284,6 +284,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/extendingAbstractCollection.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mapOfPrimitivesFullJdk.kt")
|
||||
public void testMapOfPrimitivesFullJdk() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/mapOfPrimitivesFullJdk.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noStubsForCollection.kt")
|
||||
public void testNoStubsForCollection() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/noStubsForCollection.kt");
|
||||
|
||||
+5
@@ -284,6 +284,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/extendingAbstractCollection.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mapOfPrimitivesFullJdk.kt")
|
||||
public void testMapOfPrimitivesFullJdk() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/mapOfPrimitivesFullJdk.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noStubsForCollection.kt")
|
||||
public void testNoStubsForCollection() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/noStubsForCollection.kt");
|
||||
|
||||
Reference in New Issue
Block a user