diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.kt index 130cc871ec6..d5cc683f4bb 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.VariableAccessorDescriptor import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors import org.jetbrains.kotlin.diagnostics.Errors.* +import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.BindingContext.* @@ -290,7 +291,7 @@ class DelegatedPropertyResolver( resolutionErrorFactory?.let { val expectedFunction = renderCall(delegateOperatorCall, trace.bindingContext) - trace.report(it.on(delegateExpression, expectedFunction, delegateOperatorResults.resultingCalls)) + trace.reportDiagnosticOnce(it.on(delegateExpression, expectedFunction, delegateOperatorResults.resultingCalls)) } return resolutionErrorFactory != null diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java index ed8faed18a8..b8c20928838 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java @@ -290,6 +290,21 @@ public class CallResolver { callResolutionContext, resolutionCandidates, TracingStrategyImpl.create(expression, call)); } + @NotNull + public OverloadResolutionResults resolveThisOrSuperCallWithGivenDescriptor( + @NotNull ExpressionTypingContext context, + @NotNull Call call, + @NotNull ReceiverParameterDescriptor descriptor + ) { + BasicCallResolutionContext callResolutionContext = BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS); + + return PSICallResolver.runResolutionAndInferenceForGivenDescriptors( + callResolutionContext, + Collections.singletonList(descriptor), + TracingStrategy.EMPTY + ); + } + @NotNull public OverloadResolutionResults resolveFunctionCall( @NotNull BindingTrace trace, @@ -605,7 +620,7 @@ public class CallResolver { if (newInferenceEnabled && resolutionKind instanceof NewResolutionOldInference.ResolutionKind.GivenCandidates) { assert resolutionTask.givenCandidates != null; BindingContextUtilsKt.recordScope(context.trace, context.scope, context.call.getCalleeExpression()); - return PSICallResolver.runResolutionAndInferenceForGivenCandidates(context, resolutionTask.givenCandidates, tracing); + return PSICallResolver.runResolutionAndInferenceForGivenOldCandidates(context, resolutionTask.givenCandidates, tracing); } TemporaryBindingTrace traceToResolveCall = TemporaryBindingTrace.create(context.trace, "trace to resolve call", call); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt index dfaedb79673..bdf3cb08ad9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt @@ -143,8 +143,36 @@ class PSICallResolver( } } + fun runResolutionAndInferenceForGivenDescriptors( + context: BasicCallResolutionContext, + descriptors: Collection, + tracingStrategy: TracingStrategy + ): OverloadResolutionResults { + val isSpecialFunction = descriptors.any { it.name in SPECIAL_FUNCTION_NAMES } + val kotlinCall = toKotlinCall( + context, KotlinCallKind.FUNCTION, context.call, givenCandidatesName, tracingStrategy, isSpecialFunction, null + ) + val scopeTower = ASTScopeTower(context) + val resolutionCallbacks = createResolutionCallbacks(context) + val givenCandidates = descriptors.map { + GivenCandidate( + it, + dispatchReceiver = null, + knownTypeParametersResultingSubstitutor = null + ) + } + + val result = kotlinCallResolver.resolveAndCompleteGivenCandidates( + scopeTower, resolutionCallbacks, kotlinCall, calculateExpectedType(context), givenCandidates, context.collectAllCandidates + ) + + return convertToOverloadResolutionResults(context, result, tracingStrategy).also { + clearCacheForApproximationResults() + } + } + // actually, `D` is at least FunctionDescriptor, but right now because of CallResolver it isn't possible change upper bound for `D` - fun runResolutionAndInferenceForGivenCandidates( + fun runResolutionAndInferenceForGivenOldCandidates( context: BasicCallResolutionContext, resolutionCandidates: Collection>, tracingStrategy: TracingStrategy diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index 9b8e9c6b328..6053dba0198 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -58,7 +58,6 @@ import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsUtil; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue; import org.jetbrains.kotlin.resolve.calls.smartcasts.Nullability; -import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind; import org.jetbrains.kotlin.resolve.calls.tasks.OldResolutionCandidate; import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy; import org.jetbrains.kotlin.resolve.calls.tower.NewAbstractResolvedCall; @@ -636,27 +635,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { ) { BindingTrace trace = context.trace; Call call = CallMaker.makeCall(expression, null, null, expression, Collections.emptyList()); - OldResolutionCandidate resolutionCandidate = - OldResolutionCandidate.create( - call, descriptor, null, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, null); + OverloadResolutionResults results = + components.callResolver.resolveThisOrSuperCallWithGivenDescriptor(context, call, descriptor); - ResolvedCallImpl resolvedCall = - ResolvedCallImpl.create(resolutionCandidate, - TemporaryBindingTrace.create(trace, "Fake trace for fake 'this' or 'super' resolved call"), - TracingStrategy.EMPTY, - new DataFlowInfoForArgumentsImpl(context.dataFlowInfo, call)); - resolvedCall.markCallAsCompleted(); + ResolvedCall resolvedCall = results.getResultingCall(); trace.record(RESOLVED_CALL, call, resolvedCall); trace.record(CALL, expression, call); - - if (context.trace.wantsDiagnostics()) { - CallCheckerContext callCheckerContext = - createCallCheckerContext(context); - for (CallChecker checker : components.callCheckers) { - checker.check(resolvedCall, expression, callCheckerContext); - } - } } private static boolean isDeclaredInClass(ReceiverParameterDescriptor receiver) { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt index 57d71ec95cc..7121c1d7567 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.model import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.ReflectionTypes import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.resolve.calls.components.* @@ -48,7 +49,7 @@ class KotlinCallComponents( ) class GivenCandidate( - val descriptor: FunctionDescriptor, + val descriptor: CallableDescriptor, val dispatchReceiver: ReceiverValueWithSmartCastInfo?, val knownTypeParametersResultingSubstitutor: TypeSubstitutor? ) diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.fir.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.fir.kt deleted file mode 100644 index 914e317e5d0..00000000000 --- a/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.fir.kt +++ /dev/null @@ -1,44 +0,0 @@ -package foo - -import kotlin.reflect.KProperty - -class A { - var a5: String by MyProperty1() - var b5: String by getMyProperty1() -} - -fun getMyProperty1() = MyProperty1() - -class MyProperty1 { - - operator fun getValue(thisRef: R, desc: KProperty<*>): T { - throw Exception() - } - - operator fun setValue(i: Int, j: Any, k: Int) { - println("set") - } -} - -// ----------------- - -class B { - var a5: String by MyProperty2() - var b5: String by getMyProperty2() -} - -fun getMyProperty2() = MyProperty2() - -class MyProperty2 { - - operator fun getValue(thisRef: R, desc: KProperty<*>): T { - throw Exception() - } - - operator fun setValue(i: Int) { - println("set") - } -} - -// ----------------- -fun println(a: Any?) = a diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.kt index 68c0eb2d53d..19e6dce1454 100644 --- a/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.kt +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.kt @@ -1,10 +1,11 @@ +// FIR_IDENTICAL package foo import kotlin.reflect.KProperty class A { - var a5: String by MyProperty1() - var b5: String by getMyProperty1() + var a5: String by MyProperty1() + var b5: String by getMyProperty1() } fun getMyProperty1() = MyProperty1() @@ -23,8 +24,8 @@ class MyProperty1 { // ----------------- class B { - var a5: String by MyProperty2() - var b5: String by getMyProperty2() + var a5: String by MyProperty2() + var b5: String by getMyProperty2() } fun getMyProperty2() = MyProperty2() diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/thisOfNothingNullableType.fir.kt b/compiler/testData/diagnostics/tests/delegatedProperty/thisOfNothingNullableType.fir.kt new file mode 100644 index 00000000000..0ef43a4fc44 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/thisOfNothingNullableType.fir.kt @@ -0,0 +1,17 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +import kotlin.reflect.KProperty + +class A { + var a: Int by Delegate() +} + +var aTopLevel: Int by Delegate() + +class Delegate { + operator fun getValue(t: Nothing?, p: KProperty<*>): Int { + return 1 + } + operator fun setValue(t: Nothing?, p: KProperty<*>, a: Int) { + } +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/thisOfNothingNullableType.kt b/compiler/testData/diagnostics/tests/delegatedProperty/thisOfNothingNullableType.kt index 166a2aa8a70..de408633be1 100644 --- a/compiler/testData/diagnostics/tests/delegatedProperty/thisOfNothingNullableType.kt +++ b/compiler/testData/diagnostics/tests/delegatedProperty/thisOfNothingNullableType.kt @@ -1,10 +1,9 @@ -// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER import kotlin.reflect.KProperty class A { - var a: Int by Delegate() + var a: Int by Delegate() } var aTopLevel: Int by Delegate() diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/thisOfNothingType.fir.kt b/compiler/testData/diagnostics/tests/delegatedProperty/thisOfNothingType.fir.kt new file mode 100644 index 00000000000..1088ea9b8fd --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/thisOfNothingType.fir.kt @@ -0,0 +1,17 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +import kotlin.reflect.KProperty + +class A { + var a: Int by Delegate() +} + +var aTopLevel: Int by Delegate() + +class Delegate { + fun getValue(t: Nothing, p: KProperty<*>): Int { + return 1 + } + fun setValue(t: Nothing, p: KProperty<*>, a: Int) { + } +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/thisOfNothingType.kt b/compiler/testData/diagnostics/tests/delegatedProperty/thisOfNothingType.kt index d916945818b..e1eadab0b52 100644 --- a/compiler/testData/diagnostics/tests/delegatedProperty/thisOfNothingType.kt +++ b/compiler/testData/diagnostics/tests/delegatedProperty/thisOfNothingType.kt @@ -1,10 +1,9 @@ -// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER import kotlin.reflect.KProperty class A { - var a: Int by Delegate() + var a: Int by Delegate() } var aTopLevel: Int by Delegate()