1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "ecmascript/builtins/builtins_plural_rules.h" 17 18#include "ecmascript/intl/locale_helper.h" 19#include "ecmascript/global_env.h" 20#include "ecmascript/js_plural_rules.h" 21 22namespace panda::ecmascript::builtins { 23JSTaggedValue BuiltinsPluralRules::PluralRulesConstructor(EcmaRuntimeCallInfo *argv) 24{ 25 JSThread *thread = argv->GetThread(); 26 BUILTINS_API_TRACE(thread, PluralRules, Constructor); 27 [[maybe_unused]] EcmaHandleScope scope(thread); 28 EcmaVM *ecmaVm = thread->GetEcmaVM(); 29 ObjectFactory *factory = ecmaVm->GetFactory(); 30 31 // 1. If NewTarget is undefined, throw a TypeError exception. 32 JSHandle<JSTaggedValue> constructor = GetConstructor(argv); 33 JSHandle<JSTaggedValue> newTarget = GetNewTarget(argv); 34 if (newTarget->IsUndefined()) { 35 THROW_TYPE_ERROR_AND_RETURN(thread, "newTarget is undefined", JSTaggedValue::Exception()); 36 } 37 38 // 2. Let pluralRules be ? OrdinaryCreateFromConstructor(NewTarget, "%PluralRulesPrototype%", 39 // « [[InitializedPluralRules]], [[Locale]], [[Type]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], 40 // [[MaximumFractionDigits]], [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[RoundingType]] »). 41 JSHandle<JSObject> newObject = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), newTarget); 42 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 43 JSHandle<JSPluralRules> pluralRules = JSHandle<JSPluralRules>::Cast(newObject); 44 45 // 3. Return ? InitializePluralRules(pluralRules, locales, options). 46 JSHandle<JSTaggedValue> locales = GetCallArg(argv, 0); 47 JSHandle<JSTaggedValue> options = GetCallArg(argv, 1); 48 JSPluralRules::InitializePluralRules(thread, pluralRules, locales, options); 49 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 50 51 return pluralRules.GetTaggedValue(); 52} 53 54JSTaggedValue BuiltinsPluralRules::SupportedLocalesOf(EcmaRuntimeCallInfo *argv) 55{ 56 JSThread *thread = argv->GetThread(); 57 BUILTINS_API_TRACE(thread, PluralRules, SupportedLocalesOf); 58 [[maybe_unused]] EcmaHandleScope scope(thread); 59 60 // 1. Let availableLocales be %PluralRules%.[[AvailableLocales]]. 61 JSHandle<TaggedArray> availableLocales = JSPluralRules::GetAvailableLocales(thread); 62 63 // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). 64 JSHandle<JSTaggedValue> locales = GetCallArg(argv, 0); 65 JSHandle<TaggedArray> requestedLocales = intl::LocaleHelper::CanonicalizeLocaleList(thread, locales); 66 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 67 68 // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). 69 JSHandle<JSTaggedValue> options = GetCallArg(argv, 1); 70 JSHandle<JSArray> result = JSLocale::SupportedLocales(thread, availableLocales, requestedLocales, options); 71 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 72 return result.GetTaggedValue(); 73} 74 75JSTaggedValue BuiltinsPluralRules::Select(EcmaRuntimeCallInfo *argv) 76{ 77 JSThread *thread = argv->GetThread(); 78 BUILTINS_API_TRACE(thread, PluralRules, Select); 79 [[maybe_unused]] EcmaHandleScope scope(thread); 80 81 // 1. Let pr be the this value. 82 JSHandle<JSTaggedValue> thisValue = GetThis(argv); 83 84 // 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]). 85 if (!thisValue->IsJSPluralRules()) { 86 THROW_TYPE_ERROR_AND_RETURN(thread, "this is not pr object", JSTaggedValue::Exception()); 87 } 88 89 // 3. Let n be ? ToNumber(value). 90 double x = 0.0; 91 JSHandle<JSTaggedValue> value = GetCallArg(argv, 0); 92 JSTaggedNumber temp = JSTaggedValue::ToNumber(thread, value); 93 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 94 x = temp.GetNumber(); 95 96 // 4. Return ? ResolvePlural(pr, n). 97 JSHandle<JSPluralRules> pluralRules = JSHandle<JSPluralRules>::Cast(thisValue); 98 JSHandle<EcmaString> result = JSPluralRules::ResolvePlural(thread, pluralRules, x); 99 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 100 return result.GetTaggedValue(); 101} 102 103JSTaggedValue BuiltinsPluralRules::ResolvedOptions(EcmaRuntimeCallInfo *argv) 104{ 105 JSThread *thread = argv->GetThread(); 106 BUILTINS_API_TRACE(thread, PluralRules, ResolvedOptions); 107 [[maybe_unused]] EcmaHandleScope scope(thread); 108 109 // 1. Let thisValue be the this value; 110 JSHandle<JSTaggedValue> thisValue = GetThis(argv); 111 112 // 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]). 113 if (!thisValue->IsJSPluralRules()) { 114 THROW_TYPE_ERROR_AND_RETURN(thread, "this is not pr object", JSTaggedValue::Exception()); 115 } 116 117 // 3. Let options be ! ObjectCreate(%ObjectPrototype%). 118 auto ecmaVm = thread->GetEcmaVM(); 119 JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv(); 120 ObjectFactory *factory = ecmaVm->GetFactory(); 121 JSHandle<JSFunction> ctor(env->GetObjectFunction()); 122 JSHandle<JSObject> options(factory->NewJSObjectByConstructor(ctor)); 123 124 // 4. Perform resolvedOptions 125 JSHandle<JSPluralRules> pluralRules = JSHandle<JSPluralRules>::Cast(thisValue); 126 JSPluralRules::ResolvedOptions(thread, pluralRules, options); 127 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 128 129 // 5. Return options. 130 return options.GetTaggedValue(); 131} 132} // namespace panda::ecmascript::builtins