Refactoring: rewrite without local any values
This commit is contained in:
+54
-36
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.injection
|
|||||||
|
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.openapi.util.Trinity
|
import com.intellij.openapi.util.Trinity
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import com.intellij.psi.PsiLanguageInjectionHost
|
import com.intellij.psi.PsiLanguageInjectionHost
|
||||||
import org.intellij.plugins.intelliLang.inject.InjectedLanguage
|
import org.intellij.plugins.intelliLang.inject.InjectedLanguage
|
||||||
import org.intellij.plugins.intelliLang.inject.InjectorUtils
|
import org.intellij.plugins.intelliLang.inject.InjectorUtils
|
||||||
@@ -48,59 +47,66 @@ fun splitLiteralToInjectionParts(injection: BaseInjection, literal: KtStringTemp
|
|||||||
result.add(Trinity.create(literal, injectedLanguage, range))
|
result.add(Trinity.create(literal, injectedLanguage, range))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun suffix(i: Int) = if (i == len - 1) injection.suffix else ""
|
||||||
|
|
||||||
var unparsable = false
|
var unparsable = false
|
||||||
|
|
||||||
var prefix = injection.prefix
|
var prefix = injection.prefix
|
||||||
val lastChild = children.lastOrNull()
|
|
||||||
|
|
||||||
var i = 0
|
var i = 0
|
||||||
while (i < len) {
|
while (i < len) {
|
||||||
val child = children[i]
|
val child = children[i]
|
||||||
val partOffsetInParent = child.startOffsetInParent
|
val partOffsetInParent = child.startOffsetInParent
|
||||||
|
|
||||||
@Suppress("IMPLICIT_CAST_TO_ANY")
|
if (child is KtSimpleNameStringTemplateEntry || child is KtBlockStringTemplateEntry) {
|
||||||
val part = when (child) {
|
if (!prefix.isEmpty() || i == 0) {
|
||||||
is KtLiteralStringTemplateEntry, is KtEscapeStringTemplateEntry -> {
|
// Store part with prefix before replacing it
|
||||||
val partSize = children.subList(i, len).asSequence()
|
addInjectionRange(TextRange.from(partOffsetInParent, 0), prefix, suffix(i))
|
||||||
.takeWhile { it is KtLiteralStringTemplateEntry || it is KtEscapeStringTemplateEntry }
|
|
||||||
.count()
|
|
||||||
i += partSize - 1
|
|
||||||
children[i]
|
|
||||||
}
|
}
|
||||||
is KtSimpleNameStringTemplateEntry ->
|
|
||||||
tryEvaluateConstant(child.expression) ?: run {
|
prefix = when (child) {
|
||||||
unparsable = true
|
is KtSimpleNameStringTemplateEntry -> {
|
||||||
child.expression?.text ?: NO_VALUE_NAME
|
tryEvaluateConstant(child.expression) ?: run {
|
||||||
|
unparsable = true
|
||||||
|
child.expression?.text ?: NO_VALUE_NAME
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is KtBlockStringTemplateEntry ->
|
is KtBlockStringTemplateEntry -> {
|
||||||
tryEvaluateConstant(child.expression) ?: run {
|
tryEvaluateConstant(child.expression) ?: run {
|
||||||
unparsable = true
|
unparsable = true
|
||||||
NO_VALUE_NAME
|
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
|
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++
|
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)
|
return InjectionSplitResult(unparsable, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,4 +118,16 @@ private fun tryEvaluateConstant(ktExpression: KtExpression?) =
|
|||||||
?.safeAs<String>()
|
?.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
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user