Simplify function hierarchy in reflection

Get rid of all classes except kotlin.reflect.KFunction, which will be used to
represent all kinds of simple functions.

Lots of changes to test data are related to the fact that KFunction is not an
extension function (as opposed to KMemberFunction and KExtensionFunction who
were) and so a member or an extension function reference now requires all
arguments be passed to it in the parentheses, including receivers. This is
probably temporary until we support calling any function both as a free
function and as an extension. In JS, functions and extension functions are not
interchangeable, so tests on this behavior are removed until this is supported
This commit is contained in:
Alexander Udalov
2015-06-23 20:34:25 +03:00
parent 3549e1e035
commit c3b97e0668
113 changed files with 350 additions and 534 deletions
@@ -225,53 +225,35 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
@NotNull @NotNull
public StackValue putInstanceOnStack(@NotNull final ExpressionCodegen codegen) { public StackValue putInstanceOnStack(@NotNull final ExpressionCodegen codegen) {
return StackValue.operation(asmType, new Function1<InstructionAdapter, Unit>() { return StackValue.operation(
@Override functionReferenceTarget != null ? K_FUNCTION : asmType,
public Unit invoke(InstructionAdapter v) { new Function1<InstructionAdapter, Unit>() {
if (isConst(closure)) { @Override
v.getstatic(asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, asmType.getDescriptor()); public Unit invoke(InstructionAdapter v) {
} if (isConst(closure)) {
else { v.getstatic(asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, asmType.getDescriptor());
v.anew(asmType); }
v.dup(); else {
v.anew(asmType);
v.dup();
codegen.pushClosureOnStack(classDescriptor, true, codegen.defaultCallGenerator); codegen.pushClosureOnStack(classDescriptor, true, codegen.defaultCallGenerator);
v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor(), false); v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor(), false);
} }
if (functionReferenceTarget != null) { if (functionReferenceTarget != null) {
equipFunctionReferenceWithReflection(v, functionReferenceTarget); v.invokestatic(REFLECTION, "function", Type.getMethodDescriptor(K_FUNCTION, FUNCTION_REFERENCE), false);
} }
return Unit.INSTANCE$; return Unit.INSTANCE$;
} }
}); }
);
} }
private static void equipFunctionReferenceWithReflection(@NotNull InstructionAdapter v, @NotNull FunctionDescriptor target) {
DeclarationDescriptor container = target.getContainingDeclaration();
Type type;
if (container instanceof PackageFragmentDescriptor) {
type = target.getExtensionReceiverParameter() != null
? K_TOP_LEVEL_EXTENSION_FUNCTION
: K_TOP_LEVEL_FUNCTION;
}
else if (container instanceof ClassDescriptor) {
type = K_MEMBER_FUNCTION;
}
else {
type = K_LOCAL_FUNCTION;
}
Method method = method("function", K_FUNCTION, FUNCTION_REFERENCE);
v.invokestatic(REFLECTION, method.getName(), method.getDescriptor(), false);
StackValue.coerce(K_FUNCTION, type, v);
}
private void generateConstInstance() { private void generateConstInstance() {
MethodVisitor mv = v.newMethod(OtherOrigin(element, funDescriptor), ACC_STATIC | ACC_SYNTHETIC, "<clinit>", "()V", null, ArrayUtil.EMPTY_STRING_ARRAY); MethodVisitor mv = v.newMethod(OtherOrigin(element, funDescriptor), ACC_STATIC | ACC_SYNTHETIC, "<clinit>", "()V", null,
ArrayUtil.EMPTY_STRING_ARRAY);
InstructionAdapter iv = new InstructionAdapter(mv); InstructionAdapter iv = new InstructionAdapter(mv);
v.newField(OtherOrigin(element, funDescriptor), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD, asmType.getDescriptor(), v.newField(OtherOrigin(element, funDescriptor), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD, asmType.getDescriptor(),
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.codegen; package org.jetbrains.kotlin.codegen;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.GenerationState;
@@ -133,8 +134,14 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
} }
private void computeAndSaveArguments(@NotNull List<? extends ValueArgument> fakeArguments, @NotNull ExpressionCodegen codegen) { private void computeAndSaveArguments(@NotNull List<? extends ValueArgument> fakeArguments, @NotNull ExpressionCodegen codegen) {
for (ValueParameterDescriptor parameter : callableDescriptor.getValueParameters()) { int receivers = (referencedFunction.getDispatchReceiverParameter() != null ? 1 : 0) +
ValueArgument fakeArgument = fakeArguments.get(parameter.getIndex()); (referencedFunction.getExtensionReceiverParameter() != null ? 1 : 0);
List<ValueParameterDescriptor> parameters = KotlinPackage.drop(callableDescriptor.getValueParameters(), receivers);
for (int i = 0; i < parameters.size(); i++) {
ValueParameterDescriptor parameter = parameters.get(i);
ValueArgument fakeArgument = fakeArguments.get(i);
Type type = state.getTypeMapper().mapType(parameter); Type type = state.getTypeMapper().mapType(parameter);
int localIndex = codegen.myFrameMap.getIndex(parameter); int localIndex = codegen.myFrameMap.getIndex(parameter);
codegen.tempVariables.put(fakeArgument.getArgumentExpression(), StackValue.local(localIndex, type)); codegen.tempVariables.put(fakeArgument.getArgumentExpression(), StackValue.local(localIndex, type));
@@ -43,10 +43,6 @@ public class AsmTypes {
public static final Type K_DECLARATION_CONTAINER_TYPE = reflect("KDeclarationContainer"); public static final Type K_DECLARATION_CONTAINER_TYPE = reflect("KDeclarationContainer");
public static final Type K_FUNCTION = reflect("KFunction"); public static final Type K_FUNCTION = reflect("KFunction");
public static final Type K_TOP_LEVEL_FUNCTION = reflect("KTopLevelFunction");
public static final Type K_MEMBER_FUNCTION = reflect("KMemberFunction");
public static final Type K_TOP_LEVEL_EXTENSION_FUNCTION = reflect("KTopLevelExtensionFunction");
public static final Type K_LOCAL_FUNCTION = reflect("KLocalFunction");
public static final Type K_MEMBER_PROPERTY_TYPE = reflect("KMemberProperty"); public static final Type K_MEMBER_PROPERTY_TYPE = reflect("KMemberProperty");
public static final Type K_MUTABLE_MEMBER_PROPERTY_TYPE = reflect("KMutableMemberProperty"); public static final Type K_MUTABLE_MEMBER_PROPERTY_TYPE = reflect("KMutableMemberProperty");
@@ -704,7 +704,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
boolean isExtension = extensionReceiver != null; boolean isExtension = extensionReceiver != null;
if (descriptor instanceof FunctionDescriptor) { if (descriptor instanceof FunctionDescriptor) {
return createFunctionReferenceType(expression, context, (FunctionDescriptor) descriptor, receiverType, isExtension); return createFunctionReferenceType(expression, context, (FunctionDescriptor) descriptor, receiverType);
} }
else if (descriptor instanceof PropertyDescriptor) { else if (descriptor instanceof PropertyDescriptor) {
return createPropertyReferenceType(expression, context, (PropertyDescriptor) descriptor, receiverType, isExtension); return createPropertyReferenceType(expression, context, (PropertyDescriptor) descriptor, receiverType, isExtension);
@@ -722,16 +722,14 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@NotNull JetCallableReferenceExpression expression, @NotNull JetCallableReferenceExpression expression,
@NotNull ExpressionTypingContext context, @NotNull ExpressionTypingContext context,
@NotNull FunctionDescriptor descriptor, @NotNull FunctionDescriptor descriptor,
@Nullable JetType receiverType, @Nullable JetType receiverType
boolean isExtension
) { ) {
//noinspection ConstantConditions //noinspection ConstantConditions
JetType type = components.reflectionTypes.getKFunctionType( JetType type = components.reflectionTypes.getKFunctionType(
Annotations.EMPTY, Annotations.EMPTY,
receiverType, receiverType,
getValueParametersTypes(descriptor.getValueParameters()), getValueParametersTypes(descriptor.getValueParameters()),
descriptor.getReturnType(), descriptor.getReturnType()
isExtension
); );
AnonymousFunctionDescriptor functionDescriptor = new AnonymousFunctionDescriptor( AnonymousFunctionDescriptor functionDescriptor = new AnonymousFunctionDescriptor(
@@ -1,9 +1,9 @@
import kotlin.jvm.functions.Function2; import kotlin.jvm.functions.Function2;
import kotlin.reflect.KMemberFunction; import kotlin.reflect.KFunction;
public class J { public class J {
public static String go() { public static String go() {
KMemberFunction<K, String> fun = K.Companion.getRef(); KFunction<String> fun = K.Companion.getRef();
Object result = ((Function2) fun).invoke(new K(), "KO"); Object result = ((Function2) fun).invoke(new K(), "KO");
return (String) result; return (String) result;
} }
@@ -6,4 +6,4 @@ class B : A() {
override fun foo() = "OK" override fun foo() = "OK"
} }
fun box(): String = B().(A::foo)() fun box(): String = (A::foo)(B())
@@ -1,5 +1,5 @@
fun box(): String { fun box(): String {
if (true.(Boolean::not)() != false) return "Fail 1" if ((Boolean::not)(true) != false) return "Fail 1"
if (false.(Boolean::not)() != true) return "Fail 2" if ((Boolean::not)(false) != true) return "Fail 2"
return "OK" return "OK"
} }
@@ -1,7 +1,7 @@
class A { class A {
fun foo(k: Int) = k fun foo(k: Int) = k
fun result() = this.(::foo)(111) fun result() = (::foo)(this, 111)
} }
fun box(): String { fun box(): String {
@@ -3,7 +3,7 @@ class A {
fun k(k: Int) = k fun k(k: Int) = k
} }
fun A.foo() = this.(::o)() + this.(A::k)(222) fun A.foo() = (::o)(this) + (A::k)(this, 222)
fun box(): String { fun box(): String {
val result = A().foo() val result = A().foo()
@@ -4,5 +4,5 @@ class A {
fun box(): String { fun box(): String {
val x = A::foo val x = A::foo
return A().x() return x(A())
} }
@@ -4,5 +4,5 @@ class A {
fun box(): String { fun box(): String {
val x = A::foo val x = A::foo
return A().x("OK") return x(A(), "OK")
} }
@@ -9,6 +9,6 @@ class A {
fun box(): String { fun box(): String {
val a = A() val a = A()
val x = A::foo val x = A::foo
a.x() x(a)
return a.result return a.result
} }
@@ -9,6 +9,6 @@ class A {
fun box(): String { fun box(): String {
val a = A() val a = A()
val x = A::foo val x = A::foo
a.x("OK") x(a, "OK")
return a.result return a.result
} }
@@ -3,7 +3,7 @@ enum class E {
} }
fun box(): String { fun box(): String {
val i = E.I.(E::name)() val i = (E::name)(E.I)
if (i != "I") return "Fail $i" if (i != "I") return "Fail $i"
return "OK" return "OK"
} }
@@ -1,3 +1,3 @@
class A class A
fun box() = if (A().(A::equals)(A())) "Fail" else "OK" fun box() = if ((A::equals)(A(), A())) "Fail" else "OK"
@@ -1,5 +1,5 @@
class A { class A {
fun result() = this.(::foo)("OK") fun result() = (::foo)(this, "OK")
} }
fun A.foo(x: String) = x fun A.foo(x: String) = x
@@ -1,6 +1,6 @@
class A class A
fun A.foo() = this.(A::bar)("OK") fun A.foo() = (A::bar)(this, "OK")
fun A.bar(x: String) = x fun A.bar(x: String) = x
@@ -4,5 +4,5 @@ fun A.foo() = "OK"
fun box(): String { fun box(): String {
val x = A::foo val x = A::foo
return A().x() return x(A())
} }
@@ -4,5 +4,5 @@ fun A.foo(result: String) = result
fun box(): String { fun box(): String {
val x = A::foo val x = A::foo
return A().x("OK") return x(A(), "OK")
} }
@@ -9,6 +9,6 @@ fun A.foo() {
fun box(): String { fun box(): String {
val a = A() val a = A()
val x = A::foo val x = A::foo
a.x() x(a)
return a.result return a.result
} }
@@ -9,6 +9,6 @@ fun A.foo(newResult: String) {
fun box(): String { fun box(): String {
val a = A() val a = A()
val x = A::foo val x = A::foo
a.x("OK") x(a, "OK")
return a.result return a.result
} }
@@ -2,4 +2,4 @@ class A<T>(val t: T) {
fun foo(): T = t fun foo(): T = t
} }
fun box() = A("OK").(A<String>::foo)() fun box() = (A<String>::foo)(A("OK"))
@@ -4,7 +4,7 @@ class A {
val k = 222 val k = 222
} }
fun result() = this.(A::Inner)().o + this.(::Inner)().k fun result() = (A::Inner)(this).o + (::Inner)(this).k
} }
fun box(): String { fun box(): String {
@@ -5,7 +5,7 @@ class A {
} }
} }
fun A.foo() = this.(A::Inner)().o + this.(::Inner)().k fun A.foo() = (A::Inner)(this).o + (::Inner)(this).k
fun box(): String { fun box(): String {
val result = A().foo() val result = A().foo()
@@ -6,7 +6,7 @@ class A {
} }
fun box(): String { fun box(): String {
val result = (::A)().(A::Inner)().o + A().(A::Inner)().k val result = (A::Inner)((::A)()).o + (A::Inner)(A()).k
if (result != 333) return "Fail $result" if (result != 333) return "Fail $result"
return "OK" return "OK"
} }
@@ -3,7 +3,7 @@ class A {
} }
fun box(): String { fun box(): String {
val result = (::A)().(A::Inner)(111).result + A().(A::Inner)(222).result val result = (A::Inner)((::A)(), 111).result + (A::Inner)(A(), 222).result
if (result != 333) return "Fail $result" if (result != 333) return "Fail $result"
return "OK" return "OK"
} }
@@ -8,5 +8,5 @@ class Outer {
fun box(): String { fun box(): String {
val f = Outer.Inner::foo val f = Outer.Inner::foo
return Outer().Inner().f() return f(Outer().Inner())
} }
@@ -4,5 +4,5 @@ fun box(): String {
} }
val ref = Local::foo val ref = Local::foo
return Local().ref() return ref(Local())
} }
@@ -7,5 +7,5 @@ enum class E : Named {
} }
fun box(): String { fun box(): String {
return E.OK.(Named::name)() return (Named::name)(E.OK)
} }
@@ -2,5 +2,5 @@ class A
fun box(): String { fun box(): String {
fun A.foo() = "OK" fun A.foo() = "OK"
return A().(A::foo)() return (A::foo)(A())
} }
@@ -1,5 +1,5 @@
fun box(): String { fun box(): String {
class A class A
fun A.foo() = "OK" fun A.foo() = "OK"
return (::A)().(A::foo)() return (A::foo)((::A)())
} }
@@ -1,4 +1,4 @@
fun box(): String { fun box(): String {
fun Int.is42With(that: Int) = this + 2 * that == 42 fun Int.is42With(that: Int) = this + 2 * that == 42
return if (16.(Int::is42With)(13)) "OK" else "Fail" return if ((Int::is42With)(16, 13)) "OK" else "Fail"
} }
@@ -6,6 +6,6 @@ fun box(): String {
fun A.ext() { result = "OK" } fun A.ext() { result = "OK" }
val f = A::ext val f = A::ext
A().f() f(A())
return result return result
} }
@@ -4,5 +4,5 @@ fun box(): String {
} }
val ref = Id<String>::invoke val ref = Id<String>::invoke
return Id<String>().ref("OK") return ref(Id<String>(), "OK")
} }
@@ -7,5 +7,5 @@ fun box(): String {
val member = Local::foo val member = Local::foo
val instance = Local() val instance = Local()
return instance.member() return member(instance)
} }
@@ -8,6 +8,6 @@ object A {
fun box(): String { fun box(): String {
val x = A::foo val x = A::foo
A.x() x(A)
return A.result return A.result
} }
@@ -8,6 +8,6 @@ object A {
fun box(): String { fun box(): String {
val x = A::foo val x = A::foo
A.x("OK") x(A, "OK")
return A.result return A.result
} }
@@ -1,7 +1,7 @@
class A { class A {
private fun foo() = "OK" private fun foo() = "OK"
fun bar() = this.(::foo)() fun bar() = (::foo)(this)
} }
fun box() = A().bar() fun box() = A().bar()
@@ -4,7 +4,7 @@ interface T {
class B : T { class B : T {
inner class C { inner class C {
fun bar() = this@B.(::foo)() fun bar() = (::foo)(this@B)
} }
} }
@@ -6,4 +6,4 @@ class B : A {
override fun foo() = "OK" override fun foo() = "OK"
} }
fun box() = B().(A::foo)() fun box() = (A::foo)(B())
@@ -28,13 +28,13 @@ object A {
} }
fun box(): String { fun box(): String {
if (A.(A::test1)() != "OK") return "fail 1" if ((A::test1)(A) != "OK") return "fail 1"
if (A.(A::test2)() != "OK") return "fail 2" if ((A::test2)(A) != "OK") return "fail 2"
if (A.(A::test3)() != "1OK") return "fail 3" if ((A::test3)(A) != "1OK") return "fail 3"
if (A.(A::test4)() != "1OK") return "fail 4" if ((A::test4)(A) != "1OK") return "fail 4"
if (((A::c).get(A)) != "OK") return "fail 5" if (((A::c).get(A)) != "OK") return "fail 5"
@@ -3,7 +3,7 @@ class Z{
fun a(s: Int) {} fun a(s: Int) {}
fun b() { fun b() {
Z().(Z::a)(1) (Z::a)(Z(), 1)
} }
} }
@@ -5,5 +5,5 @@ open class A {
} }
fun test() { fun test() {
A.B.(A::foo)() (A::foo)(A.B)
} }
@@ -22,7 +22,7 @@ fun main() {
val y = first.A::bar val y = first.A::bar
val z = A::baz val z = A::baz
checkSubtype<KMemberFunction0<A, Unit>>(x) checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KMemberFunction1<A, Int, Unit>>(y) checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KMemberFunction0<A, String>>(z) checkSubtype<KFunction1<A, String>>(z)
} }
@@ -14,7 +14,7 @@ fun A.baz() {}
package other package other
import kotlin.reflect.KExtensionFunction0 import kotlin.reflect.KFunction1
import first.A import first.A
import first.foo import first.foo
@@ -24,5 +24,5 @@ fun main() {
first.A::<!UNRESOLVED_REFERENCE!>bar<!> first.A::<!UNRESOLVED_REFERENCE!>bar<!>
A::<!UNRESOLVED_REFERENCE!>baz<!> A::<!UNRESOLVED_REFERENCE!>baz<!>
checkSubtype<KExtensionFunction0<A, Unit>>(x) checkSubtype<KFunction1<A, Unit>>(x)
} }
@@ -8,9 +8,9 @@ class A {
val y = ::bar val y = ::bar
val z = ::baz val z = ::baz
checkSubtype<KExtensionFunction0<A, Unit>>(x) checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KExtensionFunction1<A, Int, Unit>>(y) checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KExtensionFunction0<A, String>>(z) checkSubtype<KFunction1<A, String>>(z)
} }
} }
@@ -9,9 +9,9 @@ fun A.main() {
val y = ::bar val y = ::bar
val z = ::baz val z = ::baz
checkSubtype<KExtensionFunction0<A, Unit>>(x) checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KExtensionFunction1<A, Int, Unit>>(y) checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KExtensionFunction0<A, String>>(z) checkSubtype<KFunction1<A, String>>(z)
} }
fun A.foo() {} fun A.foo() {}
@@ -10,9 +10,9 @@ class A {
val y = ::bar val y = ::bar
val z = ::baz val z = ::baz
checkSubtype<KExtensionFunction0<A, Unit>>(x) checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KExtensionFunction1<A, Int, Unit>>(y) checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KExtensionFunction0<A, String>>(z) checkSubtype<KFunction1<A, String>>(z)
} }
} }
@@ -13,11 +13,11 @@ fun main() {
val y = A::bar val y = A::bar
val z = A::baz val z = A::baz
checkSubtype<KExtensionFunction0<A, Unit>>(x) checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KExtensionFunction1<A, Int, Unit>>(y) checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KExtensionFunction0<A, String>>(z) checkSubtype<KFunction1<A, String>>(z)
checkSubtype<KExtensionFunction<A, Unit>>(x) checkSubtype<KFunction<Unit>>(x)
checkSubtype<KExtensionFunction<A, Unit>>(y) checkSubtype<KFunction<Unit>>(y)
checkSubtype<KExtensionFunction<A, String>>(z) checkSubtype<KFunction<String>>(z)
} }
@@ -8,5 +8,5 @@ class A {
fun A?.foo() {} fun A?.foo() {}
val f: KMemberFunction0<A, Unit> = A::foo val f: KFunction1<A, Unit> = A::foo
val g: KExtensionFunction0<A, Unit> = A?::foo val g: KFunction1<A, Unit> = A?::foo
@@ -1,7 +1,7 @@
package package
internal val f: kotlin.reflect.KMemberFunction0<A, kotlin.Unit> internal val f: kotlin.reflect.KFunction1<A, kotlin.Unit>
internal val g: kotlin.reflect.KExtensionFunction0<A, kotlin.Unit> internal val g: kotlin.reflect.KFunction1<A, kotlin.Unit>
internal fun A?.foo(): kotlin.Unit internal fun A?.foo(): kotlin.Unit
internal final class A { internal final class A {
@@ -1,6 +1,6 @@
// !CHECK_TYPE // !CHECK_TYPE
import kotlin.reflect.KMemberFunction0 import kotlin.reflect.KFunction1
class A<T>(val t: T) { class A<T>(val t: T) {
fun foo(): T = t fun foo(): T = t
@@ -9,5 +9,5 @@ class A<T>(val t: T) {
fun bar() { fun bar() {
val x = A<String>::foo val x = A<String>::foo
checkSubtype<KMemberFunction0<A<String>, String>>(x) checkSubtype<KFunction1<A<String>, String>>(x)
} }
@@ -1,6 +1,6 @@
// !CHECK_TYPE // !CHECK_TYPE
// !DIAGNOSTICS: -UNUSED_EXPRESSION // !DIAGNOSTICS: -UNUSED_EXPRESSION
import kotlin.reflect.KMemberFunction0 import kotlin.reflect.KFunction1
class A { class A {
inner class Inner inner class Inner
@@ -9,8 +9,8 @@ class A {
val x = ::Inner val x = ::Inner
val y = A::Inner val y = A::Inner
checkSubtype<KMemberFunction0<A, A.Inner>>(x) checkSubtype<KFunction1<A, A.Inner>>(x)
checkSubtype<KMemberFunction0<A, Inner>>(y) checkSubtype<KFunction1<A, Inner>>(y)
} }
companion object { companion object {
@@ -18,7 +18,7 @@ class A {
::<!INACCESSIBLE_OUTER_CLASS_EXPRESSION!>Inner<!> ::<!INACCESSIBLE_OUTER_CLASS_EXPRESSION!>Inner<!>
val y = A::Inner val y = A::Inner
checkSubtype<KMemberFunction0<A, A.Inner>>(y) checkSubtype<KFunction1<A, A.Inner>>(y)
} }
} }
} }
@@ -28,6 +28,6 @@ class B {
::<!UNRESOLVED_REFERENCE!>Inner<!> ::<!UNRESOLVED_REFERENCE!>Inner<!>
val y = A::Inner val y = A::Inner
checkSubtype<KMemberFunction0<A, A.Inner>>(y) checkSubtype<KFunction1<A, A.Inner>>(y)
} }
} }
@@ -1,6 +1,6 @@
// !CHECK_TYPE // !CHECK_TYPE
// !DIAGNOSTICS: -UNUSED_EXPRESSION // !DIAGNOSTICS: -UNUSED_EXPRESSION
import kotlin.reflect.KMemberFunction0 import kotlin.reflect.KFunction1
class A { class A {
inner class Inner inner class Inner
@@ -10,13 +10,13 @@ fun A.main() {
val x = ::Inner val x = ::Inner
val y = A::Inner val y = A::Inner
checkSubtype<KMemberFunction0<A, A.Inner>>(x) checkSubtype<KFunction1<A, A.Inner>>(x)
checkSubtype<KMemberFunction0<A, A.Inner>>(y) checkSubtype<KFunction1<A, A.Inner>>(y)
} }
fun Int.main() { fun Int.main() {
::<!UNRESOLVED_REFERENCE!>Inner<!> ::<!UNRESOLVED_REFERENCE!>Inner<!>
val y = A::Inner val y = A::Inner
checkSubtype<KMemberFunction0<A, A.Inner>>(y) checkSubtype<KFunction1<A, A.Inner>>(y)
} }
@@ -1,6 +1,6 @@
// !CHECK_TYPE // !CHECK_TYPE
// !DIAGNOSTICS: -UNUSED_EXPRESSION // !DIAGNOSTICS: -UNUSED_EXPRESSION
import kotlin.reflect.KMemberFunction0 import kotlin.reflect.KFunction1
class A { class A {
inner class Inner inner class Inner
@@ -10,5 +10,5 @@ fun main() {
::<!UNRESOLVED_REFERENCE!>Inner<!> ::<!UNRESOLVED_REFERENCE!>Inner<!>
val y = A::Inner val y = A::Inner
checkSubtype<KMemberFunction0<A, A.Inner>>(y) checkSubtype<KFunction1<A, A.Inner>>(y)
} }
@@ -9,10 +9,10 @@ class D {
// FILE: b.kt // FILE: b.kt
import kotlin.reflect.KMemberFunction0 import kotlin.reflect.KFunction1
fun main() { fun main() {
val x = a.b.c.D::foo val x = a.b.c.D::foo
checkSubtype<KMemberFunction0<a.b.c.D, Int>>(x) checkSubtype<KFunction1<a.b.c.D, Int>>(x)
} }
@@ -9,10 +9,10 @@ class D<E, F> {
// FILE: b.kt // FILE: b.kt
import kotlin.reflect.KMemberFunction2 import kotlin.reflect.KFunction3
fun main() { fun main() {
val x = a.b.c.D<String, Int>::foo val x = a.b.c.D<String, Int>::foo
checkSubtype<KMemberFunction2<a.b.c.D<String, Int>, String, Int, a.b.c.D<String, Int>>>(x) checkSubtype<KFunction3<a.b.c.D<String, Int>, String, Int, a.b.c.D<String, Int>>>(x)
} }
@@ -12,8 +12,8 @@ class A {
val y = ::bar val y = ::bar
val z = ::baz val z = ::baz
checkSubtype<KMemberFunction0<A, Unit>>(x) checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KMemberFunction1<A, Int, Unit>>(y) checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KMemberFunction0<A, String>>(z) checkSubtype<KFunction1<A, String>>(z)
} }
} }
@@ -13,7 +13,7 @@ fun A.main() {
val y = ::bar val y = ::bar
val z = ::baz val z = ::baz
checkSubtype<KMemberFunction0<A, Unit>>(x) checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KMemberFunction1<A, Int, Unit>>(y) checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KMemberFunction0<A, String>>(z) checkSubtype<KFunction1<A, String>>(z)
} }
@@ -14,8 +14,8 @@ class B {
val y = ::bar val y = ::bar
val z = ::baz val z = ::baz
checkSubtype<KMemberFunction0<A, Unit>>(x) checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KMemberFunction1<A, Int, Unit>>(y) checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KMemberFunction0<A, String>>(z) checkSubtype<KFunction1<A, String>>(z)
} }
} }
@@ -13,11 +13,11 @@ fun main() {
val y = A::bar val y = A::bar
val z = A::baz val z = A::baz
checkSubtype<KMemberFunction0<A, Unit>>(x) checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KMemberFunction1<A, Int, Unit>>(y) checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KMemberFunction0<A, String>>(z) checkSubtype<KFunction1<A, String>>(z)
checkSubtype<KMemberFunction<A, Unit>>(x) checkSubtype<KFunction<Unit>>(x)
checkSubtype<KMemberFunction<A, Unit>>(y) checkSubtype<KFunction<Unit>>(y)
checkSubtype<KMemberFunction<A, String>>(z) checkSubtype<KFunction<String>>(z)
} }
@@ -1,6 +1,6 @@
// !CHECK_TYPE // !CHECK_TYPE
import kotlin.reflect.KMemberFunction0 import kotlin.reflect.KFunction1
class A { class A {
fun foo() = 42 fun foo() = 42
@@ -11,5 +11,5 @@ fun A.foo() {}
fun main() { fun main() {
val x = A::foo val x = A::foo
checkSubtype<KMemberFunction0<A, Int>>(x) checkSubtype<KFunction1<A, Int>>(x)
} }
@@ -1,6 +1,6 @@
// !CHECK_TYPE // !CHECK_TYPE
import kotlin.reflect.KMemberFunction0 import kotlin.reflect.KFunction1
fun foo() {} fun foo() {}
@@ -10,6 +10,6 @@ class A {
fun main() { fun main() {
val x = ::foo val x = ::foo
checkSubtype<KMemberFunction0<A, Unit>>(x) checkSubtype<KFunction1<A, Unit>>(x)
} }
} }
@@ -25,6 +25,6 @@ fun main() {
val z = AA::bazbaz val z = AA::bazbaz
checkSubtype<KFunction0<Unit>>(x) checkSubtype<KFunction0<Unit>>(x)
checkSubtype<KMemberFunction0<AA, Int>>(y) checkSubtype<KFunction1<AA, Int>>(y)
checkSubtype<KExtensionFunction1<AA, String, Unit>>(z) checkSubtype<KFunction2<AA, String, Unit>>(z)
} }
@@ -5,7 +5,7 @@ internal fun block(): kotlin.Unit
internal fun expression(): UsefulClass internal fun expression(): UsefulClass
internal fun invoker(): kotlin.Unit internal fun invoker(): kotlin.Unit
internal fun reflection(): kotlin.reflect.KFunction1<kotlin.Int, UsefulClass> internal fun reflection(): kotlin.reflect.KFunction1<kotlin.Int, UsefulClass>
internal fun reflection2(): kotlin.reflect.KMemberFunction0<UsefulClass, kotlin.Unit> internal fun reflection2(): kotlin.reflect.KFunction1<UsefulClass, kotlin.Unit>
kotlin.deprecated(value = "does nothing good") internal fun kotlin.Any.doNothing(): kotlin.String kotlin.deprecated(value = "does nothing good") internal fun kotlin.Any.doNothing(): kotlin.String
internal final class Delegation { internal final class Delegation {
@@ -1,27 +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
/**
* Represents an extension function.
* See the [Kotlin language documentation](http://kotlinlang.org/docs/reference/extensions.html#extension-functions)
* for more information.
*
* @param E the type of the extension receiver.
* @param R the return type of the function.
*/
public interface KExtensionFunction<in E, out R> : KFunction<R>
@@ -1,24 +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
/**
* Represents a local function.
*
* @param R the return type of the function.
*/
public interface KLocalFunction<out R> : KFunction<R>
@@ -1,26 +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
/**
* Represents a member function.
*
* @param T the type of the instance which should be used to call the function.
* Must be derived either from a class declaring this function, or any subclass of that class.
* @param R the return type of the function.
*/
public interface KMemberFunction<in T : Any, out R> : KFunction<R>
@@ -1,25 +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
/**
* Represents an extension function declared in a package.
*
* @param E the type of the extension receiver.
* @param R the return type of the function.
*/
public interface KTopLevelExtensionFunction<in E, out R> : KExtensionFunction<E, R>
@@ -1,22 +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
/**
* Represents a function declared in a package.
*/
public interface KTopLevelFunction<out R> : KFunction<R>
@@ -80,10 +80,9 @@ public class JavaToKotlinClassMap implements PlatformToKotlinClassMap {
for (int i = 0; i < 23; i++) { for (int i = 0; i < 23; i++) {
add(ClassId.topLevel(new FqName("kotlin.jvm.functions.Function" + i)), builtIns.getFunction(i)); add(ClassId.topLevel(new FqName("kotlin.jvm.functions.Function" + i)), builtIns.getFunction(i));
for (FunctionClassDescriptor.Kind kind : FunctionClassDescriptor.Kinds.KFunctions) { FunctionClassDescriptor.Kind kFunction = FunctionClassDescriptor.Kind.KFunction;
String kFun = kind.getPackageFqName() + "." + kind.getClassNamePrefix(); String kFun = kFunction.getPackageFqName() + "." + kFunction.getClassNamePrefix();
addKotlinToJava(new FqNameUnsafe(kFun + i), ClassId.topLevel(new FqName(kFun))); addKotlinToJava(new FqNameUnsafe(kFun + i), ClassId.topLevel(new FqName(kFun)));
}
} }
addJavaToKotlin(classId(Deprecated.class), builtIns.getDeprecatedAnnotation()); addJavaToKotlin(classId(Deprecated.class), builtIns.getDeprecatedAnnotation());
@@ -48,8 +48,6 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
} }
public fun getKFunction(n: Int): ClassDescriptor = find("KFunction$n") public fun getKFunction(n: Int): ClassDescriptor = find("KFunction$n")
public fun getKExtensionFunction(n: Int): ClassDescriptor = find("KExtensionFunction$n")
public fun getKMemberFunction(n: Int): ClassDescriptor = find("KMemberFunction$n")
public val kClass: ClassDescriptor by ClassLookup public val kClass: ClassDescriptor by ClassLookup
public val kTopLevelVariable: ClassDescriptor by ClassLookup public val kTopLevelVariable: ClassDescriptor by ClassLookup
@@ -73,20 +71,16 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
annotations: Annotations, annotations: Annotations,
receiverType: JetType?, receiverType: JetType?,
parameterTypes: List<JetType>, parameterTypes: List<JetType>,
returnType: JetType, returnType: JetType
extensionFunction: Boolean
): JetType { ): JetType {
val arity = parameterTypes.size() val arguments = KotlinBuiltIns.getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType)
val classDescriptor =
if (extensionFunction) getKExtensionFunction(arity) val classDescriptor = getKFunction(arguments.size() - 1 /* return type */)
else if (receiverType != null) getKMemberFunction(arity)
else getKFunction(arity)
if (ErrorUtils.isError(classDescriptor)) { if (ErrorUtils.isError(classDescriptor)) {
return classDescriptor.getDefaultType() return classDescriptor.getDefaultType()
} }
val arguments = KotlinBuiltIns.getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType)
return JetTypeImpl(annotations, classDescriptor.getTypeConstructor(), false, arguments, classDescriptor.getMemberScope(arguments)) return JetTypeImpl(annotations, classDescriptor.getTypeConstructor(), false, arguments, classDescriptor.getMemberScope(arguments))
} }
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.storage.StorageManager
import kotlin.platform.platformStatic import kotlin.platform.platformStatic
/** /**
* Produces descriptors representing the fictitious classes for function types, such as kotlin.Function1 or kotlin.reflect.KMemberFunction0. * Produces descriptors representing the fictitious classes for function types, such as kotlin.Function1 or kotlin.reflect.KFunction2.
*/ */
public class BuiltInFictitiousFunctionClassFactory( public class BuiltInFictitiousFunctionClassFactory(
private val storageManager: StorageManager, private val storageManager: StorageManager,
@@ -37,17 +37,15 @@ public class BuiltInFictitiousFunctionClassFactory(
companion object { companion object {
platformStatic public fun parseClassName(className: String, packageFqName: FqName): KindWithArity? { platformStatic public fun parseClassName(className: String, packageFqName: FqName): KindWithArity? {
for (kind in FunctionClassDescriptor.Kinds.byPackage(packageFqName)) { val kind = FunctionClassDescriptor.Kind.byPackage(packageFqName) ?: return null
val prefix = kind.classNamePrefix
if (!className.startsWith(prefix)) continue
val arity = toInt(className.substring(prefix.length())) ?: continue val prefix = kind.classNamePrefix
if (!className.startsWith(prefix)) return null
// TODO: validate arity, should be <= 255 for functions, <= 254 for members/extensions val arity = toInt(className.substring(prefix.length())) ?: return null
return KindWithArity(kind, arity)
}
return null // TODO: validate arity, should be <= 255
return KindWithArity(kind, arity)
} }
private fun toInt(s: String): Int? { private fun toInt(s: String): Int? {
@@ -70,8 +68,7 @@ public class BuiltInFictitiousFunctionClassFactory(
if ("Function" !in className) return null // An optimization if ("Function" !in className) return null // An optimization
val packageFqName = classId.getPackageFqName() val packageFqName = classId.getPackageFqName()
val kindWithArity = parseClassName(className, packageFqName) ?: return null val (kind, arity) = parseClassName(className, packageFqName) ?: return null
val (kind, arity) = kindWithArity // KT-5100
val containingPackageFragment = module.getPackage(packageFqName).fragments.single() val containingPackageFragment = module.getPackage(packageFqName).fragments.single()
@@ -17,12 +17,10 @@
package org.jetbrains.kotlin.builtins.functions package org.jetbrains.kotlin.builtins.functions
import org.jetbrains.kotlin.builtins.KOTLIN_REFLECT_FQ_NAME import org.jetbrains.kotlin.builtins.KOTLIN_REFLECT_FQ_NAME
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME import org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor.Kind import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor.Kind
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
import org.jetbrains.kotlin.descriptors.impl.AbstractClassDescriptor import org.jetbrains.kotlin.descriptors.impl.AbstractClassDescriptor
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -32,18 +30,14 @@ import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.utils.toReadOnlyList import org.jetbrains.kotlin.utils.toReadOnlyList
import java.util.ArrayList import java.util.ArrayList
import java.util.EnumSet
/** /**
* A [ClassDescriptor] representing the fictitious class for a function type, such as kotlin.Function1 or kotlin.reflect.KMemberFunction0. * A [ClassDescriptor] representing the fictitious class for a function type, such as kotlin.Function1 or kotlin.reflect.KFunction2.
* *
* Classes which are represented by this descriptor include (with supertypes): * If the class represents kotlin.Function1, its only supertype is kotlin.Function.
* *
* Function1 : Function * If the class represents kotlin.reflect.KFunction1, it has two supertypes: kotlin.Function1 and kotlin.reflect.KFunction.
* KFunction1 : Function1, KFunction * This allows to use both 'invoke' and reflection API on function references obtained by '::'.
* KMemberFunction1 : Function2, KMemberFunction
* KExtensionFunction1 : Function2, KExtensionFunction
* (TODO) KMemberExtensionFunction1 : Function3, KMemberExtensionFunction
*/ */
public class FunctionClassDescriptor( public class FunctionClassDescriptor(
private val storageManager: StorageManager, private val storageManager: StorageManager,
@@ -54,24 +48,16 @@ public class FunctionClassDescriptor(
public enum class Kind(val packageFqName: FqName, val classNamePrefix: String) { public enum class Kind(val packageFqName: FqName, val classNamePrefix: String) {
Function(BUILT_INS_PACKAGE_FQ_NAME, "Function"), Function(BUILT_INS_PACKAGE_FQ_NAME, "Function"),
KFunction(KOTLIN_REFLECT_FQ_NAME, "KFunction"), KFunction(KOTLIN_REFLECT_FQ_NAME, "KFunction");
KMemberFunction(KOTLIN_REFLECT_FQ_NAME, "KMemberFunction"),
KExtensionFunction(KOTLIN_REFLECT_FQ_NAME, "KExtensionFunction");
// TODO: KMemberExtensionFunction
fun numberedClassName(arity: Int) = Name.identifier("$classNamePrefix$arity") fun numberedClassName(arity: Int) = Name.identifier("$classNamePrefix$arity")
val hasDispatchReceiver: Boolean get() = this == KMemberFunction
val hasExtensionReceiver: Boolean get() = this == KExtensionFunction
}
public object Kinds { companion object {
val Functions = EnumSet.of(Kind.Function) fun byPackage(fqName: FqName) = when (fqName) {
val KFunctions = EnumSet.complementOf(Functions) BUILT_INS_PACKAGE_FQ_NAME -> Function
KOTLIN_REFLECT_FQ_NAME -> KFunction
fun byPackage(fqName: FqName) = when (fqName) { else -> null
BUILT_INS_PACKAGE_FQ_NAME -> Functions }
KOTLIN_REFLECT_FQ_NAME -> KFunctions
else -> error(fqName)
} }
} }
@@ -110,13 +96,6 @@ public class FunctionClassDescriptor(
)) ))
} }
if (functionKind.hasDispatchReceiver) {
typeParameter(Variance.IN_VARIANCE, "T")
}
if (functionKind.hasExtensionReceiver) {
typeParameter(Variance.IN_VARIANCE, "E")
}
(1..arity).map { i -> (1..arity).map { i ->
typeParameter(Variance.IN_VARIANCE, "P$i") typeParameter(Variance.IN_VARIANCE, "P$i")
} }
@@ -129,48 +108,29 @@ public class FunctionClassDescriptor(
private val supertypes = storageManager.createLazyValue { private val supertypes = storageManager.createLazyValue {
val result = ArrayList<JetType>(2) val result = ArrayList<JetType>(2)
fun add( fun add(packageFragment: PackageFragmentDescriptor, name: Name) {
packageFragment: PackageFragmentDescriptor,
name: Name,
annotations: Annotations,
supertypeArguments: (superParameters: List<TypeParameterDescriptor>) -> List<TypeProjection>
) {
val descriptor = packageFragment.getMemberScope().getClassifier(name) as? ClassDescriptor val descriptor = packageFragment.getMemberScope().getClassifier(name) as? ClassDescriptor
?: error("Class $name not found in $packageFragment") ?: error("Class $name not found in $packageFragment")
val typeConstructor = descriptor.getTypeConstructor() val typeConstructor = descriptor.getTypeConstructor()
val arguments = supertypeArguments(typeConstructor.getParameters())
result.add(JetTypeImpl(annotations, typeConstructor, false, arguments, descriptor.getMemberScope(arguments))) // Substitute all type parameters of the super class with our last type parameters
val arguments = getParameters().takeLast(typeConstructor.getParameters().size()).map {
TypeProjectionImpl(it.getDefaultType())
}
result.add(JetTypeImpl(Annotations.EMPTY, typeConstructor, false, arguments, descriptor.getMemberScope(arguments)))
} }
// Add unnumbered base class, e.g. KMemberFunction for KMemberFunction5, or Function for Function0 // Add unnumbered base class, e.g. Function for Function{n}, KFunction for KFunction{n}
add(containingDeclaration, Name.identifier(functionKind.classNamePrefix), Annotations.EMPTY) { superParameters -> add(containingDeclaration, Name.identifier(functionKind.classNamePrefix))
// Substitute type parameters of the super class with our type parameters with the same names
val parametersByName = getParameters().toMap { it.getName() }
superParameters.map { TypeProjectionImpl(parametersByName[it.getName()]!!.getDefaultType()) }
}
// For K*Functions, add corresponding numbered Function class, e.g. Function2 for KMemberFunction1
if (functionKind in Kinds.KFunctions) {
var functionArity = arity
if (functionKind.hasDispatchReceiver) functionArity++
if (functionKind.hasExtensionReceiver) functionArity++
// For KFunction{n}, add corresponding numbered Function{n} class, e.g. Function2 for KFunction2
if (functionKind == Kind.KFunction) {
val module = containingDeclaration.getContainingDeclaration() val module = containingDeclaration.getContainingDeclaration()
val kotlinPackageFragment = module.getPackage(BUILT_INS_PACKAGE_FQ_NAME).fragments.single() val kotlinPackageFragment = module.getPackage(BUILT_INS_PACKAGE_FQ_NAME).fragments.single()
// If this is a KMemberFunction{n} or KExtensionFunction{n}, it extends Function{n} with the annotation kotlin.extension, add(kotlinPackageFragment, Kind.Function.numberedClassName(arity))
// so that the value of this type is callable as an extension function, with the receiver before the dot
val annotations =
if (functionKind.hasDispatchReceiver || functionKind.hasExtensionReceiver)
AnnotationsImpl(listOf(KotlinBuiltIns.getInstance().createExtensionAnnotation()))
else Annotations.EMPTY
add(kotlinPackageFragment, Kind.Function.numberedClassName(functionArity), annotations) {
// Substitute all type parameters of the super class with all our type parameters
getParameters().map { TypeProjectionImpl(it.getDefaultType()) }
}
} }
result.toReadOnlyList() result.toReadOnlyList()
@@ -0,0 +1,69 @@
/*
* 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.internal
import org.jetbrains.kotlin.resolve.scopes.JetScope
import kotlin.jvm.internal.FunctionReference
import kotlin.reflect.KotlinReflectionInternalError
class KFunctionFromReferenceImpl(
val reference: FunctionReference
): KFunctionImpl(
reference.getOwner() as? KCallableContainerImpl ?: EmptyContainerForLocal,
reference.getName(),
reference.getSignature()
) {
override fun getArity() = reference.getArity()
override val name = reference.getName()
// The rest of the class is auto-generated. Use the following script:
// (0..22).forEach { n -> println("override fun invoke(" + (1..n).joinToString { "p$it: Any?" } + "): Any? = reference(" + (1..n).joinToString { "p$it" } + ")") }
override fun invoke(): Any? = reference()
override fun invoke(p1: Any?): Any? = reference(p1)
override fun invoke(p1: Any?, p2: Any?): Any? = reference(p1, p2)
override fun invoke(p1: Any?, p2: Any?, p3: Any?): Any? = reference(p1, p2, p3)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?): Any? = reference(p1, p2, p3, p4)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?): Any? = reference(p1, p2, p3, p4, p5)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?): Any? = reference(p1, p2, p3, p4, p5, p6)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7, p8)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7, p8, p9)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?, p19: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?, p19: Any?, p20: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?, p19: Any?, p20: Any?, p21: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21)
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?, p19: Any?, p20: Any?, p21: Any?, p22: Any?): Any? = reference(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22)
}
object EmptyContainerForLocal : KCallableContainerImpl() {
override val jClass: Class<*>
get() = fail()
override val scope: JetScope
get() = fail()
private fun fail() = throw KotlinReflectionInternalError("Introspecting local functions is not yet supported in Kotlin reflection")
}
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import kotlin.jvm.internal.FunctionImpl import kotlin.jvm.internal.FunctionImpl
import kotlin.reflect.KFunction import kotlin.reflect.KFunction
abstract class KFunctionImpl private constructor( open class KFunctionImpl protected constructor(
container: KCallableContainerImpl, container: KCallableContainerImpl,
name: String, name: String,
signature: String, signature: String,
@@ -44,7 +44,7 @@ public class ReflectionFactoryImpl extends ReflectionFactory {
@Override @Override
public KFunction function(FunctionReference f) { public KFunction function(FunctionReference f) {
return new KTopLevelFreeFunctionImpl((KPackageImpl) f.getOwner(), f.getName(), f.getSignature()); return new KFunctionFromReferenceImpl(f);
} }
// Properties // Properties
@@ -1,26 +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.internal
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import kotlin.reflect.KTopLevelFunction
class KTopLevelFreeFunctionImpl : KFunctionImpl, KTopLevelFunction<Any?> {
constructor(container: KPackageImpl, name: String, signature: String): super(container, name, signature)
constructor(container: KPackageImpl, descriptor: FunctionDescriptor): super(container, descriptor)
}
@@ -17,14 +17,10 @@
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;
public class FunctionReference public class FunctionReference extends FunctionImpl implements KFunction {
extends FunctionImpl
implements KTopLevelFunction,
KMemberFunction,
KTopLevelExtensionFunction,
KLocalFunction {
private final int arity; private final int arity;
public FunctionReference(int arity) { public FunctionReference(int arity) {
@@ -122,7 +122,7 @@ public final class FunctionCallableReferenceTest extends AbstractCallableReferen
checkFooBoxIsOk(); checkFooBoxIsOk();
} }
public void testClassMemberAndExtensionCompatibility() throws Exception { public void testClassMemberAndNonExtensionCompatibility() throws Exception {
checkFooBoxIsOk(); checkFooBoxIsOk();
} }
@@ -173,9 +173,7 @@ object InvokeIntrinsic : FunctionCallCase {
funDeclaration == callableDescriptor.builtIns.getFunction(parameterCount) || funDeclaration == callableDescriptor.builtIns.getFunction(parameterCount) ||
funDeclaration == reflectionTypes.getKFunction(parameterCount) funDeclaration == reflectionTypes.getKFunction(parameterCount)
else else
funDeclaration == callableDescriptor.builtIns.getExtensionFunction(parameterCount) || funDeclaration == callableDescriptor.builtIns.getExtensionFunction(parameterCount)
funDeclaration == reflectionTypes.getKExtensionFunction(parameterCount) ||
funDeclaration == reflectionTypes.getKMemberFunction(parameterCount)
} }
override fun FunctionCallInfo.dispatchReceiver(): JsExpression { override fun FunctionCallInfo.dispatchReceiver(): JsExpression {
@@ -17,8 +17,8 @@
package org.jetbrains.kotlin.js.translate.context; package org.jetbrains.kotlin.js.translate.context;
import com.google.dart.compiler.backend.js.ast.*; import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.backend.js.ast.metadata.TypeCheck;
import com.google.dart.compiler.backend.js.ast.metadata.MetadataPackage; import com.google.dart.compiler.backend.js.ast.metadata.MetadataPackage;
import com.google.dart.compiler.backend.js.ast.metadata.TypeCheck;
import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
@@ -71,6 +71,7 @@ public final class Namer {
private static final String OBJECT_OBJECT_NAME = "createObject"; private static final String OBJECT_OBJECT_NAME = "createObject";
private static final String CALLABLE_REF_FOR_MEMBER_FUNCTION_NAME = "getCallableRefForMemberFunction"; private static final String CALLABLE_REF_FOR_MEMBER_FUNCTION_NAME = "getCallableRefForMemberFunction";
private static final String CALLABLE_REF_FOR_EXTENSION_FUNCTION_NAME = "getCallableRefForExtensionFunction"; private static final String CALLABLE_REF_FOR_EXTENSION_FUNCTION_NAME = "getCallableRefForExtensionFunction";
private static final String CALLABLE_REF_FOR_LOCAL_EXTENSION_FUNCTION_NAME = "getCallableRefForLocalExtensionFunction";
private static final String CALLABLE_REF_FOR_CONSTRUCTOR_NAME = "getCallableRefForConstructor"; private static final String CALLABLE_REF_FOR_CONSTRUCTOR_NAME = "getCallableRefForConstructor";
private static final String CALLABLE_REF_FOR_TOP_LEVEL_PROPERTY = "getCallableRefForTopLevelProperty"; private static final String CALLABLE_REF_FOR_TOP_LEVEL_PROPERTY = "getCallableRefForTopLevelProperty";
private static final String CALLABLE_REF_FOR_MEMBER_PROPERTY = "getCallableRefForMemberProperty"; private static final String CALLABLE_REF_FOR_MEMBER_PROPERTY = "getCallableRefForMemberProperty";
@@ -261,6 +262,8 @@ public final class Namer {
@NotNull @NotNull
private final JsName callableRefForExtensionFunctionName; private final JsName callableRefForExtensionFunctionName;
@NotNull @NotNull
private final JsName callableRefForLocalExtensionFunctionName;
@NotNull
private final JsName callableRefForConstructorName; private final JsName callableRefForConstructorName;
@NotNull @NotNull
private final JsName callableRefForTopLevelProperty; private final JsName callableRefForTopLevelProperty;
@@ -295,6 +298,7 @@ public final class Namer {
objectName = kotlinScope.declareName(OBJECT_OBJECT_NAME); objectName = kotlinScope.declareName(OBJECT_OBJECT_NAME);
callableRefForMemberFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_MEMBER_FUNCTION_NAME); callableRefForMemberFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_MEMBER_FUNCTION_NAME);
callableRefForExtensionFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_EXTENSION_FUNCTION_NAME); callableRefForExtensionFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_EXTENSION_FUNCTION_NAME);
callableRefForLocalExtensionFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_LOCAL_EXTENSION_FUNCTION_NAME);
callableRefForConstructorName = kotlinScope.declareName(CALLABLE_REF_FOR_CONSTRUCTOR_NAME); callableRefForConstructorName = kotlinScope.declareName(CALLABLE_REF_FOR_CONSTRUCTOR_NAME);
callableRefForTopLevelProperty = kotlinScope.declareName(CALLABLE_REF_FOR_TOP_LEVEL_PROPERTY); callableRefForTopLevelProperty = kotlinScope.declareName(CALLABLE_REF_FOR_TOP_LEVEL_PROPERTY);
callableRefForMemberProperty = kotlinScope.declareName(CALLABLE_REF_FOR_MEMBER_PROPERTY); callableRefForMemberProperty = kotlinScope.declareName(CALLABLE_REF_FOR_MEMBER_PROPERTY);
@@ -344,6 +348,11 @@ public final class Namer {
return kotlin(callableRefForExtensionFunctionName); return kotlin(callableRefForExtensionFunctionName);
} }
@NotNull
public JsExpression callableRefForLocalExtensionFunctionReference() {
return kotlin(callableRefForLocalExtensionFunctionName);
}
@NotNull @NotNull
public JsExpression callableRefForConstructorReference() { public JsExpression callableRefForConstructorReference() {
return kotlin(callableRefForConstructorName); return kotlin(callableRefForConstructorName);
@@ -130,15 +130,18 @@ object CallableReferenceTranslator {
assert(receiverParameterDescriptor != null, "receiverParameter for extension should not be null") assert(receiverParameterDescriptor != null, "receiverParameter for extension should not be null")
val jsFunctionRef = ReferenceTranslator.translateAsFQReference(descriptor, context) val jsFunctionRef = ReferenceTranslator.translateAsFQReference(descriptor, context)
if (descriptor.getVisibility() == Visibilities.LOCAL) if (descriptor.getVisibility() == Visibilities.LOCAL) {
return jsFunctionRef return JsInvocation(context.namer().callableRefForLocalExtensionFunctionReference(), jsFunctionRef)
}
else if (AnnotationsUtils.isNativeObject(descriptor)) { else if (AnnotationsUtils.isNativeObject(descriptor)) {
val jetType = receiverParameterDescriptor!!.getType() val jetType = receiverParameterDescriptor!!.getType()
val receiverClassDescriptor = DescriptorUtils.getClassDescriptorForType(jetType) val receiverClassDescriptor = DescriptorUtils.getClassDescriptorForType(jetType)
return translateAsMemberFunctionReference(descriptor, receiverClassDescriptor, context) return translateAsMemberFunctionReference(descriptor, receiverClassDescriptor, context)
} }
else else {
return JsInvocation(context.namer().callableRefForExtensionFunctionReference(), jsFunctionRef) return JsInvocation(context.namer().callableRefForExtensionFunctionReference(), jsFunctionRef)
}
} }
private fun translateForMemberFunction(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression { private fun translateForMemberFunction(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression {
@@ -9,4 +9,4 @@ class B : A() {
override fun foo() = "OK" override fun foo() = "OK"
} }
fun box(): String = B().(A::foo)() fun box(): String = (A::foo)(B())
@@ -2,7 +2,7 @@
package foo package foo
fun box(): String { fun box(): String {
if (true.(Boolean::not)() != false) return "Fail 1" if ((Boolean::not)(true) != false) return "Fail 1"
if (false.(Boolean::not)() != true) return "Fail 2" if ((Boolean::not)(false) != true) return "Fail 2"
return "OK" return "OK"
} }
@@ -12,13 +12,13 @@ fun box():String {
val a = A() val a = A()
var r = a.(A::memBar)("!!") var r = (A::memBar)(a, "!!")
if (r != "sA:memBar:!!") return r if (r != "sA:memBar:!!") return r
r = a.(A::extBar)("!!") r = (A::extBar)(a, "!!")
if (r != "sA:extBar:!!") return r if (r != "sA:extBar:!!") return r
r = a.(A::locExtBar)("!!") r = (A::locExtBar)(a, "!!")
if (r != "sA:locExtBar:!!") return r if (r != "sA:locExtBar:!!") return r
return "OK" return "OK"
@@ -1,7 +1,7 @@
package foo package foo
fun run(a: A, arg: String, funRef:A.(String) -> String): String { fun run(a: A, arg: String, funRef:(A, String) -> String): String {
return a.(funRef)(arg) return funRef(a, arg)
} }
class A { class A {
@@ -25,7 +25,7 @@ fun box():String {
r = run(a, "!!", A::locExtBar) r = run(a, "!!", A::locExtBar)
if (r != "sA:locExtBar:!!") return r if (r != "sA:locExtBar:!!") return r
r = run(a, "!!") {A.(other:String):String -> s + ":literal:" + other } r = run(a, "!!") {(a: A, other: String): String -> a.s + ":literal:" + other }
if (r != "sA:literal:!!") return r if (r != "sA:literal:!!") return r
return "OK" return "OK"
@@ -4,7 +4,7 @@ package foo
class A { class A {
fun bar(k: Int) = k fun bar(k: Int) = k
fun result() = this.(::bar)(111) fun result() = (::bar)(this, 111)
} }
fun box(): String { fun box(): String {
@@ -6,7 +6,7 @@ class A {
fun k(k: Int) = k fun k(k: Int) = k
} }
fun A.bar() = this.(::o)() + this.(A::k)(222) fun A.bar() = (::o)(this) + (A::k)(this, 222)
fun box(): String { fun box(): String {
val result = A().bar() val result = A().bar()
@@ -1,22 +1,12 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/. // This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo package foo
fun run(arg1: A, funRef:A.() -> String): String {
return arg1.funRef()
}
class A { class A {
fun foo() = "OK" fun foo() = "OK"
} }
fun box(): String { fun box(): String {
val x = A::foo val x = A::foo
var r = A().x() var r = x(A())
if (r != "OK") return r return r
r = run(A(), A::foo)
if (r != "OK") return r
return "OK"
} }
@@ -1,21 +1,13 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/. // This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo package foo
fun run(arg1: A, arg2: String, funRef:A.(String) -> String): String {
return arg1.funRef(arg2)
}
class A { class A {
fun foo(result: String):String = result fun foo(result: String):String = result
} }
fun box(): String { fun box(): String {
val x = A::foo val x = A::foo
var r = A().x("OK") var r = x(A(), "OK")
if (r != "OK") return r return r
r = run(A(), "OK", A::foo)
if (r != "OK") return r
return "OK"
} }
@@ -1,10 +1,6 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/. // This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo package foo
fun run(arg1: A, funRef:A.() -> Unit): Unit {
return arg1.funRef()
}
class A { class A {
var result = "Fail" var result = "Fail"
@@ -16,14 +12,6 @@ class A {
fun box(): String { fun box(): String {
val a = A() val a = A()
val x = A::foo val x = A::foo
a.x() x(a)
var r = a.result return a.result
if (r != "OK") return r
val a1 = A()
run(a1, A::foo)
r = a.result
if (r != "OK") return r
return "OK"
} }
@@ -1,10 +1,6 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/. // This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo package foo
fun run(arg1: A, arg2: String, funRef:A.(String) -> Unit): Unit {
return arg1.funRef(arg2)
}
class A { class A {
var result = "Fail" var result = "Fail"
@@ -16,14 +12,6 @@ class A {
fun box(): String { fun box(): String {
val a = A() val a = A()
val x = A::foo val x = A::foo
a.x("OK") x(a, "OK")
var r = a.result return a.result
if (r != "OK") return r
val a1 = A()
run(a1, "OK", A::foo)
r = a1.result
if (r != "OK") return r
return "OK"
} }
@@ -11,6 +11,6 @@ class B : A() {
fun box(): String { fun box(): String {
val b = B() val b = B()
var ref = A::foo var ref = A::foo
val result = b.(ref)("1", "2") val result = ref(b, "1", "2")
return (if (result == "fooB:12") "OK" else result) return (if (result == "fooB:12") "OK" else result)
} }
@@ -10,6 +10,6 @@ object B : A() {
fun box(): String { fun box(): String {
var ref = B::foo var ref = B::foo
val result = B.(ref)("1", "2") val result = ref(B, "1", "2")
return (if (result == "fooB:12") "OK" else result) return (if (result == "fooB:12") "OK" else result)
} }
@@ -5,5 +5,5 @@ class A
fun box(): String { fun box(): String {
fun A.foo() = "OK" fun A.foo() = "OK"
return A().(A::foo)() return (A::foo)(A())
} }
@@ -2,7 +2,7 @@
package foo package foo
class A { class A {
fun result() = this.(::bar)("OK") fun result() = (::bar)(this, "OK")
} }
fun A.bar(x: String) = x fun A.bar(x: String) = x
@@ -3,7 +3,7 @@ package foo
class A class A
fun A.foo() = this.(A::bar)("OK") fun A.foo() = (A::bar)(this, "OK")
fun A.bar(x: String) = x fun A.bar(x: String) = x
@@ -1,8 +1,8 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/. // This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo package foo
fun <T> run(arg1: A, arg2: T, funRef:A.(T) -> T): T { fun <T> run(arg1: A, arg2: T, funRef:(A, T) -> T): T {
return arg1.funRef(arg2) return funRef(arg1, arg2)
} }
class A { class A {
@@ -17,7 +17,7 @@ fun A.bar(x: Int): Int {
fun box(): Boolean { fun box(): Boolean {
val funRef = A::bar val funRef = A::bar
val obj = A() val obj = A()
var result = obj.(funRef)(25) var result = funRef(obj, 25)
if (result != 25 || obj.xx != 200) return false if (result != 25 || obj.xx != 200) return false
result = run(A(), 25, funRef) result = run(A(), 25, funRef)
@@ -11,7 +11,7 @@ fun A.foo() = "OK"
fun box(): String { fun box(): String {
val x = A::foo val x = A::foo
var r = A().x() var r = x(A())
if (r != "OK") return r if (r != "OK") return r
r = run(A(), A::foo) r = run(A(), A::foo)

Some files were not shown because too many files have changed in this diff Show More