From 5ddf8e60e602dc370fa2a227eae2c9fb3f1d5015 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Tue, 6 Dec 2016 14:57:18 +0300 Subject: [PATCH] Use delegate initializer expression resolution scope for 'toDelegateFor' resolution. --- .../resolve/DelegatedPropertyResolver.kt | 55 ++++++++++--------- .../VariableTypeAndInitializerResolver.kt | 4 +- .../toDelegateFor/extensionDelegated.kt | 16 ++++++ .../toDelegateFor/extensionDelegated.txt | 19 +++++++ .../delegatedProperty/severalReceivers.kt | 13 +++++ .../delegatedProperty/severalReceivers.txt | 26 +++++++++ .../toDelegateFor/commonCaseForInference.kt | 13 +++++ .../toDelegateFor/commonCaseForInference.txt | 19 +++++++ .../toDelegateFor/hostAndReceiver1.kt | 9 +++ .../toDelegateFor/hostAndReceiver1.txt | 12 ++++ .../toDelegateFor/hostAndReceiver2.kt | 13 +++++ .../toDelegateFor/hostAndReceiver2.txt | 19 +++++++ .../toDelegateFor/hostAndReceiver3.kt | 12 ++++ .../toDelegateFor/hostAndReceiver3.txt | 18 ++++++ .../toDelegateFor/inferenceFromReceiver1.kt | 14 +++++ .../toDelegateFor/inferenceFromReceiver1.txt | 18 ++++++ .../toDelegateFor/inferenceFromReceiver2.kt | 13 +++++ .../toDelegateFor/inferenceFromReceiver2.txt | 19 +++++++ .../toDelegateFor/setValue.kt | 16 ++++++ .../toDelegateFor/setValue.txt | 17 ++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 15 +++++ .../checkers/DiagnosticsTestGenerated.java | 48 ++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 15 +++++ ...LightAnalysisModeCodegenTestGenerated.java | 15 +++++ .../semantics/JsCodegenBoxTestGenerated.java | 15 +++++ 25 files changed, 424 insertions(+), 29 deletions(-) create mode 100644 compiler/testData/codegen/box/delegatedProperty/toDelegateFor/extensionDelegated.kt create mode 100644 compiler/testData/codegen/light-analysis/delegatedProperty/toDelegateFor/extensionDelegated.txt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/severalReceivers.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/severalReceivers.txt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/commonCaseForInference.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/commonCaseForInference.txt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver1.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver1.txt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver2.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver2.txt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver3.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver3.txt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver1.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver1.txt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver2.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver2.txt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/setValue.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/setValue.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.kt index 86dd26d91e1..0649a55b0ba 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.kt @@ -86,12 +86,12 @@ class DelegatedPropertyResolver( val byExpressionType = resolveDelegateExpression(delegateExpression, property, variableDescriptor, initializerScope, trace, outerDataFlowInfo) - resolveToDelegateForMethod(variableDescriptor, delegateExpression, byExpressionType, trace, delegateFunctionsScope, outerDataFlowInfo) + resolveToDelegateForMethod(variableDescriptor, delegateExpression, byExpressionType, trace, initializerScope, outerDataFlowInfo) val delegateType = getResolvedDelegateType(variableDescriptor, delegateExpression, byExpressionType, trace) - resolveGetValueMethod(variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, outerDataFlowInfo) + resolveGetValueMethod(variableDescriptor, delegateExpression, delegateType, trace, initializerScope, outerDataFlowInfo) if (property.isVar) { - resolveSetValueMethod(variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, outerDataFlowInfo) + resolveSetValueMethod(variableDescriptor, delegateExpression, delegateType, trace, initializerScope, outerDataFlowInfo) } resolvePropertyDelegatedMethod(variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, outerDataFlowInfo) @@ -116,12 +116,12 @@ class DelegatedPropertyResolver( delegateExpression: KtExpression, byExpressionType: KotlinType, trace: BindingTrace, - delegateFunctionsScope: LexicalScope, + initializerScope: LexicalScope, dataFlowInfo: DataFlowInfo ): KotlinType? { - resolveToDelegateForMethod(variableDescriptor, delegateExpression, byExpressionType, trace, delegateFunctionsScope, dataFlowInfo) + resolveToDelegateForMethod(variableDescriptor, delegateExpression, byExpressionType, trace, initializerScope, dataFlowInfo) val delegateType = getResolvedDelegateType(variableDescriptor, delegateExpression, byExpressionType, trace) - resolveGetSetValueMethod(variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, dataFlowInfo, true) + resolveGetSetValueMethod(variableDescriptor, delegateExpression, delegateType, trace, initializerScope, dataFlowInfo, true) val resolvedCall = trace.bindingContext.get(DELEGATED_PROPERTY_RESOLVED_CALL, variableDescriptor.getter) return if (resolvedCall != null) resolvedCall.resultingDescriptor.returnType else null @@ -135,10 +135,10 @@ class DelegatedPropertyResolver( delegateExpression: KtExpression, delegateType: KotlinType, trace: BindingTrace, - delegateFunctionsScope: LexicalScope, + initializerScope: LexicalScope, dataFlowInfo: DataFlowInfo ) { - val returnType = getGetValueMethodReturnType(variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, dataFlowInfo) + val returnType = getGetValueMethodReturnType(variableDescriptor, delegateExpression, delegateType, trace, initializerScope, dataFlowInfo) val propertyType = variableDescriptor.type /* Do not check return type of get() method of delegate for properties with DeferredType because property type is taken from it */ @@ -155,11 +155,11 @@ class DelegatedPropertyResolver( delegateExpression: KtExpression, delegateType: KotlinType, trace: BindingTrace, - delegateFunctionsScope: LexicalScope, + initializerScope: LexicalScope, dataFlowInfo: DataFlowInfo ) { resolveGetSetValueMethod(variableDescriptor, delegateExpression, delegateType, trace, - delegateFunctionsScope, dataFlowInfo, false) + initializerScope, dataFlowInfo, false) } private fun KtPsiFactory.createExpressionForProperty(): KtExpression { @@ -208,7 +208,7 @@ class DelegatedPropertyResolver( delegateExpression: KtExpression, delegateType: KotlinType, trace: BindingTrace, - delegateFunctionsScope: LexicalScope, + initializerScope: LexicalScope, dataFlowInfo: DataFlowInfo, isGet: Boolean ) { @@ -218,7 +218,7 @@ class DelegatedPropertyResolver( if (trace.bindingContext.get(DELEGATED_PROPERTY_CALL, accessor) != null) return val functionResults = getGetSetValueMethod( - propertyDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, dataFlowInfo, + propertyDescriptor, delegateExpression, delegateType, trace, initializerScope, dataFlowInfo, isGet = isGet, isComplete = true ) @@ -273,14 +273,14 @@ class DelegatedPropertyResolver( byExpression: KtExpression, byExpressionType: KotlinType, trace: BindingTrace, - delegateFunctionsScope: LexicalScope, + initializerScope: LexicalScope, dataFlowInfo: DataFlowInfo ) { if (!isOperatorToDelegateForSupported) return if (trace.bindingContext.get(BindingContext.TO_DELEGATE_FOR_CALL, propertyDescriptor) != null) return val toDelegateForResults = getToDelegateForMethod(propertyDescriptor, byExpression, byExpressionType, - trace, delegateFunctionsScope, dataFlowInfo) + trace, initializerScope, dataFlowInfo) if (!toDelegateForResults.isSuccess) { val call = trace.bindingContext.get(BindingContext.TO_DELEGATE_FOR_CALL, propertyDescriptor) ?: throw AssertionError("'getDelegatedPropertyConventionMethod' didn't record a call") @@ -305,11 +305,13 @@ class DelegatedPropertyResolver( delegateExpression: KtExpression, delegateType: KotlinType, trace: BindingTrace, - delegateFunctionsScope: LexicalScope, + scopeForDelegate: LexicalScope, dataFlowInfo: DataFlowInfo, isGet: Boolean, isComplete: Boolean ): OverloadResolutionResults { + val delegateFunctionsScope = ScopeUtils.makeScopeForDelegateConventionFunctions(scopeForDelegate, propertyDescriptor) + val accessor = (if (isGet) propertyDescriptor.getter else propertyDescriptor.setter) ?: throw AssertionError("Delegated property should have getter/setter $propertyDescriptor ${delegateExpression.text}") @@ -350,13 +352,12 @@ class DelegatedPropertyResolver( delegateExpression: KtExpression, delegateExpressionType: KotlinType, trace: BindingTrace, - delegateFunctionsScope: LexicalScope, + initializerScope: LexicalScope, dataFlowInfo: DataFlowInfo ): OverloadResolutionResults { val expectedType = TypeUtils.NO_EXPECTED_TYPE - val context = ExpressionTypingContext.newContext(trace, delegateFunctionsScope, dataFlowInfo, expectedType) - val propertyHasReceiver = propertyDescriptor.extensionReceiverParameter != null || - propertyDescriptor.dispatchReceiverParameter != null + val context = ExpressionTypingContext.newContext(trace, initializerScope, dataFlowInfo, expectedType) + val propertyHasReceiver = propertyDescriptor.dispatchReceiverParameter != null val arguments = KtPsiFactory(delegateExpression).run { listOf( createExpression(if (propertyHasReceiver) "this" else "null"), @@ -420,7 +421,6 @@ class DelegatedPropertyResolver( trace: BindingTrace, dataFlowInfo: DataFlowInfo ): ConstraintSystemCompleter { - val delegateFunctionsScope = ScopeUtils.makeScopeForDelegateConventionFunctions(scopeForDelegate, variableDescriptor) val expectedType = if (property.typeReference != null) variableDescriptor.type else NO_EXPECTED_TYPE return object : ConstraintSystemCompleter { @@ -435,7 +435,7 @@ class DelegatedPropertyResolver( val delegateType = getDelegateType(returnType, constraintSystem, typeVariableSubstitutor, traceToResolveConventionMethods) val getValueResults = getGetSetValueMethod( - variableDescriptor, delegateExpression, delegateType, traceToResolveConventionMethods, delegateFunctionsScope, dataFlowInfo, + variableDescriptor, delegateExpression, delegateType, traceToResolveConventionMethods, scopeForDelegate, dataFlowInfo, isGet = true, isComplete = false ) if (conventionMethodFound(getValueResults)) { @@ -457,7 +457,7 @@ class DelegatedPropertyResolver( if (variableDescriptor.returnType is DeferredType) return val setValueResults = getGetSetValueMethod( - variableDescriptor, delegateExpression, delegateType, traceToResolveConventionMethods, delegateFunctionsScope, dataFlowInfo, + variableDescriptor, delegateExpression, delegateType, traceToResolveConventionMethods, scopeForDelegate, dataFlowInfo, isGet = false, isComplete = false ) if (conventionMethodFound(setValueResults)) { @@ -483,13 +483,14 @@ class DelegatedPropertyResolver( if (isOperatorToDelegateForSupported) { val toDelegateForResults = getToDelegateForMethod( variableDescriptor, delegateExpression, byExpressionType, - traceToResolveConventionMethods, delegateFunctionsScope, dataFlowInfo + traceToResolveConventionMethods, scopeForDelegate, dataFlowInfo ) if (conventionMethodFound(toDelegateForResults)) { val toDelegateForDescriptor = toDelegateForResults.resultingDescriptor val toDelegateForReturnType = toDelegateForDescriptor.returnType if (toDelegateForDescriptor.isOperator) { - addConstraintForThisValue(constraintSystem, typeVariableSubstitutor, toDelegateForDescriptor) + addConstraintForThisValue(constraintSystem, typeVariableSubstitutor, toDelegateForDescriptor, + dispatchReceiverOnly = true) return toDelegateForReturnType ?: throw AssertionError("No return type fore 'createDelegate' of ${delegateExpression.text}") } @@ -506,11 +507,13 @@ class DelegatedPropertyResolver( private fun addConstraintForThisValue( constraintSystem: ConstraintSystem.Builder, typeVariableSubstitutor: TypeSubstitutor, - resultingDescriptor: FunctionDescriptor + resultingDescriptor: FunctionDescriptor, + dispatchReceiverOnly: Boolean = false ) { val extensionReceiver = variableDescriptor.extensionReceiverParameter val dispatchReceiver = variableDescriptor.dispatchReceiverParameter - val typeOfThis = extensionReceiver?.type ?: dispatchReceiver?.type ?: builtIns.nullableNothingType + val typeOfThis = (if (dispatchReceiverOnly) dispatchReceiver?.type else (extensionReceiver?.type ?: dispatchReceiver?.type)) + ?: builtIns.nullableNothingType val valueParameters = resultingDescriptor.valueParameters if (valueParameters.isEmpty()) return diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt index 9836b42dab6..b078ad29b01 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt @@ -27,7 +27,6 @@ import org.jetbrains.kotlin.resolve.DescriptorResolver.transformAnonymousTypeIfN import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator import org.jetbrains.kotlin.resolve.scopes.LexicalScope -import org.jetbrains.kotlin.resolve.scopes.ScopeUtils import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.DeferredType import org.jetbrains.kotlin.types.ErrorUtils @@ -139,9 +138,8 @@ class VariableTypeAndInitializerResolver( val type = delegatedPropertyResolver.resolveDelegateExpression( delegateExpression, property, variableDescriptor, scopeForInitializer, trace, dataFlowInfo) - val delegateFunctionsScope = ScopeUtils.makeScopeForDelegateConventionFunctions(scopeForInitializer, variableDescriptor) val getterReturnType = delegatedPropertyResolver.getGetValueMethodReturnType( - variableDescriptor, delegateExpression, type, trace, delegateFunctionsScope, dataFlowInfo + variableDescriptor, delegateExpression, type, trace, scopeForInitializer, dataFlowInfo ) getterReturnType ?: ErrorUtils.createErrorType("Type from delegate") diff --git a/compiler/testData/codegen/box/delegatedProperty/toDelegateFor/extensionDelegated.kt b/compiler/testData/codegen/box/delegatedProperty/toDelegateFor/extensionDelegated.kt new file mode 100644 index 00000000000..f44e553e7f7 --- /dev/null +++ b/compiler/testData/codegen/box/delegatedProperty/toDelegateFor/extensionDelegated.kt @@ -0,0 +1,16 @@ +import kotlin.reflect.KProperty + +var log = "" + +class UserDataProperty(val key: String) { + operator fun getValue(thisRef: R, desc: KProperty<*>) = thisRef.toString() + key + + operator fun setValue(thisRef: R, desc: KProperty<*>, value: String?) { log += "set"} +} + + +var String.calc: String by UserDataProperty("K") + +fun box(): String { + return "O".calc +} \ No newline at end of file diff --git a/compiler/testData/codegen/light-analysis/delegatedProperty/toDelegateFor/extensionDelegated.txt b/compiler/testData/codegen/light-analysis/delegatedProperty/toDelegateFor/extensionDelegated.txt new file mode 100644 index 00000000000..4e6484ef7d8 --- /dev/null +++ b/compiler/testData/codegen/light-analysis/delegatedProperty/toDelegateFor/extensionDelegated.txt @@ -0,0 +1,19 @@ +public final class ExtensionDelegatedKt { + private synthetic final static field $$delegatedProperties: kotlin.reflect.KProperty[] + private final static @org.jetbrains.annotations.NotNull field calc$delegate: UserDataProperty + private static @org.jetbrains.annotations.NotNull field log: java.lang.String + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + public final static @org.jetbrains.annotations.NotNull method getCalc(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.String + public final static @org.jetbrains.annotations.NotNull method getLog(): java.lang.String + public final static method setCalc(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: java.lang.String): void + public final static method setLog(@org.jetbrains.annotations.NotNull p0: java.lang.String): void +} + + +public final class UserDataProperty { + private final @org.jetbrains.annotations.NotNull field key: java.lang.String + public method (@org.jetbrains.annotations.NotNull p0: java.lang.String): void + public final @org.jetbrains.annotations.NotNull method getKey(): java.lang.String + public final @org.jetbrains.annotations.NotNull method getValue(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.reflect.KProperty): java.lang.String + public final method setValue(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.reflect.KProperty, @org.jetbrains.annotations.Nullable p2: java.lang.String): void +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/severalReceivers.kt b/compiler/testData/diagnostics/tests/delegatedProperty/severalReceivers.kt new file mode 100644 index 00000000000..f1864d532dc --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/severalReceivers.kt @@ -0,0 +1,13 @@ +import kotlin.reflect.KProperty + +class A + +object Delegate { + operator fun getValue(state: A, desc: KProperty<*>): Int = 0 + operator fun setValue(state: A, desc: KProperty<*>, value: Int) {} +} + +open class B { + val A.foo: Int by Delegate + var A.bar: Int by Delegate +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/severalReceivers.txt b/compiler/testData/diagnostics/tests/delegatedProperty/severalReceivers.txt new file mode 100644 index 00000000000..72d5d8aaaf5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/severalReceivers.txt @@ -0,0 +1,26 @@ +package + +public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class B { + public constructor B() + public final var A.bar: kotlin.Int + public final val A.foo: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public object Delegate { + private constructor Delegate() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final operator fun getValue(/*0*/ state: A, /*1*/ desc: kotlin.reflect.KProperty<*>): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final operator fun setValue(/*0*/ state: A, /*1*/ desc: kotlin.reflect.KProperty<*>, /*2*/ value: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/commonCaseForInference.kt b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/commonCaseForInference.kt new file mode 100644 index 00000000000..8bd333de979 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/commonCaseForInference.kt @@ -0,0 +1,13 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +object CommonCase { + interface Fas + + fun delegate() : Fas = TODO() + + operator fun Fas.toDelegateFor(host: D, p: Any?): Fas = TODO() + operator fun Fas.getValue(receiver: E, p: Any?): R = TODO() + + val Long.test1: String by delegate() // common test, not working because of Inference1 + val Long.test2: String by delegate() // should work +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/commonCaseForInference.txt b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/commonCaseForInference.txt new file mode 100644 index 00000000000..33752f70eb9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/commonCaseForInference.txt @@ -0,0 +1,19 @@ +package + +public object CommonCase { + private constructor CommonCase() + public final val kotlin.Long.test1: kotlin.String + public final val kotlin.Long.test2: kotlin.String + public final fun delegate(): CommonCase.Fas + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public final operator fun CommonCase.Fas.getValue(/*0*/ receiver: E, /*1*/ p: kotlin.Any?): R + public final operator fun CommonCase.Fas.toDelegateFor(/*0*/ host: D, /*1*/ p: kotlin.Any?): CommonCase.Fas + + public interface Fas { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver1.kt b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver1.kt new file mode 100644 index 00000000000..e6948ab1028 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver1.kt @@ -0,0 +1,9 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +object T1 { + operator fun Int.toDelegateFor(host: T1, p: Any): Long = 2 + operator fun Long.getValue(receiver: String, p: Any): Double = 1.0 + + val String.test1 by 1 + val test2 by 1 +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver1.txt b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver1.txt new file mode 100644 index 00000000000..3d691cecb47 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver1.txt @@ -0,0 +1,12 @@ +package + +public object T1 { + private constructor T1() + public final val test2: [ERROR : Type from delegate] + public final val kotlin.String.test1: kotlin.Double + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public final operator fun kotlin.Long.getValue(/*0*/ receiver: kotlin.String, /*1*/ p: kotlin.Any): kotlin.Double + public final operator fun kotlin.Int.toDelegateFor(/*0*/ host: T1, /*1*/ p: kotlin.Any): kotlin.Long +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver2.kt b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver2.kt new file mode 100644 index 00000000000..695c9bc5436 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver2.kt @@ -0,0 +1,13 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +object T2 { + interface Foo + + fun delegate(): Foo = TODO() + + operator fun Foo.toDelegateFor(host: T2, p: Any?): Foo = TODO() + operator fun Foo.getValue(receiver: String, p: Any?): T = TODO() + + val String.test1: String by delegate() + val test2: String by delegate() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver2.txt b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver2.txt new file mode 100644 index 00000000000..c0458a3ec02 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver2.txt @@ -0,0 +1,19 @@ +package + +public object T2 { + private constructor T2() + public final val test2: kotlin.String + public final val kotlin.String.test1: kotlin.String + public final fun delegate(): T2.Foo + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public final operator fun T2.Foo.getValue(/*0*/ receiver: kotlin.String, /*1*/ p: kotlin.Any?): T + public final operator fun T2.Foo.toDelegateFor(/*0*/ host: T2, /*1*/ p: kotlin.Any?): T2.Foo + + public interface Foo { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver3.kt b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver3.kt new file mode 100644 index 00000000000..f408772b82a --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver3.kt @@ -0,0 +1,12 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +object T3 { + interface Foo + + fun delegate(): Foo = TODO() + + operator fun Foo.toDelegateFor(host: T3, p: Any?): Foo = TODO() + operator fun Foo.getValue(receiver: T3, p: Any?): T = TODO() + + val test1: String by delegate() +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver3.txt b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver3.txt new file mode 100644 index 00000000000..8c2839bdd3b --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver3.txt @@ -0,0 +1,18 @@ +package + +public object T3 { + private constructor T3() + public final val test1: kotlin.String + public final fun delegate(): T3.Foo + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public final operator fun T3.Foo.getValue(/*0*/ receiver: T3, /*1*/ p: kotlin.Any?): T + public final operator fun T3.Foo.toDelegateFor(/*0*/ host: T3, /*1*/ p: kotlin.Any?): T3.Foo + + public interface Foo { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver1.kt b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver1.kt new file mode 100644 index 00000000000..e2fcf5fc23c --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver1.kt @@ -0,0 +1,14 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +object Inference1 { + interface Foo + + fun delegate(): Foo = TODO() + + operator fun Foo.getValue(receiver: T, p: Any?): String = TODO() + + // not working because resulting descriptor for getValue contains type `???` instead of `T` + val test1: String by delegate() + + val test2: String by delegate() +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver1.txt b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver1.txt new file mode 100644 index 00000000000..3c3fab2cb36 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver1.txt @@ -0,0 +1,18 @@ +package + +public object Inference1 { + private constructor Inference1() + public final val test1: kotlin.String + public final val test2: kotlin.String + public final fun delegate(): Inference1.Foo + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public final operator fun Inference1.Foo.getValue(/*0*/ receiver: T, /*1*/ p: kotlin.Any?): kotlin.String + + public interface Foo { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver2.kt b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver2.kt new file mode 100644 index 00000000000..21ec10f39c3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver2.kt @@ -0,0 +1,13 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +object Inference2 { + interface Foo + + fun delegate(): Foo = TODO() + + operator fun Foo.toDelegateFor(host: T, p: Any?): Foo = TODO() + operator fun Foo.getValue(receiver: Inference2, p: Any?): String = TODO() + + val test1: String by delegate() // same story like in Inference1 + val test2: String by delegate() +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver2.txt b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver2.txt new file mode 100644 index 00000000000..fbdd2001b3c --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver2.txt @@ -0,0 +1,19 @@ +package + +public object Inference2 { + private constructor Inference2() + public final val test1: kotlin.String + public final val test2: kotlin.String + public final fun delegate(): Inference2.Foo + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public final operator fun Inference2.Foo.getValue(/*0*/ receiver: Inference2, /*1*/ p: kotlin.Any?): kotlin.String + public final operator fun Inference2.Foo.toDelegateFor(/*0*/ host: T, /*1*/ p: kotlin.Any?): Inference2.Foo + + public interface Foo { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/setValue.kt b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/setValue.kt new file mode 100644 index 00000000000..fcfca632533 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/setValue.kt @@ -0,0 +1,16 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +class Delegate + +operator fun Delegate<*>.getValue(receiver: Any?, p: Any): String = "" +operator fun Delegate.setValue(receiver: Any?, p: Any, value: T) {} + +operator fun String.toDelegateFor(receiver: Any?, p: Any) = Delegate() + +var test1: String by Delegate() +var test2: String by Delegate() + +var test3: String by "OK" + +var test4: String by "OK".toDelegateFor(null, "") +var test5: String by "OK".toDelegateFor(null, "") \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/setValue.txt b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/setValue.txt new file mode 100644 index 00000000000..197f0da8529 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/setValue.txt @@ -0,0 +1,17 @@ +package + +public var test1: kotlin.String +public var test2: kotlin.String +public var test3: kotlin.String +public var test4: kotlin.String +public var test5: kotlin.String +public operator fun Delegate<*>.getValue(/*0*/ receiver: kotlin.Any?, /*1*/ p: kotlin.Any): kotlin.String +public operator fun Delegate.setValue(/*0*/ receiver: kotlin.Any?, /*1*/ p: kotlin.Any, /*2*/ value: T): kotlin.Unit +public operator fun kotlin.String.toDelegateFor(/*0*/ receiver: kotlin.Any?, /*1*/ p: kotlin.Any): Delegate + +public final class Delegate { + public constructor Delegate() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 2e8b0f3d1a1..d701b01ae99 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -5992,6 +5992,21 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } } + + @TestMetadata("compiler/testData/codegen/box/delegatedProperty/toDelegateFor") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ToDelegateFor extends AbstractIrBlackBoxCodegenTest { + public void testAllFilesPresentInToDelegateFor() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/delegatedProperty/toDelegateFor"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("extensionDelegated.kt") + public void testExtensionDelegated() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/toDelegateFor/extensionDelegated.kt"); + doTest(fileName); + } + } } @TestMetadata("compiler/testData/codegen/box/delegation") diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index dbaa30805aa..f01916c473b 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -5680,6 +5680,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("severalReceivers.kt") + public void testSeveralReceivers() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/severalReceivers.kt"); + doTest(fileName); + } + @TestMetadata("thisInDelegate.kt") public void testThisInDelegate() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/thisInDelegate.kt"); @@ -5841,12 +5847,48 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("commonCaseForInference.kt") + public void testCommonCaseForInference() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/commonCaseForInference.kt"); + doTest(fileName); + } + @TestMetadata("genericToDelegateFor.kt") public void testGenericToDelegateFor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/genericToDelegateFor.kt"); doTest(fileName); } + @TestMetadata("hostAndReceiver1.kt") + public void testHostAndReceiver1() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver1.kt"); + doTest(fileName); + } + + @TestMetadata("hostAndReceiver2.kt") + public void testHostAndReceiver2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver2.kt"); + doTest(fileName); + } + + @TestMetadata("hostAndReceiver3.kt") + public void testHostAndReceiver3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/hostAndReceiver3.kt"); + doTest(fileName); + } + + @TestMetadata("inferenceFromReceiver1.kt") + public void testInferenceFromReceiver1() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver1.kt"); + doTest(fileName); + } + + @TestMetadata("inferenceFromReceiver2.kt") + public void testInferenceFromReceiver2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/inferenceFromReceiver2.kt"); + doTest(fileName); + } + @TestMetadata("localDelegatedProperty.kt") public void testLocalDelegatedProperty() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/localDelegatedProperty.kt"); @@ -5859,6 +5901,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("setValue.kt") + public void testSetValue() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/setValue.kt"); + doTest(fileName); + } + @TestMetadata("simpleToDelegateFor.kt") public void testSimpleToDelegateFor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/toDelegateFor/simpleToDelegateFor.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 3769a835bc3..b09361d3853 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -5992,6 +5992,21 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } } + + @TestMetadata("compiler/testData/codegen/box/delegatedProperty/toDelegateFor") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ToDelegateFor extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInToDelegateFor() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/delegatedProperty/toDelegateFor"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("extensionDelegated.kt") + public void testExtensionDelegated() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/toDelegateFor/extensionDelegated.kt"); + doTest(fileName); + } + } } @TestMetadata("compiler/testData/codegen/box/delegation") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java index 979470f3e51..e9242fdf678 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java @@ -5992,6 +5992,21 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis doTest(fileName); } } + + @TestMetadata("compiler/testData/codegen/box/delegatedProperty/toDelegateFor") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ToDelegateFor extends AbstractLightAnalysisModeCodegenTest { + public void testAllFilesPresentInToDelegateFor() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/delegatedProperty/toDelegateFor"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("extensionDelegated.kt") + public void testExtensionDelegated() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/toDelegateFor/extensionDelegated.kt"); + doTest(fileName); + } + } } @TestMetadata("compiler/testData/codegen/box/delegation") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 11b1a589a95..b732f83e594 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -6887,6 +6887,21 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } } + + @TestMetadata("compiler/testData/codegen/box/delegatedProperty/toDelegateFor") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ToDelegateFor extends AbstractJsCodegenBoxTest { + public void testAllFilesPresentInToDelegateFor() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/delegatedProperty/toDelegateFor"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); + } + + @TestMetadata("extensionDelegated.kt") + public void testExtensionDelegated() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/toDelegateFor/extensionDelegated.kt"); + doTest(fileName); + } + } } @TestMetadata("compiler/testData/codegen/box/delegation")