IfToWhenIntention - no use of WhenBuilder

This commit is contained in:
Valentin Kipyatkov
2015-05-06 00:08:13 +03:00
parent 47c613c477
commit b1d0365c2f
2 changed files with 79 additions and 28 deletions
@@ -48,13 +48,13 @@ public fun JetPsiFactory.createExpressionByPattern(pattern: String, vararg args:
val elementRange = element.getTextRange().shiftRight(-start)
if (elementRange == range) {
val elementToUse = element.parents(withItself = false).firstIsInstanceOrNull<JetExpression>()
?: error("Invalid pattern - no JetExpression found for $n")
?: error("Invalid pattern '$pattern' - no JetExpression found for $n text = " + processedText)
val pointer = pointerManager.createSmartPsiElementPointer(elementToUse)
pointers.put(pointer, n)
break
}
else if (!range.contains(elementRange)) {
throw IllegalArgumentException("Invalid pattern - no PsiElement found for $$n")
throw IllegalArgumentException("Invalid pattern '$pattern' - no PsiElement found for $$n text = " + processedText)
}
}
}
@@ -106,7 +106,7 @@ private data class PatternData(val processedText: String, val placeholders: Map<
private fun processPattern(pattern: String, args: Array<out Any>): PatternData {
val ranges = LinkedHashMap<Int, MutableList<Placeholder>>()
fun charOrNull(i: Int) = if (i < pattern.length()) pattern[i] else null
fun charOrNull(i: Int) = if (0 <= i && i < pattern.length()) pattern[i] else null
fun check(condition: Boolean, message: String) {
if (!condition) {
@@ -118,6 +118,7 @@ private fun processPattern(pattern: String, args: Array<out Any>): PatternData {
var i = 0
while (i < pattern.length()) {
var c = pattern[i]
var prevChar = charOrNull(i - 1)
if (c == '$') {
val nextChar = charOrNull(++i)
@@ -134,7 +135,15 @@ private fun processPattern(pattern: String, args: Array<out Any>): PatternData {
val arg: Any? = if (n < args.size()) args[n] else null /* report wrong number of arguments later */
val placeholderText = if (charOrNull(i) != '=') {
arg as? String ?: "xyz"
if (arg is String) {
arg
}
else {
if (prevChar?.isJavaIdentifierPart() ?: false) {
append(" ")
}
"xyz"
}
}
else {
check(arg !is String, "do not specify placeholder text for $$n - String argument passed")
@@ -173,3 +182,35 @@ private fun processPattern(pattern: String, args: Array<out Any>): PatternData {
return PatternData(text, ranges)
}
public class ExpressionBuilder {
private val patternBuilder = StringBuilder()
private val arguments = ArrayList<Any>()
public fun appendFixedText(text: String): ExpressionBuilder {
patternBuilder.append(text)
return this
}
public fun appendNonFormattedText(text: String): ExpressionBuilder {
patternBuilder.append("$" + arguments.size())
arguments.add(text)
return this
}
public fun appendExpression(expression: JetExpression): ExpressionBuilder {
patternBuilder.append("$" + arguments.size())
arguments.add(expression)
return this
}
public fun createExpression(factory: JetPsiFactory): JetExpression {
return factory.createExpressionByPattern(patternBuilder.toString(), *arguments.toArray())
}
}
public fun JetPsiFactory.buildExpression(build: ExpressionBuilder.() -> Unit): JetExpression {
val builder = ExpressionBuilder()
builder.build()
return builder.createExpression(this)
}
@@ -31,35 +31,45 @@ public class IfToWhenIntention : JetSelfTargetingIntention<JetIfExpression>(java
}
override fun applyTo(element: JetIfExpression, editor: Editor) {
val builder = JetPsiFactory(element).WhenBuilder()
var whenExpression = JetPsiFactory(element).buildExpression {
appendFixedText("when {\n")
var ifExpression = element
while (true) {
val condition = ifExpression.getCondition()
val orBranches = ArrayList<JetExpression>()
if (condition != null) {
orBranches.addOrBranches(condition)
}
if (orBranches.isNotEmpty()) {
orBranches.forEach { builder.condition(it) }
}
else {
builder.condition(null)
var ifExpression = element
while (true) {
val condition = ifExpression.getCondition()
val orBranches = ArrayList<JetExpression>()
if (condition != null) {
orBranches.addOrBranches(condition)
}
for ((i, expr) in orBranches.withIndex()) {
if (i > 0) appendFixedText(",")
appendExpression(expr)
}
appendFixedText("->")
val thenBranch = ifExpression.getThen()
if (thenBranch != null) {
appendExpression(thenBranch)
}
appendFixedText("\n")
val elseBranch = ifExpression.getElse() ?: break
if (elseBranch is JetIfExpression) {
ifExpression = elseBranch
}
else {
appendFixedText("else->")
appendExpression(elseBranch)
appendFixedText("\n")
break
}
}
builder.branchExpression(ifExpression.getThen())
appendFixedText("}")
} as JetWhenExpression
val elseBranch = ifExpression.getElse() ?: break
if (elseBranch is JetIfExpression) {
ifExpression = elseBranch
}
else {
builder.elseEntry(elseBranch)
break
}
}
var whenExpression = builder.toExpression()
if (whenExpression.canIntroduceSubject()) {
whenExpression = whenExpression.introduceSubject()
}