Do not enter in recursion for implicit invoke on variable with un inferred type
This commit is contained in:
@@ -96,6 +96,7 @@ internal class InvokeTowerProcessor<C>(
|
||||
// todo filter by operator
|
||||
override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor<C> {
|
||||
val (variableReceiver, invokeContext) = functionContext.contextForInvoke(variableCandidate, useExplicitReceiver = false)
|
||||
?: return KnownResultProcessor(emptyList())
|
||||
return ExplicitReceiverScopeTowerProcessor(invokeContext, variableReceiver, ScopeTowerLevel::getFunctions)
|
||||
}
|
||||
}
|
||||
@@ -110,6 +111,7 @@ internal class InvokeExtensionTowerProcessor<C>(
|
||||
|
||||
override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor<C> {
|
||||
val (variableReceiver, invokeContext) = functionContext.contextForInvoke(variableCandidate, useExplicitReceiver = true)
|
||||
?: return KnownResultProcessor(emptyList())
|
||||
val invokeDescriptor = functionContext.scopeTower.getExtensionInvokeCandidateDescriptor(variableReceiver)
|
||||
?: return KnownResultProcessor(emptyList())
|
||||
return InvokeExtensionScopeTowerProcessor(invokeContext, invokeDescriptor, explicitReceiver)
|
||||
|
||||
+8
-2
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyForInvoke
|
||||
import org.jetbrains.kotlin.resolve.isAnnotatedAsHidden
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||
import org.jetbrains.kotlin.types.DeferredType
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.isDynamic
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
@@ -243,7 +244,7 @@ class NewResolveOldInference(
|
||||
return Context(scopeTower, name, basicCallResolutionContext, tracing)
|
||||
}
|
||||
|
||||
override fun contextForInvoke(variable: Candidate, useExplicitReceiver: Boolean): Pair<ReceiverValue, TowerContext<Candidate>> {
|
||||
override fun contextForInvoke(variable: Candidate, useExplicitReceiver: Boolean): Pair<ReceiverValue, TowerContext<Candidate>>? {
|
||||
assert(variable.resolvedCall.status.possibleTransformToSuccess()) {
|
||||
"Incorrect status: ${variable.resolvedCall.status} for variable call: ${variable.resolvedCall} " +
|
||||
"and descriptor: ${variable.resolvedCall.candidateDescriptor}"
|
||||
@@ -253,8 +254,13 @@ class NewResolveOldInference(
|
||||
assert(variable.resolvedCall.status.possibleTransformToSuccess() && calleeExpression != null && variableDescriptor is VariableDescriptor) {
|
||||
"Unexpected varialbe candidate: $variable"
|
||||
}
|
||||
val variableType = (variableDescriptor as VariableDescriptor).type
|
||||
|
||||
if (variableType is DeferredType && variableType.isComputing) {
|
||||
return null // todo: create special check that there is no invoke on variable
|
||||
}
|
||||
val variableReceiver = ExpressionReceiver.create(calleeExpression!!,
|
||||
(variableDescriptor as VariableDescriptor).type,
|
||||
variableType,
|
||||
basicCallContext.trace.bindingContext)
|
||||
// used for smartCasts, see: DataFlowValueFactory.getIdForSimpleNameExpression
|
||||
tracing.bindReference(variable.resolvedCall.trace, variable.resolvedCall)
|
||||
|
||||
@@ -39,7 +39,8 @@ interface TowerContext<C> {
|
||||
fun contextForVariable(stripExplicitReceiver: Boolean): TowerContext<C>
|
||||
|
||||
// foo() -> ReceiverValue(foo), context for invoke
|
||||
fun contextForInvoke(variable: C, useExplicitReceiver: Boolean): Pair<ReceiverValue, TowerContext<C>>
|
||||
// null means that there is no invoke on variable
|
||||
fun contextForInvoke(variable: C, useExplicitReceiver: Boolean): Pair<ReceiverValue, TowerContext<C>>?
|
||||
}
|
||||
|
||||
internal sealed class TowerData {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
fun test() = 3
|
||||
|
||||
fun <T> proxy(t: T) = t
|
||||
|
||||
class A {
|
||||
val test = test()
|
||||
}
|
||||
|
||||
class B {
|
||||
val test = proxy(test())
|
||||
}
|
||||
|
||||
class C {
|
||||
val bar = <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!><!UNINITIALIZED_VARIABLE!>test<!>()<!>
|
||||
val test = <!FUNCTION_EXPECTED!>bar<!>()
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package
|
||||
|
||||
public fun </*0*/ T> proxy(/*0*/ t: T): T
|
||||
public fun test(): kotlin.Int
|
||||
|
||||
public final class A {
|
||||
public constructor A()
|
||||
public final val test: 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 final class B {
|
||||
public constructor B()
|
||||
public final val test: 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 final class C {
|
||||
public constructor C()
|
||||
public final val bar: [ERROR : <ERROR FUNCTION RETURN TYPE>]
|
||||
public final val test: [ERROR : Type for bar()]
|
||||
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
|
||||
}
|
||||
@@ -325,6 +325,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InvokeAndRecursiveResolve.kt")
|
||||
public void testInvokeAndRecursiveResolve() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/InvokeAndRecursiveResolve.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("IsExpressions.kt")
|
||||
public void testIsExpressions() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/IsExpressions.kt");
|
||||
|
||||
Reference in New Issue
Block a user