Add Kotlin hack to avoid using regexp in
String.toFloatOrNull and String.toDoubleOrNull
@@ -22,17 +22,30 @@ import org.teavm.model.BasicBlock;
import org.teavm.model.ClassHolder;
import org.teavm.model.ClassHolderTransformer;
import org.teavm.model.ClassHolderTransformerContext;
+import org.teavm.model.ClassReader;
+import org.teavm.model.ClassReaderSource;
import org.teavm.model.ElementModifier;
import org.teavm.model.MethodHolder;
+import org.teavm.model.MethodReader;
import org.teavm.model.Program;
import org.teavm.model.instructions.ExitInstruction;
import org.teavm.model.instructions.StringConstantInstruction;
+import org.teavm.model.util.ProgramUtils;
public class KotlinHacks implements ClassHolderTransformer {
@Override
public void transformClass(ClassHolder cls, ClassHolderTransformerContext context) {
if (cls.getName().equals("kotlin.jvm.internal.Lambda")
|| cls.getName().equals("kotlin.coroutines.jvm.internal.BaseContinuationImpl")) {
+ patchContinuation(cls);
+ } else if (cls.getName().equals("kotlin.jvm.internal.Reflection")) {
+ patchReflection(cls);
+ } else if (cls.getName().equals("kotlin.text.StringsKt__StringNumberConversionsJVMKt")) {
+ patchStrings(cls, context.getHierarchy().getClassSource());
+ }
+ }
+
+ private void patchContinuation(ClassHolder cls) {
List<MethodHolder> methodsToRemove = new ArrayList<>();
for (MethodHolder method : cls.getMethods()) {
if (method.getName().equals("toString")) {
@@ -42,7 +55,9 @@ public class KotlinHacks implements ClassHolderTransformer {
for (MethodHolder method : methodsToRemove) {
cls.removeMethod(method);
}
- } else if (cls.getName().equals("kotlin.jvm.internal.Reflection")) {
+ }
+
+ private void patchReflection(ClassHolder cls) {
for (MethodHolder method : cls.getMethods()) {
if (method.getLevel() == AccessLevel.PUBLIC && method.hasModifier(ElementModifier.STATIC)
&& method.getName().equals("renderLambdaToString")
@@ -67,5 +82,34 @@ public class KotlinHacks implements ClassHolderTransformer {
}
}
}
+
+ private void patchStrings(ClassHolder cls, ClassReaderSource source) {
+ ClassReader templateClass = source.get(KotlinStrings.class.getName());
+ for (MethodHolder method : cls.getMethods()) {
+ if (method.getName().equals("toDoubleOrNull") || method.getName().equals("toFloatOrNull")) {
+ MethodReader templateMethod = templateClass.getMethod(method.getDescriptor());
+ if (templateMethod != null) {
+ method.setProgram(ProgramUtils.copy(templateMethod.getProgram()));
+ }
+ }
+ }
+ }
+
+ static class KotlinStrings {
+ static Float toFloatOrNull(String value) {
+ try {
+ return Float.parseFloat(value);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
+ static Double toDoubleOrNull(String value) {
+ try {
+ return Double.parseDouble(value);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
}
}
