More correct check for ResolvedCall status everywhere in the IDE + added assert into ResolvedCallImpl

This commit is contained in:
Valentin Kipyatkov
2015-09-28 21:28:55 +03:00
parent 110d53b4a6
commit 45748eb169
15 changed files with 42 additions and 27 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve.calls.model package org.jetbrains.kotlin.resolve.calls.model
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.types.ErrorUtils
public interface ArgumentMapping { public interface ArgumentMapping {
public fun isError(): Boolean public fun isError(): Boolean
@@ -61,3 +62,7 @@ class ArgumentMatchImpl(override val valueParameter: ValueParameterDescriptor):
return newArgumentMatch return newArgumentMatch
} }
} }
//TODO: temporary hack until status.isSuccess is not always correct
fun ResolvedCall<*>.isReallySuccess(): Boolean
= status.isSuccess && !ErrorUtils.isError(resultingDescriptor)
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve.calls.model; package org.jetbrains.kotlin.resolve.calls.model;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.Function; import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -46,6 +47,7 @@ import static org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.INCOMP
import static org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.UNKNOWN_STATUS; import static org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.UNKNOWN_STATUS;
public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableResolvedCall<D> { public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableResolvedCall<D> {
private static final Logger LOG = Logger.getInstance(ResolvedCallImpl.class);
public static final Function<MutableResolvedCall<?>, CallableDescriptor> MAP_TO_CANDIDATE = new Function<MutableResolvedCall<?>, CallableDescriptor>() { public static final Function<MutableResolvedCall<?>, CallableDescriptor> MAP_TO_CANDIDATE = new Function<MutableResolvedCall<?>, CallableDescriptor>() {
@Override @Override
@@ -275,6 +277,9 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
public ArgumentMapping getArgumentMapping(@NotNull ValueArgument valueArgument) { public ArgumentMapping getArgumentMapping(@NotNull ValueArgument valueArgument) {
ArgumentMatch argumentMatch = argumentToParameterMap.get(valueArgument); ArgumentMatch argumentMatch = argumentToParameterMap.get(valueArgument);
if (argumentMatch == null) { if (argumentMatch == null) {
if (ArgumentMappingKt.isReallySuccess(this)) {
LOG.error("ArgumentUnmapped for " + valueArgument + " in successfully resolved call: " + call.getCallElement().getText());
}
return ArgumentUnmapped.INSTANCE$; return ArgumentUnmapped.INSTANCE$;
} }
return argumentMatch; return argumentMatch;
@@ -28,15 +28,15 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.utils.addToStdlib.constant import org.jetbrains.kotlin.utils.addToStdlib.constant
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.emptyOrSingletonList import org.jetbrains.kotlin.utils.emptyOrSingletonList
import java.util.HashSet import java.util.*
// Navigation element of the resolved reference // Navigation element of the resolved reference
// For property accessor return enclosing property // For property accessor return enclosing property
@@ -168,7 +168,7 @@ public fun JetExpression.readWriteAccess(useResolveForReadWrite: Boolean): Refer
val bindingContext = assignment.analyze(BodyResolveMode.PARTIAL) val bindingContext = assignment.analyze(BodyResolveMode.PARTIAL)
val resolvedCall = assignment.getResolvedCall(bindingContext) ?: return ReferenceAccess.READ_WRITE val resolvedCall = assignment.getResolvedCall(bindingContext) ?: return ReferenceAccess.READ_WRITE
if (!resolvedCall.status.isSuccess) return ReferenceAccess.READ_WRITE if (!resolvedCall.isReallySuccess()) return ReferenceAccess.READ_WRITE
return if (resolvedCall.resultingDescriptor.name in OperatorConventions.ASSIGNMENT_OPERATIONS.values()) return if (resolvedCall.resultingDescriptor.name in OperatorConventions.ASSIGNMENT_OPERATIONS.values())
ReferenceAccess.READ ReferenceAccess.READ
else else
@@ -32,9 +32,9 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument
import org.jetbrains.kotlin.resolve.calls.callUtil.getValueArgumentsInParentheses import org.jetbrains.kotlin.resolve.calls.callUtil.getValueArgumentsInParentheses
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import java.util.ArrayList import java.util.*
import java.util.HashMap
public object OptionalParametersHelper { public object OptionalParametersHelper {
public fun detectArgumentsToDropForDefaults( public fun detectArgumentsToDropForDefaults(
@@ -42,7 +42,7 @@ public object OptionalParametersHelper {
project: Project, project: Project,
canDrop: (ValueArgument) -> Boolean = { true } canDrop: (ValueArgument) -> Boolean = { true }
): Collection<ValueArgument> { ): Collection<ValueArgument> {
if (!resolvedCall.getStatus().isSuccess()) return emptyList() if (!resolvedCall.isReallySuccess()) return emptyList()
val descriptor = resolvedCall.getResultingDescriptor() val descriptor = resolvedCall.getResultingDescriptor()
val parameterToDefaultValue = descriptor.getValueParameters() val parameterToDefaultValue = descriptor.getValueParameters()
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.renderer.render import org.jetbrains.kotlin.renderer.render
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotatedAsHidden import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotatedAsHidden
import org.jetbrains.kotlin.resolve.scopes.FileScope import org.jetbrains.kotlin.resolve.scopes.FileScope
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
@@ -131,7 +132,7 @@ public class ConflictingExtensionPropertyInspection : AbstractKotlinInspection()
when (this) { when (this) {
is JetCallExpression -> { is JetCallExpression -> {
val resolvedCall = getResolvedCall(analyze()) val resolvedCall = getResolvedCall(analyze())
return resolvedCall != null && resolvedCall.status.isSuccess && resolvedCall.resultingDescriptor.original == getMethod.original return resolvedCall != null && resolvedCall.isReallySuccess() && resolvedCall.resultingDescriptor.original == getMethod.original
} }
is JetQualifiedExpression -> { is JetQualifiedExpression -> {
@@ -148,7 +149,7 @@ public class ConflictingExtensionPropertyInspection : AbstractKotlinInspection()
is JetCallExpression -> { is JetCallExpression -> {
if ((valueArguments.singleOrNull()?.getArgumentExpression() as? JetSimpleNameExpression)?.getReferencedNameAsName() != valueParameterName) return false if ((valueArguments.singleOrNull()?.getArgumentExpression() as? JetSimpleNameExpression)?.getReferencedNameAsName() != valueParameterName) return false
val resolvedCall = getResolvedCall(analyze()) val resolvedCall = getResolvedCall(analyze())
return resolvedCall != null && resolvedCall.status.isSuccess && resolvedCall.resultingDescriptor.original == setMethod.original return resolvedCall != null && resolvedCall.isReallySuccess() && resolvedCall.resultingDescriptor.original == setMethod.original
} }
is JetQualifiedExpression -> { is JetQualifiedExpression -> {
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.resolve.BindingTraceContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
import org.jetbrains.kotlin.resolve.calls.CallResolver import org.jetbrains.kotlin.resolve.calls.CallResolver
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.utils.getFileScope import org.jetbrains.kotlin.resolve.scopes.utils.getFileScope
@@ -155,7 +156,7 @@ public class RedundantSamConstructorInspection : AbstractKotlinInspection() {
val bindingContext = functionCall.analyze(BodyResolveMode.PARTIAL) val bindingContext = functionCall.analyze(BodyResolveMode.PARTIAL)
val functionResolvedCall = functionCall.getResolvedCall(bindingContext) ?: return emptyList() val functionResolvedCall = functionCall.getResolvedCall(bindingContext) ?: return emptyList()
if (!functionResolvedCall.status.isSuccess) return emptyList() if (!functionResolvedCall.isReallySuccess()) return emptyList()
val samConstructorCalls = functionCall.valueArguments.map { val samConstructorCalls = functionCall.valueArguments.map {
(it.getArgumentExpression() as? JetCallExpression) (it.getArgumentExpression() as? JetCallExpression)
@@ -26,21 +26,21 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport
import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
import org.jetbrains.kotlin.idea.quickfix.moveCaret import org.jetbrains.kotlin.idea.quickfix.moveCaret
import org.jetbrains.kotlin.idea.util.ImportInsertHelper import org.jetbrains.kotlin.idea.util.ImportInsertHelper
import org.jetbrains.kotlin.idea.util.ShortenReferences import org.jetbrains.kotlin.idea.util.ShortenReferences
import org.jetbrains.kotlin.types.typeUtil.isUnit
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.ImportPath import org.jetbrains.kotlin.resolve.ImportPath
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import java.util.ArrayList import org.jetbrains.kotlin.types.typeUtil.isUnit
import java.util.*
public class DeprecatedCallableAddReplaceWithInspection : IntentionBasedInspection<JetCallableDeclaration>(DeprecatedCallableAddReplaceWithIntention()) public class DeprecatedCallableAddReplaceWithInspection : IntentionBasedInspection<JetCallableDeclaration>(DeprecatedCallableAddReplaceWithIntention())
@@ -108,7 +108,7 @@ public class DeprecatedCallableAddReplaceWithIntention : JetSelfTargetingRangeIn
for (entry in getAnnotationEntries()) { for (entry in getAnnotationEntries()) {
entry.analyze() entry.analyze()
val resolvedCall = entry.getCalleeExpression().getResolvedCall(bindingContext) ?: continue val resolvedCall = entry.getCalleeExpression().getResolvedCall(bindingContext) ?: continue
if (!resolvedCall.getStatus().isSuccess()) continue if (!resolvedCall.isReallySuccess()) continue
// if (resolvedCall.getResultingDescriptor() != deprecatedConstructor) continue // if (resolvedCall.getResultingDescriptor() != deprecatedConstructor) continue
//TODO //TODO
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
@@ -82,7 +83,7 @@ class UsePropertyAccessSyntaxIntention : JetSelfTargetingOffsetIndependentIntent
val resolutionFacade = callExpression.getResolutionFacade() val resolutionFacade = callExpression.getResolutionFacade()
val bindingContext = resolutionFacade.analyze(callExpression, BodyResolveMode.PARTIAL) val bindingContext = resolutionFacade.analyze(callExpression, BodyResolveMode.PARTIAL)
val resolvedCall = callExpression.getResolvedCall(bindingContext) ?: return null val resolvedCall = callExpression.getResolvedCall(bindingContext) ?: return null
if (!resolvedCall.getStatus().isSuccess()) return null if (!resolvedCall.isReallySuccess()) return null
val function = resolvedCall.getResultingDescriptor() as? FunctionDescriptor ?: return null val function = resolvedCall.getResultingDescriptor() as? FunctionDescriptor ?: return null
val resolutionScope = callExpression.getResolutionScope(bindingContext, resolutionFacade) val resolutionScope = callExpression.getResolutionScope(bindingContext, resolutionFacade)
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.psi.JetDotQualifiedExpression
import org.jetbrains.kotlin.psi.JetPsiFactory import org.jetbrains.kotlin.psi.JetPsiFactory
import org.jetbrains.kotlin.psi.createExpressionByPattern import org.jetbrains.kotlin.psi.createExpressionByPattern
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.expressions.OperatorConventions
public class ReplaceCallWithBinaryOperatorIntention : JetSelfTargetingRangeIntention<JetDotQualifiedExpression>(javaClass(), "Replace call with binary operator"), HighPriorityAction { public class ReplaceCallWithBinaryOperatorIntention : JetSelfTargetingRangeIntention<JetDotQualifiedExpression>(javaClass(), "Replace call with binary operator"), HighPriorityAction {
@@ -32,7 +33,7 @@ public class ReplaceCallWithBinaryOperatorIntention : JetSelfTargetingRangeInten
val operation = operation(element.calleeName) ?: return null val operation = operation(element.calleeName) ?: return null
val resolvedCall = element.toResolvedCall() ?: return null val resolvedCall = element.toResolvedCall() ?: return null
if (!resolvedCall.getStatus().isSuccess()) return null if (!resolvedCall.isReallySuccess()) return null
if (resolvedCall.getCall().getTypeArgumentList() != null) return null if (resolvedCall.getCall().getTypeArgumentList() != null) return null
val argument = resolvedCall.getCall().getValueArguments().singleOrNull() ?: return null val argument = resolvedCall.getCall().getValueArguments().singleOrNull() ?: return null
if ((resolvedCall.getArgumentMapping(argument) as ArgumentMatch).valueParameter.getIndex() != 0) return null if ((resolvedCall.getArgumentMapping(argument) as ArgumentMatch).valueParameter.getIndex() != 0) return null
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.idea.intentions.*
import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.expressions.OperatorConventions
@@ -31,7 +32,7 @@ public class ReplaceContainsIntention : JetSelfTargetingRangeIntention<JetDotQua
if (element.calleeName != OperatorConventions.CONTAINS.asString()) return null if (element.calleeName != OperatorConventions.CONTAINS.asString()) return null
val resolvedCall = element.toResolvedCall() ?: return null val resolvedCall = element.toResolvedCall() ?: return null
if (!resolvedCall.getStatus().isSuccess()) return null if (!resolvedCall.isReallySuccess()) return null
val argument = resolvedCall.getCall().getValueArguments().singleOrNull() ?: return null val argument = resolvedCall.getCall().getValueArguments().singleOrNull() ?: return null
if ((resolvedCall.getArgumentMapping(argument) as ArgumentMatch).valueParameter.getIndex() != 0) return null if ((resolvedCall.getArgumentMapping(argument) as ArgumentMatch).valueParameter.getIndex() != 0) return null
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.psi.JetSecondaryConstructor import org.jetbrains.kotlin.psi.JetSecondaryConstructor
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
public class InsertDelegationCallQuickfix(val isThis: Boolean, element: JetSecondaryConstructor) : JetIntentionAction<JetSecondaryConstructor>(element) { public class InsertDelegationCallQuickfix(val isThis: Boolean, element: JetSecondaryConstructor) : JetIntentionAction<JetSecondaryConstructor>(element) {
@@ -48,7 +49,7 @@ public class InsertDelegationCallQuickfix(val isThis: Boolean, element: JetSecon
val descriptor = element.resolveToDescriptor() val descriptor = element.resolveToDescriptor()
// if empty call is ok and it's resolved to another constructor, do not move caret // if empty call is ok and it's resolved to another constructor, do not move caret
if (resolvedCall?.getStatus()?.isSuccess() ?: false && resolvedCall!!.getCandidateDescriptor().getOriginal() != descriptor) return if (resolvedCall?.isReallySuccess() ?: false && resolvedCall!!.getCandidateDescriptor().getOriginal() != descriptor) return
val leftParOffset = newDelegationCall.getValueArgumentList()!!.getLeftParenthesis()!!.getTextOffset() val leftParOffset = newDelegationCall.getValueArgumentList()!!.getLeftParenthesis()!!.getTextOffset()
@@ -57,7 +57,7 @@ class CallableUsageReplacementStrategy(
override fun createReplacer(usage: JetSimpleNameExpression): (() -> JetElement)? { override fun createReplacer(usage: JetSimpleNameExpression): (() -> JetElement)? {
val bindingContext = usage.analyze(BodyResolveMode.PARTIAL) val bindingContext = usage.analyze(BodyResolveMode.PARTIAL)
val resolvedCall = usage.getResolvedCall(bindingContext) ?: return null val resolvedCall = usage.getResolvedCall(bindingContext) ?: return null
if (!resolvedCall.status.isSuccess) return null if (!resolvedCall.isReallySuccess()) return null
return { return {
// copy replacement expression because it is modified by performCallReplacement // copy replacement expression because it is modified by performCallReplacement
performCallReplacement(usage, bindingContext, resolvedCall, replacement.copy()) performCallReplacement(usage, bindingContext, resolvedCall, replacement.copy())
@@ -430,7 +430,7 @@ private fun introduceNamedArguments(result: JetExpression) {
for (callExpression in callsToProcess) { for (callExpression in callsToProcess) {
val bindingContext = callExpression.analyze(BodyResolveMode.PARTIAL) val bindingContext = callExpression.analyze(BodyResolveMode.PARTIAL)
val resolvedCall = callExpression.getResolvedCall(bindingContext) ?: return val resolvedCall = callExpression.getResolvedCall(bindingContext) ?: return
if (!resolvedCall.status.isSuccess) return if (!resolvedCall.isReallySuccess()) return
val argumentsToMakeNamed = callExpression.valueArguments.dropWhile { !it[MAKE_ARGUMENT_NAMED_KEY] } val argumentsToMakeNamed = callExpression.valueArguments.dropWhile { !it[MAKE_ARGUMENT_NAMED_KEY] }
for (argument in argumentsToMakeNamed) { for (argument in argumentsToMakeNamed) {
@@ -549,7 +549,7 @@ private fun restoreFunctionLiteralArguments(expression: JetExpression) {
if (callExpression.functionLiteralArguments.isNotEmpty()) return if (callExpression.functionLiteralArguments.isNotEmpty()) return
val resolvedCall = callExpression.getResolvedCall(callExpression.analyze(BodyResolveMode.PARTIAL)) ?: return val resolvedCall = callExpression.getResolvedCall(callExpression.analyze(BodyResolveMode.PARTIAL)) ?: return
if (!resolvedCall.status.isSuccess) return if (!resolvedCall.isReallySuccess()) return
val argumentMatch = resolvedCall.getArgumentMapping(argument) as ArgumentMatch val argumentMatch = resolvedCall.getArgumentMapping(argument) as ArgumentMatch
if (argumentMatch.valueParameter != resolvedCall.resultingDescriptor.valueParameters.last()) return if (argumentMatch.valueParameter != resolvedCall.resultingDescriptor.valueParameters.last()) return
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
@@ -132,7 +133,7 @@ object ReplaceWithAnnotationAnalyzer {
} }
val resolvedCall = expression.getResolvedCall(bindingContext) val resolvedCall = expression.getResolvedCall(bindingContext)
if (resolvedCall != null && resolvedCall.status.isSuccess) { if (resolvedCall != null && resolvedCall.isReallySuccess()) {
val receiver = if (resolvedCall.resultingDescriptor.isExtension) val receiver = if (resolvedCall.resultingDescriptor.isExtension)
resolvedCall.extensionReceiver resolvedCall.extensionReceiver
else else
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.psi.JetElement import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.psi.JetSimpleNameExpression import org.jetbrains.kotlin.psi.JetSimpleNameExpression
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
interface UsageReplacementStrategy { interface UsageReplacementStrategy {
@@ -47,7 +48,7 @@ interface UsageReplacementStrategy {
when (target) { when (target) {
is CallableDescriptor -> { is CallableDescriptor -> {
val resolvedCall = element.getResolvedCall(bindingContext) ?: return null val resolvedCall = element.getResolvedCall(bindingContext) ?: return null
if (!resolvedCall.status.isSuccess) return null if (!resolvedCall.isReallySuccess()) return null
val replacement = ReplaceWithAnnotationAnalyzer.analyzeCallableReplacement(replaceWith, target, resolutionFacade) ?: return null val replacement = ReplaceWithAnnotationAnalyzer.analyzeCallableReplacement(replaceWith, target, resolutionFacade) ?: return null
return CallableUsageReplacementStrategy(replacement) return CallableUsageReplacementStrategy(replacement)
} }
@@ -45,10 +45,7 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage; import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch; import org.jetbrains.kotlin.resolve.calls.model.*;
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode; import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
@@ -122,7 +119,7 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
private boolean shouldSkipUsage(JetCallElement element) { private boolean shouldSkipUsage(JetCallElement element) {
// TODO: We probable need more clever processing of invalid calls, but for now default to Java-like behaviour // TODO: We probable need more clever processing of invalid calls, but for now default to Java-like behaviour
if (resolvedCall == null && !(element instanceof JetDelegatorToSuperCall)) return true; if (resolvedCall == null && !(element instanceof JetDelegatorToSuperCall)) return true;
if (resolvedCall != null && !resolvedCall.getStatus().isSuccess()) { if (resolvedCall != null && !ArgumentMappingKt.isReallySuccess(resolvedCall)) {
// TODO: investigate why arguments are not recorded for enum constructor call // TODO: investigate why arguments are not recorded for enum constructor call
if (element instanceof JetDelegatorToSuperCall && element.getParent().getParent() instanceof JetEnumEntry) return false; if (element instanceof JetDelegatorToSuperCall && element.getParent().getParent() instanceof JetEnumEntry) return false;
for (ValueArgument valueArgument : resolvedCall.getCall().getValueArguments()) { for (ValueArgument valueArgument : resolvedCall.getCall().getValueArguments()) {