More correct check for ResolvedCall status everywhere in the IDE + added assert into ResolvedCallImpl
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.resolve.calls.model
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
|
||||
public interface ArgumentMapping {
|
||||
public fun isError(): Boolean
|
||||
@@ -61,3 +62,7 @@ class ArgumentMatchImpl(override val valueParameter: ValueParameterDescriptor):
|
||||
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;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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;
|
||||
|
||||
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>() {
|
||||
@Override
|
||||
@@ -275,6 +277,9 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
|
||||
public ArgumentMapping getArgumentMapping(@NotNull ValueArgument valueArgument) {
|
||||
ArgumentMatch argumentMatch = argumentToParameterMap.get(valueArgument);
|
||||
if (argumentMatch == null) {
|
||||
if (ArgumentMappingKt.isReallySuccess(this)) {
|
||||
LOG.error("ArgumentUnmapped for " + valueArgument + " in successfully resolved call: " + call.getCallElement().getText());
|
||||
}
|
||||
return ArgumentUnmapped.INSTANCE$;
|
||||
}
|
||||
return argumentMatch;
|
||||
|
||||
@@ -28,15 +28,15 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
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.model.isReallySuccess
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.constant
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlin.utils.emptyOrSingletonList
|
||||
import java.util.HashSet
|
||||
import java.util.*
|
||||
|
||||
// Navigation element of the resolved reference
|
||||
// For property accessor return enclosing property
|
||||
@@ -168,7 +168,7 @@ public fun JetExpression.readWriteAccess(useResolveForReadWrite: Boolean): Refer
|
||||
|
||||
val bindingContext = assignment.analyze(BodyResolveMode.PARTIAL)
|
||||
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())
|
||||
ReferenceAccess.READ
|
||||
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.model.ExpressionValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
||||
import java.util.ArrayList
|
||||
import java.util.HashMap
|
||||
import java.util.*
|
||||
|
||||
public object OptionalParametersHelper {
|
||||
public fun detectArgumentsToDropForDefaults(
|
||||
@@ -42,7 +42,7 @@ public object OptionalParametersHelper {
|
||||
project: Project,
|
||||
canDrop: (ValueArgument) -> Boolean = { true }
|
||||
): Collection<ValueArgument> {
|
||||
if (!resolvedCall.getStatus().isSuccess()) return emptyList()
|
||||
if (!resolvedCall.isReallySuccess()) return emptyList()
|
||||
val descriptor = resolvedCall.getResultingDescriptor()
|
||||
|
||||
val parameterToDefaultValue = descriptor.getValueParameters()
|
||||
|
||||
+3
-2
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.renderer.render
|
||||
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.scopes.FileScope
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||
@@ -131,7 +132,7 @@ public class ConflictingExtensionPropertyInspection : AbstractKotlinInspection()
|
||||
when (this) {
|
||||
is JetCallExpression -> {
|
||||
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 -> {
|
||||
@@ -148,7 +149,7 @@ public class ConflictingExtensionPropertyInspection : AbstractKotlinInspection()
|
||||
is JetCallExpression -> {
|
||||
if ((valueArguments.singleOrNull()?.getArgumentExpression() as? JetSimpleNameExpression)?.getReferencedNameAsName() != valueParameterName) return false
|
||||
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 -> {
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.resolve.BindingTraceContext
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolver
|
||||
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.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.getFileScope
|
||||
@@ -155,7 +156,7 @@ public class RedundantSamConstructorInspection : AbstractKotlinInspection() {
|
||||
|
||||
val bindingContext = functionCall.analyze(BodyResolveMode.PARTIAL)
|
||||
val functionResolvedCall = functionCall.getResolvedCall(bindingContext) ?: return emptyList()
|
||||
if (!functionResolvedCall.status.isSuccess) return emptyList()
|
||||
if (!functionResolvedCall.isReallySuccess()) return emptyList()
|
||||
|
||||
val samConstructorCalls = functionCall.valueArguments.map {
|
||||
(it.getArgumentExpression() as? JetCallExpression)
|
||||
|
||||
+4
-4
@@ -26,21 +26,21 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
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.inspections.IntentionBasedInspection
|
||||
import org.jetbrains.kotlin.idea.quickfix.moveCaret
|
||||
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
|
||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.ImportPath
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
|
||||
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())
|
||||
|
||||
@@ -108,7 +108,7 @@ public class DeprecatedCallableAddReplaceWithIntention : JetSelfTargetingRangeIn
|
||||
for (entry in getAnnotationEntries()) {
|
||||
entry.analyze()
|
||||
val resolvedCall = entry.getCalleeExpression().getResolvedCall(bindingContext) ?: continue
|
||||
if (!resolvedCall.getStatus().isSuccess()) continue
|
||||
if (!resolvedCall.isReallySuccess()) continue
|
||||
// if (resolvedCall.getResultingDescriptor() != deprecatedConstructor) continue
|
||||
|
||||
//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.ContextDependency
|
||||
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.util.DelegatingCall
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
@@ -82,7 +83,7 @@ class UsePropertyAccessSyntaxIntention : JetSelfTargetingOffsetIndependentIntent
|
||||
val resolutionFacade = callExpression.getResolutionFacade()
|
||||
val bindingContext = resolutionFacade.analyze(callExpression, BodyResolveMode.PARTIAL)
|
||||
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 resolutionScope = callExpression.getResolutionScope(bindingContext, resolutionFacade)
|
||||
|
||||
+2
-1
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.psi.JetDotQualifiedExpression
|
||||
import org.jetbrains.kotlin.psi.JetPsiFactory
|
||||
import org.jetbrains.kotlin.psi.createExpressionByPattern
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
|
||||
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
|
||||
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 resolvedCall = element.toResolvedCall() ?: return null
|
||||
if (!resolvedCall.getStatus().isSuccess()) return null
|
||||
if (!resolvedCall.isReallySuccess()) return null
|
||||
if (resolvedCall.getCall().getTypeArgumentList() != null) return null
|
||||
val argument = resolvedCall.getCall().getValueArguments().singleOrNull() ?: return null
|
||||
if ((resolvedCall.getArgumentMapping(argument) as ArgumentMatch).valueParameter.getIndex() != 0) return null
|
||||
|
||||
+2
-1
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.idea.intentions.*
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
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.types.expressions.OperatorConventions
|
||||
|
||||
@@ -31,7 +32,7 @@ public class ReplaceContainsIntention : JetSelfTargetingRangeIntention<JetDotQua
|
||||
if (element.calleeName != OperatorConventions.CONTAINS.asString()) 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
|
||||
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.psiUtil.getNonStrictParentOfType
|
||||
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) {
|
||||
@@ -48,7 +49,7 @@ public class InsertDelegationCallQuickfix(val isThis: Boolean, element: JetSecon
|
||||
val descriptor = element.resolveToDescriptor()
|
||||
|
||||
// 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()
|
||||
|
||||
|
||||
+3
-3
@@ -57,7 +57,7 @@ class CallableUsageReplacementStrategy(
|
||||
override fun createReplacer(usage: JetSimpleNameExpression): (() -> JetElement)? {
|
||||
val bindingContext = usage.analyze(BodyResolveMode.PARTIAL)
|
||||
val resolvedCall = usage.getResolvedCall(bindingContext) ?: return null
|
||||
if (!resolvedCall.status.isSuccess) return null
|
||||
if (!resolvedCall.isReallySuccess()) return null
|
||||
return {
|
||||
// copy replacement expression because it is modified by performCallReplacement
|
||||
performCallReplacement(usage, bindingContext, resolvedCall, replacement.copy())
|
||||
@@ -430,7 +430,7 @@ private fun introduceNamedArguments(result: JetExpression) {
|
||||
for (callExpression in callsToProcess) {
|
||||
val bindingContext = callExpression.analyze(BodyResolveMode.PARTIAL)
|
||||
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] }
|
||||
for (argument in argumentsToMakeNamed) {
|
||||
@@ -549,7 +549,7 @@ private fun restoreFunctionLiteralArguments(expression: JetExpression) {
|
||||
if (callExpression.functionLiteralArguments.isNotEmpty()) 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
|
||||
if (argumentMatch.valueParameter != resolvedCall.resultingDescriptor.valueParameters.last()) return
|
||||
|
||||
|
||||
+2
-1
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
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.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
||||
@@ -132,7 +133,7 @@ object ReplaceWithAnnotationAnalyzer {
|
||||
}
|
||||
|
||||
val resolvedCall = expression.getResolvedCall(bindingContext)
|
||||
if (resolvedCall != null && resolvedCall.status.isSuccess) {
|
||||
if (resolvedCall != null && resolvedCall.isReallySuccess()) {
|
||||
val receiver = if (resolvedCall.resultingDescriptor.isExtension)
|
||||
resolvedCall.extensionReceiver
|
||||
else
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.psi.JetElement
|
||||
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
interface UsageReplacementStrategy {
|
||||
@@ -47,7 +48,7 @@ interface UsageReplacementStrategy {
|
||||
when (target) {
|
||||
is CallableDescriptor -> {
|
||||
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
|
||||
return CallableUsageReplacementStrategy(replacement)
|
||||
}
|
||||
|
||||
+2
-5
@@ -45,10 +45,7 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch;
|
||||
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.calls.model.*;
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
|
||||
@@ -122,7 +119,7 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
||||
private boolean shouldSkipUsage(JetCallElement element) {
|
||||
// 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 && !resolvedCall.getStatus().isSuccess()) {
|
||||
if (resolvedCall != null && !ArgumentMappingKt.isReallySuccess(resolvedCall)) {
|
||||
// TODO: investigate why arguments are not recorded for enum constructor call
|
||||
if (element instanceof JetDelegatorToSuperCall && element.getParent().getParent() instanceof JetEnumEntry) return false;
|
||||
for (ValueArgument valueArgument : resolvedCall.getCall().getValueArguments()) {
|
||||
|
||||
Reference in New Issue
Block a user