Bläddra i källkod

LibWeb: Add dictionary types to idl_type_name_to_cpp_type

This allows dictionaries to appear in sequences, records and unions.
Luke Wilde 3 år sedan
förälder
incheckning
d0ebe80f69

+ 16 - 9
Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLGenerators.cpp

@@ -60,7 +60,7 @@ static StringView sequence_storage_type_to_cpp_storage_type_name(SequenceStorage
     }
 }
 
-CppType idl_type_name_to_cpp_type(Type const& type)
+CppType idl_type_name_to_cpp_type(Type const& type, Interface const& interface)
 {
     if (is_wrappable_type(type)) {
         if (type.nullable)
@@ -93,7 +93,7 @@ CppType idl_type_name_to_cpp_type(Type const& type)
     if (type.name == "sequence") {
         auto& parameterized_type = verify_cast<ParameterizedType>(type);
         auto& sequence_type = parameterized_type.parameters.first();
-        auto sequence_cpp_type = idl_type_name_to_cpp_type(sequence_type);
+        auto sequence_cpp_type = idl_type_name_to_cpp_type(sequence_type, interface);
         auto storage_type_name = sequence_storage_type_to_cpp_storage_type_name(sequence_cpp_type.sequence_storage_type);
 
         if (sequence_cpp_type.sequence_storage_type == SequenceStorageType::MarkedVector)
@@ -106,15 +106,22 @@ CppType idl_type_name_to_cpp_type(Type const& type)
         auto& parameterized_type = verify_cast<ParameterizedType>(type);
         auto& record_key_type = parameterized_type.parameters[0];
         auto& record_value_type = parameterized_type.parameters[1];
-        auto record_key_cpp_type = idl_type_name_to_cpp_type(record_key_type);
-        auto record_value_cpp_type = idl_type_name_to_cpp_type(record_value_type);
+        auto record_key_cpp_type = idl_type_name_to_cpp_type(record_key_type, interface);
+        auto record_value_cpp_type = idl_type_name_to_cpp_type(record_value_type, interface);
 
         return { .name = String::formatted("OrderedHashMap<{}, {}>", record_key_cpp_type.name, record_value_cpp_type.name), .sequence_storage_type = SequenceStorageType::Vector };
     }
 
     if (is<UnionType>(type)) {
         auto& union_type = verify_cast<UnionType>(type);
-        return { .name = union_type.to_variant(), .sequence_storage_type = SequenceStorageType::Vector };
+        return { .name = union_type.to_variant(interface), .sequence_storage_type = SequenceStorageType::Vector };
+    }
+
+    if (!type.nullable) {
+        for (auto& dictionary : interface.dictionaries) {
+            if (type.name == dictionary.key)
+                return { .name = type.name, .sequence_storage_type = SequenceStorageType::Vector };
+        }
     }
 
     dbgln("Unimplemented type for idl_type_name_to_cpp_type: {}{}", type.name, type.nullable ? "?" : "");
@@ -612,7 +619,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
         //       4. Set result[typedKey] to typedValue.
         // 5. Return result.
 
-        auto record_cpp_type = IDL::idl_type_name_to_cpp_type(parameterized_type);
+        auto record_cpp_type = IDL::idl_type_name_to_cpp_type(parameterized_type, interface);
         record_generator.set("record.type", record_cpp_type.name);
 
         // If this is a recursive call to generate_to_cpp, assume that the caller has already handled converting the JS value to an object for us.
@@ -661,7 +668,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
         auto union_generator = scoped_generator.fork();
 
         auto& union_type = verify_cast<IDL::UnionType>(*parameter.type);
-        union_generator.set("union_type", union_type.to_variant());
+        union_generator.set("union_type", union_type.to_variant(interface));
         union_generator.set("recursion_depth", String::number(recursion_depth));
 
         // A lambda is used because Variants without "Empty" can't easily be default initialized.
@@ -940,7 +947,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
             // 4. Return the result of converting x to T.
 
             auto union_numeric_type_generator = union_generator.fork();
-            auto cpp_type = IDL::idl_type_name_to_cpp_type(*numeric_type);
+            auto cpp_type = IDL::idl_type_name_to_cpp_type(*numeric_type, interface);
             union_numeric_type_generator.set("numeric_type", cpp_type.name);
 
             union_numeric_type_generator.append(R"~~~(
@@ -1086,7 +1093,7 @@ void IDL::ParameterizedType::generate_sequence_from_iterable(SourceGenerator& ge
     sequence_generator.set("iterable_cpp_name", iterable_cpp_name);
     sequence_generator.set("iterator_method_cpp_name", iterator_method_cpp_name);
     sequence_generator.set("recursion_depth", String::number(recursion_depth));
-    auto sequence_cpp_type = idl_type_name_to_cpp_type(parameters.first());
+    auto sequence_cpp_type = idl_type_name_to_cpp_type(parameters.first(), interface);
     sequence_generator.set("sequence.type", sequence_cpp_type.name);
     sequence_generator.set("sequence.storage_type", sequence_storage_type_to_cpp_storage_type_name(sequence_cpp_type.sequence_storage_type));
 

+ 123 - 123
Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator/IDLTypes.h

@@ -64,129 +64,6 @@ struct Type : public RefCounted<Type> {
     bool is_numeric() const { return is_integer() || name.is_one_of("float", "unrestricted float", "double", "unrestricted double"); }
 };
 
-CppType idl_type_name_to_cpp_type(Type const& type);
-
-struct UnionType : public Type {
-    UnionType() = default;
-
-    UnionType(String name, bool nullable, NonnullRefPtrVector<Type> member_types)
-        : Type(move(name), nullable)
-        , member_types(move(member_types))
-    {
-    }
-
-    virtual ~UnionType() override = default;
-
-    NonnullRefPtrVector<Type> member_types;
-
-    // https://webidl.spec.whatwg.org/#dfn-flattened-union-member-types
-    NonnullRefPtrVector<Type> flattened_member_types() const
-    {
-        // 1. Let T be the union type.
-
-        // 2. Initialize S to ∅.
-        NonnullRefPtrVector<Type> types;
-
-        // 3. For each member type U of T:
-        for (auto& type : member_types) {
-            // FIXME: 1. If U is an annotated type, then set U to be the inner type of U.
-
-            // 2. If U is a nullable type, then set U to be the inner type of U. (NOTE: Not necessary as nullable is stored with Type and not as a separate struct)
-
-            // 3. If U is a union type, then add to S the flattened member types of U.
-            if (is<UnionType>(type)) {
-                auto& union_member_type = verify_cast<UnionType>(type);
-                types.extend(union_member_type.flattened_member_types());
-            } else {
-                // 4. Otherwise, U is not a union type. Add U to S.
-                types.append(type);
-            }
-        }
-
-        // 4. Return S.
-        return types;
-    }
-
-    // https://webidl.spec.whatwg.org/#dfn-number-of-nullable-member-types
-    size_t number_of_nullable_member_types() const
-    {
-        // 1. Let T be the union type.
-
-        // 2. Initialize n to 0.
-        size_t num_nullable_member_types = 0;
-
-        // 3. For each member type U of T:
-        for (auto& type : member_types) {
-            // 1. If U is a nullable type, then:
-            if (type.nullable) {
-                // 1. Set n to n + 1.
-                ++num_nullable_member_types;
-
-                // 2. Set U to be the inner type of U. (NOTE: Not necessary as nullable is stored with Type and not as a separate struct)
-            }
-
-            // 2. If U is a union type, then:
-            if (is<UnionType>(type)) {
-                auto& union_member_type = verify_cast<UnionType>(type);
-
-                // 1. Let m be the number of nullable member types of U.
-                // 2. Set n to n + m.
-                num_nullable_member_types += union_member_type.number_of_nullable_member_types();
-            }
-        }
-
-        // 4. Return n.
-        return num_nullable_member_types;
-    }
-
-    // https://webidl.spec.whatwg.org/#dfn-includes-a-nullable-type
-    bool includes_nullable_type() const
-    {
-        // -> the type is a union type and its number of nullable member types is 1.
-        return number_of_nullable_member_types() == 1;
-    }
-
-    // -> https://webidl.spec.whatwg.org/#dfn-includes-undefined
-    bool includes_undefined() const
-    {
-        // -> the type is a union type and one of its member types includes undefined.
-        for (auto& type : member_types) {
-            if (is<UnionType>(type)) {
-                auto& union_type = verify_cast<UnionType>(type);
-                if (union_type.includes_undefined())
-                    return true;
-            }
-
-            if (type.name == "undefined"sv)
-                return true;
-        }
-        return false;
-    }
-
-    String to_variant() const
-    {
-        StringBuilder builder;
-        builder.append("Variant<");
-
-        auto flattened_types = flattened_member_types();
-        for (size_t type_index = 0; type_index < flattened_types.size(); ++type_index) {
-            auto& type = flattened_types.at(type_index);
-
-            if (type_index > 0)
-                builder.append(", ");
-
-            auto cpp_type = idl_type_name_to_cpp_type(type);
-            builder.append(cpp_type.name);
-        }
-
-        if (includes_undefined())
-            builder.append(", Empty");
-
-        builder.append('>');
-        return builder.to_string();
-    }
-};
-
 struct Parameter {
     NonnullRefPtr<Type> type;
     String name;
@@ -322,4 +199,127 @@ struct Interface {
     bool is_legacy_platform_object() const { return !extended_attributes.contains("Global") && (supports_indexed_properties() || supports_named_properties()); }
 };
 
+CppType idl_type_name_to_cpp_type(Type const& type, IDL::Interface const& interface);
+
+struct UnionType : public Type {
+    UnionType() = default;
+
+    UnionType(String name, bool nullable, NonnullRefPtrVector<Type> member_types)
+        : Type(move(name), nullable)
+        , member_types(move(member_types))
+    {
+    }
+
+    virtual ~UnionType() override = default;
+
+    NonnullRefPtrVector<Type> member_types;
+
+    // https://webidl.spec.whatwg.org/#dfn-flattened-union-member-types
+    NonnullRefPtrVector<Type> flattened_member_types() const
+    {
+        // 1. Let T be the union type.
+
+        // 2. Initialize S to ∅.
+        NonnullRefPtrVector<Type> types;
+
+        // 3. For each member type U of T:
+        for (auto& type : member_types) {
+            // FIXME: 1. If U is an annotated type, then set U to be the inner type of U.
+
+            // 2. If U is a nullable type, then set U to be the inner type of U. (NOTE: Not necessary as nullable is stored with Type and not as a separate struct)
+
+            // 3. If U is a union type, then add to S the flattened member types of U.
+            if (is<UnionType>(type)) {
+                auto& union_member_type = verify_cast<UnionType>(type);
+                types.extend(union_member_type.flattened_member_types());
+            } else {
+                // 4. Otherwise, U is not a union type. Add U to S.
+                types.append(type);
+            }
+        }
+
+        // 4. Return S.
+        return types;
+    }
+
+    // https://webidl.spec.whatwg.org/#dfn-number-of-nullable-member-types
+    size_t number_of_nullable_member_types() const
+    {
+        // 1. Let T be the union type.
+
+        // 2. Initialize n to 0.
+        size_t num_nullable_member_types = 0;
+
+        // 3. For each member type U of T:
+        for (auto& type : member_types) {
+            // 1. If U is a nullable type, then:
+            if (type.nullable) {
+                // 1. Set n to n + 1.
+                ++num_nullable_member_types;
+
+                // 2. Set U to be the inner type of U. (NOTE: Not necessary as nullable is stored with Type and not as a separate struct)
+            }
+
+            // 2. If U is a union type, then:
+            if (is<UnionType>(type)) {
+                auto& union_member_type = verify_cast<UnionType>(type);
+
+                // 1. Let m be the number of nullable member types of U.
+                // 2. Set n to n + m.
+                num_nullable_member_types += union_member_type.number_of_nullable_member_types();
+            }
+        }
+
+        // 4. Return n.
+        return num_nullable_member_types;
+    }
+
+    // https://webidl.spec.whatwg.org/#dfn-includes-a-nullable-type
+    bool includes_nullable_type() const
+    {
+        // -> the type is a union type and its number of nullable member types is 1.
+        return number_of_nullable_member_types() == 1;
+    }
+
+    // -> https://webidl.spec.whatwg.org/#dfn-includes-undefined
+    bool includes_undefined() const
+    {
+        // -> the type is a union type and one of its member types includes undefined.
+        for (auto& type : member_types) {
+            if (is<UnionType>(type)) {
+                auto& union_type = verify_cast<UnionType>(type);
+                if (union_type.includes_undefined())
+                    return true;
+            }
+
+            if (type.name == "undefined"sv)
+                return true;
+        }
+        return false;
+    }
+
+    String to_variant(IDL::Interface const& interface) const
+    {
+        StringBuilder builder;
+        builder.append("Variant<");
+
+        auto flattened_types = flattened_member_types();
+        for (size_t type_index = 0; type_index < flattened_types.size(); ++type_index) {
+            auto& type = flattened_types.at(type_index);
+
+            if (type_index > 0)
+                builder.append(", ");
+
+            auto cpp_type = idl_type_name_to_cpp_type(type, interface);
+            builder.append(cpp_type.name);
+        }
+
+        if (includes_undefined())
+            builder.append(", Empty");
+
+        builder.append('>');
+        return builder.to_string();
+    }
+};
+
 }