Parcourir la source

AK+GMLCompiler: Remove JsonValue::as_double()

Replace its single (non-test) usage with newly created as_number(),
which does not leak information about internal integer storage type.
Dan Klishch il y a 1 an
Parent
commit
faef802229
3 fichiers modifiés avec 27 ajouts et 13 suppressions
  1. 17 3
      AK/JsonValue.h
  2. 7 7
      Meta/Lagom/Tools/CodeGenerators/GMLCompiler/main.cpp
  3. 3 3
      Tests/AK/TestJSON.cpp

+ 17 - 3
AK/JsonValue.h

@@ -154,10 +154,24 @@ public:
         return *m_value.as_array;
         return *m_value.as_array;
     }
     }
 
 
-    double as_double() const
+    Variant<u64, i64, double> as_number() const
     {
     {
-        VERIFY(is_double());
-        return m_value.as_double;
+        VERIFY(is_number());
+
+        switch (m_type) {
+        case Type::Int32:
+            return static_cast<i64>(m_value.as_i32);
+        case Type::UnsignedInt32:
+            return static_cast<i64>(m_value.as_u32);
+        case Type::Int64:
+            return m_value.as_i64;
+        case Type::UnsignedInt64:
+            return m_value.as_u64;
+        case Type::Double:
+            return m_value.as_double;
+        default:
+            VERIFY_NOT_REACHED();
+        }
     }
     }
 
 
     Type type() const
     Type type() const

+ 7 - 7
Meta/Lagom/Tools/CodeGenerators/GMLCompiler/main.cpp

@@ -210,15 +210,15 @@ static ErrorOr<String> generate_initializer_for(Optional<StringView> property_na
 
 
         return String::formatted(R"~~~("{}"_string)~~~", TRY(escape_string(value)));
         return String::formatted(R"~~~("{}"_string)~~~", TRY(escape_string(value)));
     }
     }
-    // No need to handle the smaller integer types separately.
-    if (value.is_integer<i64>())
-        return String::formatted("static_cast<i64>({})", value.as_integer<i64>());
-    if (value.is_integer<u64>())
-        return String::formatted("static_cast<u64>({})", value.as_integer<u64>());
     if (value.is_bool())
     if (value.is_bool())
         return String::formatted("{}", value.as_bool());
         return String::formatted("{}", value.as_bool());
-    if (value.is_double())
-        return String::formatted("static_cast<double>({})", value.as_double());
+    if (value.is_number()) {
+        return value.as_number().visit(
+            // NOTE: Passing by mutable reference here in order to disallow implicit casts.
+            [](u64& value) { return String::formatted("static_cast<u64>({})", value); },
+            [](i64& value) { return String::formatted("static_cast<i64>({})", value); },
+            [](double& value) { return String::formatted("static_cast<double>({})", value); });
+    }
     if (value.is_array()) {
     if (value.is_array()) {
         auto const& array = value.as_array();
         auto const& array = value.as_array();
         auto child_type = Optional<StringView> {};
         auto child_type = Optional<StringView> {};

+ 3 - 3
Tests/AK/TestJSON.cpp

@@ -133,16 +133,16 @@ TEST_CASE(json_parse_empty_string)
 TEST_CASE(json_parse_long_decimals)
 TEST_CASE(json_parse_long_decimals)
 {
 {
     auto value = JsonValue::from_string("1644452550.6489999294281"sv);
     auto value = JsonValue::from_string("1644452550.6489999294281"sv);
-    EXPECT_EQ(value.value().as_double(), 1644452550.6489999294281);
+    EXPECT_EQ(value.value().to_number<double>(), 1644452550.6489999294281);
 }
 }
 
 
 TEST_CASE(json_parse_number_with_exponent)
 TEST_CASE(json_parse_number_with_exponent)
 {
 {
     auto value_without_fraction = JsonValue::from_string("10e5"sv);
     auto value_without_fraction = JsonValue::from_string("10e5"sv);
-    EXPECT_EQ(value_without_fraction.value().as_double(), 1000000.0);
+    EXPECT_EQ(value_without_fraction.value().to_number<double>(), 1000000.0);
 
 
     auto value_with_fraction = JsonValue::from_string("10.5e5"sv);
     auto value_with_fraction = JsonValue::from_string("10.5e5"sv);
-    EXPECT_EQ(value_with_fraction.value().as_double(), 1050000.0);
+    EXPECT_EQ(value_with_fraction.value().to_number<double>(), 1050000.0);
 }
 }
 
 
 TEST_CASE(json_parse_special_numbers)
 TEST_CASE(json_parse_special_numbers)