CFA: No more UNRESOLVED_CALL for object / enum entry qualifiers
(cherry picked from commit 4b09de8)
This commit is contained in:
committed by
Mikhail Glukhikh
parent
962c2e5dd2
commit
b7ed68db05
@@ -129,6 +129,8 @@ interface ControlFlowBuilder {
|
||||
operation: PredefinedOperation,
|
||||
inputValues: List<PseudoValue>): OperationInstruction
|
||||
|
||||
fun read(element: KtElement, target: AccessTarget, receiverValues: Map<PseudoValue, ReceiverValue>): ReadValueInstruction
|
||||
|
||||
fun write(
|
||||
assignment: KtElement,
|
||||
lValue: KtElement,
|
||||
|
||||
@@ -176,6 +176,9 @@ abstract class ControlFlowBuilderAdapter : ControlFlowBuilder {
|
||||
delegateBuilder.returnNoValue(returnExpression, subroutine)
|
||||
}
|
||||
|
||||
override fun read(element: KtElement, target: AccessTarget, receiverValues: Map<PseudoValue, ReceiverValue>) =
|
||||
delegateBuilder.read(element, target, receiverValues)
|
||||
|
||||
override fun write(
|
||||
assignment: KtElement,
|
||||
lValue: KtElement,
|
||||
|
||||
@@ -48,12 +48,11 @@ import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.getFakeDescriptorForObject
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
|
||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import java.util.*
|
||||
|
||||
@@ -266,8 +265,14 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
||||
if (resolvedCall is VariableAsFunctionResolvedCall) {
|
||||
generateCall(resolvedCall.variableCall)
|
||||
}
|
||||
else if (!generateCall(expression) && expression.parent !is KtCallExpression) {
|
||||
createNonSyntheticValue(expression, MagicKind.UNRESOLVED_CALL, generateAndGetReceiverIfAny(expression))
|
||||
else {
|
||||
if (resolvedCall == null) {
|
||||
val qualifier = trace.bindingContext[BindingContext.QUALIFIER, expression]
|
||||
if (qualifier != null && generateQualifier(expression, qualifier)) return
|
||||
}
|
||||
if (!generateCall(expression) && expression.parent !is KtCallExpression) {
|
||||
createNonSyntheticValue(expression, MagicKind.UNRESOLVED_CALL, generateAndGetReceiverIfAny(expression))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1366,6 +1371,18 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
||||
createNonSyntheticValue(element, MagicKind.UNSUPPORTED_ELEMENT)
|
||||
}
|
||||
|
||||
private fun generateQualifier(expression: KtExpression, qualifier: Qualifier): Boolean {
|
||||
val qualifierDescriptor = qualifier.descriptor
|
||||
if (qualifierDescriptor is ClassDescriptor) {
|
||||
getFakeDescriptorForObject(qualifierDescriptor)?.let {
|
||||
mark(expression)
|
||||
builder.read(expression, AccessTarget.Declaration(it), emptyMap())
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun generateCall(callElement: KtElement): Boolean {
|
||||
return checkAndGenerateCall(callElement.getResolvedCall(trace.bindingContext))
|
||||
}
|
||||
|
||||
+22
-22
@@ -331,21 +331,19 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() {
|
||||
labelCount = pseudocode.repeatPart(startLabel, finishLabel, labelCount)
|
||||
}
|
||||
|
||||
override fun loadConstant(expression: KtExpression, constant: CompileTimeConstant<*>?): InstructionWithValue {
|
||||
return read(expression)
|
||||
}
|
||||
override fun loadConstant(expression: KtExpression, constant: CompileTimeConstant<*>?) = read(expression)
|
||||
|
||||
override fun createAnonymousObject(expression: KtObjectLiteralExpression): InstructionWithValue {
|
||||
return read(expression)
|
||||
}
|
||||
override fun createAnonymousObject(expression: KtObjectLiteralExpression) = read(expression)
|
||||
|
||||
override fun createLambda(expression: KtFunction): InstructionWithValue {
|
||||
return read(if (expression is KtFunctionLiteral) expression.getParent() as KtLambdaExpression else expression)
|
||||
}
|
||||
override fun createLambda(expression: KtFunction) =
|
||||
read(if (expression is KtFunctionLiteral) expression.getParent() as KtLambdaExpression else expression)
|
||||
|
||||
override fun loadStringTemplate(expression: KtStringTemplateExpression, inputValues: List<PseudoValue>): InstructionWithValue {
|
||||
return if (inputValues.isEmpty()) read(expression) else magic(expression, expression, inputValues, MagicKind.STRING_TEMPLATE)
|
||||
}
|
||||
override fun loadStringTemplate(
|
||||
expression: KtStringTemplateExpression,
|
||||
inputValues: List<PseudoValue>
|
||||
): InstructionWithValue =
|
||||
if (inputValues.isEmpty()) read(expression)
|
||||
else magic(expression, expression, inputValues, MagicKind.STRING_TEMPLATE)
|
||||
|
||||
override fun magic(
|
||||
instructionElement: KtElement,
|
||||
@@ -367,9 +365,8 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() {
|
||||
override fun readVariable(
|
||||
expression: KtExpression,
|
||||
resolvedCall: ResolvedCall<*>,
|
||||
receiverValues: Map<PseudoValue, ReceiverValue>): ReadValueInstruction {
|
||||
return read(expression, resolvedCall, receiverValues)
|
||||
}
|
||||
receiverValues: Map<PseudoValue, ReceiverValue>
|
||||
) = read(expression, resolvedCall, receiverValues)
|
||||
|
||||
override fun call(
|
||||
valueElement: KtElement,
|
||||
@@ -404,16 +401,19 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun read(
|
||||
element: KtElement,
|
||||
target: AccessTarget,
|
||||
receiverValues: Map<PseudoValue, ReceiverValue>
|
||||
) = ReadValueInstruction(element, currentScope, target, receiverValues, valueFactory).apply {
|
||||
add(this)
|
||||
}
|
||||
|
||||
private fun read(
|
||||
expression: KtExpression,
|
||||
resolvedCall: ResolvedCall<*>? = null,
|
||||
receiverValues: Map<PseudoValue, ReceiverValue> = emptyMap<PseudoValue, ReceiverValue>()): ReadValueInstruction {
|
||||
val accessTarget = if (resolvedCall != null) AccessTarget.Call(resolvedCall) else AccessTarget.BlackBox
|
||||
val instruction = ReadValueInstruction(
|
||||
expression, currentScope, accessTarget, receiverValues, valueFactory)
|
||||
add(instruction)
|
||||
return instruction
|
||||
}
|
||||
receiverValues: Map<PseudoValue, ReceiverValue> = emptyMap<PseudoValue, ReceiverValue>()
|
||||
) = read(expression, if (resolvedCall != null) AccessTarget.Call(resolvedCall) else AccessTarget.BlackBox, receiverValues)
|
||||
}
|
||||
|
||||
private class TryFinallyBlockInfo(private val finallyBlock: GenerationTrigger) : BlockInfo() {
|
||||
|
||||
Reference in New Issue
Block a user