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