Catch IllegalAccessException in KFunction.call
Rename IllegalPropertyAccessException -> IllegalCallableAccessException
This commit is contained in:
+22
@@ -0,0 +1,22 @@
|
||||
import kotlin.reflect.*
|
||||
import kotlin.reflect.jvm.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class A {
|
||||
private fun foo() = "A"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val f = A::class.declaredFunctions.single() as KFunction<String>
|
||||
|
||||
try {
|
||||
f.call(A())
|
||||
return "Fail: no exception was thrown"
|
||||
} catch (e: IllegalCallableAccessException) {}
|
||||
|
||||
f.isAccessible = true
|
||||
|
||||
assertEquals("A", f.call(A()))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+1
-1
@@ -9,7 +9,7 @@ fun box(): String {
|
||||
try {
|
||||
return p.get(K("Fail: private property should not be accessible by default"))
|
||||
}
|
||||
catch (e: IllegalPropertyAccessException) {
|
||||
catch (e: IllegalCallableAccessException) {
|
||||
// OK
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ fun box(): String {
|
||||
try {
|
||||
p.get(Result())
|
||||
return "Fail: private property is accessible by default"
|
||||
} catch(e: IllegalPropertyAccessException) { }
|
||||
} catch(e: IllegalCallableAccessException) { }
|
||||
|
||||
p.isAccessible = true
|
||||
|
||||
@@ -22,7 +22,7 @@ fun box(): String {
|
||||
try {
|
||||
p.get(Result())
|
||||
return "Fail: setAccessible(false) had no effect"
|
||||
} catch(e: IllegalPropertyAccessException) { }
|
||||
} catch(e: IllegalCallableAccessException) { }
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ fun box(): String {
|
||||
try {
|
||||
p.set(a, 1)
|
||||
return "Fail: private property is accessible by default"
|
||||
} catch(e: IllegalPropertyAccessException) { }
|
||||
} catch(e: IllegalCallableAccessException) { }
|
||||
|
||||
p.isAccessible = true
|
||||
|
||||
@@ -24,7 +24,7 @@ fun box(): String {
|
||||
try {
|
||||
p.set(a, 3)
|
||||
return "Fail: setAccessible(false) had no effect"
|
||||
} catch(e: IllegalPropertyAccessException) { }
|
||||
} catch(e: IllegalCallableAccessException) { }
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
+2
-2
@@ -14,12 +14,12 @@ fun box(): String {
|
||||
try {
|
||||
f.get(a)
|
||||
return "Fail: protected property getter is accessible by default"
|
||||
} catch (e: IllegalPropertyAccessException) { }
|
||||
} catch (e: IllegalCallableAccessException) { }
|
||||
|
||||
try {
|
||||
f.set(a, ":D")
|
||||
return "Fail: protected property setter is accessible by default"
|
||||
} catch (e: IllegalPropertyAccessException) { }
|
||||
} catch (e: IllegalCallableAccessException) { }
|
||||
|
||||
f.isAccessible = true
|
||||
|
||||
|
||||
+6
@@ -3126,6 +3126,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("privateMemberFunction.kt")
|
||||
public void testPrivateMemberFunction() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/functions/privateMemberFunction.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simpleGetFunctions.kt")
|
||||
public void testSimpleGetFunctions() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/functions/simpleGetFunctions.kt");
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
package kotlin.reflect
|
||||
|
||||
/**
|
||||
* An exception that is thrown when `get` or `set` is called on a property
|
||||
* and that property is not accessible (in JVM terms) from the calling method.
|
||||
* An exception that is thrown when `call` is invoked on a callable or `get` or `set` is invoked on a property
|
||||
* and that callable is not accessible (in JVM terms) from the calling method.
|
||||
*
|
||||
* @param cause the original exception thrown by the JVM.
|
||||
*
|
||||
* @see [kotlin.reflect.jvm.isAccessible]
|
||||
*/
|
||||
public class IllegalPropertyAccessException(cause: IllegalAccessException) : Exception(cause.getMessage()) {
|
||||
public class IllegalCallableAccessException(cause: IllegalAccessException) : Exception(cause.getMessage()) {
|
||||
init {
|
||||
@suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
||||
(this as java.lang.Throwable).initCause(cause)
|
||||
|
||||
@@ -74,7 +74,9 @@ open class KFunctionImpl protected constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun call(vararg args: Any?): Any? = caller.call(args)
|
||||
override fun call(vararg args: Any?): Any? = reflectionCall {
|
||||
caller.call(args)
|
||||
}
|
||||
|
||||
override fun getArity(): Int {
|
||||
return descriptor.valueParameters.size() +
|
||||
|
||||
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import java.lang.reflect.Method
|
||||
import kotlin.jvm.internal.MutablePropertyReference0
|
||||
import kotlin.jvm.internal.PropertyReference0
|
||||
import kotlin.reflect.IllegalPropertyAccessException
|
||||
import kotlin.reflect.KMutableProperty0
|
||||
import kotlin.reflect.KProperty0
|
||||
|
||||
@@ -35,14 +34,9 @@ open class KProperty0Impl<out R> : DescriptorBasedProperty<R>, KProperty0<R>, KP
|
||||
|
||||
override val javaGetter: Method get() = super.javaGetter!!
|
||||
|
||||
override fun get(): R {
|
||||
try {
|
||||
@suppress("UNCHECKED_CAST")
|
||||
return javaGetter.invoke(null) as R
|
||||
}
|
||||
catch (e: IllegalAccessException) {
|
||||
throw IllegalPropertyAccessException(e)
|
||||
}
|
||||
@suppress("UNCHECKED_CAST")
|
||||
override fun get(): R = reflectionCall {
|
||||
return javaGetter.invoke(null) as R
|
||||
}
|
||||
|
||||
override fun call(vararg args: Any?): R {
|
||||
@@ -65,12 +59,9 @@ open class KMutableProperty0Impl<R> : KProperty0Impl<R>, KMutableProperty0<R>, K
|
||||
override val javaSetter: Method get() = super.javaSetter!!
|
||||
|
||||
override fun set(value: R) {
|
||||
try {
|
||||
reflectionCall {
|
||||
javaSetter.invoke(null, value)
|
||||
}
|
||||
catch (e: IllegalAccessException) {
|
||||
throw IllegalPropertyAccessException(e)
|
||||
}
|
||||
}
|
||||
|
||||
class Setter<R>(override val property: KMutableProperty0Impl<R>) : KMutablePropertyImpl.Setter<R>(), KMutableProperty0.Setter<R> {
|
||||
|
||||
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import java.lang.reflect.Modifier
|
||||
import kotlin.jvm.internal.MutablePropertyReference1
|
||||
import kotlin.jvm.internal.PropertyReference1
|
||||
import kotlin.reflect.IllegalPropertyAccessException
|
||||
import kotlin.reflect.KMutableProperty1
|
||||
import kotlin.reflect.KProperty1
|
||||
|
||||
@@ -34,26 +33,18 @@ open class KProperty1Impl<T, out R> : DescriptorBasedProperty<R>, KProperty1<T,
|
||||
override val getter by ReflectProperties.lazy { Getter(this) }
|
||||
|
||||
// TODO: consider optimizing this, not to do complex checks on every access
|
||||
@suppress("UNCHECKED_CAST")
|
||||
override fun get(receiver: T): R {
|
||||
try {
|
||||
val getter = javaGetter ?:
|
||||
return javaField!!.get(receiver) as R
|
||||
|
||||
if (Modifier.isStatic(getter.getModifiers())) {
|
||||
@suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_UNIT_OR_ANY" /* KT-8619 */)
|
||||
override fun get(receiver: T): R = reflectionCall {
|
||||
val getter = javaGetter
|
||||
return when {
|
||||
getter == null -> javaField!!.get(receiver)
|
||||
Modifier.isStatic(getter.modifiers) -> {
|
||||
// Workaround the case of platformStatic property in object, getter of which doesn't take a receiver
|
||||
if (getter.getParameterTypes().isEmpty()) {
|
||||
return getter.invoke(null) as R
|
||||
}
|
||||
|
||||
return getter.invoke(null, receiver) as R
|
||||
if (getter.parameterTypes.isEmpty()) getter.invoke(null)
|
||||
else getter.invoke(null, receiver)
|
||||
}
|
||||
|
||||
return getter.invoke(receiver) as R
|
||||
}
|
||||
catch (e: IllegalAccessException) {
|
||||
throw IllegalPropertyAccessException(e)
|
||||
}
|
||||
else -> getter.invoke(receiver)
|
||||
} as R
|
||||
}
|
||||
|
||||
@suppress("UNCHECKED_CAST")
|
||||
@@ -76,25 +67,17 @@ open class KMutableProperty1Impl<T, R> : KProperty1Impl<T, R>, KMutableProperty1
|
||||
override val setter by ReflectProperties.lazy { Setter(this) }
|
||||
|
||||
override fun set(receiver: T, value: R) {
|
||||
try {
|
||||
val setter = javaSetter ?:
|
||||
return javaField!!.set(receiver, value)
|
||||
|
||||
if (Modifier.isStatic(setter.getModifiers())) {
|
||||
// Workaround the case of platformStatic property in object, setter of which doesn't take a receiver
|
||||
if (setter.getParameterTypes().size() == 1) {
|
||||
setter.invoke(null, value)
|
||||
}
|
||||
else {
|
||||
setter.invoke(null, receiver, value)
|
||||
reflectionCall {
|
||||
val setter = javaSetter
|
||||
when {
|
||||
setter == null -> javaField!!.set(receiver, value)
|
||||
Modifier.isStatic(setter.modifiers) -> {
|
||||
// Workaround the case of platformStatic property in object, setter of which doesn't take a receiver
|
||||
if (setter.parameterTypes.size() == 1) setter.invoke(null, value)
|
||||
else setter.invoke(null, receiver, value)
|
||||
}
|
||||
else -> setter.invoke(receiver, value)
|
||||
}
|
||||
else {
|
||||
setter.invoke(receiver, value)
|
||||
}
|
||||
}
|
||||
catch (e: IllegalAccessException) {
|
||||
throw IllegalPropertyAccessException(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ package kotlin.reflect.jvm.internal
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Method
|
||||
import kotlin.reflect.IllegalPropertyAccessException
|
||||
import kotlin.reflect.KMutableProperty2
|
||||
import kotlin.reflect.KProperty2
|
||||
|
||||
@@ -36,14 +35,9 @@ open class KProperty2Impl<D, E, out R> : DescriptorBasedProperty<R>, KProperty2<
|
||||
|
||||
override val javaField: Field? get() = null
|
||||
|
||||
override fun get(receiver1: D, receiver2: E): R {
|
||||
try {
|
||||
@suppress("UNCHECKED_CAST")
|
||||
return javaGetter.invoke(receiver1, receiver2) as R
|
||||
}
|
||||
catch (e: IllegalAccessException) {
|
||||
throw IllegalPropertyAccessException(e)
|
||||
}
|
||||
@suppress("UNCHECKED_CAST")
|
||||
override fun get(receiver1: D, receiver2: E): R = reflectionCall {
|
||||
return javaGetter.invoke(receiver1, receiver2) as R
|
||||
}
|
||||
|
||||
@suppress("UNCHECKED_CAST")
|
||||
@@ -68,12 +62,9 @@ class KMutableProperty2Impl<D, E, R> : KProperty2Impl<D, E, R>, KMutableProperty
|
||||
override val javaSetter: Method get() = super.javaSetter!!
|
||||
|
||||
override fun set(receiver1: D, receiver2: E, value: R) {
|
||||
try {
|
||||
reflectionCall {
|
||||
javaSetter.invoke(receiver1, receiver2, value)
|
||||
}
|
||||
catch (e: IllegalAccessException) {
|
||||
throw IllegalPropertyAccessException(e)
|
||||
}
|
||||
}
|
||||
|
||||
class Setter<D, E, R>(override val property: KMutableProperty2Impl<D, E, R>) : KMutablePropertyImpl.Setter<R>(), KMutableProperty2.Setter<D, E, R> {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import kotlin.reflect.IllegalCallableAccessException
|
||||
|
||||
// TODO: wrap other exceptions
|
||||
internal inline fun <R> reflectionCall(block: () -> R): R =
|
||||
try {
|
||||
block()
|
||||
}
|
||||
catch (e: IllegalAccessException) {
|
||||
throw IllegalCallableAccessException(e)
|
||||
}
|
||||
Reference in New Issue
Block a user