Inherit FunctionReference from CallableReference
This became possible now because FunctionImpl is no longer a class
This commit is contained in:
@@ -105,9 +105,4 @@ public class ReflectionFactoryImpl extends ReflectionFactory {
|
||||
KDeclarationContainer owner = reference.getOwner();
|
||||
return owner instanceof KDeclarationContainerImpl ? ((KDeclarationContainerImpl) owner) : EmptyContainerForLocal.INSTANCE;
|
||||
}
|
||||
|
||||
private static KDeclarationContainerImpl getOwner(FunctionReference reference) {
|
||||
KDeclarationContainer owner = reference.getOwner();
|
||||
return owner instanceof KDeclarationContainerImpl ? ((KDeclarationContainerImpl) owner) : EmptyContainerForLocal.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,14 +28,36 @@ import java.util.Map;
|
||||
/**
|
||||
* A superclass for all classes generated by Kotlin compiler for callable references.
|
||||
*
|
||||
* All methods from reflection API should be implemented here to throw informative exceptions (see KotlinReflectionNotSupportedError)
|
||||
* All methods from KCallable should be implemented here and should delegate to the actual implementation, loaded dynamically
|
||||
* and stored in the {@link CallableReference#reflected} field.
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "NullableProblems"})
|
||||
public abstract class CallableReference implements KCallable {
|
||||
protected KCallable reflected;
|
||||
// This field is not volatile intentionally:
|
||||
// 1) It's fine if the value is computed multiple times in different threads;
|
||||
// 2) An uninitialized value cannot be observed in this field from other thread because only already initialized or safely initialized
|
||||
// objects are written to it. The latter is guaranteed because both KFunctionImpl and KPropertyImpl have at least one final field.
|
||||
private KCallable reflected;
|
||||
|
||||
protected abstract KCallable computeReflected();
|
||||
|
||||
public KCallable compute() {
|
||||
KCallable result = reflected;
|
||||
if (result == null) {
|
||||
result = computeReflected();
|
||||
reflected = result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected KCallable getReflected() {
|
||||
KCallable result = compute();
|
||||
if (result == this) {
|
||||
throw new KotlinReflectionNotSupportedError();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 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).
|
||||
|
||||
@@ -66,8 +88,8 @@ public abstract class CallableReference implements KCallable {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
|
||||
// The following methods are the stub implementations of reflection functions.
|
||||
// They are called when you're using reflection on a property reference without the reflection implementation in the classpath.
|
||||
// The following methods are the delegating implementations of reflection functions. They are called when you're using reflection
|
||||
// on a callable reference. Without kotlin-reflect.jar in the classpath, getReflected() throws an exception.
|
||||
|
||||
@Override
|
||||
public List<KParameter> getParameters() {
|
||||
@@ -120,21 +142,4 @@ public abstract class CallableReference implements KCallable {
|
||||
public boolean isAbstract() {
|
||||
return getReflected().isAbstract();
|
||||
}
|
||||
|
||||
public KCallable compute() {
|
||||
KCallable result = reflected;
|
||||
if (result == null) {
|
||||
result = computeReflected();
|
||||
reflected = result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected KCallable getReflected() {
|
||||
KCallable result = compute();
|
||||
if (result == this) {
|
||||
throw new KotlinReflectionNotSupportedError();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,19 +16,11 @@
|
||||
|
||||
package kotlin.jvm.internal;
|
||||
|
||||
import kotlin.jvm.KotlinReflectionNotSupportedError;
|
||||
import kotlin.reflect.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import kotlin.reflect.KCallable;
|
||||
import kotlin.reflect.KFunction;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings({"unchecked", "NullableProblems"})
|
||||
public class FunctionReference implements FunctionImpl, KFunction {
|
||||
public class FunctionReference extends CallableReference implements FunctionImpl, KFunction {
|
||||
private final int arity;
|
||||
private KFunction reflected;
|
||||
|
||||
public FunctionReference(int arity) {
|
||||
this.arity = arity;
|
||||
@@ -39,71 +31,14 @@ public class FunctionReference implements FunctionImpl, KFunction {
|
||||
return arity;
|
||||
}
|
||||
|
||||
// Most of the following methods are copies from CallableReference, since this class cannot inherit from it
|
||||
|
||||
public KDeclarationContainer getOwner() {
|
||||
throw new AbstractMethodError();
|
||||
@Override
|
||||
protected KFunction getReflected() {
|
||||
return (KFunction) super.getReflected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<KParameter> getParameters() {
|
||||
return getReflected().getParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public KType getReturnType() {
|
||||
return getReflected().getReturnType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Annotation> getAnnotations() {
|
||||
return getReflected().getAnnotations();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<KTypeParameter> getTypeParameters() {
|
||||
return getReflected().getTypeParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object call(@NotNull Object... args) {
|
||||
return getReflected().call(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object callBy(@NotNull Map args) {
|
||||
return getReflected().callBy(args);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public KVisibility getVisibility() {
|
||||
return getReflected().getVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
return getReflected().isFinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return getReflected().isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return getReflected().isAbstract();
|
||||
protected KCallable computeReflected() {
|
||||
return Reflection.function(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -158,7 +93,7 @@ public class FunctionReference implements FunctionImpl, KFunction {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
KFunction reflected = compute();
|
||||
KCallable reflected = compute();
|
||||
if (reflected != this) {
|
||||
return reflected.toString();
|
||||
}
|
||||
@@ -168,21 +103,4 @@ public class FunctionReference implements FunctionImpl, KFunction {
|
||||
? "constructor" + Reflection.REFLECTION_NOT_AVAILABLE
|
||||
: "function " + getName() + Reflection.REFLECTION_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
public KFunction compute() {
|
||||
KFunction result = reflected;
|
||||
if (result == null) {
|
||||
result = Reflection.function(this);
|
||||
reflected = result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private KFunction getReflected() {
|
||||
KFunction result = compute();
|
||||
if (result == this) {
|
||||
throw new KotlinReflectionNotSupportedError();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,7 @@ public abstract class PropertyReference extends CallableReference implements KPr
|
||||
getSignature().equals(other.getSignature());
|
||||
}
|
||||
if (obj instanceof KProperty) {
|
||||
compute();
|
||||
return obj.equals(reflected);
|
||||
return obj.equals(compute());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user