Remove parentheses: add semicolon before lambda if necessary

In 2010b175, it was suggested just not to suggest parentheses removal.
However, it contradicts with behaviour of "Replace contains" which
adds semicolon before lambda in this case. So in this commit I made
behaviour of remove parentheses the same.

This commit reverts production part of 2010b175
Fixes failing test of "replace contains"
This commit is contained in:
Mikhail Glukhikh
2019-01-10 10:45:46 +03:00
parent 62222460b6
commit 18ea86cfb4
8 changed files with 37 additions and 18 deletions
@@ -448,7 +448,7 @@ public class KtPsiUtil {
}
}
if (innerExpression instanceof KtLambdaExpression || innerExpression.getFirstChild() instanceof KtLambdaExpression) {
if (innerExpression instanceof KtLambdaExpression) {
PsiElement prevSibling = PsiTreeUtil.skipWhitespacesAndCommentsBackward(currentInner);
if (prevSibling != null && prevSibling.getText().endsWith(KtTokens.RPAR.getValue())) return true;
}
@@ -19,10 +19,11 @@ package org.jetbrains.kotlin.idea.intentions
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.idea.util.CommentSaver
import org.jetbrains.kotlin.psi.KtParenthesizedExpression
import org.jetbrains.kotlin.psi.KtPsiUtil
import org.jetbrains.kotlin.psi.*
class RemoveUnnecessaryParenthesesIntention : SelfTargetingRangeIntention<KtParenthesizedExpression>(KtParenthesizedExpression::class.java, "Remove unnecessary parentheses") {
class RemoveUnnecessaryParenthesesIntention : SelfTargetingRangeIntention<KtParenthesizedExpression>(
KtParenthesizedExpression::class.java, "Remove unnecessary parentheses"
) {
override fun applicabilityRange(element: KtParenthesizedExpression): TextRange? {
element.expression ?: return null
if (!KtPsiUtil.areParenthesesUseless(element)) return null
@@ -31,7 +32,11 @@ class RemoveUnnecessaryParenthesesIntention : SelfTargetingRangeIntention<KtPare
override fun applyTo(element: KtParenthesizedExpression, editor: Editor?) {
val commentSaver = CommentSaver(element)
val replaced = element.replace(element.expression!!)
val innerExpression = element.expression ?: return
val replaced = element.replace(innerExpression)
if (innerExpression.firstChild is KtLambdaExpression) {
KtPsiFactory(element).appendSemicolonBeforeLambdaContainingElement(replaced)
}
commentSaver.restore(replaced)
}
}
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.idea.intentions
import com.intellij.psi.PsiElement
import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
@@ -340,3 +341,12 @@ val FunctionDescriptor.isOperatorOrCompatible: Boolean
}
return isOperator
}
fun KtPsiFactory.appendSemicolonBeforeLambdaContainingElement(element: PsiElement) {
val previousElement = KtPsiUtil.skipSiblingsBackwardByPredicate(element) {
it!!.node.elementType in KtTokens.WHITE_SPACE_OR_COMMENT_BIT_SET
}
if (previousElement != null && previousElement is KtExpression) {
previousElement.parent.addAfter(createSemicolon(), previousElement)
}
}
@@ -30,7 +30,9 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.util.OperatorNameConventions
class ReplaceContainsIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(KtDotQualifiedExpression::class.java, "Replace 'contains' call with 'in' operator"), HighPriorityAction {
class ReplaceContainsIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(
KtDotQualifiedExpression::class.java, "Replace 'contains' call with 'in' operator"
), HighPriorityAction {
override fun applicabilityRange(element: KtDotQualifiedExpression): TextRange? {
if (element.calleeName != OperatorNameConventions.CONTAINS.asString()) return null
@@ -61,19 +63,13 @@ class ReplaceContainsIntention : SelfTargetingRangeIntention<KtDotQualifiedExpre
val prefixExpression = element.parent as? KtPrefixExpression
val expression = if (prefixExpression != null && prefixExpression.operationToken == KtTokens.EXCL) {
prefixExpression.replace(psiFactory.createExpressionByPattern("$0 !in $1", argument, receiver))
}
else {
} else {
element.replace(psiFactory.createExpressionByPattern("$0 in $1", argument, receiver))
}
// Append semicolon to previous statement if needed
if (argument is KtLambdaExpression) {
val previousElement = KtPsiUtil.skipSiblingsBackwardByPredicate(expression) {
it!!.node.elementType in KtTokens.WHITE_SPACE_OR_COMMENT_BIT_SET
}
if (previousElement != null && previousElement is KtExpression) {
previousElement.parent.addAfter(psiFactory.createSemicolon(), previousElement)
}
psiFactory.appendSemicolonBeforeLambdaContainingElement(expression)
}
}
@@ -1,5 +1,3 @@
// IS_APPLICABLE: false
fun main() {
foo()
<caret>({ foo() } as? () -> Unit)
@@ -0,0 +1,6 @@
fun main() {
foo();
{ foo() } as? () -> Unit
}
fun foo() {}
@@ -1,5 +1,3 @@
// IS_APPLICABLE: false
fun main() {
foo()
<caret>({ foo() }.invoke())
@@ -0,0 +1,6 @@
fun main() {
foo();
{ foo() }.invoke()
}
fun foo() {}