diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java index b8b654c4ea5..15686432816 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java @@ -168,6 +168,8 @@ public interface BindingContext { * Has type of current expression has been already resolved */ WritableSlice PROCESSED = Slices.createSimpleSlice(); + // Please do not use this slice (USED_AS_EXPRESSION) directly, + // use extension element.isUsedAsExpression() instead WritableSlice USED_AS_EXPRESSION = Slices.createSimpleSetSlice(); WritableSlice USED_AS_RESULT_OF_LAMBDA = Slices.createSimpleSetSlice(); WritableSlice UNREACHABLE_CODE = Slices.createSimpleSetSlice(); diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinExpressionTypeProvider.kt b/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinExpressionTypeProvider.kt index 8b8cf46f38b..1d9bf55ce9b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinExpressionTypeProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinExpressionTypeProvider.kt @@ -39,6 +39,7 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.RenderingFormat import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getType @@ -90,7 +91,7 @@ class KotlinExpressionTypeProvider : ExpressionTypeProvider() { private fun KtExpression.shouldShowStatementType(): Boolean { if (parent !is KtBlockExpression) return true if (parent.children.lastOrNull() == this) { - return analyze(BodyResolveMode.PARTIAL_WITH_CFA)[BindingContext.USED_AS_EXPRESSION, this] ?: false + return isUsedAsExpression(analyze(BodyResolveMode.PARTIAL_WITH_CFA)) } return false } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantElseInIfInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantElseInIfInspection.kt index 8fdcc479f64..5784414c5d7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantElseInIfInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantElseInIfInspection.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.idea.refactoring.getLineNumber import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.types.typeUtil.isNothing class RedundantElseInIfInspection : AbstractKotlinInspection() { @@ -87,7 +88,7 @@ private fun KtIfExpression.lastSingleElseKeyword(): PsiElement? { private fun KtIfExpression.hasRedundantElse(): Boolean { val context = analyze() - if (context[BindingContext.USED_AS_EXPRESSION, this] == true) return false + if (isUsedAsExpression(context)) return false var ifExpression = this while (true) { if ((ifExpression.then)?.isReturnOrNothing(context) != true) return false diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantWithInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantWithInspection.kt index c014a24fbd3..20db00355a9 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantWithInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantWithInspection.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode @@ -34,7 +35,7 @@ class RedundantWithInspection : AbstractKotlinInspection() { val lambdaBody = lambda.bodyExpression ?: return val context = callExpression.analyze(BodyResolveMode.PARTIAL_WITH_CFA) - if (lambdaBody.statements.size > 1 && context[BindingContext.USED_AS_EXPRESSION, callExpression] == true) return + if (lambdaBody.statements.size > 1 && callExpression.isUsedAsExpression(context)) return if (callExpression.getResolvedCall(context)?.resultingDescriptor?.fqNameSafe != FqName("kotlin.with")) return val lambdaDescriptor = context[BindingContext.FUNCTION, lambda.functionLiteral] ?: return diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/SafeCastWithReturnInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/SafeCastWithReturnInspection.kt index 4e8ff0ef796..4903940f98e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/SafeCastWithReturnInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/SafeCastWithReturnInspection.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode class SafeCastWithReturnInspection : AbstractKotlinInspection() { @@ -30,11 +31,11 @@ class SafeCastWithReturnInspection : AbstractKotlinInspection() { if (KtPsiUtil.deparenthesize(parent.right) !is KtReturnExpression) return val context = expression.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS) - if (context[BindingContext.USED_AS_EXPRESSION, parent] == true) { + if (parent.isUsedAsExpression(context)) { val lambda = expression.getStrictParentOfType() ?: return if (lambda.functionLiteral.bodyExpression?.statements?.lastOrNull() != parent) return val call = lambda.getStrictParentOfType() ?: return - if (context[BindingContext.USED_AS_EXPRESSION, call] == true) return + if (call.isUsedAsExpression(context)) return } if (context.diagnostics.forElement(expression.operationReference).any { it.factory == Errors.CAST_NEVER_SUCCEEDS }) return diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedLambdaExpressionBodyInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedLambdaExpressionBodyInspection.kt index e581c5958d1..08edaa9a0b2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedLambdaExpressionBodyInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedLambdaExpressionBodyInspection.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.KtLambdaExpression import org.jetbrains.kotlin.psi.callExpressionVisitor import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl import org.jetbrains.kotlin.resolve.calls.tower.NewVariableAsFunctionResolvedCallImpl @@ -31,7 +32,7 @@ class UnusedLambdaExpressionBodyInspection : AbstractKotlinInspection() { override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { return callExpressionVisitor(fun(expression) { val context = expression.analyze(BodyResolveMode.PARTIAL_WITH_CFA) - if (expression.used(context)) { + if (expression.isUsedAsExpression(context)) { return } @@ -54,8 +55,6 @@ class UnusedLambdaExpressionBodyInspection : AbstractKotlinInspection() { }) } - private fun KtExpression.used(context: BindingContext): Boolean = context[BindingContext.USED_AS_EXPRESSION, this] ?: true - private fun CallableDescriptor.returnsFunction() = returnType?.isFunctionType ?: false class RemoveEqTokenFromFunctionDeclarationFix(function: KtFunction) : LocalQuickFixOnPsiElement(function) {