Refactoring: use isUsedAsExpression instead of USED_AS_EXPRESSION slice

This commit is contained in:
Mikhail Glukhikh
2019-07-09 11:43:36 +03:00
parent 5afa5de1d7
commit 5e94f537ef
6 changed files with 13 additions and 8 deletions
@@ -168,6 +168,8 @@ public interface BindingContext {
* Has type of current expression has been already resolved * Has type of current expression has been already resolved
*/ */
WritableSlice<KtExpression, Boolean> PROCESSED = Slices.createSimpleSlice(); WritableSlice<KtExpression, Boolean> PROCESSED = Slices.createSimpleSlice();
// Please do not use this slice (USED_AS_EXPRESSION) directly,
// use extension element.isUsedAsExpression() instead
WritableSlice<KtElement, Boolean> USED_AS_EXPRESSION = Slices.createSimpleSetSlice(); WritableSlice<KtElement, Boolean> USED_AS_EXPRESSION = Slices.createSimpleSetSlice();
WritableSlice<KtElement, Boolean> USED_AS_RESULT_OF_LAMBDA = Slices.createSimpleSetSlice(); WritableSlice<KtElement, Boolean> USED_AS_RESULT_OF_LAMBDA = Slices.createSimpleSetSlice();
WritableSlice<KtElement, Boolean> UNREACHABLE_CODE = Slices.createSimpleSetSlice(); WritableSlice<KtElement, Boolean> UNREACHABLE_CODE = Slices.createSimpleSetSlice();
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.renderer.RenderingFormat import org.jetbrains.kotlin.renderer.RenderingFormat
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.bindingContextUtil.isUsedAsExpression
import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getType import org.jetbrains.kotlin.resolve.calls.callUtil.getType
@@ -90,7 +91,7 @@ class KotlinExpressionTypeProvider : ExpressionTypeProvider<KtExpression>() {
private fun KtExpression.shouldShowStatementType(): Boolean { private fun KtExpression.shouldShowStatementType(): Boolean {
if (parent !is KtBlockExpression) return true if (parent !is KtBlockExpression) return true
if (parent.children.lastOrNull() == this) { 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 return false
} }
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.idea.refactoring.getLineNumber
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
import org.jetbrains.kotlin.types.typeUtil.isNothing import org.jetbrains.kotlin.types.typeUtil.isNothing
class RedundantElseInIfInspection : AbstractKotlinInspection() { class RedundantElseInIfInspection : AbstractKotlinInspection() {
@@ -87,7 +88,7 @@ private fun KtIfExpression.lastSingleElseKeyword(): PsiElement? {
private fun KtIfExpression.hasRedundantElse(): Boolean { private fun KtIfExpression.hasRedundantElse(): Boolean {
val context = analyze() val context = analyze()
if (context[BindingContext.USED_AS_EXPRESSION, this] == true) return false if (isUsedAsExpression(context)) return false
var ifExpression = this var ifExpression = this
while (true) { while (true) {
if ((ifExpression.then)?.isReturnOrNothing(context) != true) return false if ((ifExpression.then)?.isReturnOrNothing(context) != true) return false
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
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.bindingContextUtil.isUsedAsExpression
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
@@ -34,7 +35,7 @@ class RedundantWithInspection : AbstractKotlinInspection() {
val lambdaBody = lambda.bodyExpression ?: return val lambdaBody = lambda.bodyExpression ?: return
val context = callExpression.analyze(BodyResolveMode.PARTIAL_WITH_CFA) 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 if (callExpression.getResolvedCall(context)?.resultingDescriptor?.fqNameSafe != FqName("kotlin.with")) return
val lambdaDescriptor = context[BindingContext.FUNCTION, lambda.functionLiteral] ?: return val lambdaDescriptor = context[BindingContext.FUNCTION, lambda.functionLiteral] ?: return
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class SafeCastWithReturnInspection : AbstractKotlinInspection() { class SafeCastWithReturnInspection : AbstractKotlinInspection() {
@@ -30,11 +31,11 @@ class SafeCastWithReturnInspection : AbstractKotlinInspection() {
if (KtPsiUtil.deparenthesize(parent.right) !is KtReturnExpression) return if (KtPsiUtil.deparenthesize(parent.right) !is KtReturnExpression) return
val context = expression.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS) val context = expression.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS)
if (context[BindingContext.USED_AS_EXPRESSION, parent] == true) { if (parent.isUsedAsExpression(context)) {
val lambda = expression.getStrictParentOfType<KtLambdaExpression>() ?: return val lambda = expression.getStrictParentOfType<KtLambdaExpression>() ?: return
if (lambda.functionLiteral.bodyExpression?.statements?.lastOrNull() != parent) return if (lambda.functionLiteral.bodyExpression?.statements?.lastOrNull() != parent) return
val call = lambda.getStrictParentOfType<KtCallExpression>() ?: return val call = lambda.getStrictParentOfType<KtCallExpression>() ?: 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 if (context.diagnostics.forElement(expression.operationReference).any { it.factory == Errors.CAST_NEVER_SUCCEEDS }) return
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtLambdaExpression import org.jetbrains.kotlin.psi.KtLambdaExpression
import org.jetbrains.kotlin.psi.callExpressionVisitor import org.jetbrains.kotlin.psi.callExpressionVisitor
import org.jetbrains.kotlin.resolve.BindingContext 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.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl
import org.jetbrains.kotlin.resolve.calls.tower.NewVariableAsFunctionResolvedCallImpl import org.jetbrains.kotlin.resolve.calls.tower.NewVariableAsFunctionResolvedCallImpl
@@ -31,7 +32,7 @@ class UnusedLambdaExpressionBodyInspection : AbstractKotlinInspection() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return callExpressionVisitor(fun(expression) { return callExpressionVisitor(fun(expression) {
val context = expression.analyze(BodyResolveMode.PARTIAL_WITH_CFA) val context = expression.analyze(BodyResolveMode.PARTIAL_WITH_CFA)
if (expression.used(context)) { if (expression.isUsedAsExpression(context)) {
return 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 private fun CallableDescriptor.returnsFunction() = returnType?.isFunctionType ?: false
class RemoveEqTokenFromFunctionDeclarationFix(function: KtFunction) : LocalQuickFixOnPsiElement(function) { class RemoveEqTokenFromFunctionDeclarationFix(function: KtFunction) : LocalQuickFixOnPsiElement(function) {