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
public StackValue putInstanceOnStack(@NotNull final ExpressionCodegen codegen) {
return StackValue.operation(asmType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
if (isConst(closure)) {
v.getstatic(asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, asmType.getDescriptor());
}
else {
v.anew(asmType);
v.dup();
return StackValue.operation(
functionReferenceTarget != null ? K_FUNCTION : asmType,
new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
if (isConst(closure)) {
v.getstatic(asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, asmType.getDescriptor());
}
else {
v.anew(asmType);
v.dup();
codegen.pushClosureOnStack(classDescriptor, true, codegen.defaultCallGenerator);
v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor(), false);
}
codegen.pushClosureOnStack(classDescriptor, true, codegen.defaultCallGenerator);
v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor(), false);
}
if (functionReferenceTarget != null) {
equipFunctionReferenceWithReflection(v, functionReferenceTarget);
}
if (functionReferenceTarget != null) {
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() {
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);
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;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
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) {
for (ValueParameterDescriptor parameter : callableDescriptor.getValueParameters()) {
ValueArgument fakeArgument = fakeArguments.get(parameter.getIndex());
int receivers = (referencedFunction.getDispatchReceiverParameter() != null ? 1 : 0) +
(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);
int localIndex = codegen.myFrameMap.getIndex(parameter);
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_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_MUTABLE_MEMBER_PROPERTY_TYPE = reflect("KMutableMemberProperty");
@@ -704,7 +704,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
boolean isExtension = extensionReceiver != null;
if (descriptor instanceof FunctionDescriptor) {
return createFunctionReferenceType(expression, context, (FunctionDescriptor) descriptor, receiverType, isExtension);
return createFunctionReferenceType(expression, context, (FunctionDescriptor) descriptor, receiverType);
}
else if (descriptor instanceof PropertyDescriptor) {
return createPropertyReferenceType(expression, context, (PropertyDescriptor) descriptor, receiverType, isExtension);
@@ -722,16 +722,14 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@NotNull JetCallableReferenceExpression expression,
@NotNull ExpressionTypingContext context,
@NotNull FunctionDescriptor descriptor,
@Nullable JetType receiverType,
boolean isExtension
@Nullable JetType receiverType
) {
//noinspection ConstantConditions
JetType type = components.reflectionTypes.getKFunctionType(
Annotations.EMPTY,
receiverType,
getValueParametersTypes(descriptor.getValueParameters()),
descriptor.getReturnType(),
isExtension
descriptor.getReturnType()
);
AnonymousFunctionDescriptor functionDescriptor = new AnonymousFunctionDescriptor(
@@ -1,9 +1,9 @@
import kotlin.jvm.functions.Function2;
import kotlin.reflect.KMemberFunction;
import kotlin.reflect.KFunction;
public class J {
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");
return (String) result;
}
@@ -6,4 +6,4 @@ class B : A() {
override fun foo() = "OK"
}
fun box(): String = B().(A::foo)()
fun box(): String = (A::foo)(B())
@@ -1,5 +1,5 @@
fun box(): String {
if (true.(Boolean::not)() != false) return "Fail 1"
if (false.(Boolean::not)() != true) return "Fail 2"
if ((Boolean::not)(true) != false) return "Fail 1"
if ((Boolean::not)(false) != true) return "Fail 2"
return "OK"
}
@@ -1,7 +1,7 @@
class A {
fun foo(k: Int) = k
fun result() = this.(::foo)(111)
fun result() = (::foo)(this, 111)
}
fun box(): String {
@@ -3,7 +3,7 @@ class A {
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 {
val result = A().foo()
@@ -4,5 +4,5 @@ class A {
fun box(): String {
val x = A::foo
return A().x()
return x(A())
}
@@ -4,5 +4,5 @@ class A {
fun box(): String {
val x = A::foo
return A().x("OK")
return x(A(), "OK")
}
@@ -9,6 +9,6 @@ class A {
fun box(): String {
val a = A()
val x = A::foo
a.x()
x(a)
return a.result
}
@@ -9,6 +9,6 @@ class A {
fun box(): String {
val a = A()
val x = A::foo
a.x("OK")
x(a, "OK")
return a.result
}
@@ -3,7 +3,7 @@ enum class E {
}
fun box(): String {
val i = E.I.(E::name)()
val i = (E::name)(E.I)
if (i != "I") return "Fail $i"
return "OK"
}
@@ -1,3 +1,3 @@
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 {
fun result() = this.(::foo)("OK")
fun result() = (::foo)(this, "OK")
}
fun A.foo(x: String) = x
@@ -1,6 +1,6 @@
class A
fun A.foo() = this.(A::bar)("OK")
fun A.foo() = (A::bar)(this, "OK")
fun A.bar(x: String) = x
@@ -4,5 +4,5 @@ fun A.foo() = "OK"
fun box(): String {
val x = A::foo
return A().x()
return x(A())
}
@@ -4,5 +4,5 @@ fun A.foo(result: String) = result
fun box(): String {
val x = A::foo
return A().x("OK")
return x(A(), "OK")
}
@@ -9,6 +9,6 @@ fun A.foo() {
fun box(): String {
val a = A()
val x = A::foo
a.x()
x(a)
return a.result
}
@@ -9,6 +9,6 @@ fun A.foo(newResult: String) {
fun box(): String {
val a = A()
val x = A::foo
a.x("OK")
x(a, "OK")
return a.result
}
@@ -2,4 +2,4 @@ class A<T>(val 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
}
fun result() = this.(A::Inner)().o + this.(::Inner)().k
fun result() = (A::Inner)(this).o + (::Inner)(this).k
}
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 {
val result = A().foo()
@@ -6,7 +6,7 @@ class A {
}
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"
return "OK"
}
@@ -3,7 +3,7 @@ class A {
}
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"
return "OK"
}
@@ -8,5 +8,5 @@ class Outer {
fun box(): String {
val f = Outer.Inner::foo
return Outer().Inner().f()
return f(Outer().Inner())
}
@@ -4,5 +4,5 @@ fun box(): String {
}
val ref = Local::foo
return Local().ref()
return ref(Local())
}
@@ -7,5 +7,5 @@ enum class E : Named {
}
fun box(): String {
return E.OK.(Named::name)()
return (Named::name)(E.OK)
}
@@ -2,5 +2,5 @@ class A
fun box(): String {
fun A.foo() = "OK"
return A().(A::foo)()
return (A::foo)(A())
}
@@ -1,5 +1,5 @@
fun box(): String {
class A
fun A.foo() = "OK"
return (::A)().(A::foo)()
return (A::foo)((::A)())
}
@@ -1,4 +1,4 @@
fun box(): String {
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" }
val f = A::ext
A().f()
f(A())
return result
}
@@ -4,5 +4,5 @@ fun box(): String {
}
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 instance = Local()
return instance.member()
return member(instance)
}
@@ -8,6 +8,6 @@ object A {
fun box(): String {
val x = A::foo
A.x()
x(A)
return A.result
}
@@ -8,6 +8,6 @@ object A {
fun box(): String {
val x = A::foo
A.x("OK")
x(A, "OK")
return A.result
}
@@ -1,7 +1,7 @@
class A {
private fun foo() = "OK"
fun bar() = this.(::foo)()
fun bar() = (::foo)(this)
}
fun box() = A().bar()
@@ -4,7 +4,7 @@ interface T {
class B : T {
inner class C {
fun bar() = this@B.(::foo)()
fun bar() = (::foo)(this@B)
}
}
@@ -6,4 +6,4 @@ class B : A {
override fun foo() = "OK"
}
fun box() = B().(A::foo)()
fun box() = (A::foo)(B())
@@ -28,15 +28,15 @@ object A {
}
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"
return "OK"
}
}
@@ -3,8 +3,8 @@ class Z{
fun a(s: Int) {}
fun b() {
Z().(Z::a)(1)
(Z::a)(Z(), 1)
}
}
// 1 invoke \(LZ;I\)V
// 1 invoke \(LZ;I\)V
@@ -5,5 +5,5 @@ open class A {
}
fun test() {
A.B.(A::foo)()
}
(A::foo)(A.B)
}
@@ -22,7 +22,7 @@ fun main() {
val y = first.A::bar
val z = A::baz
checkSubtype<KMemberFunction0<A, Unit>>(x)
checkSubtype<KMemberFunction1<A, Int, Unit>>(y)
checkSubtype<KMemberFunction0<A, String>>(z)
checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KFunction1<A, String>>(z)
}
@@ -14,7 +14,7 @@ fun A.baz() {}
package other
import kotlin.reflect.KExtensionFunction0
import kotlin.reflect.KFunction1
import first.A
import first.foo
@@ -24,5 +24,5 @@ fun main() {
first.A::<!UNRESOLVED_REFERENCE!>bar<!>
A::<!UNRESOLVED_REFERENCE!>baz<!>
checkSubtype<KExtensionFunction0<A, Unit>>(x)
}
checkSubtype<KFunction1<A, Unit>>(x)
}
@@ -8,9 +8,9 @@ class A {
val y = ::bar
val z = ::baz
checkSubtype<KExtensionFunction0<A, Unit>>(x)
checkSubtype<KExtensionFunction1<A, Int, Unit>>(y)
checkSubtype<KExtensionFunction0<A, String>>(z)
checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KFunction1<A, String>>(z)
}
}
@@ -9,9 +9,9 @@ fun A.main() {
val y = ::bar
val z = ::baz
checkSubtype<KExtensionFunction0<A, Unit>>(x)
checkSubtype<KExtensionFunction1<A, Int, Unit>>(y)
checkSubtype<KExtensionFunction0<A, String>>(z)
checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KFunction1<A, String>>(z)
}
fun A.foo() {}
@@ -10,9 +10,9 @@ class A {
val y = ::bar
val z = ::baz
checkSubtype<KExtensionFunction0<A, Unit>>(x)
checkSubtype<KExtensionFunction1<A, Int, Unit>>(y)
checkSubtype<KExtensionFunction0<A, String>>(z)
checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KFunction1<A, String>>(z)
}
}
@@ -13,11 +13,11 @@ fun main() {
val y = A::bar
val z = A::baz
checkSubtype<KExtensionFunction0<A, Unit>>(x)
checkSubtype<KExtensionFunction1<A, Int, Unit>>(y)
checkSubtype<KExtensionFunction0<A, String>>(z)
checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KFunction1<A, String>>(z)
checkSubtype<KExtensionFunction<A, Unit>>(x)
checkSubtype<KExtensionFunction<A, Unit>>(y)
checkSubtype<KExtensionFunction<A, String>>(z)
checkSubtype<KFunction<Unit>>(x)
checkSubtype<KFunction<Unit>>(y)
checkSubtype<KFunction<String>>(z)
}
@@ -8,5 +8,5 @@ class A {
fun A?.foo() {}
val f: KMemberFunction0<A, Unit> = A::foo
val g: KExtensionFunction0<A, Unit> = A?::foo
val f: KFunction1<A, Unit> = A::foo
val g: KFunction1<A, Unit> = A?::foo
@@ -1,7 +1,7 @@
package
internal val f: kotlin.reflect.KMemberFunction0<A, kotlin.Unit>
internal val g: kotlin.reflect.KExtensionFunction0<A, kotlin.Unit>
internal val f: kotlin.reflect.KFunction1<A, kotlin.Unit>
internal val g: kotlin.reflect.KFunction1<A, kotlin.Unit>
internal fun A?.foo(): kotlin.Unit
internal final class A {
@@ -1,6 +1,6 @@
// !CHECK_TYPE
import kotlin.reflect.KMemberFunction0
import kotlin.reflect.KFunction1
class A<T>(val t: T) {
fun foo(): T = t
@@ -9,5 +9,5 @@ class A<T>(val t: T) {
fun bar() {
val x = A<String>::foo
checkSubtype<KMemberFunction0<A<String>, String>>(x)
checkSubtype<KFunction1<A<String>, String>>(x)
}
@@ -1,6 +1,6 @@
// !CHECK_TYPE
// !DIAGNOSTICS: -UNUSED_EXPRESSION
import kotlin.reflect.KMemberFunction0
import kotlin.reflect.KFunction1
class A {
inner class Inner
@@ -9,8 +9,8 @@ class A {
val x = ::Inner
val y = A::Inner
checkSubtype<KMemberFunction0<A, A.Inner>>(x)
checkSubtype<KMemberFunction0<A, Inner>>(y)
checkSubtype<KFunction1<A, A.Inner>>(x)
checkSubtype<KFunction1<A, Inner>>(y)
}
companion object {
@@ -18,7 +18,7 @@ class A {
::<!INACCESSIBLE_OUTER_CLASS_EXPRESSION!>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<!>
val y = A::Inner
checkSubtype<KMemberFunction0<A, A.Inner>>(y)
checkSubtype<KFunction1<A, A.Inner>>(y)
}
}
}
@@ -1,6 +1,6 @@
// !CHECK_TYPE
// !DIAGNOSTICS: -UNUSED_EXPRESSION
import kotlin.reflect.KMemberFunction0
import kotlin.reflect.KFunction1
class A {
inner class Inner
@@ -10,13 +10,13 @@ fun A.main() {
val x = ::Inner
val y = A::Inner
checkSubtype<KMemberFunction0<A, A.Inner>>(x)
checkSubtype<KMemberFunction0<A, A.Inner>>(y)
checkSubtype<KFunction1<A, A.Inner>>(x)
checkSubtype<KFunction1<A, A.Inner>>(y)
}
fun Int.main() {
::<!UNRESOLVED_REFERENCE!>Inner<!>
val y = A::Inner
checkSubtype<KMemberFunction0<A, A.Inner>>(y)
}
checkSubtype<KFunction1<A, A.Inner>>(y)
}
@@ -1,6 +1,6 @@
// !CHECK_TYPE
// !DIAGNOSTICS: -UNUSED_EXPRESSION
import kotlin.reflect.KMemberFunction0
import kotlin.reflect.KFunction1
class A {
inner class Inner
@@ -10,5 +10,5 @@ fun main() {
::<!UNRESOLVED_REFERENCE!>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
import kotlin.reflect.KMemberFunction0
import kotlin.reflect.KFunction1
fun main() {
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
import kotlin.reflect.KMemberFunction2
import kotlin.reflect.KFunction3
fun main() {
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 z = ::baz
checkSubtype<KMemberFunction0<A, Unit>>(x)
checkSubtype<KMemberFunction1<A, Int, Unit>>(y)
checkSubtype<KMemberFunction0<A, String>>(z)
checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KFunction1<A, String>>(z)
}
}
@@ -13,7 +13,7 @@ fun A.main() {
val y = ::bar
val z = ::baz
checkSubtype<KMemberFunction0<A, Unit>>(x)
checkSubtype<KMemberFunction1<A, Int, Unit>>(y)
checkSubtype<KMemberFunction0<A, String>>(z)
checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KFunction1<A, String>>(z)
}
@@ -14,8 +14,8 @@ class B {
val y = ::bar
val z = ::baz
checkSubtype<KMemberFunction0<A, Unit>>(x)
checkSubtype<KMemberFunction1<A, Int, Unit>>(y)
checkSubtype<KMemberFunction0<A, String>>(z)
checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KFunction1<A, String>>(z)
}
}
@@ -13,11 +13,11 @@ fun main() {
val y = A::bar
val z = A::baz
checkSubtype<KMemberFunction0<A, Unit>>(x)
checkSubtype<KMemberFunction1<A, Int, Unit>>(y)
checkSubtype<KMemberFunction0<A, String>>(z)
checkSubtype<KFunction1<A, Unit>>(x)
checkSubtype<KFunction2<A, Int, Unit>>(y)
checkSubtype<KFunction1<A, String>>(z)
checkSubtype<KMemberFunction<A, Unit>>(x)
checkSubtype<KMemberFunction<A, Unit>>(y)
checkSubtype<KMemberFunction<A, String>>(z)
checkSubtype<KFunction<Unit>>(x)
checkSubtype<KFunction<Unit>>(y)
checkSubtype<KFunction<String>>(z)
}
@@ -1,6 +1,6 @@
// !CHECK_TYPE
import kotlin.reflect.KMemberFunction0
import kotlin.reflect.KFunction1
class A {
fun foo() = 42
@@ -11,5 +11,5 @@ fun A.foo() {}
fun main() {
val x = A::foo
checkSubtype<KMemberFunction0<A, Int>>(x)
checkSubtype<KFunction1<A, Int>>(x)
}
@@ -1,6 +1,6 @@
// !CHECK_TYPE
import kotlin.reflect.KMemberFunction0
import kotlin.reflect.KFunction1
fun foo() {}
@@ -10,6 +10,6 @@ class A {
fun main() {
val x = ::foo
checkSubtype<KMemberFunction0<A, Unit>>(x)
checkSubtype<KFunction1<A, Unit>>(x)
}
}
@@ -25,6 +25,6 @@ fun main() {
val z = AA::bazbaz
checkSubtype<KFunction0<Unit>>(x)
checkSubtype<KMemberFunction0<AA, Int>>(y)
checkSubtype<KExtensionFunction1<AA, String, Unit>>(z)
checkSubtype<KFunction1<AA, Int>>(y)
checkSubtype<KFunction2<AA, String, Unit>>(z)
}
@@ -5,7 +5,7 @@ internal fun block(): kotlin.Unit
internal fun expression(): UsefulClass
internal fun invoker(): kotlin.Unit
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
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++) {
add(ClassId.topLevel(new FqName("kotlin.jvm.functions.Function" + i)), builtIns.getFunction(i));
for (FunctionClassDescriptor.Kind kind : FunctionClassDescriptor.Kinds.KFunctions) {
String kFun = kind.getPackageFqName() + "." + kind.getClassNamePrefix();
addKotlinToJava(new FqNameUnsafe(kFun + i), ClassId.topLevel(new FqName(kFun)));
}
FunctionClassDescriptor.Kind kFunction = FunctionClassDescriptor.Kind.KFunction;
String kFun = kFunction.getPackageFqName() + "." + kFunction.getClassNamePrefix();
addKotlinToJava(new FqNameUnsafe(kFun + i), ClassId.topLevel(new FqName(kFun)));
}
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 getKExtensionFunction(n: Int): ClassDescriptor = find("KExtensionFunction$n")
public fun getKMemberFunction(n: Int): ClassDescriptor = find("KMemberFunction$n")
public val kClass: ClassDescriptor by ClassLookup
public val kTopLevelVariable: ClassDescriptor by ClassLookup
@@ -73,20 +71,16 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
annotations: Annotations,
receiverType: JetType?,
parameterTypes: List<JetType>,
returnType: JetType,
extensionFunction: Boolean
returnType: JetType
): JetType {
val arity = parameterTypes.size()
val classDescriptor =
if (extensionFunction) getKExtensionFunction(arity)
else if (receiverType != null) getKMemberFunction(arity)
else getKFunction(arity)
val arguments = KotlinBuiltIns.getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType)
val classDescriptor = getKFunction(arguments.size() - 1 /* return type */)
if (ErrorUtils.isError(classDescriptor)) {
return classDescriptor.getDefaultType()
}
val arguments = KotlinBuiltIns.getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType)
return JetTypeImpl(annotations, classDescriptor.getTypeConstructor(), false, arguments, classDescriptor.getMemberScope(arguments))
}
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.storage.StorageManager
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(
private val storageManager: StorageManager,
@@ -37,17 +37,15 @@ public class BuiltInFictitiousFunctionClassFactory(
companion object {
platformStatic public fun parseClassName(className: String, packageFqName: FqName): KindWithArity? {
for (kind in FunctionClassDescriptor.Kinds.byPackage(packageFqName)) {
val prefix = kind.classNamePrefix
if (!className.startsWith(prefix)) continue
val kind = FunctionClassDescriptor.Kind.byPackage(packageFqName) ?: return null
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
return KindWithArity(kind, arity)
}
val arity = toInt(className.substring(prefix.length())) ?: return null
return null
// TODO: validate arity, should be <= 255
return KindWithArity(kind, arity)
}
private fun toInt(s: String): Int? {
@@ -70,8 +68,7 @@ public class BuiltInFictitiousFunctionClassFactory(
if ("Function" !in className) return null // An optimization
val packageFqName = classId.getPackageFqName()
val kindWithArity = parseClassName(className, packageFqName) ?: return null
val (kind, arity) = kindWithArity // KT-5100
val (kind, arity) = parseClassName(className, packageFqName) ?: return null
val containingPackageFragment = module.getPackage(packageFqName).fragments.single()
@@ -17,12 +17,10 @@
package org.jetbrains.kotlin.builtins.functions
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.functions.FunctionClassDescriptor.Kind
import org.jetbrains.kotlin.descriptors.*
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.TypeParameterDescriptorImpl
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.utils.toReadOnlyList
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
* KFunction1 : Function1, KFunction
* KMemberFunction1 : Function2, KMemberFunction
* KExtensionFunction1 : Function2, KExtensionFunction
* (TODO) KMemberExtensionFunction1 : Function3, KMemberExtensionFunction
* If the class represents kotlin.reflect.KFunction1, it has two supertypes: kotlin.Function1 and kotlin.reflect.KFunction.
* This allows to use both 'invoke' and reflection API on function references obtained by '::'.
*/
public class FunctionClassDescriptor(
private val storageManager: StorageManager,
@@ -54,24 +48,16 @@ public class FunctionClassDescriptor(
public enum class Kind(val packageFqName: FqName, val classNamePrefix: String) {
Function(BUILT_INS_PACKAGE_FQ_NAME, "Function"),
KFunction(KOTLIN_REFLECT_FQ_NAME, "KFunction"),
KMemberFunction(KOTLIN_REFLECT_FQ_NAME, "KMemberFunction"),
KExtensionFunction(KOTLIN_REFLECT_FQ_NAME, "KExtensionFunction");
// TODO: KMemberExtensionFunction
KFunction(KOTLIN_REFLECT_FQ_NAME, "KFunction");
fun numberedClassName(arity: Int) = Name.identifier("$classNamePrefix$arity")
val hasDispatchReceiver: Boolean get() = this == KMemberFunction
val hasExtensionReceiver: Boolean get() = this == KExtensionFunction
}
public object Kinds {
val Functions = EnumSet.of(Kind.Function)
val KFunctions = EnumSet.complementOf(Functions)
fun byPackage(fqName: FqName) = when (fqName) {
BUILT_INS_PACKAGE_FQ_NAME -> Functions
KOTLIN_REFLECT_FQ_NAME -> KFunctions
else -> error(fqName)
companion object {
fun byPackage(fqName: FqName) = when (fqName) {
BUILT_INS_PACKAGE_FQ_NAME -> Function
KOTLIN_REFLECT_FQ_NAME -> KFunction
else -> null
}
}
}
@@ -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 ->
typeParameter(Variance.IN_VARIANCE, "P$i")
}
@@ -129,48 +108,29 @@ public class FunctionClassDescriptor(
private val supertypes = storageManager.createLazyValue {
val result = ArrayList<JetType>(2)
fun add(
packageFragment: PackageFragmentDescriptor,
name: Name,
annotations: Annotations,
supertypeArguments: (superParameters: List<TypeParameterDescriptor>) -> List<TypeProjection>
) {
fun add(packageFragment: PackageFragmentDescriptor, name: Name) {
val descriptor = packageFragment.getMemberScope().getClassifier(name) as? ClassDescriptor
?: error("Class $name not found in $packageFragment")
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(containingDeclaration, Name.identifier(functionKind.classNamePrefix), Annotations.EMPTY) { superParameters ->
// 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++
// Add unnumbered base class, e.g. Function for Function{n}, KFunction for KFunction{n}
add(containingDeclaration, Name.identifier(functionKind.classNamePrefix))
// For KFunction{n}, add corresponding numbered Function{n} class, e.g. Function2 for KFunction2
if (functionKind == Kind.KFunction) {
val module = containingDeclaration.getContainingDeclaration()
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,
// 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()) }
}
add(kotlinPackageFragment, Kind.Function.numberedClassName(arity))
}
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.reflect.KFunction
abstract class KFunctionImpl private constructor(
open class KFunctionImpl protected constructor(
container: KCallableContainerImpl,
name: String,
signature: String,
@@ -44,7 +44,7 @@ public class ReflectionFactoryImpl extends ReflectionFactory {
@Override
public KFunction function(FunctionReference f) {
return new KTopLevelFreeFunctionImpl((KPackageImpl) f.getOwner(), f.getName(), f.getSignature());
return new KFunctionFromReferenceImpl(f);
}
// 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;
import kotlin.jvm.KotlinReflectionNotSupportedError;
import kotlin.reflect.*;
import kotlin.reflect.KDeclarationContainer;
import kotlin.reflect.KFunction;
public class FunctionReference
extends FunctionImpl
implements KTopLevelFunction,
KMemberFunction,
KTopLevelExtensionFunction,
KLocalFunction {
public class FunctionReference extends FunctionImpl implements KFunction {
private final int arity;
public FunctionReference(int arity) {
@@ -122,7 +122,7 @@ public final class FunctionCallableReferenceTest extends AbstractCallableReferen
checkFooBoxIsOk();
}
public void testClassMemberAndExtensionCompatibility() throws Exception {
public void testClassMemberAndNonExtensionCompatibility() throws Exception {
checkFooBoxIsOk();
}
@@ -173,9 +173,7 @@ object InvokeIntrinsic : FunctionCallCase {
funDeclaration == callableDescriptor.builtIns.getFunction(parameterCount) ||
funDeclaration == reflectionTypes.getKFunction(parameterCount)
else
funDeclaration == callableDescriptor.builtIns.getExtensionFunction(parameterCount) ||
funDeclaration == reflectionTypes.getKExtensionFunction(parameterCount) ||
funDeclaration == reflectionTypes.getKMemberFunction(parameterCount)
funDeclaration == callableDescriptor.builtIns.getExtensionFunction(parameterCount)
}
override fun FunctionCallInfo.dispatchReceiver(): JsExpression {
@@ -17,8 +17,8 @@
package org.jetbrains.kotlin.js.translate.context;
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.TypeCheck;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
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 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_LOCAL_EXTENSION_FUNCTION_NAME = "getCallableRefForLocalExtensionFunction";
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_MEMBER_PROPERTY = "getCallableRefForMemberProperty";
@@ -261,6 +262,8 @@ public final class Namer {
@NotNull
private final JsName callableRefForExtensionFunctionName;
@NotNull
private final JsName callableRefForLocalExtensionFunctionName;
@NotNull
private final JsName callableRefForConstructorName;
@NotNull
private final JsName callableRefForTopLevelProperty;
@@ -295,6 +298,7 @@ public final class Namer {
objectName = kotlinScope.declareName(OBJECT_OBJECT_NAME);
callableRefForMemberFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_MEMBER_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);
callableRefForTopLevelProperty = kotlinScope.declareName(CALLABLE_REF_FOR_TOP_LEVEL_PROPERTY);
callableRefForMemberProperty = kotlinScope.declareName(CALLABLE_REF_FOR_MEMBER_PROPERTY);
@@ -344,6 +348,11 @@ public final class Namer {
return kotlin(callableRefForExtensionFunctionName);
}
@NotNull
public JsExpression callableRefForLocalExtensionFunctionReference() {
return kotlin(callableRefForLocalExtensionFunctionName);
}
@NotNull
public JsExpression callableRefForConstructorReference() {
return kotlin(callableRefForConstructorName);
@@ -130,15 +130,18 @@ object CallableReferenceTranslator {
assert(receiverParameterDescriptor != null, "receiverParameter for extension should not be null")
val jsFunctionRef = ReferenceTranslator.translateAsFQReference(descriptor, context)
if (descriptor.getVisibility() == Visibilities.LOCAL)
return jsFunctionRef
if (descriptor.getVisibility() == Visibilities.LOCAL) {
return JsInvocation(context.namer().callableRefForLocalExtensionFunctionReference(), jsFunctionRef)
}
else if (AnnotationsUtils.isNativeObject(descriptor)) {
val jetType = receiverParameterDescriptor!!.getType()
val receiverClassDescriptor = DescriptorUtils.getClassDescriptorForType(jetType)
return translateAsMemberFunctionReference(descriptor, receiverClassDescriptor, context)
}
else
else {
return JsInvocation(context.namer().callableRefForExtensionFunctionReference(), jsFunctionRef)
}
}
private fun translateForMemberFunction(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression {
@@ -9,4 +9,4 @@ class B : A() {
override fun foo() = "OK"
}
fun box(): String = B().(A::foo)()
fun box(): String = (A::foo)(B())
@@ -2,7 +2,7 @@
package foo
fun box(): String {
if (true.(Boolean::not)() != false) return "Fail 1"
if (false.(Boolean::not)() != true) return "Fail 2"
if ((Boolean::not)(true) != false) return "Fail 1"
if ((Boolean::not)(false) != true) return "Fail 2"
return "OK"
}
@@ -12,14 +12,14 @@ fun box():String {
val a = A()
var r = a.(A::memBar)("!!")
var r = (A::memBar)(a, "!!")
if (r != "sA:memBar:!!") return r
r = a.(A::extBar)("!!")
r = (A::extBar)(a, "!!")
if (r != "sA:extBar:!!") return r
r = a.(A::locExtBar)("!!")
r = (A::locExtBar)(a, "!!")
if (r != "sA:locExtBar:!!") return r
return "OK"
}
}
@@ -1,7 +1,7 @@
package foo
fun run(a: A, arg: String, funRef:A.(String) -> String): String {
return a.(funRef)(arg)
fun run(a: A, arg: String, funRef:(A, String) -> String): String {
return funRef(a, arg)
}
class A {
@@ -25,8 +25,8 @@ fun box():String {
r = run(a, "!!", A::locExtBar)
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
return "OK"
}
}
@@ -4,7 +4,7 @@ package foo
class A {
fun bar(k: Int) = k
fun result() = this.(::bar)(111)
fun result() = (::bar)(this, 111)
}
fun box(): String {
@@ -6,7 +6,7 @@ class A {
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 {
val result = A().bar()
@@ -1,22 +1,12 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo
fun run(arg1: A, funRef:A.() -> String): String {
return arg1.funRef()
}
class A {
fun foo() = "OK"
}
fun box(): String {
val x = A::foo
var r = A().x()
if (r != "OK") return r
r = run(A(), A::foo)
if (r != "OK") return r
return "OK"
var r = x(A())
return r
}
@@ -1,21 +1,13 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo
fun run(arg1: A, arg2: String, funRef:A.(String) -> String): String {
return arg1.funRef(arg2)
}
class A {
fun foo(result: String):String = result
}
fun box(): String {
val x = A::foo
var r = A().x("OK")
var r = x(A(), "OK")
if (r != "OK") return r
r = run(A(), "OK", A::foo)
if (r != "OK") return r
return "OK"
return r
}
@@ -1,10 +1,6 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo
fun run(arg1: A, funRef:A.() -> Unit): Unit {
return arg1.funRef()
}
class A {
var result = "Fail"
@@ -16,14 +12,6 @@ class A {
fun box(): String {
val a = A()
val x = A::foo
a.x()
var r = a.result
if (r != "OK") return r
val a1 = A()
run(a1, A::foo)
r = a.result
if (r != "OK") return r
return "OK"
x(a)
return a.result
}
@@ -1,10 +1,6 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo
fun run(arg1: A, arg2: String, funRef:A.(String) -> Unit): Unit {
return arg1.funRef(arg2)
}
class A {
var result = "Fail"
@@ -16,14 +12,6 @@ class A {
fun box(): String {
val a = A()
val x = A::foo
a.x("OK")
var r = 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"
x(a, "OK")
return a.result
}
@@ -11,6 +11,6 @@ class B : A() {
fun box(): String {
val b = B()
var ref = A::foo
val result = b.(ref)("1", "2")
val result = ref(b, "1", "2")
return (if (result == "fooB:12") "OK" else result)
}
@@ -10,6 +10,6 @@ object B : A() {
fun box(): String {
var ref = B::foo
val result = B.(ref)("1", "2")
val result = ref(B, "1", "2")
return (if (result == "fooB:12") "OK" else result)
}
@@ -5,5 +5,5 @@ class A
fun box(): String {
fun A.foo() = "OK"
return A().(A::foo)()
return (A::foo)(A())
}
@@ -2,7 +2,7 @@
package foo
class A {
fun result() = this.(::bar)("OK")
fun result() = (::bar)(this, "OK")
}
fun A.bar(x: String) = x
@@ -3,7 +3,7 @@ package foo
class A
fun A.foo() = this.(A::bar)("OK")
fun A.foo() = (A::bar)(this, "OK")
fun A.bar(x: String) = x
@@ -1,8 +1,8 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo
fun <T> run(arg1: A, arg2: T, funRef:A.(T) -> T): T {
return arg1.funRef(arg2)
fun <T> run(arg1: A, arg2: T, funRef:(A, T) -> T): T {
return funRef(arg1, arg2)
}
class A {
@@ -17,9 +17,9 @@ fun A.bar(x: Int): Int {
fun box(): Boolean {
val funRef = A::bar
val obj = A()
var result = obj.(funRef)(25)
var result = funRef(obj, 25)
if (result != 25 || obj.xx != 200) return false
result = run(A(), 25, funRef)
return result == 25 && obj.xx == 200
}
}
@@ -11,7 +11,7 @@ fun A.foo() = "OK"
fun box(): String {
val x = A::foo
var r = A().x()
var r = x(A())
if (r != "OK") return r
r = run(A(), A::foo)

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