ConvertToStringTemplateIntention - minor code improvements
This commit is contained in:
@@ -331,8 +331,6 @@ make.type.implicit.in.lambda=Make types implicit in lambda (may break code)
|
|||||||
make.type.implicit.in.lambda.family=Make Types Implicit In Lambda (May Break Code)
|
make.type.implicit.in.lambda.family=Make Types Implicit In Lambda (May Break Code)
|
||||||
invert.if.condition=Invert If Condition
|
invert.if.condition=Invert If Condition
|
||||||
invert.if.condition.family=Invert If Condition
|
invert.if.condition.family=Invert If Condition
|
||||||
convert.to.string.template=Convert concatenation to template
|
|
||||||
convert.to.string.template.family=Convert Concatenation to Template
|
|
||||||
|
|
||||||
property.is.implemented.too.many=Has implementations
|
property.is.implemented.too.many=Has implementations
|
||||||
property.is.overridden.too.many=Is overridden in subclasses
|
property.is.overridden.too.many=Is overridden in subclasses
|
||||||
|
|||||||
@@ -35,18 +35,16 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
|
||||||
|
|
||||||
public class ConvertToStringTemplateIntention : JetSelfTargetingOffsetIndependentIntention<JetBinaryExpression>("convert.to.string.template", javaClass()) {
|
public class ConvertToStringTemplateIntention : JetSelfTargetingOffsetIndependentIntention<JetBinaryExpression>(javaClass(), "Convert concatenation to template") {
|
||||||
override fun isApplicableTo(element: JetBinaryExpression): Boolean {
|
override fun isApplicableTo(element: JetBinaryExpression): Boolean {
|
||||||
if (element.getOperationToken() != JetTokens.PLUS) return false
|
if (element.getOperationToken() != JetTokens.PLUS) return false
|
||||||
|
|
||||||
val context = element.analyze()
|
val elementType = BindingContextUtils.getRecordedTypeInfo(element, element.analyze())?.getType()
|
||||||
val elementType = BindingContextUtils.getRecordedTypeInfo(element, context)?.getType()
|
if (!KotlinBuiltIns.isString(elementType)) return false
|
||||||
if (!(KotlinBuiltIns.isString(elementType))) return false
|
|
||||||
|
|
||||||
val (left, right) = Pair(element.getLeft(), element.getRight())
|
val left = element.getLeft() ?: return false
|
||||||
if (left == null || right == null) return false
|
val right = element.getRight() ?: return false
|
||||||
|
return !PsiUtilCore.hasErrorElementChild(left) && !PsiUtilCore.hasErrorElementChild(right)
|
||||||
return !(PsiUtilCore.hasErrorElementChild(left) || PsiUtilCore.hasErrorElementChild(right))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyTo(element: JetBinaryExpression, editor: Editor) {
|
override fun applyTo(element: JetBinaryExpression, editor: Editor) {
|
||||||
@@ -55,61 +53,63 @@ public class ConvertToStringTemplateIntention : JetSelfTargetingOffsetIndependen
|
|||||||
return applyTo(parent, editor)
|
return applyTo(parent, editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
val rightStr = mkString(element.getRight(), false)
|
val rightText = buildText(element.getRight(), false)
|
||||||
val resultStr = fold(element.getLeft(), rightStr)
|
val text = fold(element.getLeft(), rightText)
|
||||||
val expr = JetPsiFactory(element).createExpression(resultStr)
|
|
||||||
|
|
||||||
element.replace(expr)
|
element.replace(JetPsiFactory(element).createExpression(text))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fold(left: JetExpression?, right: String): String {
|
private fun fold(left: JetExpression?, right: String): String {
|
||||||
val needsBraces = !right.isEmpty() && right.first() != '$' && Character.isJavaIdentifierPart(right.first())
|
val needsBraces = !right.isEmpty() && right.first() != '$' && right.first().isJavaIdentifierPart()
|
||||||
|
|
||||||
if (left is JetBinaryExpression && isApplicableTo(left)) {
|
if (left is JetBinaryExpression && isApplicableTo(left)) {
|
||||||
val l_right = mkString(left.getRight(), needsBraces)
|
val leftRight = buildText(left.getRight(), needsBraces)
|
||||||
val newBase = "%s%s".format(l_right, right)
|
return fold(left.getLeft(), leftRight + right)
|
||||||
return fold(left.getLeft(), newBase)
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val leftStr = mkString(left, needsBraces)
|
val leftText = buildText(left, needsBraces)
|
||||||
return "\"%s%s\"".format(leftStr, right)
|
return "\"" + leftText + right + "\""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mkString(expr: JetExpression?, needsBraces: Boolean): String {
|
private fun buildText(expr: JetExpression?, needsBraces: Boolean): String {
|
||||||
val expression = JetPsiUtil.deparenthesize(expr)
|
val expression = JetPsiUtil.deparenthesize(expr)
|
||||||
val expressionText = expression?.getText() ?: ""
|
val expressionText = expression?.getText() ?: ""
|
||||||
return when (expression) {
|
return when (expression) {
|
||||||
is JetConstantExpression -> {
|
is JetConstantExpression -> {
|
||||||
val context = expression.analyze()
|
val context = expression.analyze()
|
||||||
val trace = DelegatingBindingTrace(context, "Trace for evaluating constant")
|
val constant = ConstantExpressionEvaluator.evaluate(expression, DelegatingBindingTrace(context, "Trace for evaluating constant"), null)
|
||||||
val constant = ConstantExpressionEvaluator.evaluate(expression, trace, null)
|
|
||||||
if (constant is IntegerValueTypeConstant) {
|
if (constant is IntegerValueTypeConstant) {
|
||||||
val elementType = BindingContextUtils.getRecordedTypeInfo(expression, context)?.getType()
|
val elementType = BindingContextUtils.getRecordedTypeInfo(expression, context)?.getType()!!
|
||||||
constant.getValue(elementType!!).toString()
|
constant.getValue(elementType).toString()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
constant?.getValue().toString()
|
constant?.getValue().toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is JetStringTemplateExpression -> {
|
is JetStringTemplateExpression -> {
|
||||||
val base = if (expressionText.startsWith("\"\"\"") && (expressionText.endsWith("\"\"\""))) {
|
val base = if (expressionText.startsWith("\"\"\"") && expressionText.endsWith("\"\"\"")) {
|
||||||
val unquoted = expressionText.substring(3, expressionText.length - 3)
|
val unquoted = expressionText.substring(3, expressionText.length() - 3)
|
||||||
StringUtil.escapeStringCharacters(unquoted)
|
StringUtil.escapeStringCharacters(unquoted)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
StringUtil.unquoteString(expressionText)
|
StringUtil.unquoteString(expressionText)
|
||||||
}
|
}
|
||||||
if (needsBraces && base.endsWith('$')) {
|
if (needsBraces && base.endsWith('$')) {
|
||||||
base.substring(0, base.length - 1) + "\\$"
|
base.substring(0, base.length() - 1) + "\\$"
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
base
|
base
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is JetSimpleNameExpression ->
|
is JetSimpleNameExpression ->
|
||||||
if (needsBraces) "\${${expressionText}}" else "\$${expressionText}"
|
if (needsBraces) "\${" + expressionText + "}" else "\$" + expressionText
|
||||||
|
|
||||||
null -> ""
|
null -> ""
|
||||||
else -> "\${${expressionText.replaceAll("\n+", " ")}}"
|
|
||||||
|
else -> "\${" + expressionText.replaceAll("\n+", " ") + "}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user