Przeglądaj źródła

LibGUI+Userland: Make GML unregistered_child_handler fallible

Sam Atkins 2 lat temu
rodzic
commit
fa98034ff7

+ 2 - 2
Userland/DevTools/GMLPlayground/main.cpp

@@ -121,8 +121,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
 
 
     editor->on_change = [&] {
     editor->on_change = [&] {
         preview->remove_all_children();
         preview->remove_all_children();
-        preview->load_from_gml(editor->text(), [](const DeprecatedString& class_name) -> RefPtr<Core::Object> {
-            return UnregisteredWidget::construct(class_name);
+        preview->load_from_gml(editor->text(), [](DeprecatedString const& class_name) -> ErrorOr<NonnullRefPtr<Core::Object>> {
+            return UnregisteredWidget::try_create(class_name);
         });
         });
     };
     };
 
 

+ 2 - 2
Userland/DevTools/HackStudio/GMLPreviewWidget.cpp

@@ -27,8 +27,8 @@ void GMLPreviewWidget::load_gml(DeprecatedString const& gml)
         return;
         return;
     }
     }
 
 
-    load_from_gml(gml, [](DeprecatedString const& name) -> RefPtr<Core::Object> {
-        return GUI::Label::construct(DeprecatedString::formatted("{} is not registered as a GML element!", name));
+    load_from_gml(gml, [](DeprecatedString const& name) -> ErrorOr<NonnullRefPtr<Core::Object>> {
+        return GUI::Label::try_create(DeprecatedString::formatted("{} is not registered as a GML element!", name));
     });
     });
 
 
     if (children().is_empty()) {
     if (children().is_empty()) {

+ 2 - 2
Userland/Libraries/LibGUI/ScrollableContainerWidget.cpp

@@ -102,7 +102,7 @@ void ScrollableContainerWidget::set_widget(GUI::Widget* widget)
     update_widget_position();
     update_widget_position();
 }
 }
 
 
-ErrorOr<void> ScrollableContainerWidget::load_from_gml_ast(NonnullRefPtr<GUI::GML::Node> ast, RefPtr<Core::Object> (*unregistered_child_handler)(DeprecatedString const&))
+ErrorOr<void> ScrollableContainerWidget::load_from_gml_ast(NonnullRefPtr<GUI::GML::Node> ast, ErrorOr<NonnullRefPtr<Core::Object>> (*unregistered_child_handler)(DeprecatedString const&))
 {
 {
     if (is<GUI::GML::GMLFile>(ast.ptr()))
     if (is<GUI::GML::GMLFile>(ast.ptr()))
         return load_from_gml_ast(static_ptr_cast<GUI::GML::GMLFile>(ast)->main_class(), unregistered_child_handler);
         return load_from_gml_ast(static_ptr_cast<GUI::GML::GMLFile>(ast)->main_class(), unregistered_child_handler);
@@ -133,7 +133,7 @@ ErrorOr<void> ScrollableContainerWidget::load_from_gml_ast(NonnullRefPtr<GUI::GM
         if (auto* registration = Core::ObjectClassRegistration::find(class_name)) {
         if (auto* registration = Core::ObjectClassRegistration::find(class_name)) {
             child = TRY(registration->construct());
             child = TRY(registration->construct());
         } else {
         } else {
-            child = unregistered_child_handler(class_name);
+            child = TRY(unregistered_child_handler(class_name));
         }
         }
         if (!child)
         if (!child)
             return Error::from_string_literal("Unable to construct a Widget class for ScrollableContainerWidget content_widget property");
             return Error::from_string_literal("Unable to construct a Widget class for ScrollableContainerWidget content_widget property");

+ 1 - 1
Userland/Libraries/LibGUI/ScrollableContainerWidget.h

@@ -30,7 +30,7 @@ private:
     void update_widget_size();
     void update_widget_size();
     void update_widget_position();
     void update_widget_position();
     void update_widget_min_size();
     void update_widget_min_size();
-    virtual ErrorOr<void> load_from_gml_ast(NonnullRefPtr<GUI::GML::Node> ast, RefPtr<Core::Object> (*unregistered_child_handler)(DeprecatedString const&)) override;
+    virtual ErrorOr<void> load_from_gml_ast(NonnullRefPtr<GUI::GML::Node> ast, ErrorOr<NonnullRefPtr<Core::Object>> (*unregistered_child_handler)(DeprecatedString const&)) override;
 
 
     ScrollableContainerWidget();
     ScrollableContainerWidget();
 
 

+ 6 - 6
Userland/Libraries/LibGUI/Widget.cpp

@@ -1147,13 +1147,13 @@ void Widget::set_override_cursor(AK::Variant<Gfx::StandardCursor, NonnullRefPtr<
 
 
 ErrorOr<void> Widget::try_load_from_gml(StringView gml_string)
 ErrorOr<void> Widget::try_load_from_gml(StringView gml_string)
 {
 {
-    return try_load_from_gml(gml_string, [](DeprecatedString const& class_name) -> RefPtr<Core::Object> {
+    return try_load_from_gml(gml_string, [](DeprecatedString const& class_name) -> ErrorOr<NonnullRefPtr<Core::Object>> {
         dbgln("Class '{}' not registered", class_name);
         dbgln("Class '{}' not registered", class_name);
-        return nullptr;
+        return Error::from_string_literal("Class not registered");
     });
     });
 }
 }
 
 
-ErrorOr<void> Widget::try_load_from_gml(StringView gml_string, RefPtr<Core::Object> (*unregistered_child_handler)(DeprecatedString const&))
+ErrorOr<void> Widget::try_load_from_gml(StringView gml_string, ErrorOr<NonnullRefPtr<Core::Object>> (*unregistered_child_handler)(DeprecatedString const&))
 {
 {
     auto value = TRY(GML::parse_gml(gml_string));
     auto value = TRY(GML::parse_gml(gml_string));
     return load_from_gml_ast(value, unregistered_child_handler);
     return load_from_gml_ast(value, unregistered_child_handler);
@@ -1164,12 +1164,12 @@ bool Widget::load_from_gml(StringView gml_string)
     return !try_load_from_gml(gml_string).is_error();
     return !try_load_from_gml(gml_string).is_error();
 }
 }
 
 
-bool Widget::load_from_gml(StringView gml_string, RefPtr<Core::Object> (*unregistered_child_handler)(DeprecatedString const&))
+bool Widget::load_from_gml(StringView gml_string, ErrorOr<NonnullRefPtr<Core::Object>> (*unregistered_child_handler)(DeprecatedString const&))
 {
 {
     return !try_load_from_gml(gml_string, unregistered_child_handler).is_error();
     return !try_load_from_gml(gml_string, unregistered_child_handler).is_error();
 }
 }
 
 
-ErrorOr<void> Widget::load_from_gml_ast(NonnullRefPtr<GUI::GML::Node> ast, RefPtr<Core::Object> (*unregistered_child_handler)(DeprecatedString const&))
+ErrorOr<void> Widget::load_from_gml_ast(NonnullRefPtr<GUI::GML::Node> ast, ErrorOr<NonnullRefPtr<Core::Object>> (*unregistered_child_handler)(DeprecatedString const&))
 {
 {
     if (is<GUI::GML::GMLFile>(ast.ptr()))
     if (is<GUI::GML::GMLFile>(ast.ptr()))
         return load_from_gml_ast(static_ptr_cast<GUI::GML::GMLFile>(ast)->main_class(), unregistered_child_handler);
         return load_from_gml_ast(static_ptr_cast<GUI::GML::GMLFile>(ast)->main_class(), unregistered_child_handler);
@@ -1226,7 +1226,7 @@ ErrorOr<void> Widget::load_from_gml_ast(NonnullRefPtr<GUI::GML::Node> ast, RefPt
                     return Error::from_string_literal("Invalid widget class");
                     return Error::from_string_literal("Invalid widget class");
                 }
                 }
             } else {
             } else {
-                child = unregistered_child_handler(class_name);
+                child = TRY(unregistered_child_handler(class_name));
             }
             }
             if (!child)
             if (!child)
                 return Error::from_string_literal("Unable to construct a Widget class for child");
                 return Error::from_string_literal("Unable to construct a Widget class for child");

+ 3 - 3
Userland/Libraries/LibGUI/Widget.h

@@ -354,11 +354,11 @@ public:
     void set_override_cursor(AK::Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>>);
     void set_override_cursor(AK::Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>>);
 
 
     ErrorOr<void> try_load_from_gml(StringView);
     ErrorOr<void> try_load_from_gml(StringView);
-    ErrorOr<void> try_load_from_gml(StringView, RefPtr<Core::Object> (*unregistered_child_handler)(DeprecatedString const&));
+    ErrorOr<void> try_load_from_gml(StringView, ErrorOr<NonnullRefPtr<Core::Object>> (*unregistered_child_handler)(DeprecatedString const&));
 
 
     // FIXME: Replace all uses of load_from_gml() with try_load_from_gml()
     // FIXME: Replace all uses of load_from_gml() with try_load_from_gml()
     bool load_from_gml(StringView gml_string);
     bool load_from_gml(StringView gml_string);
-    bool load_from_gml(StringView, RefPtr<Core::Object> (*unregistered_child_handler)(DeprecatedString const&));
+    bool load_from_gml(StringView, ErrorOr<NonnullRefPtr<Core::Object>> (*unregistered_child_handler)(DeprecatedString const&));
 
 
     // FIXME: remove this when all uses of shrink_to_fit are eliminated
     // FIXME: remove this when all uses of shrink_to_fit are eliminated
     void set_shrink_to_fit(bool);
     void set_shrink_to_fit(bool);
@@ -367,7 +367,7 @@ public:
     bool has_pending_drop() const;
     bool has_pending_drop() const;
 
 
     // In order for others to be able to call this, it needs to be public.
     // In order for others to be able to call this, it needs to be public.
-    virtual ErrorOr<void> load_from_gml_ast(NonnullRefPtr<GUI::GML::Node> ast, RefPtr<Core::Object> (*unregistered_child_handler)(DeprecatedString const&));
+    virtual ErrorOr<void> load_from_gml_ast(NonnullRefPtr<GUI::GML::Node> ast, ErrorOr<NonnullRefPtr<Core::Object>> (*unregistered_child_handler)(DeprecatedString const&));
 
 
 protected:
 protected:
     Widget();
     Widget();