1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 08:57:34 +00:00

Spreadsheet: Convert JSIntegration to ThrowCompletionOr

This commit is contained in:
Timothy Flynn 2021-10-31 08:20:21 -04:00 committed by Linus Groh
parent 7653be6062
commit 1939c72ecc
2 changed files with 80 additions and 131 deletions

View file

@ -151,12 +151,12 @@ void SheetGlobalObject::initialize_global_object()
{ {
Base::initialize_global_object(); Base::initialize_global_object();
u8 attr = JS::Attribute::Configurable | JS::Attribute::Writable | JS::Attribute::Enumerable; u8 attr = JS::Attribute::Configurable | JS::Attribute::Writable | JS::Attribute::Enumerable;
define_old_native_function("get_real_cell_contents", get_real_cell_contents, 1, attr); define_native_function("get_real_cell_contents", get_real_cell_contents, 1, attr);
define_old_native_function("set_real_cell_contents", set_real_cell_contents, 2, attr); define_native_function("set_real_cell_contents", set_real_cell_contents, 2, attr);
define_old_native_function("parse_cell_name", parse_cell_name, 1, attr); define_native_function("parse_cell_name", parse_cell_name, 1, attr);
define_old_native_function("current_cell_position", current_cell_position, 0, attr); define_native_function("current_cell_position", current_cell_position, 0, attr);
define_old_native_function("column_arithmetic", column_arithmetic, 2, attr); define_native_function("column_arithmetic", column_arithmetic, 2, attr);
define_old_native_function("column_index", column_index, 1, attr); define_native_function("column_index", column_index, 1, attr);
} }
void SheetGlobalObject::visit_edges(Visitor& visitor) void SheetGlobalObject::visit_edges(Visitor& visitor)
@ -169,32 +169,24 @@ void SheetGlobalObject::visit_edges(Visitor& visitor)
} }
} }
JS_DEFINE_OLD_NATIVE_FUNCTION(SheetGlobalObject::get_real_cell_contents) JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_real_cell_contents)
{ {
auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object)); auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
if (!is<SheetGlobalObject>(this_object)) { if (!is<SheetGlobalObject>(this_object))
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
return {};
}
auto sheet_object = static_cast<SheetGlobalObject*>(this_object); auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
if (vm.argument_count() != 1) { if (vm.argument_count() != 1)
vm.throw_exception<JS::TypeError>(global_object, "Expected exactly one argument to get_real_cell_contents()"); return vm.throw_completion<JS::TypeError>(global_object, "Expected exactly one argument to get_real_cell_contents()");
return {};
}
auto name_value = vm.argument(0); auto name_value = vm.argument(0);
if (!name_value.is_string()) { if (!name_value.is_string())
vm.throw_exception<JS::TypeError>(global_object, "Expected a String argument to get_real_cell_contents()"); return vm.throw_completion<JS::TypeError>(global_object, "Expected a String argument to get_real_cell_contents()");
return {};
}
auto position = sheet_object->m_sheet.parse_cell_name(name_value.as_string().string()); auto position = sheet_object->m_sheet.parse_cell_name(name_value.as_string().string());
if (!position.has_value()) { if (!position.has_value())
vm.throw_exception<JS::TypeError>(global_object, "Invalid cell name"); return vm.throw_completion<JS::TypeError>(global_object, "Invalid cell name");
return {};
}
const auto* cell = sheet_object->m_sheet.at(position.value()); const auto* cell = sheet_object->m_sheet.at(position.value());
if (!cell) if (!cell)
@ -206,38 +198,28 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(SheetGlobalObject::get_real_cell_contents)
return JS::js_string(vm, cell->data()); return JS::js_string(vm, cell->data());
} }
JS_DEFINE_OLD_NATIVE_FUNCTION(SheetGlobalObject::set_real_cell_contents) JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::set_real_cell_contents)
{ {
auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object)); auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
if (!is<SheetGlobalObject>(this_object)) { if (!is<SheetGlobalObject>(this_object))
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
return {};
}
auto sheet_object = static_cast<SheetGlobalObject*>(this_object); auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
if (vm.argument_count() != 2) { if (vm.argument_count() != 2)
vm.throw_exception<JS::TypeError>(global_object, "Expected exactly two arguments to set_real_cell_contents()"); return vm.throw_completion<JS::TypeError>(global_object, "Expected exactly two arguments to set_real_cell_contents()");
return {};
}
auto name_value = vm.argument(0); auto name_value = vm.argument(0);
if (!name_value.is_string()) { if (!name_value.is_string())
vm.throw_exception<JS::TypeError>(global_object, "Expected the first argument of set_real_cell_contents() to be a String"); return vm.throw_completion<JS::TypeError>(global_object, "Expected the first argument of set_real_cell_contents() to be a String");
return {};
}
auto position = sheet_object->m_sheet.parse_cell_name(name_value.as_string().string()); auto position = sheet_object->m_sheet.parse_cell_name(name_value.as_string().string());
if (!position.has_value()) { if (!position.has_value())
vm.throw_exception<JS::TypeError>(global_object, "Invalid cell name"); return vm.throw_completion<JS::TypeError>(global_object, "Invalid cell name");
return {};
}
auto new_contents_value = vm.argument(1); auto new_contents_value = vm.argument(1);
if (!new_contents_value.is_string()) { if (!new_contents_value.is_string())
vm.throw_exception<JS::TypeError>(global_object, "Expected the second argument of set_real_cell_contents() to be a String"); return vm.throw_completion<JS::TypeError>(global_object, "Expected the second argument of set_real_cell_contents() to be a String");
return {};
}
auto& cell = sheet_object->m_sheet.ensure(position.value()); auto& cell = sheet_object->m_sheet.ensure(position.value());
auto& new_contents = new_contents_value.as_string().string(); auto& new_contents = new_contents_value.as_string().string();
@ -245,26 +227,20 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(SheetGlobalObject::set_real_cell_contents)
return JS::js_null(); return JS::js_null();
} }
JS_DEFINE_OLD_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name) JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name)
{ {
auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object)); auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
if (!is<SheetGlobalObject>(this_object)) { if (!is<SheetGlobalObject>(this_object))
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
return {};
}
auto sheet_object = static_cast<SheetGlobalObject*>(this_object); auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
if (vm.argument_count() != 1) { if (vm.argument_count() != 1)
vm.throw_exception<JS::TypeError>(global_object, "Expected exactly one argument to parse_cell_name()"); return vm.throw_completion<JS::TypeError>(global_object, "Expected exactly one argument to parse_cell_name()");
return {};
}
auto name_value = vm.argument(0); auto name_value = vm.argument(0);
if (!name_value.is_string()) { if (!name_value.is_string())
vm.throw_exception<JS::TypeError>(global_object, "Expected a String argument to parse_cell_name()"); return vm.throw_completion<JS::TypeError>(global_object, "Expected a String argument to parse_cell_name()");
return {};
}
auto position = sheet_object->m_sheet.parse_cell_name(name_value.as_string().string()); auto position = sheet_object->m_sheet.parse_cell_name(name_value.as_string().string());
if (!position.has_value()) if (!position.has_value())
return JS::js_undefined(); return JS::js_undefined();
@ -276,19 +252,15 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name)
return object; return object;
} }
JS_DEFINE_OLD_NATIVE_FUNCTION(SheetGlobalObject::current_cell_position) JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::current_cell_position)
{ {
if (vm.argument_count() != 0) { if (vm.argument_count() != 0)
vm.throw_exception<JS::TypeError>(global_object, "Expected no arguments to current_cell_position()"); return vm.throw_completion<JS::TypeError>(global_object, "Expected no arguments to current_cell_position()");
return {};
}
auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object)); auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
if (!is<SheetGlobalObject>(this_object)) { if (!is<SheetGlobalObject>(this_object))
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
return {};
}
auto sheet_object = static_cast<SheetGlobalObject*>(this_object); auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
auto* current_cell = sheet_object->m_sheet.current_evaluated_cell(); auto* current_cell = sheet_object->m_sheet.current_evaluated_cell();
@ -304,72 +276,55 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(SheetGlobalObject::current_cell_position)
return object; return object;
} }
JS_DEFINE_OLD_NATIVE_FUNCTION(SheetGlobalObject::column_index) JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_index)
{ {
if (vm.argument_count() != 1) { if (vm.argument_count() != 1)
vm.throw_exception<JS::TypeError>(global_object, "Expected exactly one argument to column_index()"); return vm.throw_completion<JS::TypeError>(global_object, "Expected exactly one argument to column_index()");
return {};
}
auto column_name = vm.argument(0); auto column_name = vm.argument(0);
if (!column_name.is_string()) { if (!column_name.is_string())
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "String"); return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "String");
return {};
}
auto& column_name_str = column_name.as_string().string(); auto& column_name_str = column_name.as_string().string();
auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object)); auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
if (!is<SheetGlobalObject>(this_object)) { if (!is<SheetGlobalObject>(this_object))
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
return {};
}
auto sheet_object = static_cast<SheetGlobalObject*>(this_object); auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
auto& sheet = sheet_object->m_sheet; auto& sheet = sheet_object->m_sheet;
auto column_index = sheet.column_index(column_name_str); auto column_index = sheet.column_index(column_name_str);
if (!column_index.has_value()) { if (!column_index.has_value())
vm.throw_exception(global_object, JS::TypeError::create(global_object, String::formatted("'{}' is not a valid column", column_name_str))); return vm.throw_completion<JS::TypeError>(global_object, String::formatted("'{}' is not a valid column", column_name_str));
return {};
}
return JS::Value((i32)column_index.value()); return JS::Value((i32)column_index.value());
} }
JS_DEFINE_OLD_NATIVE_FUNCTION(SheetGlobalObject::column_arithmetic) JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_arithmetic)
{ {
if (vm.argument_count() != 2) { if (vm.argument_count() != 2)
vm.throw_exception<JS::TypeError>(global_object, "Expected exactly two arguments to column_arithmetic()"); return vm.throw_completion<JS::TypeError>(global_object, "Expected exactly two arguments to column_arithmetic()");
return {};
}
auto column_name = vm.argument(0); auto column_name = vm.argument(0);
if (!column_name.is_string()) { if (!column_name.is_string())
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "String"); return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "String");
return {};
}
auto& column_name_str = column_name.as_string().string(); auto& column_name_str = column_name.as_string().string();
auto offset = TRY_OR_DISCARD(vm.argument(1).to_number(global_object)); auto offset = TRY(vm.argument(1).to_number(global_object));
auto offset_number = offset.as_i32(); auto offset_number = offset.as_i32();
auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object)); auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
if (!is<SheetGlobalObject>(this_object)) { if (!is<SheetGlobalObject>(this_object))
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
return {};
}
auto sheet_object = static_cast<SheetGlobalObject*>(this_object); auto sheet_object = static_cast<SheetGlobalObject*>(this_object);
auto& sheet = sheet_object->m_sheet; auto& sheet = sheet_object->m_sheet;
auto new_column = sheet.column_arithmetic(column_name_str, offset_number); auto new_column = sheet.column_arithmetic(column_name_str, offset_number);
if (!new_column.has_value()) { if (!new_column.has_value())
vm.throw_exception(global_object, JS::TypeError::create(global_object, String::formatted("'{}' is not a valid column", column_name_str))); return vm.throw_completion<JS::TypeError>(global_object, String::formatted("'{}' is not a valid column", column_name_str));
return {};
}
return JS::js_string(vm, new_column.release_value()); return JS::js_string(vm, new_column.release_value());
} }
@ -387,7 +342,7 @@ WorkbookObject::~WorkbookObject()
void WorkbookObject::initialize(JS::GlobalObject& global_object) void WorkbookObject::initialize(JS::GlobalObject& global_object)
{ {
Object::initialize(global_object); Object::initialize(global_object);
define_old_native_function("sheet", sheet, 1, JS::default_attributes); define_native_function("sheet", sheet, 1, JS::default_attributes);
} }
void WorkbookObject::visit_edges(Visitor& visitor) void WorkbookObject::visit_edges(Visitor& visitor)
@ -397,24 +352,18 @@ void WorkbookObject::visit_edges(Visitor& visitor)
visitor.visit(&sheet.global_object()); visitor.visit(&sheet.global_object());
} }
JS_DEFINE_OLD_NATIVE_FUNCTION(WorkbookObject::sheet) JS_DEFINE_NATIVE_FUNCTION(WorkbookObject::sheet)
{ {
if (vm.argument_count() != 1) { if (vm.argument_count() != 1)
vm.throw_exception<JS::TypeError>(global_object, "Expected exactly one argument to sheet()"); return vm.throw_completion<JS::TypeError>(global_object, "Expected exactly one argument to sheet()");
return {};
}
auto name_value = vm.argument(0); auto name_value = vm.argument(0);
if (!name_value.is_string() && !name_value.is_number()) { if (!name_value.is_string() && !name_value.is_number())
vm.throw_exception<JS::TypeError>(global_object, "Expected a String or Number argument to sheet()"); return vm.throw_completion<JS::TypeError>(global_object, "Expected a String or Number argument to sheet()");
return {};
}
auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object)); auto* this_object = TRY(vm.this_value(global_object).to_object(global_object));
if (!is<WorkbookObject>(this_object)) { if (!is<WorkbookObject>(this_object))
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WorkbookObject"); return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WorkbookObject");
return {};
}
auto& workbook = static_cast<WorkbookObject*>(this_object)->m_workbook; auto& workbook = static_cast<WorkbookObject*>(this_object)->m_workbook;
@ -425,7 +374,7 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(WorkbookObject::sheet)
return JS::Value(&sheet.global_object()); return JS::Value(&sheet.global_object());
} }
} else { } else {
auto index = TRY_OR_DISCARD(name_value.to_length(global_object)); auto index = TRY(name_value.to_length(global_object));
if (index < workbook.sheets().size()) if (index < workbook.sheets().size())
return JS::Value(&workbook.sheets()[index].global_object()); return JS::Value(&workbook.sheets()[index].global_object());
} }

View file

@ -32,12 +32,12 @@ public:
virtual JS::ThrowCompletionOr<bool> internal_set(JS::PropertyKey const&, JS::Value value, JS::Value receiver) override; virtual JS::ThrowCompletionOr<bool> internal_set(JS::PropertyKey const&, JS::Value value, JS::Value receiver) override;
virtual void initialize_global_object() override; virtual void initialize_global_object() override;
JS_DECLARE_OLD_NATIVE_FUNCTION(get_real_cell_contents); JS_DECLARE_NATIVE_FUNCTION(get_real_cell_contents);
JS_DECLARE_OLD_NATIVE_FUNCTION(set_real_cell_contents); JS_DECLARE_NATIVE_FUNCTION(set_real_cell_contents);
JS_DECLARE_OLD_NATIVE_FUNCTION(parse_cell_name); JS_DECLARE_NATIVE_FUNCTION(parse_cell_name);
JS_DECLARE_OLD_NATIVE_FUNCTION(current_cell_position); JS_DECLARE_NATIVE_FUNCTION(current_cell_position);
JS_DECLARE_OLD_NATIVE_FUNCTION(column_index); JS_DECLARE_NATIVE_FUNCTION(column_index);
JS_DECLARE_OLD_NATIVE_FUNCTION(column_arithmetic); JS_DECLARE_NATIVE_FUNCTION(column_arithmetic);
private: private:
virtual void visit_edges(Visitor&) override; virtual void visit_edges(Visitor&) override;
@ -54,7 +54,7 @@ public:
virtual void initialize(JS::GlobalObject&) override; virtual void initialize(JS::GlobalObject&) override;
JS_DECLARE_OLD_NATIVE_FUNCTION(sheet); JS_DECLARE_NATIVE_FUNCTION(sheet);
private: private:
virtual void visit_edges(Visitor&) override; virtual void visit_edges(Visitor&) override;