Inherit KProperty interfaces from function types
To be able to write the following: listOfStrings.map(String::length)
This commit is contained in:
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.modules.TargetId;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
||||
@@ -538,9 +539,16 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
|
||||
/*lambda or callable reference*/
|
||||
public static boolean isInliningParameter(KtExpression expression, ValueParameterDescriptor valueParameterDescriptor) {
|
||||
public boolean isInliningParameter(KtExpression expression, ValueParameterDescriptor valueParameterDescriptor) {
|
||||
//TODO deparenthisise typed
|
||||
KtExpression deparenthesized = KtPsiUtil.deparenthesize(expression);
|
||||
|
||||
if (deparenthesized instanceof KtCallableReferenceExpression) {
|
||||
// TODO: support inline of property references passed to inlinable function parameters
|
||||
SimpleFunctionDescriptor functionReference = state.getBindingContext().get(BindingContext.FUNCTION, deparenthesized);
|
||||
if (functionReference == null) return false;
|
||||
}
|
||||
|
||||
return InlineUtil.isInlineLambdaParameter(valueParameterDescriptor) &&
|
||||
isInlinableParameterExpression(deparenthesized);
|
||||
}
|
||||
|
||||
Vendored
+31
@@ -0,0 +1,31 @@
|
||||
var state = ""
|
||||
|
||||
var topLevel: Int
|
||||
get() {
|
||||
state += "1"
|
||||
return 42
|
||||
}
|
||||
set(value) {
|
||||
throw AssertionError("Nooo")
|
||||
}
|
||||
|
||||
class A {
|
||||
val member: String
|
||||
get() {
|
||||
state += "2"
|
||||
return "42"
|
||||
}
|
||||
}
|
||||
|
||||
val A.ext: Any
|
||||
get() {
|
||||
state += "3"
|
||||
return this
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
(::topLevel)()
|
||||
(A::member)(A())
|
||||
(A::ext)(A())
|
||||
return if (state == "123") "OK" else "Fail $state"
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import kotlin.reflect.declaredMemberProperties
|
||||
|
||||
class A(val foo: String)
|
||||
|
||||
fun box(): String {
|
||||
return (A::class.declaredMemberProperties.single()).invoke(A("OK")) as String
|
||||
}
|
||||
+12
@@ -816,6 +816,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("invokePropertyReference.kt")
|
||||
public void testInvokePropertyReference() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/callableReference/property/invokePropertyReference.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("javaBeanConvention.kt")
|
||||
public void testJavaBeanConvention() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/callableReference/property/javaBeanConvention.kt");
|
||||
@@ -4191,6 +4197,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("invokeKProperty.kt")
|
||||
public void testInvokeKProperty() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/properties/invokeKProperty.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("memberAndMemberExtensionWithSameName.kt")
|
||||
public void testMemberAndMemberExtensionWithSameName() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/properties/memberAndMemberExtensionWithSameName.kt");
|
||||
|
||||
@@ -65,7 +65,7 @@ public interface KMutableProperty<R> : KProperty<R> {
|
||||
* Such property is either originally declared in a receiverless context such as a package,
|
||||
* or has the receiver bound to it.
|
||||
*/
|
||||
public interface KProperty0<out R> : KProperty<R> {
|
||||
public interface KProperty0<out R> : KProperty<R>, () -> R {
|
||||
/**
|
||||
* Returns the current value of the property.
|
||||
*/
|
||||
@@ -99,7 +99,7 @@ public interface KMutableProperty0<R> : KProperty0<R>, KMutableProperty<R> {
|
||||
* @param T the type of the receiver which should be used to obtain the value of the property.
|
||||
* @param R the type of the property.
|
||||
*/
|
||||
public interface KProperty1<T, out R> : KProperty<R> {
|
||||
public interface KProperty1<T, out R> : KProperty<R>, (T) -> R {
|
||||
/**
|
||||
* Returns the current value of the property.
|
||||
*
|
||||
@@ -144,7 +144,7 @@ public interface KMutableProperty1<T, R> : KProperty1<T, R>, KMutableProperty<R>
|
||||
* the type of the extension receiver.
|
||||
* @param R the type of the property.
|
||||
*/
|
||||
public interface KProperty2<D, E, out R> : KProperty<R> {
|
||||
public interface KProperty2<D, E, out R> : KProperty<R>, (D, E) -> R {
|
||||
/**
|
||||
* Returns the current value of the property. In case of the extension property in a class,
|
||||
* the instance of the class should be passed first and the instance of the extension receiver second.
|
||||
|
||||
@@ -31,6 +31,8 @@ internal open class KProperty0Impl<out R> : DescriptorBasedProperty<R>, KPropert
|
||||
|
||||
override fun get(): R = getter.call()
|
||||
|
||||
override fun invoke(): R = get()
|
||||
|
||||
class Getter<out R>(override val property: KProperty0Impl<R>) : KPropertyImpl.Getter<R>(), KProperty0.Getter<R> {
|
||||
override fun invoke(): R = property.get()
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ internal open class KProperty1Impl<T, out R> : DescriptorBasedProperty<R>, KProp
|
||||
|
||||
override fun get(receiver: T): R = getter.call(receiver)
|
||||
|
||||
override fun invoke(receiver: T): R = get(receiver)
|
||||
|
||||
class Getter<T, out R>(override val property: KProperty1Impl<T, R>) : KPropertyImpl.Getter<R>(), KProperty1.Getter<T, R> {
|
||||
override fun invoke(receiver: T): R = property.get(receiver)
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ internal open class KProperty2Impl<D, E, out R> : DescriptorBasedProperty<R>, KP
|
||||
|
||||
override fun get(receiver1: D, receiver2: E): R = getter.call(receiver1, receiver2)
|
||||
|
||||
override fun invoke(receiver1: D, receiver2: E): R = get(receiver1, receiver2)
|
||||
|
||||
class Getter<D, E, out R>(override val property: KProperty2Impl<D, E, R>) : KPropertyImpl.Getter<R>(), KProperty2.Getter<D, E, R> {
|
||||
override fun invoke(receiver1: D, receiver2: E): R = property.get(receiver1, receiver2)
|
||||
}
|
||||
|
||||
@@ -36,6 +36,11 @@ public class MutablePropertyReference0 extends MutablePropertyReference implemen
|
||||
((KMutableProperty0) getReflected()).set(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke() {
|
||||
return get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public KProperty0.Getter getGetter() {
|
||||
return ((KMutableProperty0) getReflected()).getGetter();
|
||||
|
||||
@@ -36,6 +36,11 @@ public class MutablePropertyReference1 extends MutablePropertyReference implemen
|
||||
((KMutableProperty1) getReflected()).set(receiver, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object receiver) {
|
||||
return get(receiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KProperty1.Getter getGetter() {
|
||||
return ((KMutableProperty1) getReflected()).getGetter();
|
||||
|
||||
@@ -36,6 +36,11 @@ public class MutablePropertyReference2 extends MutablePropertyReference implemen
|
||||
((KMutableProperty2) getReflected()).set(receiver1, receiver2, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object receiver1, Object receiver2) {
|
||||
return get(receiver1, receiver2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KProperty2.Getter getGetter() {
|
||||
return ((KMutableProperty2) getReflected()).getGetter();
|
||||
|
||||
@@ -30,6 +30,11 @@ public class PropertyReference0 extends PropertyReference implements KProperty0
|
||||
return ((KProperty0) getReflected()).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke() {
|
||||
return get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public KProperty0.Getter getGetter() {
|
||||
return ((KProperty0) getReflected()).getGetter();
|
||||
|
||||
@@ -30,6 +30,11 @@ public class PropertyReference1 extends PropertyReference implements KProperty1
|
||||
return ((KProperty1) getReflected()).get(receiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object receiver) {
|
||||
return get(receiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KProperty1.Getter getGetter() {
|
||||
return ((KProperty1) getReflected()).getGetter();
|
||||
|
||||
@@ -30,6 +30,11 @@ public class PropertyReference2 extends PropertyReference implements KProperty2
|
||||
return ((KProperty2) getReflected()).get(receiver1, receiver2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object receiver1, Object receiver2) {
|
||||
return get(receiver1, receiver2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KProperty2.Getter getGetter() {
|
||||
return ((KProperty2) getReflected()).getGetter();
|
||||
|
||||
Reference in New Issue
Block a user