From 2819c69bc1d49c0b8489a53d2ad84ca2dea00b73 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 21 Apr 2016 11:48:32 +0300 Subject: [PATCH] Introduce BLACK_LIST_CONSTRUCTOR_SIGNATURES To prevent loading senseless constructors to built-in classes from JDK --- .../testData/builtin-classes/java6/kotlin.txt | 19 -------------- .../testData/builtin-classes/java8/kotlin.txt | 19 -------------- .../BuiltInClassesAreSerializableOnJvm.kt | 26 ++++++++++++++++--- 3 files changed, 23 insertions(+), 41 deletions(-) diff --git a/compiler/testData/builtin-classes/java6/kotlin.txt b/compiler/testData/builtin-classes/java6/kotlin.txt index afc2e125dd8..957a9d5fe3b 100644 --- a/compiler/testData/builtin-classes/java6/kotlin.txt +++ b/compiler/testData/builtin-classes/java6/kotlin.txt @@ -33,7 +33,6 @@ public final class Array : kotlin.Cloneable, java.io.Serializable { public final class Boolean : kotlin.Comparable, java.io.Serializable { /*primary*/ private constructor Boolean() - public constructor Boolean(/*0*/ p0: kotlin.String!) public final infix fun and(/*0*/ other: kotlin.Boolean): kotlin.Boolean public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Boolean): kotlin.Int public final operator fun not(): kotlin.Boolean @@ -54,7 +53,6 @@ public final class BooleanArray : kotlin.Cloneable, java.io.Serializable { public final class Byte : kotlin.Number, kotlin.Comparable, java.io.Serializable { /*primary*/ private constructor Byte() - public constructor Byte(/*0*/ p0: kotlin.String!) public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int @@ -221,7 +219,6 @@ public final enum class DeprecationLevel : kotlin.Enum public final class Double : kotlin.Number, kotlin.Comparable, java.io.Serializable { /*primary*/ private constructor Double() - public constructor Double(/*0*/ p0: kotlin.String!) public final operator fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int @@ -318,8 +315,6 @@ public abstract class Enum> : kotlin.Comparable, jav public final class Float : kotlin.Number, kotlin.Comparable, java.io.Serializable { /*primary*/ private constructor Float() - public constructor Float(/*0*/ p0: kotlin.Double) - public constructor Float(/*0*/ p0: kotlin.String!) public final operator fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int @@ -399,7 +394,6 @@ public interface Function { public final class Int : kotlin.Number, kotlin.Comparable, java.io.Serializable { /*primary*/ private constructor Int() - public constructor Int(/*0*/ p0: kotlin.String!) public final infix fun and(/*0*/ other: kotlin.Int): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int @@ -481,7 +475,6 @@ public final class IntArray : kotlin.Cloneable, java.io.Serializable { public final class Long : kotlin.Number, kotlin.Comparable, java.io.Serializable { /*primary*/ private constructor Long() - public constructor Long(/*0*/ p0: kotlin.String!) public final infix fun and(/*0*/ other: kotlin.Long): kotlin.Long public final operator fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int @@ -586,7 +579,6 @@ public abstract class Number : kotlin.Any, java.io.Serializable { public final class Short : kotlin.Number, kotlin.Comparable, java.io.Serializable { /*primary*/ private constructor Short() - public constructor Short(/*0*/ p0: kotlin.String!) public final operator fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int @@ -661,17 +653,6 @@ public final class ShortArray : kotlin.Cloneable, java.io.Serializable { public final class String : kotlin.Comparable, kotlin.CharSequence, java.io.Serializable { /*primary*/ public constructor String() - public constructor String(/*0*/ p0: java.lang.StringBuffer!) - public constructor String(/*0*/ p0: java.lang.StringBuilder!) - public constructor String(/*0*/ p0: kotlin.ByteArray!) - public constructor String(/*0*/ p0: kotlin.ByteArray!, /*1*/ p1: java.nio.charset.Charset!) - public constructor String(/*0*/ p0: kotlin.ByteArray!, /*1*/ p1: kotlin.Int, /*2*/ p2: kotlin.Int) - public constructor String(/*0*/ p0: kotlin.ByteArray!, /*1*/ p1: kotlin.Int, /*2*/ p2: kotlin.Int, /*3*/ p3: java.nio.charset.Charset!) - public constructor String(/*0*/ p0: kotlin.ByteArray!, /*1*/ p1: kotlin.Int, /*2*/ p2: kotlin.Int, /*3*/ p3: kotlin.String!) - public constructor String(/*0*/ p0: kotlin.ByteArray!, /*1*/ p1: kotlin.String!) - public constructor String(/*0*/ p0: kotlin.CharArray!) - public constructor String(/*0*/ p0: kotlin.CharArray!, /*1*/ p1: kotlin.Int, /*2*/ p2: kotlin.Int) - public constructor String(/*0*/ p0: kotlin.IntArray!, /*1*/ p1: kotlin.Int, /*2*/ p2: kotlin.Int) public open override /*1*/ val length: kotlin.Int public open override /*1*/ fun (): kotlin.Int public open override /*1*/ fun compareTo(/*0*/ other: kotlin.String): kotlin.Int diff --git a/compiler/testData/builtin-classes/java8/kotlin.txt b/compiler/testData/builtin-classes/java8/kotlin.txt index 0c021114448..97171362b37 100644 --- a/compiler/testData/builtin-classes/java8/kotlin.txt +++ b/compiler/testData/builtin-classes/java8/kotlin.txt @@ -33,7 +33,6 @@ public final class Array : kotlin.Cloneable, java.io.Serializable { public final class Boolean : kotlin.Comparable, java.io.Serializable { /*primary*/ private constructor Boolean() - public constructor Boolean(/*0*/ p0: kotlin.String!) public final infix fun and(/*0*/ other: kotlin.Boolean): kotlin.Boolean public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Boolean): kotlin.Int public final operator fun not(): kotlin.Boolean @@ -54,7 +53,6 @@ public final class BooleanArray : kotlin.Cloneable, java.io.Serializable { public final class Byte : kotlin.Number, kotlin.Comparable, java.io.Serializable { /*primary*/ private constructor Byte() - public constructor Byte(/*0*/ p0: kotlin.String!) public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int @@ -223,7 +221,6 @@ public final enum class DeprecationLevel : kotlin.Enum public final class Double : kotlin.Number, kotlin.Comparable, java.io.Serializable { /*primary*/ private constructor Double() - public constructor Double(/*0*/ p0: kotlin.String!) public final operator fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int @@ -320,8 +317,6 @@ public abstract class Enum> : kotlin.Comparable, jav public final class Float : kotlin.Number, kotlin.Comparable, java.io.Serializable { /*primary*/ private constructor Float() - public constructor Float(/*0*/ p0: kotlin.Double) - public constructor Float(/*0*/ p0: kotlin.String!) public final operator fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int @@ -401,7 +396,6 @@ public interface Function { public final class Int : kotlin.Number, kotlin.Comparable, java.io.Serializable { /*primary*/ private constructor Int() - public constructor Int(/*0*/ p0: kotlin.String!) public final infix fun and(/*0*/ other: kotlin.Int): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int @@ -483,7 +477,6 @@ public final class IntArray : kotlin.Cloneable, java.io.Serializable { public final class Long : kotlin.Number, kotlin.Comparable, java.io.Serializable { /*primary*/ private constructor Long() - public constructor Long(/*0*/ p0: kotlin.String!) public final infix fun and(/*0*/ other: kotlin.Long): kotlin.Long public final operator fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int @@ -588,7 +581,6 @@ public abstract class Number : kotlin.Any, java.io.Serializable { public final class Short : kotlin.Number, kotlin.Comparable, java.io.Serializable { /*primary*/ private constructor Short() - public constructor Short(/*0*/ p0: kotlin.String!) public final operator fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int public final operator fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int @@ -663,17 +655,6 @@ public final class ShortArray : kotlin.Cloneable, java.io.Serializable { public final class String : kotlin.Comparable, kotlin.CharSequence, java.io.Serializable { /*primary*/ public constructor String() - public constructor String(/*0*/ p0: java.lang.StringBuffer!) - public constructor String(/*0*/ p0: java.lang.StringBuilder!) - public constructor String(/*0*/ p0: kotlin.ByteArray!) - public constructor String(/*0*/ p0: kotlin.ByteArray!, /*1*/ p1: java.nio.charset.Charset!) - public constructor String(/*0*/ p0: kotlin.ByteArray!, /*1*/ p1: kotlin.Int, /*2*/ p2: kotlin.Int) - public constructor String(/*0*/ p0: kotlin.ByteArray!, /*1*/ p1: kotlin.Int, /*2*/ p2: kotlin.Int, /*3*/ p3: java.nio.charset.Charset!) - public constructor String(/*0*/ p0: kotlin.ByteArray!, /*1*/ p1: kotlin.Int, /*2*/ p2: kotlin.Int, /*3*/ p3: kotlin.String!) - public constructor String(/*0*/ p0: kotlin.ByteArray!, /*1*/ p1: kotlin.String!) - public constructor String(/*0*/ p0: kotlin.CharArray!) - public constructor String(/*0*/ p0: kotlin.CharArray!, /*1*/ p1: kotlin.Int, /*2*/ p2: kotlin.Int) - public constructor String(/*0*/ p0: kotlin.IntArray!, /*1*/ p1: kotlin.Int, /*2*/ p2: kotlin.Int) public open override /*1*/ val length: kotlin.Int public open override /*1*/ fun (): kotlin.Int public open override /*1*/ /*fake_override*/ fun chars(): java.util.stream.IntStream! diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BuiltInClassesAreSerializableOnJvm.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BuiltInClassesAreSerializableOnJvm.kt index a10c4e37337..a1753a418e5 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BuiltInClassesAreSerializableOnJvm.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BuiltInClassesAreSerializableOnJvm.kt @@ -196,7 +196,8 @@ open class BuiltInClassesAreSerializableOnJvm( javaConstructor.visibility.isPublicAPI && defaultKotlinVersion.constructors.none { it.isEffectivelyTheSameAs(javaConstructor) } && !javaConstructor.isTrivialCopyConstructorFor(classDescriptor) && - !KotlinBuiltIns.isDeprecated(javaConstructor) + !KotlinBuiltIns.isDeprecated(javaConstructor) && + signature(javaAnalogueDescriptor, javaConstructor.computeJvmDescriptor()) !in BLACK_LIST_CONSTRUCTOR_SIGNATURES }.map { javaConstructor -> javaConstructor.newCopyBuilder().apply { @@ -261,6 +262,10 @@ open class BuiltInClassesAreSerializableOnJvm( inJavaUtil("Collection", "toArray([$objectType)[$objectType", "toArray()[$objectType") + private fun buildPrimitiveValueMethodsSet(): Set = + JvmPrimitiveType.values().flatMapTo(LinkedHashSet()) { + inJavaLang(it.wrapperFqName.shortName().asString(), "${it.javaKeywordName}Value()${it.desc}") + } private val MUTABLE_METHOD_SIGNATURES: Set = inJavaUtil("Collection", "removeIf(Ljava/util/function/Predicate;)Z") + @@ -278,9 +283,22 @@ open class BuiltInClassesAreSerializableOnJvm( "replace($objectType$objectType)$objectType", "replace($objectType$objectType$objectType)Z") - private fun buildPrimitiveValueMethodsSet(): Set = + private val BLACK_LIST_CONSTRUCTOR_SIGNATURES: Set = + buildPrimitiveStringConstructorsSet() + + inJavaLang("Float", *constructors("D")) + + inJavaLang("String", *constructors( + "[C", "[CII", "[III", "[BIILjava/lang/String;", + "[BIILjava/nio/charset/Charset;", + "[BLjava/lang/String;", + "[BLjava/nio/charset/Charset;", + "[BII", "[B", + "Ljava/lang/StringBuffer;", + "Ljava/lang/StringBuilder;" + )) + + private fun buildPrimitiveStringConstructorsSet(): Set = JvmPrimitiveType.values().flatMapTo(LinkedHashSet()) { - inJavaLang(it.wrapperFqName.shortName().asString(), "${it.javaKeywordName}Value()${it.desc}") + inJavaLang(it.wrapperFqName.shortName().asString(), *constructors(stringType)) } } } @@ -296,6 +314,8 @@ private val objectType = javaLang("Object").t private fun javaLang(name: String) = "java/lang/$name" private fun javaUtil(name: String) = "java/util/$name" +private fun constructors(vararg signatures: String) = signatures.map { "($it)V" }.toTypedArray() + private fun inJavaLang(name: String, vararg signatures: String) = inClass(javaLang(name), *signatures) private fun inJavaUtil(name: String, vararg signatures: String) = inClass(javaUtil(name), *signatures)