New J2K: Move literal conversion internals to expression.kt
This commit is contained in:
committed by
Ilya Kirillov
parent
60d498cedc
commit
84ad58b50b
@@ -5,108 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.conversions
|
||||
|
||||
import org.jetbrains.kotlin.j2k.fixLiteral
|
||||
import org.jetbrains.kotlin.j2k.tree.JKJavaLiteralExpression
|
||||
import org.jetbrains.kotlin.j2k.tree.JKKtLiteralExpression
|
||||
import org.jetbrains.kotlin.j2k.tree.JKLiteralExpression.LiteralType.*
|
||||
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.JKKtLiteralExpressionImpl
|
||||
import java.math.BigInteger
|
||||
|
||||
class LiteralConversion : RecursiveApplicableConversionBase() {
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
if (element !is JKJavaLiteralExpression) return recurse(element)
|
||||
|
||||
return when {
|
||||
element.type == DOUBLE -> convertDoubleLiteral(element.literal)
|
||||
element.type == FLOAT -> convertFloatLiteral(element.literal)
|
||||
element.type == LONG || element.type == INT -> convertIntegerLiteral(element)
|
||||
element.type == CHAR -> convertCharLiteral(element.literal)
|
||||
element.type == STRING -> convertStringLiteral(element.literal)
|
||||
else -> element
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertDoubleLiteral(text: String): JKKtLiteralExpression {
|
||||
var newText =
|
||||
text
|
||||
.replace("d", "", true)
|
||||
.replace(".e", "e", true)
|
||||
.replace(".f", "", true)
|
||||
.replace("f", "", true)
|
||||
|
||||
if (!newText.contains(".") && !newText.contains("e", true))
|
||||
newText += "."
|
||||
if (newText.endsWith("."))
|
||||
newText += "0"
|
||||
|
||||
return JKKtLiteralExpressionImpl(
|
||||
newText,
|
||||
DOUBLE
|
||||
)
|
||||
}
|
||||
|
||||
private fun convertFloatLiteral(text: String): JKKtLiteralExpressionImpl {
|
||||
return JKKtLiteralExpressionImpl(
|
||||
text.replace(".f", "f", true)
|
||||
.replace("F", "f")
|
||||
.replace(".e", "e", true)
|
||||
.let {
|
||||
if (!it.endsWith("f")) "${it}f"
|
||||
else it
|
||||
},
|
||||
FLOAT
|
||||
)
|
||||
}
|
||||
|
||||
private fun convertStringLiteral(text: String): JKKtLiteralExpressionImpl {
|
||||
var newText = text.replace("((?:\\\\)*)\\\\([0-3]?[0-7]{1,2})".toRegex()) {
|
||||
val leadingBackslashes = it.groupValues[1]
|
||||
if (leadingBackslashes.length % 2 == 0) {
|
||||
String.format("%s\\u%04x", leadingBackslashes, Integer.parseInt(it.groupValues[2], 8))
|
||||
} else {
|
||||
it.value
|
||||
}
|
||||
}
|
||||
newText = newText.replace("\\$([A-Za-z]+|\\{)".toRegex(), "\\\\$0")
|
||||
|
||||
return JKKtLiteralExpressionImpl(newText, STRING)
|
||||
}
|
||||
|
||||
private fun convertCharLiteral(text: String): JKKtLiteralExpression {
|
||||
return JKKtLiteralExpressionImpl(
|
||||
text.replace("\\\\([0-3]?[0-7]{1,2})".toRegex()) {
|
||||
String.format("\\u%04x", Integer.parseInt(it.groupValues[1], 8))
|
||||
},
|
||||
CHAR
|
||||
)
|
||||
}
|
||||
|
||||
private fun convertIntegerLiteral(element: JKJavaLiteralExpression): JKKtLiteralExpression {
|
||||
var text = element.literal
|
||||
if (element.type == LONG) {
|
||||
text = text.replace("l", "L")
|
||||
}
|
||||
|
||||
fun isHexLiteral(text: String) = text.startsWith("0x") || text.startsWith("0X")
|
||||
|
||||
if ((element.type == LONG || element.type == INT) && isHexLiteral(text)) {
|
||||
val v = BigInteger(text.substring(2).replace("L", ""), 16)
|
||||
if (text.contains("L")) {
|
||||
if (v.bitLength() > 63) {
|
||||
text = "-0x${v.toLong().toString(16).substring(1)}L"
|
||||
}
|
||||
} else {
|
||||
if (v.bitLength() > 31) {
|
||||
text = "-0x${v.toInt().toString(16).substring(1)}"
|
||||
}
|
||||
}
|
||||
} else if (element.type == INT) {
|
||||
text = element.literal
|
||||
}
|
||||
|
||||
return JKKtLiteralExpressionImpl(
|
||||
text,
|
||||
element.type
|
||||
)
|
||||
return element.fixLiteral(element.type)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.j2k.tree.*
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import java.math.BigInteger
|
||||
|
||||
fun kotlinTypeByName(name: String, symbolProvider: JKSymbolProvider, nullability: Nullability = Nullability.Nullable): JKClassType {
|
||||
val symbol =
|
||||
@@ -283,4 +284,100 @@ fun JKVariable.hasWritableUsages(scope: JKTreeElement, context: ConversionContex
|
||||
findUsages(scope, context).any {
|
||||
it.asAssignmentFromTarget() != null
|
||||
|| it.isInDecrementOrIncrement()
|
||||
}
|
||||
}
|
||||
|
||||
fun JKLiteralExpression.fixLiteral(expectedType: JKLiteralExpression.LiteralType): JKLiteralExpression =
|
||||
when (expectedType) {
|
||||
JKLiteralExpression.LiteralType.DOUBLE -> convertDoubleLiteral(literal)
|
||||
JKLiteralExpression.LiteralType.FLOAT -> convertFloatLiteral(literal)
|
||||
JKLiteralExpression.LiteralType.LONG, JKLiteralExpression.LiteralType.INT -> convertIntegerLiteral(this)
|
||||
JKLiteralExpression.LiteralType.CHAR -> convertCharLiteral(literal)
|
||||
JKLiteralExpression.LiteralType.STRING -> convertStringLiteral(literal)
|
||||
else -> this
|
||||
}
|
||||
|
||||
|
||||
private fun convertDoubleLiteral(text: String): JKKtLiteralExpression {
|
||||
var newText =
|
||||
text.replace("L", "", true)
|
||||
.replace("d", "", true)
|
||||
.replace(".e", "e", true)
|
||||
.replace(".f", "", true)
|
||||
.replace("f", "", true)
|
||||
|
||||
if (!newText.contains(".") && !newText.contains("e", true))
|
||||
newText += "."
|
||||
if (newText.endsWith("."))
|
||||
newText += "0"
|
||||
|
||||
return JKKtLiteralExpressionImpl(
|
||||
newText,
|
||||
JKLiteralExpression.LiteralType.DOUBLE
|
||||
)
|
||||
}
|
||||
|
||||
private fun convertFloatLiteral(text: String): JKKtLiteralExpressionImpl {
|
||||
return JKKtLiteralExpressionImpl(
|
||||
text.replace("L", "", true)
|
||||
.replace(".f", "f", true)
|
||||
.replace("F", "f")
|
||||
.replace(".e", "e", true)
|
||||
.let {
|
||||
if (!it.endsWith("f")) "${it}f"
|
||||
else it
|
||||
},
|
||||
JKLiteralExpression.LiteralType.FLOAT
|
||||
)
|
||||
}
|
||||
|
||||
private fun convertStringLiteral(text: String): JKKtLiteralExpressionImpl {
|
||||
var newText = text.replace("((?:\\\\)*)\\\\([0-3]?[0-7]{1,2})".toRegex()) {
|
||||
val leadingBackslashes = it.groupValues[1]
|
||||
if (leadingBackslashes.length % 2 == 0) {
|
||||
String.format("%s\\u%04x", leadingBackslashes, Integer.parseInt(it.groupValues[2], 8))
|
||||
} else {
|
||||
it.value
|
||||
}
|
||||
}
|
||||
newText = newText.replace("\\$([A-Za-z]+|\\{)".toRegex(), "\\\\$0")
|
||||
|
||||
return JKKtLiteralExpressionImpl(newText, JKLiteralExpression.LiteralType.STRING)
|
||||
}
|
||||
|
||||
private fun convertCharLiteral(text: String): JKKtLiteralExpression {
|
||||
return JKKtLiteralExpressionImpl(
|
||||
text.replace("\\\\([0-3]?[0-7]{1,2})".toRegex()) {
|
||||
String.format("\\u%04x", Integer.parseInt(it.groupValues[1], 8))
|
||||
},
|
||||
JKLiteralExpression.LiteralType.CHAR
|
||||
)
|
||||
}
|
||||
|
||||
private fun convertIntegerLiteral(element: JKLiteralExpression): JKKtLiteralExpression {
|
||||
var text = element.literal
|
||||
if (element.type == JKLiteralExpression.LiteralType.LONG) {
|
||||
text = text.replace("l", "L")
|
||||
}
|
||||
|
||||
fun isHexLiteral(text: String) = text.startsWith("0x") || text.startsWith("0X")
|
||||
|
||||
if ((element.type == JKLiteralExpression.LiteralType.LONG || element.type == JKLiteralExpression.LiteralType.INT) && isHexLiteral(text)) {
|
||||
val v = BigInteger(text.substring(2).replace("L", ""), 16)
|
||||
if (text.contains("L")) {
|
||||
if (v.bitLength() > 63) {
|
||||
text = "-0x${v.toLong().toString(16).substring(1)}L"
|
||||
}
|
||||
} else {
|
||||
if (v.bitLength() > 31) {
|
||||
text = "-0x${v.toInt().toString(16).substring(1)}"
|
||||
}
|
||||
}
|
||||
} else if (element.type == JKLiteralExpression.LiteralType.INT) {
|
||||
text = element.literal
|
||||
}
|
||||
|
||||
return JKKtLiteralExpressionImpl(
|
||||
text,
|
||||
element.type
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user