Inherit FunctionReference from CallableReference

This became possible now because FunctionImpl is no longer a class
This commit is contained in:
Alexander Udalov
2016-09-07 13:31:00 +03:00
parent a10cf8a931
commit d128827a34
4 changed files with 36 additions and 119 deletions
@@ -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;
}