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:
@@ -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(),
|
||||
|
||||
+9
-2
@@ -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");
|
||||
|
||||
+3
-5
@@ -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(
|
||||
|
||||
+2
-2
@@ -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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,4 +6,4 @@ class B : A() {
|
||||
override fun foo() = "OK"
|
||||
}
|
||||
|
||||
fun box(): String = B().(A::foo)()
|
||||
fun box(): String = (A::foo)(B())
|
||||
|
||||
+2
-2
@@ -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
-1
@@ -1,7 +1,7 @@
|
||||
class A {
|
||||
fun foo(k: Int) = k
|
||||
|
||||
fun result() = this.(::foo)(111)
|
||||
fun result() = (::foo)(this, 111)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
|
||||
Vendored
+1
-1
@@ -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()
|
||||
|
||||
+1
-1
@@ -4,5 +4,5 @@ class A {
|
||||
|
||||
fun box(): String {
|
||||
val x = A::foo
|
||||
return A().x()
|
||||
return x(A())
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,5 +4,5 @@ class A {
|
||||
|
||||
fun box(): String {
|
||||
val x = A::foo
|
||||
return A().x("OK")
|
||||
return x(A(), "OK")
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,6 +9,6 @@ class A {
|
||||
fun box(): String {
|
||||
val a = A()
|
||||
val x = A::foo
|
||||
a.x()
|
||||
x(a)
|
||||
return a.result
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
-1
@@ -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
-1
@@ -1,5 +1,5 @@
|
||||
class A {
|
||||
fun result() = this.(::foo)("OK")
|
||||
fun result() = (::foo)(this, "OK")
|
||||
}
|
||||
|
||||
fun A.foo(x: String) = x
|
||||
|
||||
Vendored
+1
-1
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -4,5 +4,5 @@ fun A.foo() = "OK"
|
||||
|
||||
fun box(): String {
|
||||
val x = A::foo
|
||||
return A().x()
|
||||
return x(A())
|
||||
}
|
||||
|
||||
+1
-1
@@ -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")
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,6 +9,6 @@ fun A.foo() {
|
||||
fun box(): String {
|
||||
val a = A()
|
||||
val x = A::foo
|
||||
a.x()
|
||||
x(a)
|
||||
return a.result
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
}
|
||||
|
||||
+1
-1
@@ -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"))
|
||||
|
||||
Vendored
+1
-1
@@ -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 {
|
||||
|
||||
Vendored
+1
-1
@@ -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()
|
||||
|
||||
+1
-1
@@ -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"
|
||||
}
|
||||
|
||||
+1
-1
@@ -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"
|
||||
}
|
||||
|
||||
+1
-1
@@ -8,5 +8,5 @@ class Outer {
|
||||
|
||||
fun box(): String {
|
||||
val f = Outer.Inner::foo
|
||||
return Outer().Inner().f()
|
||||
return f(Outer().Inner())
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,5 +4,5 @@ fun box(): String {
|
||||
}
|
||||
|
||||
val ref = Local::foo
|
||||
return Local().ref()
|
||||
return ref(Local())
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -7,5 +7,5 @@ enum class E : Named {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return E.OK.(Named::name)()
|
||||
return (Named::name)(E.OK)
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,5 +2,5 @@ class A
|
||||
|
||||
fun box(): String {
|
||||
fun A.foo() = "OK"
|
||||
return A().(A::foo)()
|
||||
return (A::foo)(A())
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
fun box(): String {
|
||||
class A
|
||||
fun A.foo() = "OK"
|
||||
return (::A)().(A::foo)()
|
||||
return (A::foo)((::A)())
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -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"
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -6,6 +6,6 @@ fun box(): String {
|
||||
fun A.ext() { result = "OK" }
|
||||
|
||||
val f = A::ext
|
||||
A().f()
|
||||
f(A())
|
||||
return result
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,5 +4,5 @@ fun box(): String {
|
||||
}
|
||||
|
||||
val ref = Id<String>::invoke
|
||||
return Id<String>().ref("OK")
|
||||
return ref(Id<String>(), "OK")
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -7,5 +7,5 @@ fun box(): String {
|
||||
|
||||
val member = Local::foo
|
||||
val instance = Local()
|
||||
return instance.member()
|
||||
return member(instance)
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -8,6 +8,6 @@ object A {
|
||||
|
||||
fun box(): String {
|
||||
val x = A::foo
|
||||
A.x()
|
||||
x(A)
|
||||
return A.result
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -8,6 +8,6 @@ object A {
|
||||
|
||||
fun box(): String {
|
||||
val x = A::foo
|
||||
A.x("OK")
|
||||
x(A, "OK")
|
||||
return A.result
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
class A {
|
||||
private fun foo() = "OK"
|
||||
|
||||
fun bar() = this.(::foo)()
|
||||
fun bar() = (::foo)(this)
|
||||
}
|
||||
|
||||
fun box() = A().bar()
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ interface T {
|
||||
|
||||
class B : T {
|
||||
inner class C {
|
||||
fun bar() = this@B.(::foo)()
|
||||
fun bar() = (::foo)(this@B)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
Vendored
+2
-2
@@ -5,5 +5,5 @@ open class A {
|
||||
}
|
||||
|
||||
fun test() {
|
||||
A.B.(A::foo)()
|
||||
}
|
||||
(A::foo)(A.B)
|
||||
}
|
||||
|
||||
+3
-3
@@ -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)
|
||||
}
|
||||
|
||||
Vendored
+3
-3
@@ -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)
|
||||
}
|
||||
|
||||
+3
-3
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -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() {}
|
||||
|
||||
Vendored
+3
-3
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -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)
|
||||
}
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+2
-2
@@ -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 {
|
||||
|
||||
+2
-2
@@ -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)
|
||||
}
|
||||
|
||||
Vendored
+6
-6
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+5
-5
@@ -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)
|
||||
}
|
||||
|
||||
Vendored
+3
-3
@@ -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)
|
||||
}
|
||||
|
||||
+2
-2
@@ -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)
|
||||
}
|
||||
|
||||
+2
-2
@@ -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)
|
||||
}
|
||||
|
||||
+3
-3
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -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)
|
||||
}
|
||||
|
||||
Vendored
+3
-3
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -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)
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -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)
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -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>
|
||||
+3
-4
@@ -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))
|
||||
}
|
||||
|
||||
|
||||
+8
-11
@@ -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()
|
||||
|
||||
|
||||
+23
-63
@@ -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) {
|
||||
|
||||
+1
-1
@@ -122,7 +122,7 @@ public final class FunctionCallableReferenceTest extends AbstractCallableReferen
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
|
||||
public void testClassMemberAndExtensionCompatibility() throws Exception {
|
||||
public void testClassMemberAndNonExtensionCompatibility() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
|
||||
|
||||
+1
-3
@@ -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);
|
||||
|
||||
+6
-3
@@ -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 {
|
||||
|
||||
+1
-1
@@ -9,4 +9,4 @@ class B : A() {
|
||||
override fun foo() = "OK"
|
||||
}
|
||||
|
||||
fun box(): String = B().(A::foo)()
|
||||
fun box(): String = (A::foo)(B())
|
||||
|
||||
+2
-2
@@ -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"
|
||||
}
|
||||
|
||||
+4
-4
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -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"
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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 {
|
||||
|
||||
+1
-1
@@ -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()
|
||||
|
||||
Vendored
+2
-12
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+2
-10
@@ -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
|
||||
}
|
||||
|
||||
Vendored
+2
-14
@@ -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
|
||||
}
|
||||
|
||||
+2
-14
@@ -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
|
||||
}
|
||||
|
||||
+1
-1
@@ -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)
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -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())
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
package foo
|
||||
|
||||
class A {
|
||||
fun result() = this.(::bar)("OK")
|
||||
fun result() = (::bar)(this, "OK")
|
||||
}
|
||||
|
||||
fun A.bar(x: String) = x
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
|
||||
+4
-4
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -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
Reference in New Issue
Block a user