OperatorToFunctionIntention and SwapBinaryExpressionIntention: more narrow availability range + no i18n
This commit is contained in:
@@ -51,18 +51,28 @@ public class JetArrayAccessExpression extends JetExpressionImpl implements JetRe
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetContainerNode getIndicesNode() {
|
public JetContainerNode getIndicesNode() {
|
||||||
JetContainerNode indicesNode = (JetContainerNode) findChildByType(JetNodeTypes.INDICES);
|
JetContainerNode indicesNode = findChildByType(JetNodeTypes.INDICES);
|
||||||
assert indicesNode != null : "Can't be null because of parser";
|
assert indicesNode != null : "Can't be null because of parser";
|
||||||
return indicesNode;
|
return indicesNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<TextRange> getBracketRanges() {
|
public List<TextRange> getBracketRanges() {
|
||||||
PsiElement lBracket = getIndicesNode().findChildByType(JetTokens.LBRACKET);
|
PsiElement lBracket = getLeftBracket();
|
||||||
PsiElement rBracket = getIndicesNode().findChildByType(JetTokens.RBRACKET);
|
PsiElement rBracket = getRightBracket();
|
||||||
if (lBracket == null || rBracket == null) {
|
if (lBracket == null || rBracket == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
return Lists.newArrayList(lBracket.getTextRange(), rBracket.getTextRange());
|
return Lists.newArrayList(lBracket.getTextRange(), rBracket.getTextRange());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public PsiElement getLeftBracket() {
|
||||||
|
return getIndicesNode().findChildByType(JetTokens.LBRACKET);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public PsiElement getRightBracket() {
|
||||||
|
return getIndicesNode().findChildByType(JetTokens.RBRACKET);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -296,8 +296,6 @@ remove.unnecessary.curly.brackets.from.string.template=Remove curly braces from
|
|||||||
remove.unnecessary.curly.brackets.from.string.template.family=Remove Curly Braces From Variable
|
remove.unnecessary.curly.brackets.from.string.template.family=Remove Curly Braces From Variable
|
||||||
insert.curly.brackets.to.string.template=Insert curly braces around variable
|
insert.curly.brackets.to.string.template=Insert curly braces around variable
|
||||||
insert.curly.brackets.to.string.template.family=Insert Curly Braces Around Variable
|
insert.curly.brackets.to.string.template.family=Insert Curly Braces Around Variable
|
||||||
swap.binary.expression=Flip binary expression
|
|
||||||
swap.binary.expression.family=Flip Binary Expression
|
|
||||||
add.name.to.argument.family=Add Name to Argument
|
add.name.to.argument.family=Add Name to Argument
|
||||||
add.name.to.argument.single=Add name to argument\: ''{0}''
|
add.name.to.argument.single=Add name to argument\: ''{0}''
|
||||||
add.name.to.argument.multiple=Add name to argument...
|
add.name.to.argument.multiple=Add name to argument...
|
||||||
@@ -349,8 +347,6 @@ make.type.implicit.in.lambda=Make types implicit in lambda (may break code)
|
|||||||
make.type.implicit.in.lambda.family=Make Types Implicit In Lambda (May Break Code)
|
make.type.implicit.in.lambda.family=Make Types Implicit In Lambda (May Break Code)
|
||||||
invert.if.condition=Invert If Condition
|
invert.if.condition=Invert If Condition
|
||||||
invert.if.condition.family=Invert If Condition
|
invert.if.condition.family=Invert If Condition
|
||||||
operator.to.function=Replace overloaded operator with function call
|
|
||||||
operator.to.function.family=Replace Overloaded Operator With Function Call
|
|
||||||
convert.to.for.each.loop.intention=Replace with a for each loop
|
convert.to.for.each.loop.intention=Replace with a for each loop
|
||||||
convert.to.for.each.loop.intention.family=Replace with a For Each Loop
|
convert.to.for.each.loop.intention.family=Replace with a For Each Loop
|
||||||
convert.to.for.each.function.call.intention=Replace with a forEach function call
|
convert.to.for.each.function.call.intention=Replace with a forEach function call
|
||||||
|
|||||||
+35
-17
@@ -16,21 +16,24 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.intentions
|
package org.jetbrains.kotlin.idea.intentions
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.intention.IntentionAction
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import org.jetbrains.kotlin.psi.JetElement
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import org.jetbrains.kotlin.idea.JetBundle
|
import org.jetbrains.kotlin.idea.JetBundle
|
||||||
|
import org.jetbrains.kotlin.psi.JetElement
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate
|
||||||
import com.intellij.codeInsight.intention.IntentionAction
|
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||||
|
|
||||||
public abstract class JetSelfTargetingIntention<T: JetElement>(
|
public abstract class JetSelfTargetingIntention<TElement : JetElement>(
|
||||||
public val elementType: Class<T>,
|
public val elementType: Class<TElement>,
|
||||||
private var text: String,
|
private var text: String,
|
||||||
private val familyName: String)
|
private val familyName: String = text)
|
||||||
: IntentionAction {
|
: IntentionAction {
|
||||||
deprecated("Use primary constructor, no need to use i18n")
|
deprecated("Use primary constructor, no need to use i18n")
|
||||||
public constructor(key: String, elementType: Class<T>) : this(elementType, JetBundle.message(key), JetBundle.message(key + ".family")) {
|
public constructor(key: String, elementType: Class<TElement>) : this(elementType, JetBundle.message(key), JetBundle.message(key + ".family")) {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun setText(text: String) {
|
protected fun setText(text: String) {
|
||||||
@@ -40,13 +43,28 @@ public abstract class JetSelfTargetingIntention<T: JetElement>(
|
|||||||
final override fun getText() = text
|
final override fun getText() = text
|
||||||
final override fun getFamilyName() = familyName
|
final override fun getFamilyName() = familyName
|
||||||
|
|
||||||
public abstract fun isApplicableTo(element: T, caretOffset: Int): Boolean
|
public abstract fun isApplicableTo(element: TElement, caretOffset: Int): Boolean
|
||||||
|
|
||||||
public abstract fun applyTo(element: T, editor: Editor)
|
public abstract fun applyTo(element: TElement, editor: Editor)
|
||||||
|
|
||||||
private fun getTarget(editor: Editor, file: PsiFile): T? {
|
private fun getTarget(editor: Editor, file: PsiFile): TElement? {
|
||||||
val offset = editor.getCaretModel().getOffset()
|
val offset = editor.getCaretModel().getOffset()
|
||||||
return file.findElementAt(offset)?.getParentOfTypesAndPredicate(false, elementType) { element -> isApplicableTo(element, offset) }
|
val leaf1 = file.findElementAt(offset)
|
||||||
|
val leaf2 = file.findElementAt(offset - 1)
|
||||||
|
val commonParent = if (leaf1 != null && leaf2 != null) PsiTreeUtil.findCommonParent(leaf1, leaf2) else null
|
||||||
|
|
||||||
|
var elementsToCheck: Sequence<PsiElement> = sequence { null }
|
||||||
|
if (leaf1 != null) {
|
||||||
|
elementsToCheck += leaf1.parents().takeWhile { it != commonParent }
|
||||||
|
}
|
||||||
|
if (leaf2 != null) {
|
||||||
|
elementsToCheck += leaf2.parents().takeWhile { it != commonParent }
|
||||||
|
}
|
||||||
|
if (commonParent != null) {
|
||||||
|
elementsToCheck += commonParent.parents()
|
||||||
|
}
|
||||||
|
|
||||||
|
return elementsToCheck.filterIsInstance(elementType).firstOrNull { isApplicableTo(it, offset) }
|
||||||
}
|
}
|
||||||
|
|
||||||
final override fun isAvailable(project: Project, editor: Editor, file: PsiFile)
|
final override fun isAvailable(project: Project, editor: Editor, file: PsiFile)
|
||||||
@@ -62,17 +80,17 @@ public abstract class JetSelfTargetingIntention<T: JetElement>(
|
|||||||
override fun toString(): String = getText()
|
override fun toString(): String = getText()
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class JetSelfTargetingOffsetIndependentIntention<T: JetElement>(
|
public abstract class JetSelfTargetingOffsetIndependentIntention<TElement : JetElement>(
|
||||||
elementType: Class<T>,
|
elementType: Class<TElement>,
|
||||||
text: String,
|
text: String,
|
||||||
familyName: String)
|
familyName: String = text)
|
||||||
: JetSelfTargetingIntention<T>(elementType, text, familyName) {
|
: JetSelfTargetingIntention<TElement>(elementType, text, familyName) {
|
||||||
|
|
||||||
deprecated("Use primary constructor, no need to use i18n")
|
deprecated("Use primary constructor, no need to use i18n")
|
||||||
public constructor(key: String, elementType: Class<T>) : this(elementType, JetBundle.message(key), JetBundle.message(key + ".family")) {
|
public constructor(key: String, elementType: Class<TElement>) : this(elementType, JetBundle.message(key), JetBundle.message(key + ".family")) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract fun isApplicableTo(element: T): Boolean
|
public abstract fun isApplicableTo(element: TElement): Boolean
|
||||||
|
|
||||||
override final fun isApplicableTo(element: T, caretOffset: Int): Boolean = isApplicableTo(element)
|
override final fun isApplicableTo(element: TElement, caretOffset: Int): Boolean = isApplicableTo(element)
|
||||||
}
|
}
|
||||||
|
|||||||
+37
-29
@@ -16,49 +16,57 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.intentions
|
package org.jetbrains.kotlin.idea.intentions
|
||||||
|
|
||||||
import org.jetbrains.kotlin.psi.JetExpression
|
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import org.jetbrains.kotlin.psi.JetPrefixExpression
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.psi.JetPostfixExpression
|
|
||||||
import org.jetbrains.kotlin.psi.JetBinaryExpression
|
|
||||||
import org.jetbrains.kotlin.psi.JetArrayAccessExpression
|
|
||||||
import org.jetbrains.kotlin.psi.JetCallExpression
|
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens
|
|
||||||
import org.jetbrains.kotlin.psi.JetPsiFactory
|
|
||||||
import org.jetbrains.kotlin.psi.JetElement
|
|
||||||
import org.jetbrains.kotlin.psi.JetDotQualifiedExpression
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.lexer.JetTokens
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
|
|
||||||
public class OperatorToFunctionIntention : JetSelfTargetingOffsetIndependentIntention<JetExpression>("operator.to.function", javaClass()) {
|
public class OperatorToFunctionIntention : JetSelfTargetingIntention<JetExpression>(javaClass(), "Replace overloaded operator with function call") {
|
||||||
companion object {
|
companion object {
|
||||||
private fun isApplicablePrefix(element: JetPrefixExpression): Boolean {
|
private fun isApplicablePrefix(element: JetPrefixExpression, caretOffset: Int): Boolean {
|
||||||
return when (element.getOperationReference().getReferencedNameElementType()) {
|
val opRef = element.getOperationReference()
|
||||||
|
if (!opRef.getTextRange().containsOffset(caretOffset)) return false
|
||||||
|
return when (opRef.getReferencedNameElementType()) {
|
||||||
JetTokens.PLUS, JetTokens.MINUS, JetTokens.PLUSPLUS, JetTokens.MINUSMINUS, JetTokens.EXCL -> true
|
JetTokens.PLUS, JetTokens.MINUS, JetTokens.PLUSPLUS, JetTokens.MINUSMINUS, JetTokens.EXCL -> true
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isApplicablePostfix(element: JetPostfixExpression): Boolean {
|
private fun isApplicablePostfix(element: JetPostfixExpression, caretOffset: Int): Boolean {
|
||||||
return when (element.getOperationReference().getReferencedNameElementType()) {
|
val opRef = element.getOperationReference()
|
||||||
|
if (!opRef.getTextRange().containsOffset(caretOffset)) return false
|
||||||
|
return when (opRef.getReferencedNameElementType()) {
|
||||||
JetTokens.PLUSPLUS, JetTokens.MINUSMINUS -> true
|
JetTokens.PLUSPLUS, JetTokens.MINUSMINUS -> true
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isApplicableBinary(element: JetBinaryExpression): Boolean {
|
private fun isApplicableBinary(element: JetBinaryExpression, caretOffset: Int): Boolean {
|
||||||
return when (element.getOperationReference().getReferencedNameElementType()) {
|
val opRef = element.getOperationReference()
|
||||||
|
if (!opRef.getTextRange().containsOffset(caretOffset)) return false
|
||||||
|
return when (opRef.getReferencedNameElementType()) {
|
||||||
JetTokens.PLUS, JetTokens.MINUS, JetTokens.MUL, JetTokens.DIV, JetTokens.PERC, JetTokens.RANGE, JetTokens.IN_KEYWORD, JetTokens.NOT_IN, JetTokens.PLUSEQ, JetTokens.MINUSEQ, JetTokens.MULTEQ, JetTokens.DIVEQ, JetTokens.PERCEQ, JetTokens.EQEQ, JetTokens.EXCLEQ, JetTokens.GT, JetTokens.LT, JetTokens.GTEQ, JetTokens.LTEQ -> true
|
JetTokens.PLUS, JetTokens.MINUS, JetTokens.MUL, JetTokens.DIV, JetTokens.PERC, JetTokens.RANGE, JetTokens.IN_KEYWORD, JetTokens.NOT_IN, JetTokens.PLUSEQ, JetTokens.MINUSEQ, JetTokens.MULTEQ, JetTokens.DIVEQ, JetTokens.PERCEQ, JetTokens.EQEQ, JetTokens.EXCLEQ, JetTokens.GT, JetTokens.LT, JetTokens.GTEQ, JetTokens.LTEQ -> true
|
||||||
JetTokens.EQ -> element.getLeft() is JetArrayAccessExpression
|
JetTokens.EQ -> element.getLeft() is JetArrayAccessExpression
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isApplicableCall(element: JetCallExpression): Boolean {
|
private fun isApplicableArrayAccess(element: JetArrayAccessExpression, caretOffset: Int): Boolean {
|
||||||
val bindingContext = element.analyze()
|
val lbracket = element.getLeftBracket() ?: return false
|
||||||
val resolvedCall = element.getResolvedCall(bindingContext)
|
return lbracket.getTextRange().containsOffset(caretOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isApplicableCall(element: JetCallExpression, caretOffset: Int): Boolean {
|
||||||
|
val lbrace = (element.getValueArgumentList()?.getLeftParenthesis()
|
||||||
|
?: element.getFunctionLiteralArguments().firstOrNull()?.getFunctionLiteral()?.getLeftCurlyBrace()
|
||||||
|
?: return false) as PsiElement
|
||||||
|
if (!lbrace.getTextRange().containsOffset(caretOffset)) return false
|
||||||
|
|
||||||
|
val resolvedCall = element.getResolvedCall(element.analyze())
|
||||||
val descriptor = resolvedCall?.getResultingDescriptor()
|
val descriptor = resolvedCall?.getResultingDescriptor()
|
||||||
if (descriptor is FunctionDescriptor && descriptor.getName().asString() == "invoke") {
|
if (descriptor is FunctionDescriptor && descriptor.getName().asString() == "invoke") {
|
||||||
val parent = element.getParent()
|
val parent = element.getParent()
|
||||||
@@ -110,7 +118,7 @@ public class OperatorToFunctionIntention : JetSelfTargetingOffsetIndependentInte
|
|||||||
|
|
||||||
if (op == JetTokens.EQ) {
|
if (op == JetTokens.EQ) {
|
||||||
if (left is JetArrayAccessExpression) {
|
if (left is JetArrayAccessExpression) {
|
||||||
convertArrayAccess(left as JetArrayAccessExpression)
|
convertArrayAccess(left)
|
||||||
}
|
}
|
||||||
return element
|
return element
|
||||||
}
|
}
|
||||||
@@ -195,13 +203,13 @@ public class OperatorToFunctionIntention : JetSelfTargetingOffsetIndependentInte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isApplicableTo(element: JetExpression): Boolean {
|
override fun isApplicableTo(element: JetExpression, caretOffset: Int): Boolean {
|
||||||
return when (element) {
|
return when (element) {
|
||||||
is JetPrefixExpression -> isApplicablePrefix(element)
|
is JetPrefixExpression -> isApplicablePrefix(element, caretOffset)
|
||||||
is JetPostfixExpression -> isApplicablePostfix(element)
|
is JetPostfixExpression -> isApplicablePostfix(element, caretOffset)
|
||||||
is JetBinaryExpression -> isApplicableBinary(element)
|
is JetBinaryExpression -> isApplicableBinary(element, caretOffset)
|
||||||
is JetArrayAccessExpression -> true
|
is JetArrayAccessExpression -> isApplicableArrayAccess(element, caretOffset)
|
||||||
is JetCallExpression -> isApplicableCall(element)
|
is JetCallExpression -> isApplicableCall(element, caretOffset)
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -745,7 +745,7 @@
|
|||||||
</intentionAction>
|
</intentionAction>
|
||||||
|
|
||||||
<intentionAction>
|
<intentionAction>
|
||||||
<className>org.jetbrains.kotlin.idea.intentions.SwapBinaryExpression</className>
|
<className>org.jetbrains.kotlin.idea.intentions.SwapBinaryExpressionIntention</className>
|
||||||
<category>Kotlin</category>
|
<category>Kotlin</category>
|
||||||
</intentionAction>
|
</intentionAction>
|
||||||
|
|
||||||
|
|||||||
+5
-10
@@ -16,21 +16,16 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.intentions
|
package org.jetbrains.kotlin.idea.intentions
|
||||||
|
|
||||||
import org.jetbrains.kotlin.psi.JetStringTemplateExpression
|
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import org.jetbrains.kotlin.psi.JetPsiFactory
|
|
||||||
import org.jetbrains.kotlin.psi.JetStringTemplateEntry
|
|
||||||
import org.jetbrains.kotlin.psi.JetBinaryExpression
|
|
||||||
import org.jetbrains.kotlin.psi.JetStringTemplateEntryWithExpression
|
|
||||||
import org.jetbrains.kotlin.psi.JetExpression
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.psi.JetIfExpression
|
|
||||||
import org.jetbrains.kotlin.psi.JetBlockExpression
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.lexer.JetTokens
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||||
|
|
||||||
public class ConvertToConcatenatedStringIntention : JetSelfTargetingOffsetIndependentIntention<JetStringTemplateExpression>("convert.to.concatenated.string.intention", javaClass()) {
|
public class ConvertToConcatenatedStringIntention : JetSelfTargetingOffsetIndependentIntention<JetStringTemplateExpression>("convert.to.concatenated.string.intention", javaClass()) {
|
||||||
override fun isApplicableTo(element: JetStringTemplateExpression): Boolean {
|
override fun isApplicableTo(element: JetStringTemplateExpression): Boolean {
|
||||||
|
if (element.getLastChild().getNode().getElementType() != JetTokens.CLOSING_QUOTE) return false // not available for unclosed literal
|
||||||
return element.getEntries().any { it is JetStringTemplateEntryWithExpression }
|
return element.getEntries().any { it is JetStringTemplateEntryWithExpression }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +34,7 @@ public class ConvertToConcatenatedStringIntention : JetSelfTargetingOffsetIndepe
|
|||||||
val quote = if (tripleQuoted) "\"\"\"" else "\""
|
val quote = if (tripleQuoted) "\"\"\"" else "\""
|
||||||
val entries = element.getEntries()
|
val entries = element.getEntries()
|
||||||
|
|
||||||
val result = entries.stream()
|
val result = entries.sequence()
|
||||||
.mapIndexed { index, entry ->
|
.mapIndexed { index, entry ->
|
||||||
entry.toSeparateString(quote, convertExplicitly = index == 0, isFinalEntry = index == entries.size() - 1)
|
entry.toSeparateString(quote, convertExplicitly = index == 0, isFinalEntry = index == entries.size() - 1)
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-12
@@ -24,23 +24,24 @@ import org.jetbrains.kotlin.idea.util.JetPsiPrecedences
|
|||||||
import org.jetbrains.kotlin.lexer.JetTokens.*
|
import org.jetbrains.kotlin.lexer.JetTokens.*
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
|
|
||||||
public class SwapBinaryExpression : JetSelfTargetingOffsetIndependentIntention<JetBinaryExpression>(
|
public class SwapBinaryExpressionIntention : JetSelfTargetingIntention<JetBinaryExpression>(javaClass(), "Flip binary expression") {
|
||||||
"swap.binary.expression", javaClass()
|
|
||||||
) {
|
|
||||||
companion object {
|
companion object {
|
||||||
val SUPPORTED_OPERATIONS = setOf(PLUS, MUL, OROR, ANDAND, EQEQ, EXCLEQ, EQEQEQ, EXCLEQEQEQ, GT, LT, GTEQ, LTEQ)
|
private val SUPPORTED_OPERATIONS = setOf(PLUS, MUL, OROR, ANDAND, EQEQ, EXCLEQ, EQEQEQ, EXCLEQEQEQ, GT, LT, GTEQ, LTEQ)
|
||||||
|
|
||||||
val SUPPORTED_OPERATION_NAMES = SUPPORTED_OPERATIONS.map { OperatorConventions.BINARY_OPERATION_NAMES[it]?.asString() }.toSet().filterNotNull() +
|
private val SUPPORTED_OPERATION_NAMES = SUPPORTED_OPERATIONS.map { OperatorConventions.BINARY_OPERATION_NAMES[it]?.asString() }.toSet().filterNotNull() +
|
||||||
setOf("xor", "or", "and", "equals", "identityEquals")
|
setOf("xor", "or", "and", "equals", "identityEquals")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isApplicableTo(element: JetBinaryExpression): Boolean {
|
override fun isApplicableTo(element: JetBinaryExpression, caretOffset: Int): Boolean {
|
||||||
|
val opRef = element.getOperationReference()
|
||||||
|
if (!opRef.getTextRange().containsOffset(caretOffset)) return false
|
||||||
|
|
||||||
if (leftSubject(element) == null || rightSubject(element) == null) {
|
if (leftSubject(element) == null || rightSubject(element) == null) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
val operationToken = element.getOperationToken()
|
val operationToken = element.getOperationToken()
|
||||||
val operationTokenText = element.getOperationReference().getText()
|
val operationTokenText = opRef.getText()
|
||||||
if (operationToken in SUPPORTED_OPERATIONS
|
if (operationToken in SUPPORTED_OPERATIONS
|
||||||
|| operationToken == IDENTIFIER && operationTokenText in SUPPORTED_OPERATION_NAMES) {
|
|| operationToken == IDENTIFIER && operationTokenText in SUPPORTED_OPERATION_NAMES) {
|
||||||
setText("Flip '$operationTokenText'")
|
setText("Flip '$operationTokenText'")
|
||||||
@@ -62,11 +63,9 @@ public class SwapBinaryExpression : JetSelfTargetingOffsetIndependentIntention<J
|
|||||||
val left = leftSubject(element)!!
|
val left = leftSubject(element)!!
|
||||||
val right = rightSubject(element)!!
|
val right = rightSubject(element)!!
|
||||||
val psiFactory = JetPsiFactory(element)
|
val psiFactory = JetPsiFactory(element)
|
||||||
val newRight = psiFactory.createExpression(left.getText()!!)
|
left.replace(psiFactory.createExpression(right.getText()))
|
||||||
val newLeft = psiFactory.createExpression(right.getText()!!)
|
right.replace(psiFactory.createExpression(left.getText()))
|
||||||
left.replace(newLeft)
|
element.replace(psiFactory.createBinaryExpression(element.getLeft()!!, convertedOperator, element.getRight()!!))
|
||||||
right.replace(newRight)
|
|
||||||
element.replace(psiFactory.createBinaryExpression(element.getLeft(), convertedOperator, element.getRight()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun leftSubject(element: JetBinaryExpression): JetExpression? {
|
private fun leftSubject(element: JetBinaryExpression): JetExpression? {
|
||||||
@@ -4,5 +4,5 @@ class coffee() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun main() {
|
fun main() {
|
||||||
val f = coffee().<caret>invoke()
|
val f = coffee().invoke<caret>()
|
||||||
}
|
}
|
||||||
+1
-1
@@ -2,5 +2,5 @@
|
|||||||
// IS_APPLICABLE: false
|
// IS_APPLICABLE: false
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val bar = { x: Int -> x + 1 }
|
val bar = { x: Int -> x + 1 }
|
||||||
val incremented = listOf(1, 2, 3).<caret>map(bar)
|
val incremented = listOf(1, 2, 3).map<caret>(bar)
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
fun foo() {
|
fun foo() {
|
||||||
var a = 5
|
var a = 5
|
||||||
<caret>a--
|
a--<caret>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
org.jetbrains.kotlin.idea.intentions.SwapBinaryExpression
|
org.jetbrains.kotlin.idea.intentions.SwapBinaryExpressionIntention
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
fun main() {
|
fun main() {
|
||||||
val ex = 4 > <caret>5
|
val ex = 4 ><caret> 5
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
fun main() {
|
fun main() {
|
||||||
val ex = 4 < <caret>5
|
val ex = 4 <<caret> 5
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
fun test(a: Int, b: Int, c: Int, d: Int, e: Int): Int {
|
fun test(a: Int, b: Int, c: Int, d: Int, e: Int): Int {
|
||||||
return a + b + <caret>c + d + e
|
return a + b +<caret> c + d + e
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
fun main() {
|
fun main() {
|
||||||
val rabbit = 1 == 2<caret> || 3 == 5
|
val rabbit = 1 == 2 <caret>|| 3 == 5
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fun main(): Boolean {
|
fun main(): Boolean {
|
||||||
if (5 != <caret>20) {
|
if (5 !=<caret> 20) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
fun neq(a: Int, b: Int) {
|
fun neq(a: Int, b: Int) {
|
||||||
if (<caret>a !== b) {}
|
if (a <caret>!== b) {}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
fun neq(a: Int, b: Int) {
|
fun neq(a: Int, b: Int) {
|
||||||
if (<caret>b !== a) {}
|
if (b <caret>!== a) {}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
fun test(a: Int, b: Int): Int {
|
fun test(a: Int, b: Int): Int {
|
||||||
return <caret>a + b
|
return a <caret>+ b
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
fun test(a: Int, b: Int): Int {
|
fun test(a: Int, b: Int): Int {
|
||||||
return <caret>a + b
|
return a <caret>+ b
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
fun test(a: Int, b: Int): Int {
|
fun test(a: Int, b: Int): Int {
|
||||||
return <caret>a plus b
|
return a <caret>plus b
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
fun test(a: Int, b: Int): Int {
|
fun test(a: Int, b: Int): Int {
|
||||||
return <caret>a times b
|
return a <caret>times b
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user