浏览代码

LibJS: Add spec comments to Value::to_primitive()

Linus Groh 2 年之前
父节点
当前提交
9c10624278
共有 1 个文件被更改,包括 36 次插入16 次删除
  1. 36 16
      Userland/Libraries/LibJS/Runtime/Value.cpp

+ 36 - 16
Userland/Libraries/LibJS/Runtime/Value.cpp

@@ -466,31 +466,51 @@ bool Value::to_boolean() const
 // 7.1.1 ToPrimitive ( input [ , preferredType ] ), https://tc39.es/ecma262/#sec-toprimitive
 ThrowCompletionOr<Value> Value::to_primitive(VM& vm, PreferredType preferred_type) const
 {
-    auto get_hint_for_preferred_type = [&]() -> DeprecatedString {
-        switch (preferred_type) {
-        case PreferredType::Default:
-            return "default";
-        case PreferredType::String:
-            return "string";
-        case PreferredType::Number:
-            return "number";
-        default:
-            VERIFY_NOT_REACHED();
-        }
-    };
+    // 1. If input is an Object, then
     if (is_object()) {
-        auto to_primitive_method = TRY(get_method(vm, *vm.well_known_symbol_to_primitive()));
-        if (to_primitive_method) {
-            auto hint = get_hint_for_preferred_type();
-            auto result = TRY(call(vm, *to_primitive_method, *this, PrimitiveString::create(vm, hint)));
+        // a. Let exoticToPrim be ? GetMethod(input, @@toPrimitive).
+        auto* exotic_to_primitive = TRY(get_method(vm, *vm.well_known_symbol_to_primitive()));
+
+        // b. If exoticToPrim is not undefined, then
+        if (exotic_to_primitive) {
+            auto hint = [&]() -> DeprecatedString {
+                switch (preferred_type) {
+                // i. If preferredType is not present, let hint be "default".
+                case PreferredType::Default:
+                    return "default";
+                // ii. Else if preferredType is string, let hint be "string".
+                case PreferredType::String:
+                    return "string";
+                // iii. Else,
+                // 1. Assert: preferredType is number.
+                // 2. Let hint be "number".
+                case PreferredType::Number:
+                    return "number";
+                default:
+                    VERIFY_NOT_REACHED();
+                }
+            }();
+
+            // iv. Let result be ? Call(exoticToPrim, input, « hint »).
+            auto result = TRY(call(vm, *exotic_to_primitive, *this, PrimitiveString::create(vm, hint)));
+
+            // v. If result is not an Object, return result.
             if (!result.is_object())
                 return result;
+
+            // vi. Throw a TypeError exception.
             return vm.throw_completion<TypeError>(ErrorType::ToPrimitiveReturnedObject, to_string_without_side_effects(), hint);
         }
+
+        // c. If preferredType is not present, let preferredType be number.
         if (preferred_type == PreferredType::Default)
             preferred_type = PreferredType::Number;
+
+        // d. Return ? OrdinaryToPrimitive(input, preferredType).
         return as_object().ordinary_to_primitive(preferred_type);
     }
+
+    // 2. Return input.
     return *this;
 }