| 
									
										
										
										
											2021-07-11 21:04:11 +03:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2022-05-24 18:26:13 +01:00
										 |  |  |  * Copyright (c) 2021-2022, Idan Horowitz <idan.horowitz@serenityos.org> | 
					
						
							| 
									
										
										
										
											2023-01-26 12:07:38 +00:00
										 |  |  |  * Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org> | 
					
						
							| 
									
										
										
										
											2021-11-09 17:19:28 +00:00
										 |  |  |  * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org> | 
					
						
							| 
									
										
										
										
											2024-11-16 13:14:14 -05:00
										 |  |  |  * Copyright (c) 2024, Tim Flynn <trflynn89@ladybird.org> | 
					
						
							| 
									
										
										
										
											2021-07-11 21:04:11 +03:00
										 |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-24 16:01:24 +02:00
										 |  |  | #include <LibJS/Runtime/PropertyKey.h>
 | 
					
						
							| 
									
										
										
										
											2021-07-11 21:04:11 +03:00
										 |  |  | #include <LibJS/Runtime/Temporal/AbstractOperations.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace JS::Temporal { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-16 13:14:14 -05:00
										 |  |  | // 14.4.1.1 GetOptionsObject ( options ), https://tc39.es/proposal-temporal/#sec-getoptionsobject
 | 
					
						
							| 
									
										
										
										
											2022-08-20 08:52:42 +01:00
										 |  |  | ThrowCompletionOr<Object*> get_options_object(VM& vm, Value options) | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-08-20 08:52:42 +01:00
										 |  |  |     auto& realm = *vm.current_realm(); | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // 1. If options is undefined, then
 | 
					
						
							|  |  |  |     if (options.is_undefined()) { | 
					
						
							| 
									
										
										
										
											2022-03-10 18:05:50 +01:00
										 |  |  |         // a. Return OrdinaryObjectCreate(null).
 | 
					
						
							| 
									
										
										
										
											2022-12-13 20:49:50 +00:00
										 |  |  |         return Object::create(realm, nullptr).ptr(); | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-16 13:14:14 -05:00
										 |  |  |     // 2. If options is an Object, then
 | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  |     if (options.is_object()) { | 
					
						
							|  |  |  |         // a. Return options.
 | 
					
						
							|  |  |  |         return &options.as_object(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // 3. Throw a TypeError exception.
 | 
					
						
							| 
									
										
										
										
											2022-08-16 20:33:17 +01:00
										 |  |  |     return vm.throw_completion<TypeError>(ErrorType::NotAnObject, "Options"); | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-16 13:14:14 -05:00
										 |  |  | // 14.4.1.2 GetOption ( options, property, type, values, default ), https://tc39.es/proposal-temporal/#sec-getoption
 | 
					
						
							| 
									
										
										
										
											2023-02-05 19:02:54 +00:00
										 |  |  | ThrowCompletionOr<Value> get_option(VM& vm, Object const& options, PropertyKey const& property, OptionType type, ReadonlySpan<StringView> values, OptionDefault const& default_) | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-08-18 20:27:44 +01:00
										 |  |  |     VERIFY(property.is_string()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-14 23:03:25 +01:00
										 |  |  |     // 1. Let value be ? Get(options, property).
 | 
					
						
							| 
									
										
										
										
											2021-10-02 23:52:27 +01:00
										 |  |  |     auto value = TRY(options.get(property)); | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-14 23:03:25 +01:00
										 |  |  |     // 2. If value is undefined, then
 | 
					
						
							|  |  |  |     if (value.is_undefined()) { | 
					
						
							| 
									
										
										
										
											2024-11-16 13:14:14 -05:00
										 |  |  |         // a. If default is REQUIRED, throw a RangeError exception.
 | 
					
						
							|  |  |  |         if (default_.has<DefaultRequired>()) | 
					
						
							| 
									
										
										
										
											2022-08-16 20:33:17 +01:00
										 |  |  |             return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, "undefined"sv, property.as_string()); | 
					
						
							| 
									
										
										
										
											2022-06-14 23:03:25 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // b. Return default.
 | 
					
						
							|  |  |  |         return default_.visit( | 
					
						
							| 
									
										
										
										
											2024-11-16 13:14:14 -05:00
										 |  |  |             [](DefaultRequired) -> Value { VERIFY_NOT_REACHED(); }, | 
					
						
							|  |  |  |             [](Empty) -> Value { return js_undefined(); }, | 
					
						
							|  |  |  |             [](bool default_) -> Value { return Value { default_ }; }, | 
					
						
							|  |  |  |             [](double default_) -> Value { return Value { default_ }; }, | 
					
						
							|  |  |  |             [&](StringView default_) -> Value { return PrimitiveString::create(vm, default_); }); | 
					
						
							| 
									
										
										
										
											2022-06-14 23:03:25 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-16 13:14:14 -05:00
										 |  |  |     // 3. If type is BOOLEAN, then
 | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  |     if (type == OptionType::Boolean) { | 
					
						
							| 
									
										
										
										
											2022-03-10 18:05:50 +01:00
										 |  |  |         // a. Set value to ToBoolean(value).
 | 
					
						
							| 
									
										
										
										
											2024-11-16 13:14:14 -05:00
										 |  |  |         value = Value { value.to_boolean() }; | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-11-16 13:14:14 -05:00
										 |  |  |     // 4. Else,
 | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  |     else { | 
					
						
							| 
									
										
										
										
											2024-11-16 13:14:14 -05:00
										 |  |  |         // a. Assert: type is STRING.
 | 
					
						
							| 
									
										
										
										
											2022-06-14 22:17:11 +01:00
										 |  |  |         VERIFY(type == OptionType::String); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // b. Set value to ? ToString(value).
 | 
					
						
							| 
									
										
										
										
											2022-08-21 14:00:56 +01:00
										 |  |  |         value = TRY(value.to_primitive_string(vm)); | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-16 13:14:14 -05:00
										 |  |  |     // 5. If values is not EMPTY and values does not contain value, throw a RangeError exception.
 | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  |     if (!values.is_empty()) { | 
					
						
							| 
									
										
										
										
											2022-06-14 22:17:11 +01:00
										 |  |  |         // NOTE: Every location in the spec that invokes GetOption with type=boolean also has values=undefined.
 | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  |         VERIFY(value.is_string()); | 
					
						
							| 
									
										
										
										
											2024-11-16 13:14:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-08 19:17:55 +02:00
										 |  |  |         if (auto value_string = value.as_string().utf8_string(); !values.contains_slow(value_string)) | 
					
						
							| 
									
										
										
										
											2023-01-07 12:24:05 -05:00
										 |  |  |             return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, value_string, property.as_string()); | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-16 13:14:14 -05:00
										 |  |  |     // 6. Return value.
 | 
					
						
							| 
									
										
										
										
											2021-07-11 22:28:49 +03:00
										 |  |  |     return value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-11 21:04:11 +03:00
										 |  |  | } |