Sfoglia il codice sorgente

LibJS: Change non-ScriptFunction source string to "[native code]"

https://tc39.es/ecma262/#sec-function.prototype.tostring - this is how
the spec wants us to do it. :^)

Also change the function name behaviour to only provide a name for
NativeFunctions, which matches other engines - presumably to not expose
Proxy objects, and to prevent "function bound foo() { [native code] }".
Linus Groh 4 anni fa
parent
commit
202f855055

+ 11 - 4
Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp

@@ -142,8 +142,8 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::to_string)
         vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Function");
         return {};
     }
-    String function_name = static_cast<Function*>(this_object)->name();
-    String function_parameters = "";
+    String function_name;
+    String function_parameters;
     String function_body;
 
     if (is<ScriptFunction>(this_object)) {
@@ -160,18 +160,25 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::to_string)
                 parameters_builder.append(" = TODO");
             }
         }
+        function_name = script_function.name();
         function_parameters = parameters_builder.build();
         // FIXME: ASTNodes should be able to dump themselves to source strings - something like this:
         // auto& body = static_cast<ScriptFunction*>(this_object)->body();
         // function_body = body.to_source();
         function_body = "  ???";
     } else {
-        function_body = String::formatted("  [{}]", this_object->class_name());
+        // This is "implementation-defined" - other engines don't include a name for
+        // ProxyObject and BoundFunction, only NativeFunction - let's do the same here.
+        if (is<NativeFunction>(this_object))
+            function_name = static_cast<NativeFunction&>(*this_object).name();
+        function_body = "  [native code]";
     }
 
     auto function_source = String::formatted(
         "function {}({}) {{\n{}\n}}",
-        function_name.is_null() ? "" : function_name, function_parameters, function_body);
+        function_name.is_null() ? "" : function_name,
+        function_parameters.is_null() ? "" : function_parameters,
+        function_body);
     return js_string(vm, function_source);
 }
 

+ 2 - 2
Userland/Libraries/LibJS/Tests/builtins/Function/Function.prototype.toString.js

@@ -12,6 +12,6 @@ test("basic functionality", () => {
             return bar + 42;
         }.toString()
     ).toBe("function (foo, bar, baz) {\n  ???\n}");
-    expect(console.debug.toString()).toBe("function debug() {\n  [NativeFunction]\n}");
-    expect(Function.toString()).toBe("function Function() {\n  [FunctionConstructor]\n}");
+    expect(console.debug.toString()).toBe("function debug() {\n  [native code]\n}");
+    expect(Function.toString()).toBe("function Function() {\n  [native code]\n}");
 });