From 9c4ba711b88648e7bcb8725d6fbc6bf0980ffe69 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 23 Jul 2015 23:10:39 +0300 Subject: [PATCH] Rename and implement KProperty.accessible -> KCallable.isAccessible --- .../call/cannotCallEnumConstructor.kt | 15 ++++ .../reflection/call/privateProperty.kt | 2 +- .../callPrivatePropertyFromGetProperties.kt | 2 +- .../reflection/properties/privateClassVal.kt | 6 +- .../reflection/properties/privateClassVar.kt | 6 +- .../properties/privateToThisAccessors.kt | 2 +- .../properties/protectedClassVar.kt | 4 +- ...lackBoxWithStdlibCodegenTestGenerated.java | 6 ++ .../src/kotlin/reflect/exceptions.kt | 2 +- .../src/kotlin/reflect/jvm/_Deprecated.kt | 6 ++ .../src/kotlin/reflect/jvm/callables.kt | 68 +++++++++++++++++++ .../src/kotlin/reflect/jvm/properties.kt | 60 ---------------- 12 files changed, 107 insertions(+), 72 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/call/cannotCallEnumConstructor.kt create mode 100644 core/reflection.jvm/src/kotlin/reflect/jvm/callables.kt delete mode 100644 core/reflection.jvm/src/kotlin/reflect/jvm/properties.kt diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/call/cannotCallEnumConstructor.kt b/compiler/testData/codegen/boxWithStdlib/reflection/call/cannotCallEnumConstructor.kt new file mode 100644 index 00000000000..48b8c8bb118 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/call/cannotCallEnumConstructor.kt @@ -0,0 +1,15 @@ +import kotlin.reflect.jvm.* + +enum class E + +fun box(): String { + try { + val c = E::class.constructors.single() + c.isAccessible = true + c.call() + return "Fail: constructing an enum class should not be allowed" + } + catch (e: Throwable) { + return "OK" + } +} diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/call/privateProperty.kt b/compiler/testData/codegen/boxWithStdlib/reflection/call/privateProperty.kt index 2c45dd1eeaa..fb5a42dbe5a 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/call/privateProperty.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/call/privateProperty.kt @@ -8,7 +8,7 @@ fun box(): String { val a = A("abc") val p = A::class.declaredMemberProperties.single() as KMutableProperty1 - p.accessible = true + p.isAccessible = true assertEquals("abc", p.call(a)) assertEquals(Unit, p.setter.call(a, "def")) assertEquals("def", p.getter.call(a)) diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/properties/callPrivatePropertyFromGetProperties.kt b/compiler/testData/codegen/boxWithStdlib/reflection/properties/callPrivatePropertyFromGetProperties.kt index 186f66b5c6b..984b66a6191 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/properties/callPrivatePropertyFromGetProperties.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/properties/callPrivatePropertyFromGetProperties.kt @@ -13,7 +13,7 @@ fun box(): String { // OK } - p.accessible = true + p.isAccessible = true return p.get(K("OK")) } diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVal.kt b/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVal.kt index ba7009782bb..3c3bbbf25b7 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVal.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVal.kt @@ -1,5 +1,5 @@ import kotlin.reflect.* -import kotlin.reflect.jvm.accessible +import kotlin.reflect.jvm.isAccessible class Result { private val value = "OK" @@ -14,11 +14,11 @@ fun box(): String { return "Fail: private property is accessible by default" } catch(e: IllegalPropertyAccessException) { } - p.accessible = true + p.isAccessible = true val r = p.get(Result()) - p.accessible = false + p.isAccessible = false try { p.get(Result()) return "Fail: setAccessible(false) had no effect" diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVar.kt b/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVar.kt index 3762d26cd52..3bd9f4d3321 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVar.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateClassVar.kt @@ -1,5 +1,5 @@ import kotlin.reflect.* -import kotlin.reflect.jvm.accessible +import kotlin.reflect.jvm.isAccessible class A { private var value = 0 @@ -15,12 +15,12 @@ fun box(): String { return "Fail: private property is accessible by default" } catch(e: IllegalPropertyAccessException) { } - p.accessible = true + p.isAccessible = true p.set(a, 2) p.get(a) - p.accessible = false + p.isAccessible = false try { p.set(a, 3) return "Fail: setAccessible(false) had no effect" diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateToThisAccessors.kt b/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateToThisAccessors.kt index 1a3a6a8d801..996eacc4a41 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateToThisAccessors.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/properties/privateToThisAccessors.kt @@ -7,7 +7,7 @@ class K { fun run(): String { val p = ::t - p.accessible = true + p.isAccessible = true p.set(this, "" as T) return p.get(this) } diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/properties/protectedClassVar.kt b/compiler/testData/codegen/boxWithStdlib/reflection/properties/protectedClassVar.kt index cbf8856c6eb..d8797af8f1f 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/properties/protectedClassVar.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/properties/protectedClassVar.kt @@ -1,5 +1,5 @@ import kotlin.reflect.* -import kotlin.reflect.jvm.accessible +import kotlin.reflect.jvm.isAccessible class A(param: String) { protected var v: String = param @@ -21,7 +21,7 @@ fun box(): String { return "Fail: protected property setter is accessible by default" } catch (e: IllegalPropertyAccessException) { } - f.accessible = true + f.isAccessible = true f.set(a, ":)") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index f4ad2ff54c5..1c15dbaff2b 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -2775,6 +2775,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection/call"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("cannotCallEnumConstructor.kt") + public void testCannotCallEnumConstructor() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/call/cannotCallEnumConstructor.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("equalsHashCodeToString.kt") public void testEqualsHashCodeToString() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/call/equalsHashCodeToString.kt"); diff --git a/core/reflection.jvm/src/kotlin/reflect/exceptions.kt b/core/reflection.jvm/src/kotlin/reflect/exceptions.kt index 7a0a7914a02..2f934081bc9 100644 --- a/core/reflection.jvm/src/kotlin/reflect/exceptions.kt +++ b/core/reflection.jvm/src/kotlin/reflect/exceptions.kt @@ -22,7 +22,7 @@ package kotlin.reflect * * @param cause the original exception thrown by the JVM. * - * @see [kotlin.reflect.jvm.accessible] + * @see [kotlin.reflect.jvm.isAccessible] */ public class IllegalPropertyAccessException(cause: IllegalAccessException) : Exception(cause.getMessage()) { init { diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/_Deprecated.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/_Deprecated.kt index 6a8ebd5bf43..537a3539db8 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/_Deprecated.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/_Deprecated.kt @@ -39,3 +39,9 @@ public val KClass.declaredProperties: Collection> @deprecated("Use declaredMemberExtensionProperties instead.", ReplaceWith("declaredMemberExtensionProperties")) public val KClass.declaredExtensionProperties: Collection> get() = declaredMemberExtensionProperties + + +@deprecated("Use isAccessible instead.", ReplaceWith("isAccessible")) +public var KProperty<*>.accessible: Boolean + get() = isAccessible + set(value) { isAccessible = value } diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/callables.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/callables.kt new file mode 100644 index 00000000000..a25fd8dcd59 --- /dev/null +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/callables.kt @@ -0,0 +1,68 @@ +/* + * 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 + +import kotlin.reflect.KCallable +import kotlin.reflect.KFunction +import kotlin.reflect.KMutableProperty +import kotlin.reflect.KProperty + +/** + * Provides a way to suppress JVM access checks for a callable. + * + * @getter returns `true` if JVM access checks are suppressed for this callable object. + * For a property, that means that all its accessors (getter, and setter for `var` properties) are accessible. + * + * @setter if set to `true`, suppresses JVM access checks for this callable object. + * For a property, both accessors are made accessible. + * + * @see [java.lang.reflect.AccessibleObject] + */ +public var KCallable<*>.isAccessible: Boolean + get() { + return when (this) { + is KMutableProperty -> + javaField?.isAccessible ?: true && + javaGetter?.isAccessible ?: true && + javaSetter?.isAccessible ?: true + is KProperty -> + javaField?.isAccessible ?: true && + javaGetter?.isAccessible ?: true + is KFunction -> + javaMethod?.isAccessible ?: true && + this.javaConstructor?.isAccessible ?: true + else -> throw UnsupportedOperationException("Unknown callable: $this ($javaClass)") + } + } + set(value) { + when (this) { + is KMutableProperty -> { + javaField?.isAccessible = value + javaGetter?.isAccessible = value + javaSetter?.isAccessible = value + } + is KProperty -> { + javaField?.isAccessible = value + javaGetter?.isAccessible = value + } + is KFunction -> { + javaMethod?.isAccessible = value + this.javaConstructor?.isAccessible = value + } + else -> throw UnsupportedOperationException("Unknown callable: $this ($javaClass)") + } + } diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/properties.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/properties.kt deleted file mode 100644 index d3b40bc1b31..00000000000 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/properties.kt +++ /dev/null @@ -1,60 +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 - -import kotlin.reflect.KProperty -import kotlin.reflect.jvm.internal.KMutablePropertyImpl -import kotlin.reflect.jvm.internal.KPropertyImpl - -/** - * Provides a way to suppress JVM access checks for a property. - * - * @getter returns `true` if JVM access checks are suppressed for this property object. - * In case of a `var` property, that means that both getter and setter are accessible. - * - * @setter if set to `true`, suppresses JVM access checks for this property object. - * In case of a `var` property, both getter and setter are made accessible. - * - * @see [java.lang.reflect.AccessibleObject] - */ -public var KProperty.accessible: Boolean - get() { - return when (this) { - is KMutablePropertyImpl -> - javaField?.isAccessible() ?: true && - javaGetter?.isAccessible() ?: true && - javaSetter?.isAccessible() ?: true - is KPropertyImpl -> - javaField?.isAccessible() ?: true && - javaGetter?.isAccessible() ?: true - else -> throw UnsupportedOperationException("Unknown property: $this ($javaClass)") - } - } - set(value) { - when (this) { - is KMutablePropertyImpl -> { - javaField?.setAccessible(value) - javaGetter?.setAccessible(value) - javaSetter?.setAccessible(value) - } - is KPropertyImpl -> { - javaField?.setAccessible(value) - javaGetter?.setAccessible(value) - } - else -> throw UnsupportedOperationException("Unknown property: $this ($javaClass)") - } - }