Fail with IllegalAccessException on :: reference to private property

Instead of mysterious NoSuchMethodException
This commit is contained in:
Alexander Udalov
2014-06-05 16:51:25 +04:00
parent a8e1de48b8
commit 1275c84f92
4 changed files with 34 additions and 2 deletions
@@ -0,0 +1,15 @@
class Result {
private val value = "OK"
fun ref(): KMemberProperty<Result, String> = ::value
}
fun box(): String {
val p = Result().ref()
try {
p.get(Result())
return "Fail: private property is accessible by default"
} catch(e: IllegalAccessException) { }
return "OK"
}
@@ -454,6 +454,11 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/callableReference/property/overriddenInSubclass.kt");
}
@TestMetadata("privateClassVal.kt")
public void testPrivateClassVal() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/callableReference/property/privateClassVal.kt");
}
@TestMetadata("simpleExtension.kt")
public void testSimpleExtension() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/callableReference/property/simpleExtension.kt");
@@ -32,7 +32,7 @@ open class KMemberPropertyImpl<T, out R>(
// TODO: extract, make lazy (weak?), use our descriptors knowledge
protected val getter: Method? =
if (owner.origin == KClassOrigin.KOTLIN) {
owner.jClass.getMethod(getterName(name))
owner.jClass.getMaybeDeclaredMethod(getterName(name))
}
else null
@@ -51,7 +51,7 @@ class KMutableMemberPropertyImpl<T, R>(
) : KMutableMemberProperty<T, R>, KMemberPropertyImpl<T, R>(name, owner) {
private val setter: Method? =
if (owner.origin == KClassOrigin.KOTLIN) {
owner.jClass.getMethod(setterName(name), getter!!.getReturnType()!!)
owner.jClass.getMaybeDeclaredMethod(setterName(name), getter!!.getReturnType()!!)
}
else null
@@ -16,6 +16,7 @@
package kotlin.reflect.jvm.internal
import java.lang.reflect.Method
import java.util.concurrent.ConcurrentHashMap
// TODO: use stdlib?
@@ -34,6 +35,17 @@ private fun getterName(propertyName: String): String = "get" + propertyName.capi
private fun setterName(propertyName: String): String = "set" + propertyName.capitalizeWithJavaBeanConvention()
private fun Class<*>.getMaybeDeclaredMethod(name: String, vararg parameterTypes: Class<*>): Method {
try {
return getMethod(name, *parameterTypes)
}
catch (e: NoSuchMethodException) {
// This is needed to support private methods
return getDeclaredMethod(name, *parameterTypes)
}
}
// TODO: should use weak references
private val foreignKClasses: MutableMap<Class<*>, KClassImpl<*>> = ConcurrentHashMap()