Avoid creation expressions by texts

This commit is contained in:
Valentin Kipyatkov
2015-05-11 17:51:36 +03:00
parent 749416434f
commit 8a30d2d664
5 changed files with 22 additions and 19 deletions
@@ -121,7 +121,13 @@ public fun JetClassOrObject.effectiveDeclarations(): List<JetDeclaration> =
public fun JetClass.isAbstract(): Boolean = isInterface() || hasModifier(JetTokens.ABSTRACT_KEYWORD)
[suppress("UNCHECKED_CAST")]
public fun <T: PsiElement> PsiElement.replaced(newElement: T): T = replace(newElement) as T
public inline fun <reified T: PsiElement> PsiElement.replaced(newElement: T): T {
val result = replace(newElement)
return if (result is T)
result
else
(result as JetParenthesizedExpression).getExpression() as T
}
[suppress("UNCHECKED_CAST")]
public fun <T: PsiElement> T.copied(): T = copy() as T
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.idea.refactoring.inline.KotlinInlineValHandler
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinIntroduceVariableHandler
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.replaced
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContextUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -58,8 +59,6 @@ fun JetExpression.unwrapBlock(): JetExpression {
return innerExpression
}
fun JetExpression.isStatement(): Boolean = isUsedAsStatement(this.analyze())
fun JetExpression?.isNullExpression(): Boolean = this?.unwrapBlock()?.getNode()?.getElementType() == JetNodeTypes.NULL
fun JetExpression?.isNullExpressionOrEmptyBlock(): Boolean = this.isNullExpression() || this is JetBlockExpression && this.getStatements().isEmpty()
@@ -81,21 +80,17 @@ fun JetExpression.evaluatesTo(other: JetExpression): Boolean {
}
fun JetExpression.convertToIfNotNullExpression(conditionLhs: JetExpression, thenClause: JetExpression, elseClause: JetExpression?): JetIfExpression {
val condition = JetPsiFactory(this).createExpression("${conditionLhs.getText()} != null")
val condition = JetPsiFactory(this).createExpressionByPattern("$0 != null", conditionLhs)
return this.convertToIfStatement(condition, thenClause, elseClause)
}
fun JetExpression.convertToIfNullExpression(conditionLhs: JetExpression, thenClause: JetExpression): JetIfExpression {
val condition = JetPsiFactory(this).createExpression("${conditionLhs.getText()} == null")
return this.convertToIfStatement(condition, thenClause, null)
val condition = JetPsiFactory(this).createExpressionByPattern("$0 == null", conditionLhs)
return this.convertToIfStatement(condition, thenClause)
}
fun JetExpression.convertToIfStatement(condition: JetExpression, thenClause: JetExpression, elseClause: JetExpression?): JetIfExpression {
val elseBranch = if (elseClause == null) "" else " else ${elseClause.getText()}"
val conditionalString = "if (${condition.getText()}) ${thenClause.getText()}$elseBranch"
val st = this.replace(conditionalString) as JetExpression
return JetPsiUtil.deparenthesize(st) as JetIfExpression
fun JetExpression.convertToIfStatement(condition: JetExpression, thenClause: JetExpression, elseClause: JetExpression? = null): JetIfExpression {
return replaced(JetPsiFactory(this).createIf(condition, thenClause, elseClause))
}
fun JetIfExpression.introduceValueForCondition(occurrenceInThenClause: JetExpression, editor: Editor) {
@@ -108,9 +103,6 @@ fun JetIfExpression.introduceValueForCondition(occurrenceInThenClause: JetExpres
null)
}
fun JetElement.replace(expressionAsString: String): PsiElement =
this.replace(JetPsiFactory(this).createExpression(expressionAsString))
fun JetSimpleNameExpression.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor: Editor) {
val declaration = this.getReference()?.resolve() as JetDeclaration
@@ -24,6 +24,7 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiDocumentManager
import org.apache.commons.lang.StringEscapeUtils.escapeJava
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingRangeIntention
import org.jetbrains.kotlin.idea.intentions.JetTypeLookupExpression
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.*
@@ -32,6 +33,7 @@ import org.jetbrains.kotlin.psi.JetPostfixExpression
import org.jetbrains.kotlin.psi.JetPsiFactory
import org.jetbrains.kotlin.psi.JetPsiUtil
import org.jetbrains.kotlin.psi.JetThrowExpression
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement
public class DoubleBangToIfThenIntention : JetSelfTargetingRangeIntention<JetPostfixExpression>(javaClass(), "Replace '!!' expression with 'if' expression") {
override fun applicabilityRange(element: JetPostfixExpression): TextRange? {
@@ -44,7 +46,7 @@ public class DoubleBangToIfThenIntention : JetSelfTargetingRangeIntention<JetPos
val defaultException = JetPsiFactory(element).createExpression("throw NullPointerException()")
val isStatement = element.isStatement()
val isStatement = element.isUsedAsStatement(element.analyze())
val isStable = base.isStableVariable()
val ifStatement = if (isStatement)
@@ -18,10 +18,12 @@ package org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingRangeIntention
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.*
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement
public class IfThenToDoubleBangIntention : JetSelfTargetingRangeIntention<JetIfExpression>(javaClass(), "Replace 'if' expression with '!!' expression") {
override fun applicabilityRange(element: JetIfExpression): TextRange? {
@@ -49,7 +51,7 @@ public class IfThenToDoubleBangIntention : JetSelfTargetingRangeIntention<JetIfE
else -> throw IllegalStateException()
}
val matchesAsStatement = element.isStatement() && (matchingClause?.isNullExpressionOrEmptyBlock() ?: true)
val matchesAsStatement = element.isUsedAsStatement(element.analyze()) && (matchingClause?.isNullExpressionOrEmptyBlock() ?: true)
if (!matchesAsStatement && !(matchingClause?.evaluatesTo(expression) ?: false && expression.isStableVariable())) return null
var text = "Replace 'if' expression with '!!' expression"
@@ -17,12 +17,13 @@
package org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions
import com.intellij.openapi.editor.Editor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingOffsetIndependentIntention
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.convertToIfNotNullExpression
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.introduceValueForCondition
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isStableVariable
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isStatement
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement
public class SafeAccessToIfThenIntention : JetSelfTargetingOffsetIndependentIntention<JetSafeQualifiedExpression>("safe.access.to.if.then", javaClass()) {
override fun isApplicableTo(element: JetSafeQualifiedExpression): Boolean = true
@@ -38,7 +39,7 @@ public class SafeAccessToIfThenIntention : JetSelfTargetingOffsetIndependentInte
val psiFactory = JetPsiFactory(element)
val dotQualifiedExpression = psiFactory.createExpression("${receiverAsString}.${selector!!.getText()}")
val elseClause = if (element.isStatement()) null else psiFactory.createExpression("null")
val elseClause = if (element.isUsedAsStatement(element.analyze())) null else psiFactory.createExpression("null")
val ifExpression = element.convertToIfNotNullExpression(receiver, dotQualifiedExpression, elseClause)
if (!receiverIsStable) {