Improve implementation of callable reference superclasses
Previously to use reflection on them, you had to wrap an already created object with a "Reflection.function" or "Reflection.propertyN" call, which the JVM back-end was doing. This was not optimal in several senses and current solution fixes that
This commit is contained in:
+20
@@ -0,0 +1,20 @@
|
|||||||
|
import kotlin.reflect.*
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class A {
|
||||||
|
fun foo() = "foo"
|
||||||
|
val bar = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkEqual(x: Any, y: Any) {
|
||||||
|
assertEquals(x, y)
|
||||||
|
assertEquals(y, x)
|
||||||
|
assertEquals(x.hashCode(), y.hashCode())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
checkEqual(A::foo, A::class.members.single { it.name == "foo" })
|
||||||
|
checkEqual(A::bar, A::class.members.single { it.name == "bar" })
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+6
@@ -3912,6 +3912,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny"), Pattern.compile("^(.+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("callableReferencesEqualToCallablesFromAPI.kt")
|
||||||
|
public void testCallableReferencesEqualToCallablesFromAPI() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/callableReferencesEqualToCallablesFromAPI.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("classToString.kt")
|
@TestMetadata("classToString.kt")
|
||||||
public void testClassToString() throws Exception {
|
public void testClassToString() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/classToString.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/classToString.kt");
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import kotlin.reflect.KCallable
|
|||||||
import kotlin.reflect.KFunction
|
import kotlin.reflect.KFunction
|
||||||
import kotlin.reflect.KMutableProperty
|
import kotlin.reflect.KMutableProperty
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
import kotlin.reflect.jvm.internal.KCallableImpl
|
import kotlin.reflect.jvm.internal.asKCallableImpl
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a way to suppress JVM access checks for a callable.
|
* Provides a way to suppress JVM access checks for a callable.
|
||||||
@@ -53,7 +53,7 @@ public var KCallable<*>.isAccessible: Boolean
|
|||||||
javaMethod?.isAccessible ?: true
|
javaMethod?.isAccessible ?: true
|
||||||
is KFunction ->
|
is KFunction ->
|
||||||
javaMethod?.isAccessible ?: true &&
|
javaMethod?.isAccessible ?: true &&
|
||||||
((this as? KCallableImpl<*>)?.defaultCaller?.member as? AccessibleObject)?.isAccessible ?: true &&
|
(this.asKCallableImpl()?.defaultCaller?.member as? AccessibleObject)?.isAccessible ?: true &&
|
||||||
this.javaConstructor?.isAccessible ?: true
|
this.javaConstructor?.isAccessible ?: true
|
||||||
else -> throw UnsupportedOperationException("Unknown callable: $this ($javaClass)")
|
else -> throw UnsupportedOperationException("Unknown callable: $this ($javaClass)")
|
||||||
}
|
}
|
||||||
@@ -79,7 +79,7 @@ public var KCallable<*>.isAccessible: Boolean
|
|||||||
}
|
}
|
||||||
is KFunction -> {
|
is KFunction -> {
|
||||||
javaMethod?.isAccessible = value
|
javaMethod?.isAccessible = value
|
||||||
((this as? KCallableImpl<*>)?.defaultCaller?.member as? AccessibleObject)?.isAccessible = true
|
(this.asKCallableImpl()?.defaultCaller?.member as? AccessibleObject)?.isAccessible = true
|
||||||
this.javaConstructor?.isAccessible = value
|
this.javaConstructor?.isAccessible = value
|
||||||
}
|
}
|
||||||
else -> throw UnsupportedOperationException("Unknown callable: $this ($javaClass)")
|
else -> throw UnsupportedOperationException("Unknown callable: $this ($javaClass)")
|
||||||
|
|||||||
@@ -23,8 +23,9 @@ import kotlin.jvm.internal.KotlinFileFacade
|
|||||||
import kotlin.jvm.internal.Reflection
|
import kotlin.jvm.internal.Reflection
|
||||||
import kotlin.reflect.*
|
import kotlin.reflect.*
|
||||||
import kotlin.reflect.jvm.internal.KCallableImpl
|
import kotlin.reflect.jvm.internal.KCallableImpl
|
||||||
import kotlin.reflect.jvm.internal.KPropertyImpl
|
|
||||||
import kotlin.reflect.jvm.internal.KTypeImpl
|
import kotlin.reflect.jvm.internal.KTypeImpl
|
||||||
|
import kotlin.reflect.jvm.internal.asKCallableImpl
|
||||||
|
import kotlin.reflect.jvm.internal.asKPropertyImpl
|
||||||
|
|
||||||
// Kotlin reflection -> Java reflection
|
// Kotlin reflection -> Java reflection
|
||||||
|
|
||||||
@@ -33,7 +34,7 @@ import kotlin.reflect.jvm.internal.KTypeImpl
|
|||||||
* or `null` if the property has no backing field.
|
* or `null` if the property has no backing field.
|
||||||
*/
|
*/
|
||||||
public val KProperty<*>.javaField: Field?
|
public val KProperty<*>.javaField: Field?
|
||||||
get() = (this as? KPropertyImpl<*>)?.javaField
|
get() = this.asKPropertyImpl()?.javaField
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a Java [Method] instance corresponding to the getter of the given property,
|
* Returns a Java [Method] instance corresponding to the getter of the given property,
|
||||||
@@ -55,7 +56,7 @@ public val KMutableProperty<*>.javaSetter: Method?
|
|||||||
* or `null` if this function is a constructor or cannot be represented by a Java [Method].
|
* or `null` if this function is a constructor or cannot be represented by a Java [Method].
|
||||||
*/
|
*/
|
||||||
public val KFunction<*>.javaMethod: Method?
|
public val KFunction<*>.javaMethod: Method?
|
||||||
get() = (this as? KCallableImpl<*>)?.caller?.member as? Method
|
get() = this.asKCallableImpl()?.caller?.member as? Method
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a Java [Constructor] instance corresponding to the given Kotlin function,
|
* Returns a Java [Constructor] instance corresponding to the given Kotlin function,
|
||||||
@@ -63,7 +64,7 @@ public val KFunction<*>.javaMethod: Method?
|
|||||||
*/
|
*/
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
public val <T> KFunction<T>.javaConstructor: Constructor<T>?
|
public val <T> KFunction<T>.javaConstructor: Constructor<T>?
|
||||||
get() = (this as? KCallableImpl<T>)?.caller?.member as? Constructor<T>
|
get() = this.asKCallableImpl()?.caller?.member as? Constructor<T>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -19,13 +19,14 @@ package kotlin.reflect.jvm.internal
|
|||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
import kotlin.reflect.jvm.internal.JvmPropertySignature.JavaField
|
import kotlin.reflect.jvm.internal.JvmPropertySignature.JavaField
|
||||||
import kotlin.reflect.jvm.internal.JvmPropertySignature.KotlinProperty
|
import kotlin.reflect.jvm.internal.JvmPropertySignature.KotlinProperty
|
||||||
|
|
||||||
internal abstract class DescriptorBasedProperty<out R> protected constructor(
|
internal abstract class DescriptorBasedProperty<out R> protected constructor(
|
||||||
val container: KDeclarationContainerImpl,
|
val container: KDeclarationContainerImpl,
|
||||||
name: String,
|
name: String,
|
||||||
signature: String,
|
val signature: String,
|
||||||
descriptorInitialValue: PropertyDescriptor?
|
descriptorInitialValue: PropertyDescriptor?
|
||||||
) : KCallableImpl<R> {
|
) : KCallableImpl<R> {
|
||||||
constructor(container: KDeclarationContainerImpl, name: String, signature: String) : this(
|
constructor(container: KDeclarationContainerImpl, name: String, signature: String) : this(
|
||||||
@@ -55,11 +56,13 @@ internal abstract class DescriptorBasedProperty<out R> protected constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean =
|
override fun equals(other: Any?): Boolean {
|
||||||
other is DescriptorBasedProperty<*> && descriptor == other.descriptor
|
val that = other.asKPropertyImpl() ?: return false
|
||||||
|
return container == that.container && name == that.name && signature == that.signature
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int =
|
override fun hashCode(): Int =
|
||||||
descriptor.hashCode()
|
(container.hashCode() * 31 + name.hashCode()) * 31 + signature.hashCode()
|
||||||
|
|
||||||
override fun toString(): String =
|
override fun toString(): String =
|
||||||
ReflectionObjectRenderer.renderProperty(descriptor)
|
ReflectionObjectRenderer.renderProperty(descriptor)
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import kotlin.reflect.jvm.internal.JvmFunctionSignature.*
|
|||||||
internal open class KFunctionImpl protected constructor(
|
internal open class KFunctionImpl protected constructor(
|
||||||
private val container: KDeclarationContainerImpl,
|
private val container: KDeclarationContainerImpl,
|
||||||
name: String,
|
name: String,
|
||||||
signature: String,
|
private val signature: String,
|
||||||
descriptorInitialValue: FunctionDescriptor?
|
descriptorInitialValue: FunctionDescriptor?
|
||||||
) : KFunction<Any?>, KCallableImpl<Any?>, FunctionImpl() {
|
) : KFunction<Any?>, KCallableImpl<Any?>, FunctionImpl() {
|
||||||
constructor(container: KDeclarationContainerImpl, name: String, signature: String) : this(container, name, signature, null)
|
constructor(container: KDeclarationContainerImpl, name: String, signature: String) : this(container, name, signature, null)
|
||||||
@@ -104,11 +104,13 @@ internal open class KFunctionImpl protected constructor(
|
|||||||
(if (descriptor.extensionReceiverParameter != null) 1 else 0)
|
(if (descriptor.extensionReceiverParameter != null) 1 else 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean =
|
override fun equals(other: Any?): Boolean {
|
||||||
other is KFunctionImpl && descriptor == other.descriptor
|
val that = other.asKFunctionImpl() ?: return false
|
||||||
|
return container == that.container && name == that.name && signature == that.signature
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int =
|
override fun hashCode(): Int =
|
||||||
descriptor.hashCode()
|
(container.hashCode() * 31 + name.hashCode()) * 31 + signature.hashCode()
|
||||||
|
|
||||||
override fun toString(): String =
|
override fun toString(): String =
|
||||||
ReflectionObjectRenderer.renderFunction(descriptor)
|
ReflectionObjectRenderer.renderFunction(descriptor)
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ internal interface KPropertyImpl<out R> : KProperty<R>, KCallableImpl<R> {
|
|||||||
|
|
||||||
val container: KDeclarationContainerImpl
|
val container: KDeclarationContainerImpl
|
||||||
|
|
||||||
|
val signature: String
|
||||||
|
|
||||||
override val getter: Getter<R>
|
override val getter: Getter<R>
|
||||||
|
|
||||||
override val descriptor: PropertyDescriptor
|
override val descriptor: PropertyDescriptor
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
package kotlin.reflect.jvm.internal
|
package kotlin.reflect.jvm.internal
|
||||||
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import kotlin.jvm.internal.FunctionReference
|
||||||
|
import kotlin.jvm.internal.PropertyReference
|
||||||
import kotlin.reflect.IllegalCallableAccessException
|
import kotlin.reflect.IllegalCallableAccessException
|
||||||
|
|
||||||
internal val JVM_STATIC = FqName("kotlin.jvm.JvmStatic")
|
internal val JVM_STATIC = FqName("kotlin.jvm.JvmStatic")
|
||||||
@@ -29,3 +31,14 @@ internal inline fun <R> reflectionCall(block: () -> R): R =
|
|||||||
catch (e: IllegalAccessException) {
|
catch (e: IllegalAccessException) {
|
||||||
throw IllegalCallableAccessException(e)
|
throw IllegalCallableAccessException(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun Any?.asKFunctionImpl(): KFunctionImpl? =
|
||||||
|
this as? KFunctionImpl ?:
|
||||||
|
(this as? FunctionReference)?.compute() as? KFunctionImpl //
|
||||||
|
|
||||||
|
internal fun Any?.asKPropertyImpl(): KPropertyImpl<*>? =
|
||||||
|
this as? KPropertyImpl<*> ?:
|
||||||
|
(this as? PropertyReference)?.compute() as? KPropertyImpl
|
||||||
|
|
||||||
|
internal fun Any?.asKCallableImpl(): KCallableImpl<*>? =
|
||||||
|
this as? KCallableImpl<*> ?: asKFunctionImpl() ?: asKPropertyImpl()
|
||||||
|
|||||||
@@ -17,10 +17,7 @@
|
|||||||
package kotlin.jvm.internal;
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
import kotlin.jvm.KotlinReflectionNotSupportedError;
|
import kotlin.jvm.KotlinReflectionNotSupportedError;
|
||||||
import kotlin.reflect.KCallable;
|
import kotlin.reflect.*;
|
||||||
import kotlin.reflect.KDeclarationContainer;
|
|
||||||
import kotlin.reflect.KParameter;
|
|
||||||
import kotlin.reflect.KType;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
@@ -32,7 +29,11 @@ import java.util.Map;
|
|||||||
*
|
*
|
||||||
* All methods from reflection API should be implemented here to throw informative exceptions (see KotlinReflectionNotSupportedError)
|
* All methods from reflection API should be implemented here to throw informative exceptions (see KotlinReflectionNotSupportedError)
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings({"unchecked", "NullableProblems"})
|
||||||
public abstract class CallableReference implements KCallable {
|
public abstract class CallableReference implements KCallable {
|
||||||
|
protected KCallable reflected;
|
||||||
|
|
||||||
|
protected abstract KCallable computeReflected();
|
||||||
|
|
||||||
// The following methods provide the information identifying this callable, which is used by the reflection implementation.
|
// The following methods provide the information identifying this callable, which is used by the reflection implementation.
|
||||||
// They are supposed to be overridden in each subclass (each anonymous class generated for a callable reference).
|
// They are supposed to be overridden in each subclass (each anonymous class generated for a callable reference).
|
||||||
@@ -41,7 +42,7 @@ public abstract class CallableReference implements KCallable {
|
|||||||
* @return the class or package where the callable should be located, usually specified on the LHS of the '::' operator
|
* @return the class or package where the callable should be located, usually specified on the LHS of the '::' operator
|
||||||
*/
|
*/
|
||||||
public KDeclarationContainer getOwner() {
|
public KDeclarationContainer getOwner() {
|
||||||
throw error();
|
throw new AbstractMethodError();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,7 +50,7 @@ public abstract class CallableReference implements KCallable {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
throw error();
|
throw new AbstractMethodError();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,7 +62,7 @@ public abstract class CallableReference implements KCallable {
|
|||||||
* but only as a unique and unambiguous way to map a function/property descriptor to a string.
|
* but only as a unique and unambiguous way to map a function/property descriptor to a string.
|
||||||
*/
|
*/
|
||||||
public String getSignature() {
|
public String getSignature() {
|
||||||
throw error();
|
throw new AbstractMethodError();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following methods are the stub implementations of reflection functions.
|
// The following methods are the stub implementations of reflection functions.
|
||||||
@@ -69,30 +70,41 @@ public abstract class CallableReference implements KCallable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<KParameter> getParameters() {
|
public List<KParameter> getParameters() {
|
||||||
throw error();
|
return getReflected().getParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KType getReturnType() {
|
public KType getReturnType() {
|
||||||
throw error();
|
return getReflected().getReturnType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Annotation> getAnnotations() {
|
public List<Annotation> getAnnotations() {
|
||||||
throw error();
|
return getReflected().getAnnotations();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call(@NotNull Object... args) {
|
public Object call(@NotNull Object... args) {
|
||||||
throw error();
|
return getReflected().call(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object callBy(@NotNull Map args) {
|
public Object callBy(@NotNull Map args) {
|
||||||
throw error();
|
return getReflected().callBy(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Error error() {
|
public KCallable compute() {
|
||||||
throw new KotlinReflectionNotSupportedError();
|
if (reflected == null) {
|
||||||
|
reflected = computeReflected();
|
||||||
|
}
|
||||||
|
return reflected;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected KCallable getReflected() {
|
||||||
|
compute();
|
||||||
|
if (reflected == this) {
|
||||||
|
throw new KotlinReflectionNotSupportedError();
|
||||||
|
}
|
||||||
|
return reflected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,15 +17,20 @@
|
|||||||
package kotlin.jvm.internal;
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
import kotlin.jvm.KotlinReflectionNotSupportedError;
|
import kotlin.jvm.KotlinReflectionNotSupportedError;
|
||||||
import kotlin.reflect.*;
|
import kotlin.reflect.KDeclarationContainer;
|
||||||
|
import kotlin.reflect.KFunction;
|
||||||
|
import kotlin.reflect.KParameter;
|
||||||
|
import kotlin.reflect.KType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "NullableProblems"})
|
||||||
public class FunctionReference extends FunctionImpl implements KFunction {
|
public class FunctionReference extends FunctionImpl implements KFunction {
|
||||||
private final int arity;
|
private final int arity;
|
||||||
|
private KFunction reflected;
|
||||||
|
|
||||||
public FunctionReference(int arity) {
|
public FunctionReference(int arity) {
|
||||||
this.arity = arity;
|
this.arity = arity;
|
||||||
@@ -39,56 +44,57 @@ public class FunctionReference extends FunctionImpl implements KFunction {
|
|||||||
// Most of the following methods are copies from CallableReference, since this class cannot inherit from it
|
// Most of the following methods are copies from CallableReference, since this class cannot inherit from it
|
||||||
|
|
||||||
public KDeclarationContainer getOwner() {
|
public KDeclarationContainer getOwner() {
|
||||||
throw error();
|
throw new AbstractMethodError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
throw error();
|
throw new AbstractMethodError();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSignature() {
|
public String getSignature() {
|
||||||
throw error();
|
throw new AbstractMethodError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<KParameter> getParameters() {
|
public List<KParameter> getParameters() {
|
||||||
throw error();
|
return getReflected().getParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KType getReturnType() {
|
public KType getReturnType() {
|
||||||
throw error();
|
return getReflected().getReturnType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Annotation> getAnnotations() {
|
public List<Annotation> getAnnotations() {
|
||||||
throw error();
|
return getReflected().getAnnotations();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call(@NotNull Object... args) {
|
public Object call(@NotNull Object... args) {
|
||||||
throw error();
|
return getReflected().call(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object callBy(@NotNull Map args) {
|
public Object callBy(@NotNull Map args) {
|
||||||
throw error();
|
return getReflected().callBy(args);
|
||||||
}
|
|
||||||
|
|
||||||
protected static Error error() {
|
|
||||||
throw new KotlinReflectionNotSupportedError();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (obj == this) return true;
|
if (obj == this) return true;
|
||||||
if (!(obj instanceof FunctionReference)) return false;
|
if (obj instanceof FunctionReference) {
|
||||||
|
FunctionReference other = (FunctionReference) obj;
|
||||||
FunctionReference other = (FunctionReference) obj;
|
return getOwner().equals(other.getOwner()) &&
|
||||||
return getOwner().equals(other.getOwner()) &&
|
getName().equals(other.getName()) &&
|
||||||
getName().equals(other.getName()) &&
|
getSignature().equals(other.getSignature());
|
||||||
getSignature().equals(other.getSignature());
|
}
|
||||||
|
if (obj instanceof KFunction) {
|
||||||
|
compute();
|
||||||
|
return obj.equals(reflected);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -98,9 +104,29 @@ public class FunctionReference extends FunctionImpl implements KFunction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
compute();
|
||||||
|
if (reflected != this) {
|
||||||
|
return reflected.toString();
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: consider adding the class name to toString() for constructors
|
// TODO: consider adding the class name to toString() for constructors
|
||||||
return "<init>".equals(getName())
|
return "<init>".equals(getName())
|
||||||
? "constructor" + Reflection.REFLECTION_NOT_AVAILABLE
|
? "constructor" + Reflection.REFLECTION_NOT_AVAILABLE
|
||||||
: "function " + getName() + Reflection.REFLECTION_NOT_AVAILABLE;
|
: "function " + getName() + Reflection.REFLECTION_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KFunction compute() {
|
||||||
|
if (reflected == null) {
|
||||||
|
reflected = Reflection.function(this);
|
||||||
|
}
|
||||||
|
return reflected;
|
||||||
|
}
|
||||||
|
|
||||||
|
private KFunction getReflected() {
|
||||||
|
compute();
|
||||||
|
if (reflected == this) {
|
||||||
|
throw new KotlinReflectionNotSupportedError();
|
||||||
|
}
|
||||||
|
return reflected;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,27 +16,33 @@
|
|||||||
|
|
||||||
package kotlin.jvm.internal;
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
|
import kotlin.reflect.KCallable;
|
||||||
import kotlin.reflect.KMutableProperty0;
|
import kotlin.reflect.KMutableProperty0;
|
||||||
import kotlin.reflect.KProperty0;
|
import kotlin.reflect.KProperty0;
|
||||||
|
|
||||||
public class MutablePropertyReference0 extends MutablePropertyReference implements KMutableProperty0 {
|
public class MutablePropertyReference0 extends MutablePropertyReference implements KMutableProperty0 {
|
||||||
|
@Override
|
||||||
|
protected KCallable computeReflected() {
|
||||||
|
return Reflection.mutableProperty0(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object get() {
|
public Object get() {
|
||||||
throw error();
|
return ((KMutableProperty0) getReflected()).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void set(Object value) {
|
public void set(Object value) {
|
||||||
throw error();
|
((KMutableProperty0) getReflected()).set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KProperty0.Getter getGetter() {
|
public KProperty0.Getter getGetter() {
|
||||||
throw error();
|
return ((KMutableProperty0) getReflected()).getGetter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KMutableProperty0.Setter getSetter() {
|
public KMutableProperty0.Setter getSetter() {
|
||||||
throw error();
|
return ((KMutableProperty0) getReflected()).getSetter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,27 +16,33 @@
|
|||||||
|
|
||||||
package kotlin.jvm.internal;
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
|
import kotlin.reflect.KCallable;
|
||||||
import kotlin.reflect.KMutableProperty1;
|
import kotlin.reflect.KMutableProperty1;
|
||||||
import kotlin.reflect.KProperty1;
|
import kotlin.reflect.KProperty1;
|
||||||
|
|
||||||
public class MutablePropertyReference1 extends MutablePropertyReference implements KMutableProperty1 {
|
public class MutablePropertyReference1 extends MutablePropertyReference implements KMutableProperty1 {
|
||||||
|
@Override
|
||||||
|
protected KCallable computeReflected() {
|
||||||
|
return Reflection.mutableProperty1(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object get(Object receiver) {
|
public Object get(Object receiver) {
|
||||||
throw error();
|
return ((KMutableProperty1) getReflected()).get(receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void set(Object receiver, Object value) {
|
public void set(Object receiver, Object value) {
|
||||||
throw error();
|
((KMutableProperty1) getReflected()).set(receiver, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KProperty1.Getter getGetter() {
|
public KProperty1.Getter getGetter() {
|
||||||
throw error();
|
return ((KMutableProperty1) getReflected()).getGetter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KMutableProperty1.Setter getSetter() {
|
public KMutableProperty1.Setter getSetter() {
|
||||||
throw error();
|
return ((KMutableProperty1) getReflected()).getSetter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,27 +16,33 @@
|
|||||||
|
|
||||||
package kotlin.jvm.internal;
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
|
import kotlin.reflect.KCallable;
|
||||||
import kotlin.reflect.KMutableProperty2;
|
import kotlin.reflect.KMutableProperty2;
|
||||||
import kotlin.reflect.KProperty2;
|
import kotlin.reflect.KProperty2;
|
||||||
|
|
||||||
public class MutablePropertyReference2 extends MutablePropertyReference implements KMutableProperty2 {
|
public class MutablePropertyReference2 extends MutablePropertyReference implements KMutableProperty2 {
|
||||||
|
@Override
|
||||||
|
protected KCallable computeReflected() {
|
||||||
|
return Reflection.mutableProperty2(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object get(Object receiver1, Object receiver2) {
|
public Object get(Object receiver1, Object receiver2) {
|
||||||
throw error();
|
return ((KMutableProperty2) getReflected()).get(receiver1, receiver2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void set(Object receiver1, Object receiver2, Object value) {
|
public void set(Object receiver1, Object receiver2, Object value) {
|
||||||
throw error();
|
((KMutableProperty2) getReflected()).set(receiver1, receiver2, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KProperty2.Getter getGetter() {
|
public KProperty2.Getter getGetter() {
|
||||||
throw error();
|
return ((KMutableProperty2) getReflected()).getGetter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KMutableProperty2.Setter getSetter() {
|
public KMutableProperty2.Setter getSetter() {
|
||||||
throw error();
|
return ((KMutableProperty2) getReflected()).getSetter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,12 +22,17 @@ public abstract class PropertyReference extends CallableReference implements KPr
|
|||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (obj == this) return true;
|
if (obj == this) return true;
|
||||||
if (!(obj instanceof PropertyReference)) return false;
|
if (obj instanceof PropertyReference) {
|
||||||
|
PropertyReference other = (PropertyReference) obj;
|
||||||
PropertyReference other = (PropertyReference) obj;
|
return getOwner().equals(other.getOwner()) &&
|
||||||
return getOwner().equals(other.getOwner()) &&
|
getName().equals(other.getName()) &&
|
||||||
getName().equals(other.getName()) &&
|
getSignature().equals(other.getSignature());
|
||||||
getSignature().equals(other.getSignature());
|
}
|
||||||
|
if (obj instanceof KProperty) {
|
||||||
|
compute();
|
||||||
|
return obj.equals(reflected);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -37,6 +42,11 @@ public abstract class PropertyReference extends CallableReference implements KPr
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
compute();
|
||||||
|
if (reflected != this) {
|
||||||
|
return reflected.toString();
|
||||||
|
}
|
||||||
|
|
||||||
return "property " + getName() + Reflection.REFLECTION_NOT_AVAILABLE;
|
return "property " + getName() + Reflection.REFLECTION_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,16 +16,22 @@
|
|||||||
|
|
||||||
package kotlin.jvm.internal;
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
|
import kotlin.reflect.KCallable;
|
||||||
import kotlin.reflect.KProperty0;
|
import kotlin.reflect.KProperty0;
|
||||||
|
|
||||||
public class PropertyReference0 extends PropertyReference implements KProperty0 {
|
public class PropertyReference0 extends PropertyReference implements KProperty0 {
|
||||||
|
@Override
|
||||||
|
protected KCallable computeReflected() {
|
||||||
|
return Reflection.property0(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object get() {
|
public Object get() {
|
||||||
throw error();
|
return ((KProperty0) getReflected()).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KProperty0.Getter getGetter() {
|
public KProperty0.Getter getGetter() {
|
||||||
throw error();
|
return ((KProperty0) getReflected()).getGetter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,16 +16,22 @@
|
|||||||
|
|
||||||
package kotlin.jvm.internal;
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
|
import kotlin.reflect.KCallable;
|
||||||
import kotlin.reflect.KProperty1;
|
import kotlin.reflect.KProperty1;
|
||||||
|
|
||||||
public class PropertyReference1 extends PropertyReference implements KProperty1 {
|
public class PropertyReference1 extends PropertyReference implements KProperty1 {
|
||||||
|
@Override
|
||||||
|
protected KCallable computeReflected() {
|
||||||
|
return Reflection.property1(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object get(Object receiver) {
|
public Object get(Object receiver) {
|
||||||
throw error();
|
return ((KProperty1) getReflected()).get(receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KProperty1.Getter getGetter() {
|
public KProperty1.Getter getGetter() {
|
||||||
throw error();
|
return ((KProperty1) getReflected()).getGetter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,16 +16,22 @@
|
|||||||
|
|
||||||
package kotlin.jvm.internal;
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
|
import kotlin.reflect.KCallable;
|
||||||
import kotlin.reflect.KProperty2;
|
import kotlin.reflect.KProperty2;
|
||||||
|
|
||||||
public class PropertyReference2 extends PropertyReference implements KProperty2 {
|
public class PropertyReference2 extends PropertyReference implements KProperty2 {
|
||||||
|
@Override
|
||||||
|
protected KCallable computeReflected() {
|
||||||
|
return Reflection.property2(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object get(Object receiver1, Object receiver2) {
|
public Object get(Object receiver1, Object receiver2) {
|
||||||
throw error();
|
return ((KProperty2) getReflected()).get(receiver1, receiver2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KProperty2.Getter getGetter() {
|
public KProperty2.Getter getGetter() {
|
||||||
throw error();
|
return ((KProperty2) getReflected()).getGetter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user