Refactoring: rewrite without local any values

This commit is contained in:
Nikolay Krasko
2018-12-26 13:03:26 +03:00
parent b232386d9d
commit 3eb4895acf
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.injection
import com.intellij.openapi.util.TextRange
import com.intellij.openapi.util.Trinity
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiLanguageInjectionHost
import org.intellij.plugins.intelliLang.inject.InjectedLanguage
import org.intellij.plugins.intelliLang.inject.InjectorUtils
@@ -48,59 +47,66 @@ fun splitLiteralToInjectionParts(injection: BaseInjection, literal: KtStringTemp
result.add(Trinity.create(literal, injectedLanguage, range))
}
fun suffix(i: Int) = if (i == len - 1) injection.suffix else ""
var unparsable = false
var prefix = injection.prefix
val lastChild = children.lastOrNull()
var i = 0
while (i < len) {
val child = children[i]
val partOffsetInParent = child.startOffsetInParent
@Suppress("IMPLICIT_CAST_TO_ANY")
val part = when (child) {
is KtLiteralStringTemplateEntry, is KtEscapeStringTemplateEntry -> {
val partSize = children.subList(i, len).asSequence()
.takeWhile { it is KtLiteralStringTemplateEntry || it is KtEscapeStringTemplateEntry }
.count()
i += partSize - 1
children[i]
if (child is KtSimpleNameStringTemplateEntry || child is KtBlockStringTemplateEntry) {
if (!prefix.isEmpty() || i == 0) {
// Store part with prefix before replacing it
addInjectionRange(TextRange.from(partOffsetInParent, 0), prefix, suffix(i))
}
is KtSimpleNameStringTemplateEntry ->
tryEvaluateConstant(child.expression) ?: run {
unparsable = true
child.expression?.text ?: NO_VALUE_NAME
prefix = when (child) {
is KtSimpleNameStringTemplateEntry -> {
tryEvaluateConstant(child.expression) ?: run {
unparsable = true
child.expression?.text ?: NO_VALUE_NAME
}
}
is KtBlockStringTemplateEntry ->
tryEvaluateConstant(child.expression) ?: run {
unparsable = true
NO_VALUE_NAME
is KtBlockStringTemplateEntry -> {
tryEvaluateConstant(child.expression) ?: run {
unparsable = true
NO_VALUE_NAME
}
}
else -> {
else -> {
error("Child type should be KtSimpleNameStringTemplateEntry or KtBlockStringTemplateEntry")
}
}
if (i == len - 1 && !prefix.isEmpty()) {
// There won't be more elements, so create part with prefix right away
addInjectionRange(TextRange.from(partOffsetInParent + child.textLength, 0), prefix, suffix(i))
}
} else {
if (child is KtLiteralStringTemplateEntry || child is KtEscapeStringTemplateEntry) {
// Merge all consecutive string literals into one part
i += children.countFromWhile(i + 1) { it is KtLiteralStringTemplateEntry || it is KtEscapeStringTemplateEntry }
} else {
unparsable = true
child
}
val lastInPart = children[i]
addInjectionRange(
TextRange.create(partOffsetInParent, lastInPart.startOffsetInParent + lastInPart.textLength),
prefix,
suffix(i)
)
prefix = ""
}
val suffix = if (i == len - 1) injection.suffix else ""
if (part is PsiElement) {
addInjectionRange(TextRange.create(partOffsetInParent, part.startOffsetInParent + part.textLength), prefix, suffix)
}
else if (!prefix.isEmpty() || i == 0) {
addInjectionRange(TextRange.from(partOffsetInParent, 0), prefix, suffix)
}
prefix = part as? String ?: ""
i++
}
if (lastChild != null && !prefix.isEmpty()) {
// Last element was interpolated part, need to add a range after it
addInjectionRange(TextRange.from(lastChild.startOffsetInParent + lastChild.textLength, 0), prefix, injection.suffix)
}
return InjectionSplitResult(unparsable, result)
}
@@ -112,4 +118,16 @@ private fun tryEvaluateConstant(ktExpression: KtExpression?) =
?.safeAs<String>()
}
private val NO_VALUE_NAME = "missingValue"
private const val NO_VALUE_NAME = "missingValue"
private inline fun <T : Any> List<T>.countFromWhile(from: Int, predicate: (T) -> Boolean): Int {
var i = from
while (i < size) {
if (!predicate(get(i))) {
break
}
i++
}
return i - from
}