Explorar o código

Improve System.Text.Json numeric type conversion under interop (#1843)

Marko Lahma hai 1 ano
pai
achega
51d5e52e90

+ 22 - 27
Jint.Tests.PublicInterface/InteropTests.SystemTextJson.cs

@@ -154,6 +154,16 @@ public partial class InteropTests
         Assert.True(engine.Evaluate("variables.employees.other == 'def'").AsBoolean());
     }
 
+    [Fact]
+    public void AccessingSystemTextJsonNumericTypes()
+    {
+        var engine = GetEngine();
+
+        Assert.Equal(15, engine.SetValue("int", JsonValue.Create(15)).Evaluate("int"));
+        Assert.Equal(15.0, engine.SetValue("double", JsonValue.Create(15.0)).Evaluate("double"));
+        Assert.Equal(15f, engine.SetValue("float", JsonValue.Create(15.0f)).Evaluate("float"));
+    }
+
     private static Engine GetEngine()
     {
         var engine = new Engine(options =>
@@ -181,34 +191,19 @@ file sealed class SystemTextJsonValueConverter : IObjectConverter
         if (value is JsonValue jsonValue)
         {
             var valueKind = jsonValue.GetValueKind();
-            switch (valueKind)
+            result = valueKind switch
             {
-                case JsonValueKind.Object:
-                case JsonValueKind.Array:
-                    result = JsValue.FromObject(engine, jsonValue);
-                    break;
-                case JsonValueKind.String:
-                    result = jsonValue.ToString();
-                    break;
-                case JsonValueKind.Number:
-                    result = jsonValue.TryGetValue<double>(out var doubleValue) ? JsNumber.Create(doubleValue) : JsValue.Undefined;
-                    break;
-                case JsonValueKind.True:
-                    result = JsBoolean.True;
-                    break;
-                case JsonValueKind.False:
-                    result = JsBoolean.False;
-                    break;
-                case JsonValueKind.Undefined:
-                    result = JsValue.Undefined;
-                    break;
-                case JsonValueKind.Null:
-                    result = JsValue.Null;
-                    break;
-                default:
-                    result = JsValue.Undefined;
-                    break;
-            }
+                JsonValueKind.Object or JsonValueKind.Array => JsValue.FromObject(engine, jsonValue),
+                JsonValueKind.String => jsonValue.ToString(),
+#pragma warning disable IL2026, IL3050
+                JsonValueKind.Number => jsonValue.TryGetValue<int>(out var intValue) ? JsNumber.Create(intValue) : JsonSerializer.Deserialize<double>(jsonValue),
+#pragma warning restore IL2026, IL3050
+                JsonValueKind.True => JsBoolean.True,
+                JsonValueKind.False => JsBoolean.False,
+                JsonValueKind.Undefined => JsValue.Undefined,
+                JsonValueKind.Null => JsValue.Null,
+                _ => JsValue.Undefined
+            };
 
             return true;
         }

+ 3 - 1
Jint/Runtime/Interop/DefaultObjectConverter.cs

@@ -167,7 +167,9 @@ namespace Jint
                 System.Text.Json.JsonValueKind.Object => JsValue.FromObject(engine, value),
                 System.Text.Json.JsonValueKind.Array => JsValue.FromObject(engine, value),
                 System.Text.Json.JsonValueKind.String => JsString.Create(value.ToString()),
-                System.Text.Json.JsonValueKind.Number => value.TryGetValue<double>(out var doubleValue) ? JsNumber.Create(doubleValue) : JsValue.Undefined,
+#pragma warning disable IL2026, IL3050
+                System.Text.Json.JsonValueKind.Number => value.TryGetValue<int>(out var intValue) ? JsNumber.Create(intValue) : System.Text.Json.JsonSerializer.Deserialize<double>(value),
+#pragma warning restore IL2026, IL3050
                 System.Text.Json.JsonValueKind.True => JsBoolean.True,
                 System.Text.Json.JsonValueKind.False => JsBoolean.False,
                 System.Text.Json.JsonValueKind.Undefined => JsValue.Undefined,