mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-20 01:37:39 +03:00
LibJS: Implement a nearly empty Intl.PluralRules object
This adds plumbing for the Intl.PluralRules object, constructor, and prototype.
This commit is contained in:
parent
ac3e42a8de
commit
0087804d10
Notes:
sideshowbarker
2024-07-17 20:05:36 +09:00
Author: https://github.com/trflynn89 Commit: https://github.com/SerenityOS/serenity/commit/0087804d109 Pull-request: https://github.com/SerenityOS/serenity/pull/12188 Reviewed-by: https://github.com/linusg ✅
@ -106,6 +106,9 @@ set(SOURCES
|
||||
Runtime/Intl/NumberFormatConstructor.cpp
|
||||
Runtime/Intl/NumberFormatFunction.cpp
|
||||
Runtime/Intl/NumberFormatPrototype.cpp
|
||||
Runtime/Intl/PluralRules.cpp
|
||||
Runtime/Intl/PluralRulesConstructor.cpp
|
||||
Runtime/Intl/PluralRulesPrototype.cpp
|
||||
Runtime/Intl/RelativeTimeFormat.cpp
|
||||
Runtime/Intl/RelativeTimeFormatConstructor.cpp
|
||||
Runtime/Intl/RelativeTimeFormatPrototype.cpp
|
||||
|
@ -73,6 +73,7 @@
|
||||
__JS_ENUMERATE(ListFormat, list_format, ListFormatPrototype, ListFormatConstructor) \
|
||||
__JS_ENUMERATE(Locale, locale, LocalePrototype, LocaleConstructor) \
|
||||
__JS_ENUMERATE(NumberFormat, number_format, NumberFormatPrototype, NumberFormatConstructor) \
|
||||
__JS_ENUMERATE(PluralRules, plural_rules, PluralRulesPrototype, PluralRulesConstructor) \
|
||||
__JS_ENUMERATE(RelativeTimeFormat, relative_time_format, RelativeTimeFormatPrototype, RelativeTimeFormatConstructor)
|
||||
|
||||
#define JS_ENUMERATE_TEMPORAL_OBJECTS \
|
||||
|
@ -61,6 +61,8 @@
|
||||
#include <LibJS/Runtime/Intl/LocalePrototype.h>
|
||||
#include <LibJS/Runtime/Intl/NumberFormatConstructor.h>
|
||||
#include <LibJS/Runtime/Intl/NumberFormatPrototype.h>
|
||||
#include <LibJS/Runtime/Intl/PluralRulesConstructor.h>
|
||||
#include <LibJS/Runtime/Intl/PluralRulesPrototype.h>
|
||||
#include <LibJS/Runtime/Intl/RelativeTimeFormatConstructor.h>
|
||||
#include <LibJS/Runtime/Intl/RelativeTimeFormatPrototype.h>
|
||||
#include <LibJS/Runtime/IteratorPrototype.h>
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <LibJS/Runtime/Intl/ListFormatConstructor.h>
|
||||
#include <LibJS/Runtime/Intl/LocaleConstructor.h>
|
||||
#include <LibJS/Runtime/Intl/NumberFormatConstructor.h>
|
||||
#include <LibJS/Runtime/Intl/PluralRulesConstructor.h>
|
||||
#include <LibJS/Runtime/Intl/RelativeTimeFormatConstructor.h>
|
||||
|
||||
namespace JS::Intl {
|
||||
@ -38,6 +39,7 @@ void Intl::initialize(GlobalObject& global_object)
|
||||
define_direct_property(vm.names.ListFormat, global_object.intl_list_format_constructor(), attr);
|
||||
define_direct_property(vm.names.Locale, global_object.intl_locale_constructor(), attr);
|
||||
define_direct_property(vm.names.NumberFormat, global_object.intl_number_format_constructor(), attr);
|
||||
define_direct_property(vm.names.PluralRules, global_object.intl_plural_rules_constructor(), attr);
|
||||
define_direct_property(vm.names.RelativeTimeFormat, global_object.intl_relative_time_format_constructor(), attr);
|
||||
|
||||
define_native_function(vm.names.getCanonicalLocales, get_canonical_locales, 1, attr);
|
||||
|
40
Userland/Libraries/LibJS/Runtime/Intl/PluralRules.cpp
Normal file
40
Userland/Libraries/LibJS/Runtime/Intl/PluralRules.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Tim Flynn <trflynn89@pm.me>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Runtime/Intl/PluralRules.h>
|
||||
|
||||
namespace JS::Intl {
|
||||
|
||||
// 16 PluralRules Objects, https://tc39.es/ecma402/#pluralrules-objects
|
||||
PluralRules::PluralRules(Object& prototype)
|
||||
: NumberFormatBase(prototype)
|
||||
{
|
||||
}
|
||||
|
||||
void PluralRules::set_type(StringView type)
|
||||
{
|
||||
if (type == "cardinal"sv) {
|
||||
m_type = Type::Cardinal;
|
||||
} else if (type == "ordinal"sv) {
|
||||
m_type = Type::Ordinal;
|
||||
} else {
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
StringView PluralRules::type_string() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::Cardinal:
|
||||
return "cardinal"sv;
|
||||
case Type::Ordinal:
|
||||
return "ordinal"sv;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
36
Userland/Libraries/LibJS/Runtime/Intl/PluralRules.h
Normal file
36
Userland/Libraries/LibJS/Runtime/Intl/PluralRules.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Tim Flynn <trflynn89@pm.me>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <LibJS/Runtime/Intl/NumberFormat.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
|
||||
namespace JS::Intl {
|
||||
|
||||
class PluralRules final : public NumberFormatBase {
|
||||
JS_OBJECT(PluralRules, NumberFormatBase);
|
||||
|
||||
public:
|
||||
enum class Type {
|
||||
Cardinal,
|
||||
Ordinal,
|
||||
};
|
||||
|
||||
PluralRules(Object& prototype);
|
||||
virtual ~PluralRules() override = default;
|
||||
|
||||
Type type() const { return m_type; }
|
||||
StringView type_string() const;
|
||||
void set_type(StringView type);
|
||||
|
||||
private:
|
||||
Type m_type { Type::Cardinal }; // [[Type]]
|
||||
};
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Tim Flynn <trflynn89@pm.me>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/Intl/PluralRules.h>
|
||||
#include <LibJS/Runtime/Intl/PluralRulesConstructor.h>
|
||||
|
||||
namespace JS::Intl {
|
||||
|
||||
// 16.2 The Intl.PluralRules Constructor, https://tc39.es/ecma402/#sec-intl-pluralrules-constructor
|
||||
PluralRulesConstructor::PluralRulesConstructor(GlobalObject& global_object)
|
||||
: NativeFunction(vm().names.PluralRules.as_string(), *global_object.function_prototype())
|
||||
{
|
||||
}
|
||||
|
||||
void PluralRulesConstructor::initialize(GlobalObject& global_object)
|
||||
{
|
||||
NativeFunction::initialize(global_object);
|
||||
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 16.3.1 Intl.PluralRules.prototype, https://tc39.es/ecma402/#sec-intl.pluralrules.prototype
|
||||
define_direct_property(vm.names.prototype, global_object.intl_plural_rules_prototype(), 0);
|
||||
define_direct_property(vm.names.length, Value(0), Attribute::Configurable);
|
||||
}
|
||||
|
||||
// 16.2.1 Intl.PluralRules ( [ locales [ , options ] ] ), https://tc39.es/ecma402/#sec-intl.pluralrules
|
||||
ThrowCompletionOr<Value> PluralRulesConstructor::call()
|
||||
{
|
||||
// 1. If NewTarget is undefined, throw a TypeError exception.
|
||||
return vm().throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, "Intl.PluralRules");
|
||||
}
|
||||
|
||||
// 16.2.1 Intl.PluralRules ( [ locales [ , options ] ] ), https://tc39.es/ecma402/#sec-intl.pluralrules
|
||||
ThrowCompletionOr<Object*> PluralRulesConstructor::construct(FunctionObject& new_target)
|
||||
{
|
||||
auto& global_object = this->global_object();
|
||||
|
||||
// 2. Let pluralRules be ? OrdinaryCreateFromConstructor(NewTarget, "%PluralRules.prototype%", « [[InitializedPluralRules]], [[Locale]], [[Type]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], [[MaximumFractionDigits]], [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[RoundingType]] »).
|
||||
auto* plural_rules = TRY(ordinary_create_from_constructor<PluralRules>(global_object, new_target, &GlobalObject::intl_plural_rules_prototype));
|
||||
|
||||
// 3. Return ? InitializePluralRules(pluralRules, locales, options).
|
||||
return plural_rules;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Tim Flynn <trflynn89@pm.me>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Runtime/NativeFunction.h>
|
||||
|
||||
namespace JS::Intl {
|
||||
|
||||
class PluralRulesConstructor final : public NativeFunction {
|
||||
JS_OBJECT(PluralRulesConstructor, NativeFunction);
|
||||
|
||||
public:
|
||||
explicit PluralRulesConstructor(GlobalObject&);
|
||||
virtual void initialize(GlobalObject&) override;
|
||||
virtual ~PluralRulesConstructor() override = default;
|
||||
|
||||
virtual ThrowCompletionOr<Value> call() override;
|
||||
virtual ThrowCompletionOr<Object*> construct(FunctionObject& new_target) override;
|
||||
|
||||
private:
|
||||
virtual bool has_constructor() const override { return true; }
|
||||
};
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Tim Flynn <trflynn89@pm.me>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/Intl/PluralRulesPrototype.h>
|
||||
|
||||
namespace JS::Intl {
|
||||
|
||||
// 16.4 Properties of the Intl.PluralRules Prototype Object, https://tc39.es/ecma402/#sec-properties-of-intl-pluralrules-prototype-object
|
||||
PluralRulesPrototype::PluralRulesPrototype(GlobalObject& global_object)
|
||||
: PrototypeObject(*global_object.object_prototype())
|
||||
{
|
||||
}
|
||||
|
||||
void PluralRulesPrototype::initialize(GlobalObject& global_object)
|
||||
{
|
||||
Object::initialize(global_object);
|
||||
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 16.4.2 Intl.PluralRules.prototype [ @@toStringTag ], https://tc39.es/ecma402/#sec-intl.pluralrules.prototype-tostringtag
|
||||
define_direct_property(*vm.well_known_symbol_to_string_tag(), js_string(vm, "Intl.PluralRules"sv), Attribute::Configurable);
|
||||
}
|
||||
|
||||
}
|
23
Userland/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.h
Normal file
23
Userland/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Tim Flynn <trflynn89@pm.me>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Runtime/Intl/PluralRules.h>
|
||||
#include <LibJS/Runtime/PrototypeObject.h>
|
||||
|
||||
namespace JS::Intl {
|
||||
|
||||
class PluralRulesPrototype final : public PrototypeObject<PluralRulesPrototype, PluralRules> {
|
||||
JS_PROTOTYPE_OBJECT(PluralRulesPrototype, PluralRules, Intl.PluralRules);
|
||||
|
||||
public:
|
||||
explicit PluralRulesPrototype(GlobalObject&);
|
||||
virtual void initialize(GlobalObject&) override;
|
||||
virtual ~PluralRulesPrototype() override = default;
|
||||
};
|
||||
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
test("basic functionality", () => {
|
||||
expect(Intl.PluralRules.prototype[Symbol.toStringTag]).toBe("Intl.PluralRules");
|
||||
});
|
@ -0,0 +1,13 @@
|
||||
describe("errors", () => {
|
||||
test("called without new", () => {
|
||||
expect(() => {
|
||||
Intl.PluralRules();
|
||||
}).toThrowWithMessage(TypeError, "Intl.PluralRules constructor must be called with 'new'");
|
||||
});
|
||||
});
|
||||
|
||||
describe("normal behavior", () => {
|
||||
test("length is 0", () => {
|
||||
expect(Intl.PluralRules).toHaveLength(0);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user