Catch IllegalAccessException in KFunction.call

Rename IllegalPropertyAccessException -> IllegalCallableAccessException
This commit is contained in:
Alexander Udalov
2015-07-24 19:32:10 +03:00
parent 262099c899
commit ef4a5e78ed
12 changed files with 96 additions and 73 deletions
@@ -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"
}
@@ -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
}
@@ -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
}
@@ -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"
}
@@ -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
@@ -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)
}