Improved logic for chained lambda indentation

#KT-22071 Fixed
This commit is contained in:
Dmitry Jemerov
2018-01-08 14:40:10 +01:00
parent 54c262c505
commit a5cc9809ac
8 changed files with 180 additions and 31 deletions
+51
View File
@@ -0,0 +1,51 @@
package templates
import kotlin.coroutines.experimental.buildSequence
import kotlin.reflect.KTypeProjection
import kotlin.reflect.full.createType
import kotlin.reflect.full.isSubtypeOf
typealias TemplateGroup = () -> Sequence<MemberTemplate>
fun templateGroupOf(vararg templates: MemberTemplate): TemplateGroup = { templates.asSequence() }
abstract class TemplateGroupBase : TemplateGroup {
override fun invoke(): Sequence<MemberTemplate> = buildSequence {
with(this@TemplateGroupBase) {
this::class.members.filter { it.name.startsWith("f_") }.forEach {
require(it.parameters.size == 1) { "Member $it violates naming convention" }
when {
it.returnType.isSubtypeOf(typeMemberTemplate) ->
yield(it.call(this) as MemberTemplate)
it.returnType.isSubtypeOf(typeIterableOfMemberTemplates) ->
@Suppress("UNCHECKED_CAST")
yieldAll(it.call(this) as Iterable<MemberTemplate>)
else ->
error("Member $it violates naming convention")
}
}
}
}.run {
if (defaultActions.isEmpty()) this else onEach { t -> defaultActions.forEach(t::builder) }
}
private val defaultActions = mutableListOf<MemberBuildAction>()
fun defaultBuilder(builderAction: MemberBuildAction) {
defaultActions += builderAction
}
companion object {
private val typeMemberTemplate = MemberTemplate::class.createType()
private val typeIterableOfMemberTemplates = Iterable::class.createType(arguments = listOf(KTypeProjection.invariant(typeMemberTemplate)))
}
}
fun foo() {
cacheFile.objectInputStream().use {
// one indent here
}
}
+51
View File
@@ -0,0 +1,51 @@
package templates
import kotlin.coroutines.experimental.buildSequence
import kotlin.reflect.KTypeProjection
import kotlin.reflect.full.createType
import kotlin.reflect.full.isSubtypeOf
typealias TemplateGroup = () -> Sequence<MemberTemplate>
fun templateGroupOf(vararg templates: MemberTemplate): TemplateGroup = { templates.asSequence() }
abstract class TemplateGroupBase : TemplateGroup {
override fun invoke(): Sequence<MemberTemplate> = buildSequence {
with(this@TemplateGroupBase) {
this::class.members.filter { it.name.startsWith("f_") }.forEach {
require(it.parameters.size == 1) { "Member $it violates naming convention" }
when {
it.returnType.isSubtypeOf(typeMemberTemplate) ->
yield(it.call(this) as MemberTemplate)
it.returnType.isSubtypeOf(typeIterableOfMemberTemplates) ->
@Suppress("UNCHECKED_CAST")
yieldAll(it.call(this) as Iterable<MemberTemplate>)
else ->
error("Member $it violates naming convention")
}
}
}
}.run {
if (defaultActions.isEmpty()) this else onEach { t -> defaultActions.forEach(t::builder) }
}
private val defaultActions = mutableListOf<MemberBuildAction>()
fun defaultBuilder(builderAction: MemberBuildAction) {
defaultActions += builderAction
}
companion object {
private val typeMemberTemplate = MemberTemplate::class.createType()
private val typeIterableOfMemberTemplates = Iterable::class.createType(arguments = listOf(KTypeProjection.invariant(typeMemberTemplate)))
}
}
fun foo() {
cacheFile.objectInputStream().use {
// one indent here
}
}
+9
View File
@@ -0,0 +1,9 @@
private fun String.foo(): List<String> = emptyList()
fun test(s: String) {
s.foo().flatMap { m ->
m.foo().map { e ->
e to m
}
}
}
+9
View File
@@ -0,0 +1,9 @@
private fun String.foo(): List<String> = emptyList()
fun test(s: String) {
s.foo().flatMap { m ->
m.foo().map { e ->
e to m
}
}
}
+14
View File
@@ -0,0 +1,14 @@
fun foo() {
async {
// ...
}.logFailures().invokeOnCompletion {
if (it != null) showErrorAndContinue()
finish()
}
FirebaseAuth.getInstance().addAuthStateListener(object : FirebaseAuth.AuthStateListener {
override fun onAuthStateChanged(auth: FirebaseAuth) {
// ...
}
})
}
+14
View File
@@ -0,0 +1,14 @@
fun foo() {
async {
// ...
}.logFailures().invokeOnCompletion {
if (it != null) showErrorAndContinue()
finish()
}
FirebaseAuth.getInstance().addAuthStateListener(object : FirebaseAuth.AuthStateListener {
override fun onAuthStateChanged(auth: FirebaseAuth) {
// ...
}
})
}