Better formatting in some cases

This commit is contained in:
Valentin Kipyatkov
2016-04-20 15:22:44 +03:00
parent fe7ddbcc0d
commit 53e3a67a7f
12 changed files with 53 additions and 20 deletions
@@ -30,7 +30,7 @@ interface ChainedCallGenerator {
/** /**
* @param pattern pattern string for generating the part of the call to the right from the dot * @param pattern pattern string for generating the part of the call to the right from the dot
*/ */
fun generate(pattern: String, vararg args: Any): KtExpression fun generate(pattern: String, vararg args: Any, receiver: KtExpression = this.receiver, safeCall: Boolean = false): KtExpression
} }
/** /**
@@ -42,7 +42,7 @@ interface Transformation {
val presentation: String val presentation: String
open fun buildPresentation(prevTransformationsPresentation: String?): String { fun buildPresentation(prevTransformationsPresentation: String?): String {
return if (prevTransformationsPresentation != null) return if (prevTransformationsPresentation != null)
prevTransformationsPresentation + "." + presentation prevTransformationsPresentation + "." + presentation
else else
@@ -50,6 +50,10 @@ interface Transformation {
} }
fun generateCode(chainedCallGenerator: ChainedCallGenerator): KtExpression fun generateCode(chainedCallGenerator: ChainedCallGenerator): KtExpression
val chainCallCount: Int
get() = 1
} }
/** /**
@@ -59,7 +63,6 @@ interface SequenceTransformation : Transformation {
fun mergeWithPrevious(previousTransformation: SequenceTransformation): SequenceTransformation? = null fun mergeWithPrevious(previousTransformation: SequenceTransformation): SequenceTransformation? = null
val affectsIndex: Boolean val affectsIndex: Boolean
} }
/** /**
@@ -169,7 +169,8 @@ private fun ResultTransformationMatch.generateCallChain(loop: KtForExpression):
sequenceTransformations = sequenceTransformations.dropLast(1) sequenceTransformations = sequenceTransformations.dropLast(1)
} }
val lineBreak = if (sequenceTransformations.isNotEmpty()) "\n" else "" val chainCallCount = sequenceTransformations.sumBy { it.chainCallCount } + resultTransformation.chainCallCount
val lineBreak = if (chainCallCount > 1) "\n" else ""
var callChain = loop.loopRange!! var callChain = loop.loopRange!!
@@ -178,9 +179,10 @@ private fun ResultTransformationMatch.generateCallChain(loop: KtForExpression):
override val receiver: KtExpression override val receiver: KtExpression
get() = callChain get() = callChain
override fun generate(pattern: String, vararg args: Any): KtExpression { override fun generate(pattern: String, vararg args: Any, receiver: KtExpression, safeCall: Boolean): KtExpression {
val newPattern = "\$${args.size}$lineBreak.$pattern" val dot = if (safeCall) "?." else "."
return psiFactory.createExpressionByPattern(newPattern, *args, callChain) val newPattern = "$" + args.size + lineBreak + dot + pattern
return psiFactory.createExpressionByPattern(newPattern, *args, receiver)
} }
} }
@@ -65,6 +65,9 @@ class AddToCollectionTransformation(
"+=" "+="
} }
override val chainCallCount: Int
get() = 0
override fun generateCode(chainedCallGenerator: ChainedCallGenerator): KtExpression { override fun generateCode(chainedCallGenerator: ChainedCallGenerator): KtExpression {
return KtPsiFactory(loop).createExpressionByPattern("$0 += $1", targetCollection, chainedCallGenerator.receiver) return KtPsiFactory(loop).createExpressionByPattern("$0 += $1", targetCollection, chainedCallGenerator.receiver)
} }
@@ -43,6 +43,9 @@ class FindAndAssignTransformation(
override val presentation: String override val presentation: String
get() = generator.functionName + (if (filter != null) "{}" else "()") get() = generator.functionName + (if (filter != null) "{}" else "()")
override val chainCallCount: Int
get() = generator.chainCallCount
override fun generateCode(chainedCallGenerator: ChainedCallGenerator): KtExpression { override fun generateCode(chainedCallGenerator: ChainedCallGenerator): KtExpression {
return generator.generate(chainedCallGenerator, filter) return generator.generate(chainedCallGenerator, filter)
} }
@@ -47,6 +47,9 @@ class FindAndReturnTransformation(
override val presentation: String override val presentation: String
get() = generator.functionName + (if (filter != null) "{}" else "()") get() = generator.functionName + (if (filter != null) "{}" else "()")
override val chainCallCount: Int
get() = generator.chainCallCount
override fun generateCode(chainedCallGenerator: ChainedCallGenerator): KtExpression { override fun generateCode(chainedCallGenerator: ChainedCallGenerator): KtExpression {
return generator.generate(chainedCallGenerator, filter) return generator.generate(chainedCallGenerator, filter)
} }
@@ -114,7 +114,11 @@ fun KtProperty.hasWriteUsages(): Boolean {
interface FindOperatorGenerator { interface FindOperatorGenerator {
val functionName: String val functionName: String
fun generate(chainedCallGenerator: ChainedCallGenerator, filter: KtExpression?): KtExpression fun generate(chainedCallGenerator: ChainedCallGenerator, filter: KtExpression?): KtExpression
val chainCallCount: Int
get() = 1
} }
fun buildFindOperationGenerator( fun buildFindOperationGenerator(
@@ -150,10 +154,7 @@ fun buildFindOperationGenerator(
// we cannot use ?: if found value can be null // we cannot use ?: if found value can be null
if (inputVariableCanHoldNull) return null if (inputVariableCanHoldNull) return null
return object: FindOperatorGenerator { return object: FindOperatorGenerator by this {
override val functionName: String
get() = this@useElvisOperatorIfNeeded.functionName
override fun generate(chainedCallGenerator: ChainedCallGenerator, filter: KtExpression?): KtExpression { override fun generate(chainedCallGenerator: ChainedCallGenerator, filter: KtExpression?): KtExpression {
val generated = this@useElvisOperatorIfNeeded.generate(chainedCallGenerator, filter) val generated = this@useElvisOperatorIfNeeded.generate(chainedCallGenerator, filter)
return KtPsiFactory(generated).createExpressionByPattern("$0 ?: $1", generated, valueIfNotFound) return KtPsiFactory(generated).createExpressionByPattern("$0 ?: $1", generated, valueIfNotFound)
@@ -184,9 +185,12 @@ fun buildFindOperationGenerator(
override val functionName: String override val functionName: String
get() = "firstOrNull" get() = "firstOrNull"
override val chainCallCount: Int
get() = 2
override fun generate(chainedCallGenerator: ChainedCallGenerator, filter: KtExpression?): KtExpression { override fun generate(chainedCallGenerator: ChainedCallGenerator, filter: KtExpression?): KtExpression {
val findFirstCall = generateChainedCall(functionName, chainedCallGenerator, filter) val findFirstCall = generateChainedCall(functionName, chainedCallGenerator, filter)
return KtPsiFactory(findFirstCall).createExpressionByPattern("$0?.$1", findFirstCall, selector) return chainedCallGenerator.generate("$0", selector, receiver = findFirstCall, safeCall = true)
} }
}.useElvisOperatorIfNeeded() }.useElvisOperatorIfNeeded()
} }
@@ -197,12 +201,15 @@ fun buildFindOperationGenerator(
return object: FindOperatorGenerator { return object: FindOperatorGenerator {
override val functionName: String override val functionName: String
get() = "firstOrNull" //TODO get() = "firstOrNull"
override val chainCallCount: Int
get() = 2 // also includes "let"
override fun generate(chainedCallGenerator: ChainedCallGenerator, filter: KtExpression?): KtExpression { override fun generate(chainedCallGenerator: ChainedCallGenerator, filter: KtExpression?): KtExpression {
val findFirstCall = generateChainedCall(functionName, chainedCallGenerator, filter) val findFirstCall = generateChainedCall(functionName, chainedCallGenerator, filter)
val letBody = generateLambda(inputVariable, valueIfFound) val letBody = generateLambda(inputVariable, valueIfFound)
return KtPsiFactory(findFirstCall).createExpressionByPattern("$0?.let $1:'{}'", findFirstCall, letBody) return chainedCallGenerator.generate("let $0:'{}'", letBody, receiver = findFirstCall, safeCall = true)
} }
}.useElvisOperatorIfNeeded() }.useElvisOperatorIfNeeded()
} }
@@ -1,7 +1,9 @@
// WITH_RUNTIME // WITH_RUNTIME
// INTENTION_TEXT: "Replace with 'firstOrNull{}'" // INTENTION_TEXT: "Replace with 'firstOrNull{}'"
fun foo(list: List<String>) { fun foo(list: List<String>) {
<caret>val result: String? = list.firstOrNull { it.length > 0 }?.let { bar(it) } <caret>val result: String? = list
.firstOrNull { it.length > 0 }
?.let { bar(it) }
} }
fun bar(s: String): String = s fun bar(s: String): String = s
@@ -1,7 +1,9 @@
// WITH_RUNTIME // WITH_RUNTIME
// INTENTION_TEXT: "Replace with 'firstOrNull{}'" // INTENTION_TEXT: "Replace with 'firstOrNull{}'"
fun foo(list: List<String>) { fun foo(list: List<String>) {
<caret>val result: String? = list.firstOrNull { it.length > 0 }?.let { it.substring(0, it.length - 1) } <caret>val result: String? = list
.firstOrNull { it.length > 0 }
?.let { it.substring(0, it.length - 1) }
} }
fun bar(s: String): String = s fun bar(s: String): String = s
@@ -1,7 +1,9 @@
// WITH_RUNTIME // WITH_RUNTIME
// INTENTION_TEXT: "Replace with 'firstOrNull{}'" // INTENTION_TEXT: "Replace with 'firstOrNull{}'"
fun foo(list: List<String>) { fun foo(list: List<String>) {
<caret>val result = list.firstOrNull { it.length > 0 }?.let { bar(it) } ?: "" <caret>val result = list
.firstOrNull { it.length > 0 }
?.let { bar(it) } ?: ""
} }
fun bar(s: String): String = s fun bar(s: String): String = s
@@ -1,5 +1,7 @@
// WITH_RUNTIME // WITH_RUNTIME
// INTENTION_TEXT: "Replace with 'firstOrNull{}'" // INTENTION_TEXT: "Replace with 'firstOrNull{}'"
fun foo(list: List<String>): Int? { fun foo(list: List<String>): Int? {
<caret>return list.firstOrNull { it.isNotEmpty() }?.length <caret>return list
.firstOrNull { it.isNotEmpty() }
?.length
} }
@@ -1,5 +1,7 @@
// WITH_RUNTIME // WITH_RUNTIME
// INTENTION_TEXT: "Replace with 'firstOrNull{}'" // INTENTION_TEXT: "Replace with 'firstOrNull{}'"
fun foo(list: List<String>): Int { fun foo(list: List<String>): Int {
<caret>return list.firstOrNull { it.isNotEmpty() }?.length ?: -1 <caret>return list
.firstOrNull { it.isNotEmpty() }
?.length ?: -1
} }
@@ -1,5 +1,7 @@
// WITH_RUNTIME // WITH_RUNTIME
// INTENTION_TEXT: "Replace with 'firstOrNull{}'" // INTENTION_TEXT: "Replace with 'firstOrNull{}'"
fun foo(list: List<String?>) { fun foo(list: List<String?>) {
<caret>val result: String? = list.firstOrNull { it != "" }?.substring(1) <caret>val result: String? = list
.firstOrNull { it != "" }
?.substring(1)
} }