Further code improvements during review
This commit is contained in:
Generated
+1
@@ -6,6 +6,7 @@
|
||||
<w>inserter</w>
|
||||
<w>pparent</w>
|
||||
<w>processings</w>
|
||||
<w>rbracket</w>
|
||||
<w>rparenth</w>
|
||||
<w>selectioner</w>
|
||||
</words>
|
||||
|
||||
+2
-1
@@ -57,7 +57,8 @@ public class OperatorToFunctionIntention : JetSelfTargetingIntention<JetExpressi
|
||||
|
||||
private fun isApplicableArrayAccess(element: JetArrayAccessExpression, caretOffset: Int): Boolean {
|
||||
val lbracket = element.getLeftBracket() ?: return false
|
||||
return lbracket.getTextRange().containsOffset(caretOffset)
|
||||
val rbracket = element.getRightBracket() ?: return false
|
||||
return lbracket.getTextRange().containsOffset(caretOffset) || rbracket.getTextRange().containsOffset(caretOffset)
|
||||
}
|
||||
|
||||
private fun isApplicableCall(element: JetCallExpression, caretOffset: Int): Boolean {
|
||||
|
||||
@@ -25,7 +25,7 @@ public class AddBracesIntention : JetSelfTargetingIntention<JetExpression>(javaC
|
||||
val expression = element.getTargetExpression(caretOffset) ?: return false
|
||||
if (expression is JetBlockExpression) return false
|
||||
|
||||
val description = (expression.getParent() as JetContainerNode).description()
|
||||
val description = (expression.getParent() as JetContainerNode).description()!!
|
||||
setText("Add braces to '$description' statement")
|
||||
return true
|
||||
}
|
||||
|
||||
+24
-30
@@ -28,12 +28,13 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
public class ConvertAssertToIfWithThrowIntention : JetSelfTargetingIntention<JetCallExpression>(javaClass(), "Replace 'assert' with 'if' statement") {
|
||||
override fun isApplicableTo(element: JetCallExpression, caretOffset: Int): Boolean {
|
||||
val callee = element.getCalleeExpression() ?: return false
|
||||
if (callee.getText() != "assert") return false
|
||||
if (!callee.getTextRange().containsOffset(caretOffset)) return false
|
||||
|
||||
val argumentSize = element.getValueArguments().size()
|
||||
if (argumentSize !in 1..2) return false
|
||||
if (element.getFunctionLiteralArguments().size() == 1 && argumentSize == 1) return false
|
||||
val functionLiterals = element.getFunctionLiteralArguments()
|
||||
if (functionLiterals.size() > 1) return false
|
||||
if (functionLiterals.size() == 1 && argumentSize == 1) return false // "assert {...}" is incorrect
|
||||
|
||||
val resolvedCall = element.getResolvedCall(element.analyze()) ?: return false
|
||||
return DescriptorUtils.getFqName(resolvedCall.getResultingDescriptor()).asString() == "kotlin.assert"
|
||||
@@ -42,14 +43,14 @@ public class ConvertAssertToIfWithThrowIntention : JetSelfTargetingIntention<Jet
|
||||
override fun applyTo(element: JetCallExpression, editor: Editor) {
|
||||
val args = element.getValueArguments()
|
||||
val conditionText = args[0]?.getArgumentExpression()?.getText() ?: return
|
||||
val functionLiterals = element.getFunctionLiteralArguments()
|
||||
val functionLiteral = element.getFunctionLiteralArguments().singleOrNull()
|
||||
val messageIsFunction = messageIsFunction(element)
|
||||
|
||||
val psiFactory = JetPsiFactory(element)
|
||||
|
||||
val messageExpr = when {
|
||||
args.size() == 2 -> args[1]?.getArgumentExpression() ?: return
|
||||
functionLiterals.isNotEmpty() -> functionLiterals.first()
|
||||
functionLiteral != null -> functionLiteral!!
|
||||
else -> psiFactory.createExpression("\"Assertion failed\"")
|
||||
}
|
||||
|
||||
@@ -58,34 +59,27 @@ public class ConvertAssertToIfWithThrowIntention : JetSelfTargetingIntention<Jet
|
||||
// shorten java.lang.AssertionError
|
||||
ShortenReferences.DEFAULT.process(ifExpression.getThen()!!)
|
||||
|
||||
fun replaceMessage() {
|
||||
val thrownExpression = ((ifExpression.getThen() as JetBlockExpression).getStatements().single() as JetThrowExpression).getThrownExpression()
|
||||
val assertionErrorCall = if (thrownExpression is JetCallExpression)
|
||||
thrownExpression
|
||||
else
|
||||
(thrownExpression as JetDotQualifiedExpression).getSelectorExpression() as JetCallExpression
|
||||
val ifCondition = ifExpression.getCondition() as JetPrefixExpression
|
||||
ifCondition.getBaseExpression()!!.replace(psiFactory.createExpression(conditionText))
|
||||
|
||||
val message = psiFactory.createExpression(
|
||||
if (messageIsFunction && messageExpr is JetCallableReferenceExpression) {
|
||||
messageExpr.getCallableReference().getText() + "()"
|
||||
}
|
||||
else if (messageIsFunction) {
|
||||
messageExpr.getText() + "()"
|
||||
}
|
||||
else {
|
||||
messageExpr.getText()
|
||||
}
|
||||
)
|
||||
assertionErrorCall.getValueArguments().single().getArgumentExpression()!!.replace(message)
|
||||
}
|
||||
val thrownExpression = ((ifExpression.getThen() as JetBlockExpression).getStatements().single() as JetThrowExpression).getThrownExpression()
|
||||
val assertionErrorCall = if (thrownExpression is JetCallExpression)
|
||||
thrownExpression
|
||||
else
|
||||
(thrownExpression as JetDotQualifiedExpression).getSelectorExpression() as JetCallExpression
|
||||
|
||||
fun replaceCondition() {
|
||||
val ifCondition = ifExpression.getCondition() as JetPrefixExpression
|
||||
ifCondition.getBaseExpression()!!.replace(psiFactory.createExpression(conditionText))
|
||||
}
|
||||
|
||||
replaceCondition()
|
||||
replaceMessage()
|
||||
val message = psiFactory.createExpression(
|
||||
if (messageIsFunction && messageExpr is JetCallableReferenceExpression) {
|
||||
messageExpr.getCallableReference().getText() + "()"
|
||||
}
|
||||
else if (messageIsFunction) {
|
||||
messageExpr.getText() + "()"
|
||||
}
|
||||
else {
|
||||
messageExpr.getText()
|
||||
}
|
||||
)
|
||||
assertionErrorCall.getValueArguments().single().getArgumentExpression()!!.replace(message)
|
||||
|
||||
simplifyConditionIfPossible(ifExpression)
|
||||
}
|
||||
|
||||
@@ -20,44 +20,38 @@ import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
|
||||
public class ConvertForEachToForLoopIntention : JetSelfTargetingIntention<JetExpression>(javaClass(), "Replace with a for each loop") {
|
||||
public class ConvertForEachToForLoopIntention : JetSelfTargetingIntention<JetExpression>(javaClass(), "Replace with a for loop") {
|
||||
override fun isApplicableTo(element: JetExpression, caretOffset: Int): Boolean {
|
||||
val data = extractData(element) ?: return false
|
||||
if (data.functionLiteral.getValueParameters().size() > 1) return false
|
||||
if (data.functionLiteral.getValueParameters().size() > 1 || data.functionLiteral.getBodyExpression() == null) return false
|
||||
val functionLiteral = extractFunctionLiteral(element) ?: return false
|
||||
if (functionLiteral.getValueParameters().size() > 1) return false
|
||||
if (functionLiteral.getBodyExpression() == null) return false
|
||||
|
||||
if (caretOffset > data.functionLiteral.getTextRange().getStartOffset()) return false // not available within function literal body
|
||||
if (caretOffset > functionLiteral.getTextRange().getStartOffset()) return false // not available within function literal body
|
||||
|
||||
val resolvedCall = element.getResolvedCall(element.analyze()) ?: return false
|
||||
return DescriptorUtils.getFqName(resolvedCall.getResultingDescriptor()).toString() == "kotlin.forEach"
|
||||
if (DescriptorUtils.getFqName(resolvedCall.getResultingDescriptor()).toString() != "kotlin.forEach") return false
|
||||
return resolvedCall.getCall().getExplicitReceiver() is ExpressionReceiver
|
||||
}
|
||||
|
||||
override fun applyTo(element: JetExpression, editor: Editor) {
|
||||
val data = extractData(element)!!
|
||||
val loopText = generateLoopText(data.functionLiteral, data.receiver)
|
||||
element.replace(JetPsiFactory(element).createExpression(loopText))
|
||||
val functionLiteral = extractFunctionLiteral(element)!!
|
||||
val receiver = element.getCall(element.analyze())!!.getExplicitReceiver() as ExpressionReceiver
|
||||
val receiverExpression = receiver.getExpression()
|
||||
val loopText = generateLoopText(functionLiteral, receiverExpression)
|
||||
val expressionToReplace = receiverExpression.getParent() // it's correct for both JetDotQualifiedExpression and JetBinaryExpression
|
||||
expressionToReplace.replace(JetPsiFactory(element).createExpression(loopText))
|
||||
}
|
||||
|
||||
private data class Data(val functionLiteral: JetFunctionLiteralExpression, val receiver: JetExpression)
|
||||
|
||||
private fun extractData(element: JetExpression): Data? {
|
||||
when (element) {
|
||||
is JetDotQualifiedExpression -> {
|
||||
val selector = element.getSelectorExpression() as? JetCallExpression ?: return null
|
||||
val argument = selector.getValueArguments().singleOrNull() ?: return null
|
||||
val functionLiteral = argument.getArgumentExpression() as? JetFunctionLiteralExpression ?: return null
|
||||
return Data(functionLiteral, element.getReceiverExpression())
|
||||
}
|
||||
|
||||
is JetBinaryExpression -> {
|
||||
val functionLiteral = element.getRight() as? JetFunctionLiteralExpression ?: return null
|
||||
return Data(functionLiteral, element.getLeft() ?: return null)
|
||||
}
|
||||
|
||||
else -> return null
|
||||
}
|
||||
private fun extractFunctionLiteral(element: JetExpression): JetFunctionLiteralExpression? {
|
||||
return when (element) {
|
||||
is JetCallExpression -> element.getValueArguments().singleOrNull()?.getArgumentExpression()
|
||||
is JetBinaryExpression -> element.getRight()
|
||||
else -> null
|
||||
} as? JetFunctionLiteralExpression
|
||||
}
|
||||
|
||||
private fun generateLoopText(functionLiteral: JetFunctionLiteralExpression, receiver: JetExpression): String {
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ public class ConvertNegatedBooleanSequenceIntention : JetSelfTargetingOffsetInde
|
||||
val operatorText = when(element.getOperationToken()) {
|
||||
JetTokens.ANDAND -> JetTokens.OROR.getValue()
|
||||
JetTokens.OROR -> JetTokens.ANDAND.getValue()
|
||||
else -> throw IllegalArgumentException()
|
||||
else -> throw IllegalArgumentException() // checked in isApplicableTo
|
||||
}
|
||||
|
||||
val elements = splitBooleanSequence(element)!!
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
import kotlin.platform.platformName
|
||||
|
||||
|
||||
+1
-8
@@ -35,17 +35,10 @@ public class ConvertToForEachFunctionCallIntention : JetSelfTargetingIntention<J
|
||||
is JetBlockExpression -> body.getStatements().map { it.getText() }.joinToString("\n")
|
||||
else -> body.getText()
|
||||
}
|
||||
val bodyText = buildFunctionLiteralBodyText(loopParameter, functionBodyText)
|
||||
val bodyText = "${loopParameter.getText()} -> $functionBodyText"
|
||||
|
||||
val foreachExpression = factory.createExpression("x.forEach { $bodyText }") as JetDotQualifiedExpression
|
||||
foreachExpression.getReceiverExpression().replace(element.getLoopRange()!!)
|
||||
element.replace(foreachExpression)
|
||||
}
|
||||
|
||||
private fun buildFunctionLiteralBodyText(loopParameter: JetParameter, functionBodyText: String): String {
|
||||
return when {
|
||||
loopParameter.getTypeReference() != null -> " (${loopParameter.getText()}) -> $functionBodyText"
|
||||
else -> "${loopParameter.getText()} -> $functionBodyText"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ public class RemoveBracesIntention : JetSelfTargetingIntention<JetBlockExpressio
|
||||
val rBrace = element.getRBrace() ?: return false
|
||||
if (!lBrace.getTextRange().containsOffset(caretOffset) && !rBrace.getTextRange().containsOffset(caretOffset)) return false
|
||||
|
||||
setText("Remove braces from '${containerNode.description()}' statement")
|
||||
val description = containerNode.description() ?: return false
|
||||
setText("Remove braces from '$description' statement")
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
fun main() {
|
||||
val x = 1..4
|
||||
|
||||
<caret>x.reverse().forEach { it }
|
||||
x.reverse().forEach<caret> { it }
|
||||
}
|
||||
@@ -2,5 +2,5 @@
|
||||
fun foo() {
|
||||
val x = 1..4
|
||||
|
||||
<caret>x.forEach({ y -> y })
|
||||
x.<caret>forEach({ y -> y })
|
||||
}
|
||||
+1
-1
@@ -2,5 +2,5 @@
|
||||
fun foo() {
|
||||
val x = 1..4
|
||||
|
||||
<caret>x.forEach { it }
|
||||
x.<caret>forEach { it }
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// WITH_RUNTIME
|
||||
fun main() {
|
||||
<caret>(1 rangeTo 2).forEach { x -> x }
|
||||
(1 rangeTo 2).<caret>forEach { x -> x }
|
||||
}
|
||||
@@ -2,5 +2,5 @@
|
||||
fun foo() {
|
||||
val x = 1..4
|
||||
|
||||
<caret>x.forEach { it.equals(1) }
|
||||
x.forEach<caret> { it.equals(1) }
|
||||
}
|
||||
@@ -2,5 +2,5 @@
|
||||
fun foo() {
|
||||
val x = 1..4
|
||||
|
||||
<caret>x.forEach<Int>({ it })
|
||||
x.forEach<Int><caret>({ it })
|
||||
}
|
||||
+1
-1
@@ -2,5 +2,5 @@
|
||||
fun main() {
|
||||
val list = 1..4
|
||||
|
||||
list.forEach {(x: Int) -> x }
|
||||
list.forEach { x: Int -> x }
|
||||
}
|
||||
+1
-1
@@ -2,5 +2,5 @@
|
||||
fun main() {
|
||||
val list = 1..4
|
||||
|
||||
list.forEach {(x: Int) -> 11 }
|
||||
list.forEach { x: Int -> 11 }
|
||||
}
|
||||
Reference in New Issue
Block a user