Refactor: Move canMoveLambdaOutsideParentheses() function to idea-core module
This commit is contained in:
+9
-36
@@ -17,58 +17,31 @@
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.core.canMoveLambdaOutsideParentheses
|
||||
import org.jetbrains.kotlin.idea.core.getLastLambdaExpression
|
||||
import org.jetbrains.kotlin.idea.core.moveFunctionLiteralOutsideParentheses
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||
import org.jetbrains.kotlin.psi.KtValueArgument
|
||||
import org.jetbrains.kotlin.psi.KtValueArgumentList
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containsInside
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
class MoveLambdaOutsideParenthesesIntention : SelfTargetingIntention<KtCallExpression>(KtCallExpression::class.java, "Move lambda argument out of parentheses") {
|
||||
companion object {
|
||||
private fun getLambdaExpression(callExpression: KtCallExpression): KtLambdaExpression? {
|
||||
if (callExpression.lambdaArguments.isNotEmpty()) return null
|
||||
return callExpression.valueArguments.lastOrNull()?.getArgumentExpression()?.unpackFunctionLiteral()
|
||||
}
|
||||
|
||||
fun canMove(element: KtCallExpression): Boolean {
|
||||
if (getLambdaExpression(element) == null) return false
|
||||
|
||||
val callee = element.calleeExpression
|
||||
if (callee is KtNameReferenceExpression) {
|
||||
val bindingContext = element.analyze(BodyResolveMode.PARTIAL)
|
||||
val targets = bindingContext[BindingContext.REFERENCE_TARGET, callee]?.let { listOf(it) }
|
||||
?: bindingContext[BindingContext.AMBIGUOUS_REFERENCE_TARGET, callee]
|
||||
?: listOf()
|
||||
val candidates = targets.filterIsInstance<FunctionDescriptor>()
|
||||
// if there are functions among candidates but none of them have last function parameter then not show the intention
|
||||
if (candidates.isNotEmpty() && candidates.none {
|
||||
val lastParameter = it.valueParameters.lastOrNull()
|
||||
lastParameter != null && lastParameter.type.isFunctionType
|
||||
}) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun moveFunctionLiteralOutsideParenthesesIfPossible(expression: KtLambdaExpression) {
|
||||
val call = ((expression.parent as? KtValueArgument)?.parent as? KtValueArgumentList)?.parent as? KtCallExpression ?: return
|
||||
if (canMove(call)) {
|
||||
if (call.canMoveLambdaOutsideParentheses()) {
|
||||
call.moveFunctionLiteralOutsideParentheses()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun isApplicableTo(element: KtCallExpression, caretOffset: Int): Boolean {
|
||||
if (!canMove(element)) return false
|
||||
if (!element.canMoveLambdaOutsideParentheses()) return false
|
||||
|
||||
val lambdaExpression = getLambdaExpression(element) ?: return false
|
||||
val lambdaExpression = element.getLastLambdaExpression() ?: return false
|
||||
val argument = lambdaExpression.getStrictParentOfType<KtValueArgument>() ?: return false
|
||||
if (caretOffset < argument.startOffset) return false
|
||||
val bodyRange = lambdaExpression.bodyExpression?.textRange ?: return true
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||
import org.jetbrains.kotlin.idea.core.canMoveLambdaOutsideParentheses
|
||||
import org.jetbrains.kotlin.idea.core.moveFunctionLiteralOutsideParentheses
|
||||
import org.jetbrains.kotlin.idea.core.replaced
|
||||
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
||||
@@ -36,7 +37,10 @@ import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.contentRange
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
@@ -152,7 +156,7 @@ class ObjectLiteralToLambdaIntention : SelfTargetingRangeIntention<KtObjectLiter
|
||||
?.parent as? KtCallExpression
|
||||
if (parentCall != null && RedundantSamConstructorInspection.samConstructorCallsToBeConverted(parentCall).singleOrNull() == callExpression) {
|
||||
RedundantSamConstructorInspection.replaceSamConstructorCall(callExpression)
|
||||
if (MoveLambdaOutsideParenthesesIntention.canMove(parentCall)) {
|
||||
if (parentCall.canMoveLambdaOutsideParentheses()) {
|
||||
parentCall.moveFunctionLiteralOutsideParentheses()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user