Migrate AndroidUnicodeUtils to Kotlin (#43929)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43929

Migrate AndroidUnicodeUtils to Kotlin

Changelog:
[Internal] [Changed] - Migrate AndroidUnicodeUtils to Kotlin

Reviewed By: tdn120

Differential Revision: D55804037

fbshipit-source-id: 932fd08e3d826ddf131c74f8b4722732cd9ac46a
This commit is contained in:
Nicola Corti
2024-04-05 13:55:48 -07:00
committed by Facebook GitHub Bot
parent 2aef4418ea
commit 47a00f97d8
2 changed files with 73 additions and 84 deletions
@@ -1,84 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.hermes.unicode;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.proguard.annotations.DoNotStrip;
import java.text.Collator;
import java.text.DateFormat;
import java.text.Normalizer;
import java.util.Locale;
// TODO: use com.facebook.common.locale.Locales.getApplicationLocale() as the current locale,
// rather than the device locale. This is challenging because getApplicationLocale() is only
// available via DI.
@Nullsafe(Nullsafe.Mode.LOCAL)
@DoNotStrip
public class AndroidUnicodeUtils {
@DoNotStrip
public static int localeCompare(String left, String right) {
Collator collator = Collator.getInstance();
return collator.compare(left, right);
}
@DoNotStrip
public static String dateFormat(double unixtimeMs, boolean formatDate, boolean formatTime) {
DateFormat format;
if (formatDate && formatTime) {
format = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
} else if (formatDate) {
format = DateFormat.getDateInstance(DateFormat.MEDIUM);
} else if (formatTime) {
format = DateFormat.getTimeInstance(DateFormat.MEDIUM);
} else {
throw new RuntimeException("Bad dateFormat configuration");
}
return format.format((long) unixtimeMs).toString();
}
@DoNotStrip
public static String convertToCase(String input, int targetCase, boolean useCurrentLocale) {
// These values must match CaseConversion in PlatformUnicode.h
final int targetUppercase = 0;
final int targetLowercase = 1;
// Note Java's case conversions use the user's locale. For example "I".toLowerCase()
// will produce a dotless i. From Java's docs: "To obtain correct results for locale
// insensitive strings, use toLowerCase(Locale.ENGLISH)."
Locale locale = useCurrentLocale ? Locale.getDefault() : Locale.ENGLISH;
switch (targetCase) {
case targetLowercase:
return input.toLowerCase(locale);
case targetUppercase:
return input.toUpperCase(locale);
default:
throw new RuntimeException("Invalid target case");
}
}
@DoNotStrip
public static String normalize(String input, int form) {
// Values must match NormalizationForm in PlatformUnicode.h.
final int formC = 0;
final int formD = 1;
final int formKC = 2;
final int formKD = 3;
switch (form) {
case formC:
return Normalizer.normalize(input, Normalizer.Form.NFC);
case formD:
return Normalizer.normalize(input, Normalizer.Form.NFD);
case formKC:
return Normalizer.normalize(input, Normalizer.Form.NFKC);
case formKD:
return Normalizer.normalize(input, Normalizer.Form.NFKD);
default:
throw new RuntimeException("Invalid form");
}
}
}
@@ -0,0 +1,73 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.hermes.unicode
import com.facebook.proguard.annotations.DoNotStrip
import java.text.Collator
import java.text.DateFormat
import java.text.Normalizer
import java.util.Locale
// TODO: use com.facebook.common.locale.Locales.getApplicationLocale() as the current locale,
// rather than the device locale. This is challenging because getApplicationLocale() is only
// available via DI.
@DoNotStrip
public object AndroidUnicodeUtils {
@DoNotStrip
public fun localeCompare(left: String?, right: String?): Int {
val collator = Collator.getInstance()
return collator.compare(left, right)
}
@DoNotStrip
public fun dateFormat(unixtimeMs: Double, formatDate: Boolean, formatTime: Boolean): String {
val format =
when {
formatDate && formatTime ->
DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM)
formatDate -> DateFormat.getDateInstance(DateFormat.MEDIUM)
formatTime -> DateFormat.getTimeInstance(DateFormat.MEDIUM)
else -> error("Bad dateFormat configuration")
}
return format.format(unixtimeMs.toLong()).toString()
}
@DoNotStrip
public fun convertToCase(input: String, targetCase: Int, useCurrentLocale: Boolean): String {
// Note Java's case conversions use the user's locale. For example "I".toLowerCase()
// will produce a dotless i. From Java's docs: "To obtain correct results for locale
// insensitive strings, use toLowerCase(Locale.ENGLISH)."
val locale = if (useCurrentLocale) Locale.getDefault() else Locale.ENGLISH
return when (targetCase) {
TARGET_LOWERCASE -> input.lowercase(locale)
TARGET_UPPERCASE -> input.uppercase(locale)
else -> error("Invalid target case")
}
}
@DoNotStrip
public fun normalize(input: String?, form: Int): String =
when (form) {
FORM_C -> Normalizer.normalize(input, Normalizer.Form.NFC)
FORM_D -> Normalizer.normalize(input, Normalizer.Form.NFD)
FORM_KC -> Normalizer.normalize(input, Normalizer.Form.NFKC)
FORM_KD -> Normalizer.normalize(input, Normalizer.Form.NFKD)
else -> error("Invalid form")
}
// These values must match CaseConversion in PlatformUnicode.h
private const val TARGET_UPPERCASE = 0
private const val TARGET_LOWERCASE = 1
// Values must match NormalizationForm in PlatformUnicode.h.
private const val FORM_C = 0
private const val FORM_D = 1
private const val FORM_KC = 2
private const val FORM_KD = 3
}