diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 636ba5a09bc..682224f1e6d 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -19022,52 +19022,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT } } - @Nested - @TestMetadata("compiler/testData/codegen/box/hashPMap") - @TestDataPath("$PROJECT_ROOT") - public class HashPMap { - @Test - public void testAllFilesPresentInHashPMap() throws Exception { - KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/hashPMap"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); - } - - @Test - @TestMetadata("empty.kt") - public void testEmpty() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/empty.kt"); - } - - @Test - @TestMetadata("manyNumbers.kt") - public void testManyNumbers() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/manyNumbers.kt"); - } - - @Test - @TestMetadata("rewriteWithDifferent.kt") - public void testRewriteWithDifferent() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/rewriteWithDifferent.kt"); - } - - @Test - @TestMetadata("rewriteWithEqual.kt") - public void testRewriteWithEqual() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/rewriteWithEqual.kt"); - } - - @Test - @TestMetadata("simplePlusGet.kt") - public void testSimplePlusGet() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/simplePlusGet.kt"); - } - - @Test - @TestMetadata("simplePlusMinus.kt") - public void testSimplePlusMinus() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/simplePlusMinus.kt"); - } - } - @Nested @TestMetadata("compiler/testData/codegen/box/ieee754") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/testData/codegen/box/hashPMap/empty.kt b/compiler/testData/codegen/box/hashPMap/empty.kt deleted file mode 100644 index 30be641c252..00000000000 --- a/compiler/testData/codegen/box/hashPMap/empty.kt +++ /dev/null @@ -1,26 +0,0 @@ -// TARGET_BACKEND: JVM - -// WITH_REFLECT - -import kotlin.reflect.jvm.internal.pcollections.HashPMap -import kotlin.test.* - -fun box(): String { - val map = HashPMap.empty()!! - - assertEquals(0, map.size()) - - assertFalse(map.containsKey("")) - assertFalse(map.containsKey("abacaba")) - assertEquals(null, map[""]) - assertEquals(null, map["lol"]) - - // Check that doesn't create a new map - assertEquals(map, map.minus("")) - - // Check that all empty()s are equal - val other = HashPMap.empty()!! - assertEquals(map, other) - - return "OK" -} diff --git a/compiler/testData/codegen/box/hashPMap/manyNumbers.kt b/compiler/testData/codegen/box/hashPMap/manyNumbers.kt deleted file mode 100644 index 36fa247c967..00000000000 --- a/compiler/testData/codegen/box/hashPMap/manyNumbers.kt +++ /dev/null @@ -1,54 +0,0 @@ -// TARGET_BACKEND: JVM - -// Out of memory on Android 4.4 -// IGNORE_BACKEND: ANDROID - -// WITH_REFLECT - -import java.util.* -import kotlin.reflect.jvm.internal.pcollections.HashPMap -import kotlin.test.* - -fun digitSum(number: Int): Int { - var x = number - var ans = 0 - while (x != 0) { - ans += x % 10 - x /= 10 - } - return ans -} - -val N = 1000000 - -fun box(): String { - var map = HashPMap.empty()!! - - for (x in 1..N) { - map = map.plus(x, digitSum(x))!! - } - - assertEquals(N, map.size()) - - // Check in reverse order just in case - for (x in N downTo 1) { - assertTrue(map.containsKey(x), "Not found: $x") - assertEquals(digitSum(x), map[x], "Incorrect value for $x") - } - - // Delete in random order - val list = (1..N).toCollection(ArrayList()) - Collections.shuffle(list, Random(42)) - for (x in list) { - map = map.minus(x)!! - } - - assertEquals(0, map.size()) - - for (x in 1..N) { - assertFalse(map.containsKey(x), "Incorrectly found: $x") - assertEquals(null, map[x], "Incorrectly found value for $x") - } - - return "OK" -} diff --git a/compiler/testData/codegen/box/hashPMap/rewriteWithDifferent.kt b/compiler/testData/codegen/box/hashPMap/rewriteWithDifferent.kt deleted file mode 100644 index 26b01a8a3c0..00000000000 --- a/compiler/testData/codegen/box/hashPMap/rewriteWithDifferent.kt +++ /dev/null @@ -1,32 +0,0 @@ -// TARGET_BACKEND: JVM - -// WITH_REFLECT - -import kotlin.reflect.jvm.internal.pcollections.HashPMap -import kotlin.test.* - -fun box(): String { - var map = HashPMap.empty()!! - - map = map.plus("lol", 42)!! - map = map.plus("lol", 239)!! - - assertEquals(1, map.size()) - assertTrue(map.containsKey("lol")) - assertFalse(map.containsKey("")) - assertEquals(239, map["lol"]) - assertEquals(null, map[""]) - - map = map.plus("", 0)!! - map = map.plus("", 2.71828)!! - map = map.plus("lol", 42)!! - map = map.plus("", 3.14)!! - - assertEquals(2, map.size()) - assertTrue(map.containsKey("lol")) - assertTrue(map.containsKey("")) - assertEquals(42, map["lol"]) - assertEquals(3.14, map[""]) - - return "OK" -} diff --git a/compiler/testData/codegen/box/hashPMap/rewriteWithEqual.kt b/compiler/testData/codegen/box/hashPMap/rewriteWithEqual.kt deleted file mode 100644 index 0e3bcf42734..00000000000 --- a/compiler/testData/codegen/box/hashPMap/rewriteWithEqual.kt +++ /dev/null @@ -1,32 +0,0 @@ -// TARGET_BACKEND: JVM - -// WITH_REFLECT - -import kotlin.reflect.jvm.internal.pcollections.HashPMap -import kotlin.test.* - -fun box(): String { - var map = HashPMap.empty()!! - - map = map.plus("lol", 42)!! - map = map.plus("lol", 42)!! - - assertEquals(1, map.size()) - assertTrue(map.containsKey("lol")) - assertFalse(map.containsKey("")) - assertEquals(42, map["lol"]) - assertEquals(null, map[""]) - - map = map.plus("", 0)!! - map = map.plus("", 0)!! - map = map.plus("lol", 42)!! - map = map.plus("", 0)!! - - assertEquals(2, map.size()) - assertTrue(map.containsKey("lol")) - assertTrue(map.containsKey("")) - assertEquals(42, map["lol"]) - assertEquals(0, map[""]) - - return "OK" -} diff --git a/compiler/testData/codegen/box/hashPMap/simplePlusGet.kt b/compiler/testData/codegen/box/hashPMap/simplePlusGet.kt deleted file mode 100644 index 6c3c67f00b5..00000000000 --- a/compiler/testData/codegen/box/hashPMap/simplePlusGet.kt +++ /dev/null @@ -1,28 +0,0 @@ -// TARGET_BACKEND: JVM - -// WITH_REFLECT - -import kotlin.reflect.jvm.internal.pcollections.HashPMap -import kotlin.test.* - -fun box(): String { - var map = HashPMap.empty()!! - - map = map.plus("lol", 42)!! - - assertEquals(1, map.size()) - assertTrue(map.containsKey("lol")) - assertFalse(map.containsKey("")) - assertEquals(42, map["lol"]) - assertEquals(null, map[""]) - - map = map.plus("", 0)!! - - assertEquals(2, map.size()) - assertTrue(map.containsKey("lol")) - assertTrue(map.containsKey("")) - assertEquals(42, map["lol"]) - assertEquals(0, map[""]) - - return "OK" -} diff --git a/compiler/testData/codegen/box/hashPMap/simplePlusMinus.kt b/compiler/testData/codegen/box/hashPMap/simplePlusMinus.kt deleted file mode 100644 index 912934e1b0f..00000000000 --- a/compiler/testData/codegen/box/hashPMap/simplePlusMinus.kt +++ /dev/null @@ -1,27 +0,0 @@ -// TARGET_BACKEND: JVM - -// WITH_REFLECT - -import kotlin.reflect.jvm.internal.pcollections.HashPMap -import kotlin.test.* - -fun box(): String { - var map = HashPMap.empty()!! - - map = map.plus("lol", 42)!! - map = map.minus("lol")!! - - assertEquals(0, map.size()) - assertFalse(map.containsKey("lol")) - assertEquals(null, map["lol"]) - - map = map.plus("abc", "a")!! - map = map.minus("abc")!! - map = map.plus("abc", "d")!! - - assertEquals(1, map.size()) - assertTrue(map.containsKey("abc")) - assertEquals("d", map["abc"]) - - return "OK" -} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 1d80de01e0c..22dbe9c6e29 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -18452,52 +18452,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } } - @Nested - @TestMetadata("compiler/testData/codegen/box/hashPMap") - @TestDataPath("$PROJECT_ROOT") - public class HashPMap { - @Test - public void testAllFilesPresentInHashPMap() throws Exception { - KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/hashPMap"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); - } - - @Test - @TestMetadata("empty.kt") - public void testEmpty() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/empty.kt"); - } - - @Test - @TestMetadata("manyNumbers.kt") - public void testManyNumbers() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/manyNumbers.kt"); - } - - @Test - @TestMetadata("rewriteWithDifferent.kt") - public void testRewriteWithDifferent() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/rewriteWithDifferent.kt"); - } - - @Test - @TestMetadata("rewriteWithEqual.kt") - public void testRewriteWithEqual() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/rewriteWithEqual.kt"); - } - - @Test - @TestMetadata("simplePlusGet.kt") - public void testSimplePlusGet() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/simplePlusGet.kt"); - } - - @Test - @TestMetadata("simplePlusMinus.kt") - public void testSimplePlusMinus() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/simplePlusMinus.kt"); - } - } - @Nested @TestMetadata("compiler/testData/codegen/box/ieee754") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index e3fd566cf4b..8962562b0b7 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -19022,52 +19022,6 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes } } - @Nested - @TestMetadata("compiler/testData/codegen/box/hashPMap") - @TestDataPath("$PROJECT_ROOT") - public class HashPMap { - @Test - public void testAllFilesPresentInHashPMap() throws Exception { - KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/hashPMap"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); - } - - @Test - @TestMetadata("empty.kt") - public void testEmpty() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/empty.kt"); - } - - @Test - @TestMetadata("manyNumbers.kt") - public void testManyNumbers() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/manyNumbers.kt"); - } - - @Test - @TestMetadata("rewriteWithDifferent.kt") - public void testRewriteWithDifferent() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/rewriteWithDifferent.kt"); - } - - @Test - @TestMetadata("rewriteWithEqual.kt") - public void testRewriteWithEqual() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/rewriteWithEqual.kt"); - } - - @Test - @TestMetadata("simplePlusGet.kt") - public void testSimplePlusGet() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/simplePlusGet.kt"); - } - - @Test - @TestMetadata("simplePlusMinus.kt") - public void testSimplePlusMinus() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/simplePlusMinus.kt"); - } - } - @Nested @TestMetadata("compiler/testData/codegen/box/ieee754") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index ae0cbeb02eb..b51c23924e8 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -15341,49 +15341,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes } } - @TestMetadata("compiler/testData/codegen/box/hashPMap") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class HashPMap extends AbstractLightAnalysisModeTest { - private void runTest(String testDataFilePath) throws Exception { - KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); - } - - public void testAllFilesPresentInHashPMap() throws Exception { - KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/hashPMap"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); - } - - @TestMetadata("empty.kt") - public void testEmpty() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/empty.kt"); - } - - @TestMetadata("manyNumbers.kt") - public void testManyNumbers() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/manyNumbers.kt"); - } - - @TestMetadata("rewriteWithDifferent.kt") - public void testRewriteWithDifferent() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/rewriteWithDifferent.kt"); - } - - @TestMetadata("rewriteWithEqual.kt") - public void testRewriteWithEqual() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/rewriteWithEqual.kt"); - } - - @TestMetadata("simplePlusGet.kt") - public void testSimplePlusGet() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/simplePlusGet.kt"); - } - - @TestMetadata("simplePlusMinus.kt") - public void testSimplePlusMinus() throws Exception { - runTest("compiler/testData/codegen/box/hashPMap/simplePlusMinus.kt"); - } - } - @TestMetadata("compiler/testData/codegen/box/ieee754") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt b/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt index 8da73f0b36c..0e06b26141c 100644 --- a/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt @@ -31,7 +31,6 @@ class CodeConformanceTest : TestCase() { "compiler/testData/psi/kdoc", "compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt", "compiler/util/src/org/jetbrains/kotlin/config/MavenComparableVersion.java", - "core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections", "dependencies", "dependencies/protobuf/protobuf-relocated/build", "dist", diff --git a/core/reflection.jvm/reflection.pro b/core/reflection.jvm/reflection.pro index 25caf9604bb..31b8b12047d 100644 --- a/core/reflection.jvm/reflection.pro +++ b/core/reflection.jvm/reflection.pro @@ -25,13 +25,6 @@ ** toString(); } -# For tests on HashPMap, see compiler/testData/codegen/box/hashPMap --keepclassmembers class kotlin.reflect.jvm.internal.pcollections.HashPMap { - public int size(); - public boolean containsKey(java.lang.Object); - public kotlin.reflect.jvm.internal.pcollections.HashPMap minus(java.lang.Object); -} - # This is needed because otherwise ProGuard strips generic signature of this class (even though we pass `-keepattributes Signature` above) # See KT-23962 and https://sourceforge.net/p/proguard/bugs/482/ -keep class kotlin.reflect.jvm.internal.impl.protobuf.GeneratedMessageLite$ExtendableMessageOrBuilder diff --git a/core/reflection.jvm/resources/META-INF/com.android.tools/proguard/kotlin-reflect.pro b/core/reflection.jvm/resources/META-INF/com.android.tools/proguard/kotlin-reflect.pro index d82eae8518c..405de56792d 100644 --- a/core/reflection.jvm/resources/META-INF/com.android.tools/proguard/kotlin-reflect.pro +++ b/core/reflection.jvm/resources/META-INF/com.android.tools/proguard/kotlin-reflect.pro @@ -18,4 +18,7 @@ -dontnote kotlin.internal.PlatformImplementationsKt # Don't note on internal APIs, as there is some class relocating that shrinkers may unnecessarily find suspicious. --dontwarn kotlin.reflect.jvm.internal.** \ No newline at end of file +-dontwarn kotlin.reflect.jvm.internal.** + +# Statically guarded by try-catch block and not used on Android, see CacheByClass +-dontwarn java.lang.ClassValue diff --git a/core/reflection.jvm/resources/META-INF/com.android.tools/r8-from-1.6.0/kotlin-reflect.pro b/core/reflection.jvm/resources/META-INF/com.android.tools/r8-from-1.6.0/kotlin-reflect.pro index 1958c717df6..d50c8ea139d 100644 --- a/core/reflection.jvm/resources/META-INF/com.android.tools/r8-from-1.6.0/kotlin-reflect.pro +++ b/core/reflection.jvm/resources/META-INF/com.android.tools/r8-from-1.6.0/kotlin-reflect.pro @@ -13,4 +13,12 @@ -dontnote kotlin.internal.PlatformImplementationsKt # Don't note on internal APIs, as there is some class relocating that shrinkers may unnecessarily find suspicious. --dontwarn kotlin.reflect.jvm.internal.** \ No newline at end of file +-dontwarn kotlin.reflect.jvm.internal.** + +# Statically guarded by try-catch block and not used on Android, see CacheByClass +-dontwarn java.lang.ClassValue + +# Do not even execute try-catch block for ClassValue +-assumenosideeffects class kotlin.reflect.jvm.internal.CacheByClassKt { + boolean useClassValue return false; +} diff --git a/core/reflection.jvm/resources/META-INF/com.android.tools/r8-upto-1.6.0/kotlin-reflect.pro b/core/reflection.jvm/resources/META-INF/com.android.tools/r8-upto-1.6.0/kotlin-reflect.pro index ff4886b5b5c..2a2a60dd110 100644 --- a/core/reflection.jvm/resources/META-INF/com.android.tools/r8-upto-1.6.0/kotlin-reflect.pro +++ b/core/reflection.jvm/resources/META-INF/com.android.tools/r8-upto-1.6.0/kotlin-reflect.pro @@ -20,4 +20,7 @@ -dontnote kotlin.internal.PlatformImplementationsKt # Don't note on internal APIs, as there is some class relocating that shrinkers may unnecessarily find suspicious. --dontwarn kotlin.reflect.jvm.internal.** \ No newline at end of file +-dontwarn kotlin.reflect.jvm.internal.** + +# Statically guarded by try-catch block and not used on Android, see CacheByClass +-dontwarn java.lang.ClassValue diff --git a/core/reflection.jvm/resources/META-INF/proguard/kotlin-reflect.pro b/core/reflection.jvm/resources/META-INF/proguard/kotlin-reflect.pro index 831b237faac..6f141cd21c6 100644 --- a/core/reflection.jvm/resources/META-INF/proguard/kotlin-reflect.pro +++ b/core/reflection.jvm/resources/META-INF/proguard/kotlin-reflect.pro @@ -20,4 +20,7 @@ -dontnote kotlin.internal.PlatformImplementationsKt # Don't note on internal APIs, as there is some class relocating that shrinkers may unnecessarily find suspicious. --dontwarn kotlin.reflect.jvm.internal.** \ No newline at end of file +-dontwarn kotlin.reflect.jvm.internal.** + +# Statically guarded by try-catch block and not used on Android, see CacheByClass +-dontwarn java.lang.ClassValue diff --git a/core/reflection.jvm/src/kotlin/reflect/full/KClassifiers.kt b/core/reflection.jvm/src/kotlin/reflect/full/KClassifiers.kt index d3166d47fb8..72e864eced2 100644 --- a/core/reflection.jvm/src/kotlin/reflect/full/KClassifiers.kt +++ b/core/reflection.jvm/src/kotlin/reflect/full/KClassifiers.kt @@ -18,7 +18,6 @@ package kotlin.reflect.full -import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.types.* import kotlin.reflect.KClassifier import kotlin.reflect.KType diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/CacheByClass.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/CacheByClass.kt new file mode 100644 index 00000000000..f95e0cc5a0b --- /dev/null +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/CacheByClass.kt @@ -0,0 +1,73 @@ +/* + * Copyright 2010-2022 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 kotlin.reflect.jvm.internal + +import java.util.concurrent.ConcurrentHashMap + +/* + * By default, we use ClassValue-based caches in reflection to avoid classloader leaks, + * but ClassValue is not available on Android, thus we attempt to check it dynamically + * and fallback to ConcurrentHashMap-based cache. + * + * NB: if you are changing the name of the outer file (CacheByClass.kt), please also change the corresponding + * proguard rules + */ +private val useClassValue = runCatching { + Class.forName("java.lang.ClassValue") +}.map { true }.getOrDefault(false) + +internal abstract class CacheByClass { + abstract fun get(key: Class<*>): V + + abstract fun clear() +} + +/** + * Creates a **strongly referenced** cache of values associated with [Class]. + * Values are computed using provided [compute] function. + * + * `null` values are not supported, though there aren't any technical limitations. + */ +internal fun createCache(compute: (Class<*>) -> V): CacheByClass { + return if (useClassValue) ClassValueCache(compute) else ConcurrentHashMapCache(compute) +} + +private class ClassValueCache(private val compute: (Class<*>) -> V) : CacheByClass() { + + @Volatile + private var classValue = initClassValue() + + private fun initClassValue() = object : ClassValue() { + override fun computeValue(type: Class<*>): V { + return compute(type) + } + } + + override fun get(key: Class<*>): V = classValue[key] + + override fun clear() { + /* + * ClassValue does not have a proper `clear()` method but is properly weak-referenced, + * thus abandoning ClassValue instance will eventually clear all associated values. + */ + classValue = initClassValue() + } +} + +/** + * We no longer support Java 6, so the only place we use this cache is Android, where there + * are no classloader leaks issue, thus we can safely use strong references and do not bother + * with WeakReference wrapping. + */ +private class ConcurrentHashMapCache(private val compute: (Class<*>) -> V) : CacheByClass() { + private val cache = ConcurrentHashMap, V>() + + override fun get(key: Class<*>): V = cache.getOrPut(key) { compute(key) } + + override fun clear() { + cache.clear() + } +} diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionFactoryImpl.java b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionFactoryImpl.java index 2e02308c7fe..c918f4ec4ac 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionFactoryImpl.java +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionFactoryImpl.java @@ -1,22 +1,11 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2022 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 kotlin.reflect.jvm.internal; -import kotlin.SinceKotlin; import kotlin.jvm.internal.*; import kotlin.reflect.*; import kotlin.reflect.full.KClassifiers; diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/kClassCache.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/kClassCache.kt index e173619e2fd..34dbeee4300 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/kClassCache.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/kClassCache.kt @@ -1,69 +1,17 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2022 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 kotlin.reflect.jvm.internal -import java.lang.ref.WeakReference -import kotlin.reflect.jvm.internal.pcollections.HashPMap -// TODO: collect nulls periodically -// Key of the map is Class.getName(), each value is either a WeakReference> or an Array>>. -// Arrays are needed because the same class can be loaded by different class loaders, which results in different Class instances. -// This variable is not volatile intentionally: we don't care if there's a data race on it and some KClass instances will be lost. -// We do care however about general performance on read access to it, thus no synchronization is done here whatsoever -private var K_CLASS_CACHE = HashPMap.empty() +private val K_CLASS_CACHE = createCache { KClassImpl(it) } // This function is invoked on each reflection access to Java classes, properties, etc. Performance is critical here. -internal fun getOrCreateKotlinClass(jClass: Class): KClassImpl { - val name = jClass.name - val cached = K_CLASS_CACHE[name] - if (cached is WeakReference<*>) { - @Suppress("UNCHECKED_CAST") - val kClass = cached.get() as KClassImpl? - if (kClass?.jClass == jClass) { - return kClass - } - } else if (cached != null) { - // If the cached value is not a weak reference, it's an array of weak references - @Suppress("UNCHECKED_CAST") - (cached as Array>>) - for (ref in cached) { - val kClass = ref.get() - if (kClass?.jClass == jClass) { - return kClass - } - } - - // This is the most unlikely case: we found a cached array of references of length at least 2 (can't be 1 because - // the single element would be cached instead), and none of those classes is the one we're looking for - val size = cached.size - val newArray = arrayOfNulls>>(size + 1) - // Don't use Arrays.copyOf because it works reflectively - System.arraycopy(cached, 0, newArray, 0, size) - val newKClass = KClassImpl(jClass) - newArray[size] = WeakReference(newKClass) - K_CLASS_CACHE = K_CLASS_CACHE.plus(name, newArray) - return newKClass - } - - val newKClass = KClassImpl(jClass) - K_CLASS_CACHE = K_CLASS_CACHE.plus(name, WeakReference(newKClass)) - return newKClass -} +@Suppress("UNCHECKED_CAST") +internal fun getOrCreateKotlinClass(jClass: Class): KClassImpl = K_CLASS_CACHE.get(jClass) as KClassImpl internal fun clearKClassCache() { - K_CLASS_CACHE = HashPMap.empty() + K_CLASS_CACHE.clear() } diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections/ConsPStack.java b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections/ConsPStack.java deleted file mode 100644 index 5f57f340bc7..00000000000 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections/ConsPStack.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package kotlin.reflect.jvm.internal.pcollections; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * A simple persistent stack of non-null values. - *

- * This implementation is thread-safe, although its iterators may not be. - */ -final class ConsPStack implements Iterable { - private static final ConsPStack EMPTY = new ConsPStack(); - - @SuppressWarnings("unchecked") - public static ConsPStack empty() { - return (ConsPStack) EMPTY; - } - - final E first; - final ConsPStack rest; - private final int size; - - private ConsPStack() { // EMPTY constructor - size = 0; - first = null; - rest = null; - } - - private ConsPStack(E first, ConsPStack rest) { - this.first = first; - this.rest = rest; - this.size = 1 + rest.size; - } - - public E get(int index) { - if (index < 0 || index > size) throw new IndexOutOfBoundsException(); - - try { - return iterator(index).next(); - } catch (NoSuchElementException e) { - throw new IndexOutOfBoundsException("Index: " + index); - } - } - - @Override - public Iterator iterator() { - return iterator(0); - } - - public int size() { - return size; - } - - private Iterator iterator(int index) { - return new Itr(subList(index)); - } - - private static class Itr implements Iterator { - private ConsPStack next; - - public Itr(ConsPStack first) { - this.next = first; - } - - @Override - public boolean hasNext() { - return next.size > 0; - } - - @Override - public E next() { - E e = next.first; - next = next.rest; - return e; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - } - - public ConsPStack plus(E e) { - return new ConsPStack(e, this); - } - - private ConsPStack minus(Object e) { - if (size == 0) return this; - if (first.equals(e)) // found it - return rest; // don't recurse (only remove one) - // otherwise keep looking: - ConsPStack newRest = rest.minus(e); - if (newRest == rest) return this; - return new ConsPStack(first, newRest); - } - - public ConsPStack minus(int i) { - return minus(get(i)); - } - - private ConsPStack subList(int start) { - if (start < 0 || start > size) - throw new IndexOutOfBoundsException(); - if (start == 0) - return this; - return rest.subList(start - 1); - } -} diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections/HashPMap.java b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections/HashPMap.java deleted file mode 100644 index c54d8f9213f..00000000000 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections/HashPMap.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package kotlin.reflect.jvm.internal.pcollections; - -import org.jetbrains.annotations.NotNull; - -/** - * A persistent map from non-null keys to non-null values. - * @suppress - */ -public final class HashPMap { - private static final HashPMap EMPTY = new HashPMap(IntTreePMap.>>empty(), 0); - - @SuppressWarnings("unchecked") - @NotNull - public static HashPMap empty() { - return (HashPMap) EMPTY; - } - - private final IntTreePMap>> intMap; - private final int size; - - private HashPMap(IntTreePMap>> intMap, int size) { - this.intMap = intMap; - this.size = size; - } - - public int size() { - return size; - } - - public boolean containsKey(Object key) { - return keyIndexIn(getEntries(key.hashCode()), key) != -1; - } - - public V get(Object key) { - ConsPStack> entries = getEntries(key.hashCode()); - while (entries != null && entries.size() > 0) { - MapEntry entry = entries.first; - if (entry.key.equals(key)) - return entry.value; - entries = entries.rest; - } - return null; - } - - @NotNull - public HashPMap plus(K key, V value) { - ConsPStack> entries = getEntries(key.hashCode()); - int size0 = entries.size(); - int i = keyIndexIn(entries, key); - if (i != -1) entries = entries.minus(i); - entries = entries.plus(new MapEntry(key, value)); - return new HashPMap(intMap.plus(key.hashCode(), entries), size - size0 + entries.size()); - } - - @NotNull - public HashPMap minus(Object key) { - ConsPStack> entries = getEntries(key.hashCode()); - int i = keyIndexIn(entries, key); - if (i == -1) // key not in this - return this; - entries = entries.minus(i); - if (entries.size() == 0) // get rid of the entire hash entry - return new HashPMap(intMap.minus(key.hashCode()), size - 1); - // otherwise replace hash entry with new smaller one: - return new HashPMap(intMap.plus(key.hashCode(), entries), size - 1); - } - - private ConsPStack> getEntries(int hash) { - ConsPStack> entries = intMap.get(hash); - if (entries == null) return ConsPStack.empty(); - return entries; - } - - private static int keyIndexIn(ConsPStack> entries, Object key) { - int i = 0; - while (entries != null && entries.size() > 0) { - MapEntry entry = entries.first; - if (entry.key.equals(key)) - return i; - entries = entries.rest; - i++; - } - return -1; - } -} diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections/IntTree.java b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections/IntTree.java deleted file mode 100644 index 0fd29862eee..00000000000 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections/IntTree.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package kotlin.reflect.jvm.internal.pcollections; - -/** - * A non-public utility class for persistent balanced tree maps with integer keys. - *

- * To allow for efficiently increasing all keys above a certain value or decreasing - * all keys below a certain value, the keys values are stored relative to their parent. - * This makes this map a good backing for fast insertion and removal of indices in a - * vector. - *

- * This implementation is thread-safe except for its iterators. - *

- * Other than that, this tree is based on the Glasgow Haskell Compiler's Data.Map implementation, - * which in turn is based on "size balanced binary trees" as described by: - *

- * Stephen Adams, "Efficient sets: a balancing act", - * Journal of Functional Programming 3(4):553-562, October 1993, - * http://www.swiss.ai.mit.edu/~adams/BB/. - *

- * J. Nievergelt and E.M. Reingold, "Binary search trees of bounded balance", - * SIAM journal of computing 2(1), March 1973. - * - * @author harold - */ -final class IntTree { - // marker value: - static final IntTree EMPTYNODE = new IntTree(); - - // we use longs so relative keys can express all ints - // (e.g. if this has key -10 and right has 'absolute' key MAXINT, - // then its relative key is MAXINT+10 which overflows) - // there might be some way to deal with this based on left-verse-right logic, - // but that sounds like a mess. - private final long key; - private final V value; // null value means this is empty node - private final IntTree left, right; - private final int size; - - private IntTree() { - size = 0; - key = 0; - value = null; - left = null; - right = null; - } - - private IntTree(long key, V value, IntTree left, IntTree right) { - this.key = key; - this.value = value; - this.left = left; - this.right = right; - size = 1 + left.size + right.size; - } - - private IntTree withKey(long newKey) { - if (size == 0 || newKey == key) return this; - return new IntTree(newKey, value, left, right); - } - - boolean containsKey(long key) { - if (size == 0) - return false; - if (key < this.key) - return left.containsKey(key - this.key); - if (key > this.key) - return right.containsKey(key - this.key); - // otherwise key==this.key: - return true; - } - - V get(long key) { - if (size == 0) - return null; - if (key < this.key) - return left.get(key - this.key); - if (key > this.key) - return right.get(key - this.key); - // otherwise key==this.key: - return value; - } - - IntTree plus(long key, V value) { - if (size == 0) - return new IntTree(key, value, this, this); - if (key < this.key) - return rebalanced(left.plus(key - this.key, value), right); - if (key > this.key) - return rebalanced(left, right.plus(key - this.key, value)); - // otherwise key==this.key, so we simply replace this, with no effect on balance: - if (value == this.value) - return this; - return new IntTree(key, value, left, right); - } - - IntTree minus(long key) { - if (size == 0) - return this; - if (key < this.key) - return rebalanced(left.minus(key - this.key), right); - if (key > this.key) - return rebalanced(left, right.minus(key - this.key)); - - // otherwise key==this.key, so we are killing this node: - - if (left.size == 0) // we can just become right node - // make key 'absolute': - return right.withKey(right.key + this.key); - if (right.size == 0) // we can just become left node - return left.withKey(left.key + this.key); - - // otherwise replace this with the next key (i.e. the smallest key to the right): - - // TODO have minNode() instead of minKey to avoid having to call get() - // TODO get node from larger subtree, i.e. if left.size>right.size use left.maxNode() - // TODO have faster minusMin() instead of just using minus() - - long newKey = right.minKey() + this.key; - //(right.minKey() is relative to this; adding this.key makes it 'absolute' - // where 'absolute' really means relative to the parent of this) - - V newValue = right.get(newKey - this.key); - // now that we've got the new stuff, take it out of the right subtree: - IntTree newRight = right.minus(newKey - this.key); - - // lastly, make the subtree keys relative to newKey (currently they are relative to this.key): - newRight = newRight.withKey((newRight.key + this.key) - newKey); - // left is definitely not empty: - IntTree newLeft = left.withKey((left.key + this.key) - newKey); - - return rebalanced(newKey, newValue, newLeft, newRight); - } - - /** - * Changes every key k>=key to k+delta. - *

- * This method will create an _invalid_ tree if delta<0 - * and the distance between the smallest k>=key in this - * and the largest j - * In other words, this method must not result in any change - * in the order of the keys in this, since the tree structure is - * not being changed at all. - */ - IntTree changeKeysAbove(long key, int delta) { - if (size == 0 || delta == 0) - return this; - - if (this.key >= key) - // adding delta to this.key changes the keys of _all_ children of this, - // so we now need to un-change the children of this smaller than key, - // all of which are to the left. note that we still use the 'old' relative key...: - return new IntTree(this.key + delta, value, left.changeKeysBelow(key - this.key, -delta), right); - - // otherwise, doesn't apply yet, look to the right: - IntTree newRight = right.changeKeysAbove(key - this.key, delta); - if (newRight == right) return this; - return new IntTree(this.key, value, left, newRight); - } - - /** - * Changes every key k - * This method will create an _invalid_ tree if delta>0 - * and the distance between the largest k=key in this is delta or less. - *

- * In other words, this method must not result in any overlap or change - * in the order of the keys in this, since the tree _structure_ is - * not being changed at all. - */ - IntTree changeKeysBelow(long key, int delta) { - if (size == 0 || delta == 0) - return this; - - if (this.key < key) - // adding delta to this.key changes the keys of _all_ children of this, - // so we now need to un-change the children of this larger than key, - // all of which are to the right. note that we still use the 'old' relative key...: - return new IntTree(this.key + delta, value, left, right.changeKeysAbove(key - this.key, -delta)); - - // otherwise, doesn't apply yet, look to the left: - IntTree newLeft = left.changeKeysBelow(key - this.key, delta); - if (newLeft == left) return this; - return new IntTree(this.key, value, newLeft, right); - } - - // min key in this: - private long minKey() { - if (left.size == 0) - return key; - // make key 'absolute' (i.e. relative to the parent of this): - return left.minKey() + this.key; - } - - private IntTree rebalanced(IntTree newLeft, IntTree newRight) { - if (newLeft == left && newRight == right) - return this; // already balanced - return rebalanced(key, value, newLeft, newRight); - } - - private static final int OMEGA = 5; - private static final int ALPHA = 2; - - // rebalance a tree that is off-balance by at most 1: - private static IntTree rebalanced(long key, V value, IntTree left, IntTree right) { - if (left.size + right.size > 1) { - if (left.size >= OMEGA * right.size) { // rotate to the right - IntTree ll = left.left, lr = left.right; - if (lr.size < ALPHA * ll.size) // single rotation - return new IntTree(left.key + key, left.value, - ll, - new IntTree(-left.key, value, - lr.withKey(lr.key + left.key), - right)); - else { // double rotation: - IntTree lrl = lr.left, lrr = lr.right; - return new IntTree(lr.key + left.key + key, lr.value, - new IntTree(-lr.key, left.value, - ll, - lrl.withKey(lrl.key + lr.key)), - new IntTree(-left.key - lr.key, value, - lrr.withKey(lrr.key + lr.key + left.key), - right)); - } - } else if (right.size >= OMEGA * left.size) { // rotate to the left - IntTree rl = right.left, rr = right.right; - if (rl.size < ALPHA * rr.size) // single rotation - return new IntTree(right.key + key, right.value, - new IntTree(-right.key, value, - left, - rl.withKey(rl.key + right.key)), - rr); - else { // double rotation: - IntTree rll = rl.left, rlr = rl.right; - return new IntTree(rl.key + right.key + key, rl.value, - new IntTree(-right.key - rl.key, value, - left, - rll.withKey(rll.key + rl.key + right.key)), - new IntTree(-rl.key, right.value, - rlr.withKey(rlr.key + rl.key), - rr)); - } - } - } - // otherwise already balanced enough: - return new IntTree(key, value, left, right); - } -} diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections/IntTreePMap.java b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections/IntTreePMap.java deleted file mode 100644 index 22bd2e7a2f8..00000000000 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections/IntTreePMap.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package kotlin.reflect.jvm.internal.pcollections; - -/** - * An efficient persistent map from integer keys to non-null values. - */ -final class IntTreePMap { - private static final IntTreePMap EMPTY = new IntTreePMap(IntTree.EMPTYNODE); - - @SuppressWarnings("unchecked") - public static IntTreePMap empty() { - return (IntTreePMap) EMPTY; - } - - private final IntTree root; - - private IntTreePMap(IntTree root) { - this.root = root; - } - - private IntTreePMap withRoot(IntTree root) { - if (root == this.root) return this; - return new IntTreePMap(root); - } - - public V get(int key) { - return root.get(key); - } - - public IntTreePMap plus(int key, V value) { - return withRoot(root.plus(key, value)); - } - - public IntTreePMap minus(int key) { - return withRoot(root.minus(key)); - } -} diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections/MapEntry.java b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections/MapEntry.java deleted file mode 100644 index f99e3158389..00000000000 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections/MapEntry.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package kotlin.reflect.jvm.internal.pcollections; - -final class MapEntry implements java.io.Serializable { - private static final long serialVersionUID = 7138329143949025153L; - - public final K key; - public final V value; - - public MapEntry(K key, V value) { - this.key = key; - this.value = value; - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof MapEntry)) return false; - MapEntry e = (MapEntry) o; - return (key == null ? e.key == null : key.equals(e.key)) && - (value == null ? e.value == null : value.equals(e.value)); - } - - @Override - public int hashCode() { - return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode()); - } - - @Override - public String toString() { - return key + "=" + value; - } -} diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java index 06a27ad1b61..be23b0942f8 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java @@ -14344,16 +14344,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { } } - @Nested - @TestMetadata("compiler/testData/codegen/box/hashPMap") - @TestDataPath("$PROJECT_ROOT") - public class HashPMap { - @Test - public void testAllFilesPresentInHashPMap() throws Exception { - KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/hashPMap"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); - } - } - @Nested @TestMetadata("compiler/testData/codegen/box/ieee754") @TestDataPath("$PROJECT_ROOT") diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java index 5e8b59dc92b..5916acbfc85 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java @@ -14386,16 +14386,6 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { } } - @Nested - @TestMetadata("compiler/testData/codegen/box/hashPMap") - @TestDataPath("$PROJECT_ROOT") - public class HashPMap { - @Test - public void testAllFilesPresentInHashPMap() throws Exception { - KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/hashPMap"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); - } - } - @Nested @TestMetadata("compiler/testData/codegen/box/ieee754") @TestDataPath("$PROJECT_ROOT") diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 3d1a0c8751c..fe7482deabd 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -12776,19 +12776,6 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest } } - @TestMetadata("compiler/testData/codegen/box/hashPMap") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class HashPMap extends AbstractIrCodegenBoxWasmTest { - private void runTest(String testDataFilePath) throws Exception { - KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath); - } - - public void testAllFilesPresentInHashPMap() throws Exception { - KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/hashPMap"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); - } - } - @TestMetadata("compiler/testData/codegen/box/ieee754") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/libraries/reflect/api/build.gradle b/libraries/reflect/api/build.gradle index 9a9e2e263cc..1d1950aa0e3 100644 --- a/libraries/reflect/api/build.gradle +++ b/libraries/reflect/api/build.gradle @@ -2,7 +2,7 @@ description = '' apply plugin: 'kotlin' -JvmToolchain.configureJvmToolchain(project, JdkMajorVersion.JDK_1_6) +JvmToolchain.configureJvmToolchain(project, JdkMajorVersion.JDK_1_8) def includeJava9 = BuildPropertiesExtKt.getIncludeJava9(project.kotlinBuildProperties) diff --git a/libraries/reflect/build.gradle.kts b/libraries/reflect/build.gradle.kts index 9a883b46904..cf7c508047f 100644 --- a/libraries/reflect/build.gradle.kts +++ b/libraries/reflect/build.gradle.kts @@ -20,7 +20,7 @@ plugins { `java-library` } -configureJavaOnlyToolchain(JdkMajorVersion.JDK_1_6) +configureJavaOnlyToolchain(JdkMajorVersion.JDK_1_8) publish() @@ -146,7 +146,7 @@ val proguard by task { injars(mapOf("filter" to "!META-INF/**,!**/*.kotlin_builtins"), proguardAdditionalInJars) outjars(fileFrom(base.libsDirectory.asFile.get(), "${base.archivesName.get()}-$version-proguard.jar")) - javaLauncher.set(project.getToolchainLauncherFor(chooseJdk18ForJpsBuild(JdkMajorVersion.JDK_1_6))) + javaLauncher.set(project.getToolchainLauncherFor(chooseJdk18ForJpsBuild(JdkMajorVersion.JDK_1_8))) libraryjars(mapOf("filter" to "!META-INF/versions/**"), proguardDeps) libraryjars( project.files( diff --git a/libraries/scripting/common/build.gradle.kts b/libraries/scripting/common/build.gradle.kts index 2b073a2ee75..1eae6d530dd 100644 --- a/libraries/scripting/common/build.gradle.kts +++ b/libraries/scripting/common/build.gradle.kts @@ -3,7 +3,7 @@ plugins { id("jps-compatible") } -project.updateJvmTarget("1.6") +project.updateJvmTarget("1.8") dependencies { api(kotlinStdlib()) diff --git a/libraries/scripting/dependencies-maven/build.gradle.kts b/libraries/scripting/dependencies-maven/build.gradle.kts index f802f76d863..c1f515bbd62 100644 --- a/libraries/scripting/dependencies-maven/build.gradle.kts +++ b/libraries/scripting/dependencies-maven/build.gradle.kts @@ -3,7 +3,7 @@ plugins { id("jps-compatible") } -project.updateJvmTarget("1.6") +project.updateJvmTarget("1.8") dependencies { implementation(kotlinStdlib()) diff --git a/libraries/scripting/dependencies/build.gradle.kts b/libraries/scripting/dependencies/build.gradle.kts index 728c14c2136..4872f3dfb8b 100644 --- a/libraries/scripting/dependencies/build.gradle.kts +++ b/libraries/scripting/dependencies/build.gradle.kts @@ -3,7 +3,7 @@ plugins { id("jps-compatible") } -project.updateJvmTarget("1.6") +project.updateJvmTarget("1.8") dependencies { api(kotlinStdlib()) diff --git a/libraries/scripting/jvm/build.gradle.kts b/libraries/scripting/jvm/build.gradle.kts index b019def9fd9..16dbce99340 100644 --- a/libraries/scripting/jvm/build.gradle.kts +++ b/libraries/scripting/jvm/build.gradle.kts @@ -3,7 +3,7 @@ plugins { id("jps-compatible") } -project.configureJvmToolchain(JdkMajorVersion.JDK_1_6) +project.configureJvmToolchain(JdkMajorVersion.JDK_1_8) dependencies { api(project(":kotlin-script-runtime")) diff --git a/license/README.md b/license/README.md index 5f0aa9f2a09..bab681c0088 100644 --- a/license/README.md +++ b/license/README.md @@ -35,10 +35,6 @@ the Kotlin IntelliJ IDEA plugin: - License: BSD ([license/third_party/asm_license.txt][asm]) - Origin: Derived from ASM: a very small and fast Java bytecode manipulation framework, Copyright (c) 2000-2011 INRIA, France Telecom - - Path: core/reflection.jvm/src/kotlin.reflect/jvm/internal/pcollections - - License: MIT ([license/third_party/pcollections_LICENSE.txt][pcollections]) - - Origin: Derived from PCollections, A Persistent Java Collections Library (https://pcollections.org/) - - Path: eval4j/src/org/jetbrains/eval4j/interpreterLoop.kt - License: BSD ([license/third_party/asm_license.txt][asm]) - Origin: Derived from ASM: a very small and fast Java bytecode manipulation framework, Copyright (c) 2000-2011 INRIA, France Telecom @@ -284,7 +280,6 @@ any distributions of the compiler, libraries or plugin: [gwt]: third_party/gwt_license.txt [jquery]: third_party/jquery_license.txt [lombok]: third_party/testdata/lombok_license.txt -[pcollections]: third_party/pcollections_LICENSE.txt [qunit]: third_party/qunit_license.txt [rhino]: third_party/rhino_LICENSE.txt [rxjava]: third_party/testdata/rxjava_license.txt diff --git a/license/third_party/pcollections_LICENSE.txt b/license/third_party/pcollections_LICENSE.txt deleted file mode 100644 index 345a0dad954..00000000000 --- a/license/third_party/pcollections_LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2008 Harold Cooper - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java index a9bd3cc3f49..ce294e14254 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java @@ -15440,18 +15440,6 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest } } - @Nested - @TestMetadata("compiler/testData/codegen/box/hashPMap") - @TestDataPath("$PROJECT_ROOT") - @Tag("codegen") - @UseExtTestCaseGroupProvider() - public class HashPMap { - @Test - public void testAllFilesPresentInHashPMap() throws Exception { - KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/hashPMap"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true); - } - } - @Nested @TestMetadata("compiler/testData/codegen/box/ieee754") @TestDataPath("$PROJECT_ROOT")