Make Throwable.addSuppressed extension work without kotlin-stdlib-jdk7*

*given that it runs on JDK7 and higher. The addSuppressed member
is called with reflection when it's available.
kotlin-stdlib-jdk7 extension still overrides that and calls
addSuppressed member statically as before.

#KT-30560 Fixed
This commit is contained in:
Ilya Gorbunov
2019-03-27 06:07:36 +03:00
parent e6e00483d4
commit 91c7233ed8
4 changed files with 67 additions and 7 deletions
+26 -6
View File
@@ -12,11 +12,6 @@ pill {
importAsLibrary = true
}
dependencies {
compile project(':kotlin-stdlib')
testCompile project(':kotlin-test:kotlin-test-junit')
}
sourceSets {
main {
kotlin {
@@ -33,6 +28,11 @@ sourceSets {
}
}
}
noJdk7Test {
kotlin {
srcDir 'testNoJdk7'
}
}
java9 {
java {
srcDir 'java9'
@@ -40,6 +40,15 @@ sourceSets {
}
}
configurations {
noJdk7TestCompile.extendsFrom(testCompile)
}
dependencies {
compile project(':kotlin-stdlib')
testCompile project(':kotlin-test:kotlin-test-junit')
}
jar {
manifestAttributes(manifest, project, 'Main' /*true*/)
// TODO: enable as soon as this doesn't cause D8/DX to crash
@@ -106,4 +115,15 @@ task testJdk6Tests(type: Test) {
}
}
check.dependsOn testJdk6Tests
task testNoJdk7(type: Test, dependsOn: noJdk7TestClasses) {
group = "verification"
executable = "$JDK_17/bin/java"
testClassesDirs = sourceSets.noJdk7Test.output.classesDirs
classpath = sourceSets.noJdk7Test.runtimeClasspath
}
check.dependsOn testJdk6Tests, testNoJdk7
@@ -0,0 +1,23 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package test.exceptions
import kotlin.addSuppressed as addSuppressedExtension
import kotlin.test.*
class ExceptionTest {
@Test
fun addSuppressedWorksWithoutJdk7Extensions() {
val e1 = Throwable()
val e2 = Exception("Suppressed")
e1.addSuppressedExtension(e2)
assertSame(e2, e1.suppressed.singleOrNull())
}
}
@@ -5,14 +5,24 @@
package kotlin.internal
import java.lang.reflect.Method
import java.util.regex.MatchResult
import kotlin.random.FallbackThreadLocalRandom
import kotlin.random.Random
internal open class PlatformImplementations {
private object ReflectAddSuppressedMethod {
@JvmField
public val method: Method? = Throwable::class.java.let { throwableClass ->
throwableClass.methods.find {
it.name == "addSuppressed" && it.parameterTypes.singleOrNull() == throwableClass
}
}
}
public open fun addSuppressed(cause: Throwable, exception: Throwable) {
// do nothing
ReflectAddSuppressedMethod.method?.invoke(cause, exception)
}
public open fun getMatchResultNamedGroup(matchResult: MatchResult, name: String): MatchGroup? {
@@ -65,4 +65,11 @@ class ExceptionJVMTest {
exception.stackTrace = stackTrace
assertArrayNotSameButEquals(stackTrace, exception.stackTrace)
}
@Test fun addSuppressedDoesNotThrow() {
val e1 = Throwable()
val e2 = Exception("Suppressed")
e1.addSuppressed(e2)
}
}