Capitalize/decapitalize only ASCII characters across project

Use {de,}capitalizeAsciiOnly and to{Lower,Upper}CaseAsciiOnly where
possible, and stdlib's functions with Locale.US everywhere else.

Otherwise, if the default system locale is Turkish, the capital latin
letter "I" is transformed in toLowerCase to "ı" (see
https://github.com/JetBrains/kotlin/blob/66bc142f92085047a1ca64f9a291f0496e33dd98/libraries/stdlib/jvm/test/text/StringJVMTest.kt#L119),
which for example breaks the codegen for `intArrayOf` in
KT-25400/KT-43405.

Similarly, lower case latin letter "i" is transformed to "İ".

 #KT-13631 Fixed
 #KT-25400 Fixed
 #KT-43405 Fixed
This commit is contained in:
Alexander Udalov
2020-11-17 20:26:19 +01:00
parent 5d4b0b19d4
commit 77a9d14f93
53 changed files with 173 additions and 121 deletions
@@ -7,18 +7,22 @@ package org.jetbrains.kotlin.ir.interpreter
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.ir.interpreter.builtins.evaluateIntrinsicAnnotation
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
import org.jetbrains.kotlin.ir.interpreter.state.*
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.interpreter.builtins.evaluateIntrinsicAnnotation
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
import org.jetbrains.kotlin.ir.interpreter.state.*
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
internal fun IrFunction.getDispatchReceiver(): IrValueParameterSymbol? = this.dispatchReceiverParameter?.symbol
@@ -202,7 +206,7 @@ internal fun State?.getCorrectReceiverByFunction(irFunction: IrFunction): State?
return generateSequence(original) { it.superClass }.firstOrNull { it.irClass.thisReceiver == other } ?: this
}
internal fun IrFunction.getCapitalizedFileName() = this.file.name.replace(".kt", "Kt").capitalize()
internal fun IrFunction.getCapitalizedFileName() = this.file.name.replace(".kt", "Kt").capitalizeAsciiOnly()
internal fun IrType.isUnsigned() = this.isUByte() || this.isUShort() || this.isUInt() || this.isULong()
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import java.lang.invoke.MethodHandle
import java.lang.invoke.MethodHandles
import java.lang.invoke.MethodType
@@ -30,7 +31,7 @@ internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex(
if (irFunction.getEvaluateIntrinsicValue()?.isEmpty() == true) return null // this method will handle IntrinsicEvaluator
// if function is actually a getter, then use "get${property.name.capitalize()}" as method name
val propertyName = (irFunction as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.name?.asString()
val propertyCall = listOfNotNull(propertyName, "get${propertyName?.capitalize()}")
val propertyCall = listOfNotNull(propertyName, "get${propertyName?.capitalizeAsciiOnly()}")
.firstOrNull { receiverClass.methods.any { method -> method.name == it } }
val intrinsicName = getJavaOriginalName(irFunction)
@@ -187,4 +188,4 @@ internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex(
override fun toString(): String {
return "Wrapper(obj='$typeFqName', value=$value)"
}
}
}