diff --git a/compiler/cli/cli-common/resources/META-INF/extensions/compiler.xml b/compiler/cli/cli-common/resources/META-INF/extensions/compiler.xml index 3e468bfc9f6..f8f16819081 100644 --- a/compiler/cli/cli-common/resources/META-INF/extensions/compiler.xml +++ b/compiler/cli/cli-common/resources/META-INF/extensions/compiler.xml @@ -23,6 +23,9 @@ + diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/AssignResolutionAltererExtension.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/AssignResolutionAltererExtension.kt new file mode 100644 index 00000000000..76fdca500f3 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/AssignResolutionAltererExtension.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.resolve.extensions + +import org.jetbrains.kotlin.extensions.AnnotationBasedExtension +import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor +import org.jetbrains.kotlin.extensions.internal.InternalNonStableExtensionPoints +import org.jetbrains.kotlin.psi.KtBinaryExpression +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.expressions.ExpressionTypingComponents +import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext +import org.jetbrains.kotlin.types.expressions.KotlinTypeInfo + +@InternalNonStableExtensionPoints +interface AssignResolutionAltererExtension : AnnotationBasedExtension { + companion object : ProjectExtensionDescriptor( + "org.jetbrains.kotlin.assignResolutionAltererExtension", + AssignResolutionAltererExtension::class.java + ) + + fun needOverloadAssign(expression: KtBinaryExpression, leftType: KotlinType?, bindingContext: BindingContext): Boolean + + fun resolveAssign( + bindingContext: BindingContext, + expression: KtBinaryExpression, + leftOperand: KtExpression, + left: KtExpression, + leftInfo: KotlinTypeInfo, + context: ExpressionTypingContext, + components: ExpressionTypingComponents, + scope: LexicalWritableScope + ): KotlinTypeInfo? +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorForStatements.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorForStatements.java index 73279fffc9f..b3f81527910 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorForStatements.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorForStatements.java @@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl; 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.extensions.AssignResolutionAltererExtension; import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil; import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope; import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver; @@ -56,6 +57,8 @@ import org.jetbrains.kotlin.util.OperatorNameConventions; import java.util.Collection; import java.util.HashSet; +import java.util.List; +import java.util.Objects; import static org.jetbrains.kotlin.diagnostics.Errors.*; import static org.jetbrains.kotlin.psi.KtPsiUtil.deparenthesize; @@ -441,6 +444,19 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito ? refineTypeByPropertyInType(bindingContext, leftOperand, leftType) : refineTypeFromPropertySetterIfPossible(bindingContext, leftOperand, leftType); + List assignAlterers = AssignResolutionAltererExtension.Companion.getInstances(expression.getProject()); + if (!assignAlterers.isEmpty()) { + KotlinTypeInfo alteredTypeInfo = assignAlterers.stream() + .filter((it) -> it.needOverloadAssign(expression, leftType, bindingContext)) + .map((it) -> it.resolveAssign(bindingContext, expression, leftOperand, left, leftInfo, context, components, scope)) + .filter(Objects::nonNull) + .findFirst() + .orElse(null); + if (alteredTypeInfo != null) { + return alteredTypeInfo; + } + } + DataFlowInfo dataFlowInfo = leftInfo.getDataFlowInfo(); KotlinTypeInfo resultInfo; if (right != null) {