diff options
author | 2023-07-11 12:48:19 -0700 | |
---|---|---|
committer | 2023-07-11 12:48:19 -0700 | |
commit | 31ab56d36238528c6f44c52a6cbf600744a91f0a (patch) | |
tree | 262d70003271800a6c2c7e9c72316ae82d037986 | |
parent | 4b333b2d3571a106e8a028ce62bf5149954d38f0 (diff) | |
download | bun-31ab56d36238528c6f44c52a6cbf600744a91f0a.tar.gz bun-31ab56d36238528c6f44c52a6cbf600744a91f0a.tar.zst bun-31ab56d36238528c6f44c52a6cbf600744a91f0a.zip |
Fix: console.log with class constructors (#3602)
* Fix console.log with class constructors
* oops
* fix it
* lol
* fix test
-rw-r--r-- | src/bun.js/bindings/bindings.cpp | 14 | ||||
-rw-r--r-- | src/bun.js/bindings/exports.zig | 37 | ||||
-rw-r--r-- | src/bun.js/test/pretty_format.zig | 42 | ||||
-rw-r--r-- | test/js/web/console/console-log.expected.txt | 8 | ||||
-rw-r--r-- | test/js/web/console/console-log.js | 6 |
5 files changed, 65 insertions, 42 deletions
diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index 9f9b20c1e..d311072e4 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -2775,8 +2775,18 @@ void JSC__JSValue__put(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, const Z bool JSC__JSValue__isClass(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1) { - JSC::JSValue value = JSC::JSValue::decode(JSValue0); - return value.isConstructor(); + JSValue value = JSValue::decode(JSValue0); + auto callData = getCallData(value); + + switch (callData.type) { + case CallData::Type::JS: + return callData.js.functionExecutable->isClassConstructorFunction(); + case CallData::Type::Native: + if (callData.native.isBoundFunction) + return false; + return value.isConstructor(); + } + return false; } bool JSC__JSValue__isCell(JSC__JSValue JSValue0) { return JSC::JSValue::decode(JSValue0).isCell(); } bool JSC__JSValue__isCustomGetterSetter(JSC__JSValue JSValue0) diff --git a/src/bun.js/bindings/exports.zig b/src/bun.js/bindings/exports.zig index 73a26e4be..db6de2ef3 100644 --- a/src/bun.js/bindings/exports.zig +++ b/src/bun.js/bindings/exports.zig @@ -1417,23 +1417,20 @@ pub const ZigConsoleClient = struct { // If we check an Object has a method table and it does not // it will crash - const callable = js_type != .Object and value.isCallable(globalThis.vm()); - - if (value.isClass(globalThis) and !callable) { - return .{ - .tag = .Object, - .cell = js_type, - }; - } + if (js_type != .Object and value.isCallable(globalThis.vm())) { + if (value.isClass(globalThis)) { + return .{ + .tag = .Class, + .cell = js_type, + }; + } - if (callable and js_type == .JSFunction) { - return .{ - .tag = .Function, - .cell = js_type, - }; - } else if (callable and js_type == .InternalFunction) { return .{ - .tag = .Object, + // TODO: we print InternalFunction as Object because we have a lot of + // callable namespaces and printing the contents of it is better than [Function: namespace] + // ideally, we would print [Function: namespace] { ... } on all functions, internal and js. + // what we'll do later is rid of .Function and .Class and handle the prefix in the .Object formatter + .tag = if (js_type == .InternalFunction) .Object else .Function, .cell = js_type, }; } @@ -1756,7 +1753,7 @@ pub const ZigConsoleClient = struct { parent: JSValue, const enable_ansi_colors = enable_ansi_colors_; pub fn handleFirstProperty(this: *@This(), globalThis: *JSC.JSGlobalObject, value: JSValue) void { - if (!value.jsType().isFunction() and !value.isClass(globalThis)) { + if (!value.jsType().isFunction()) { var writer = WrappedWriter(Writer){ .ctx = this.writer, .failed = false, @@ -2094,9 +2091,9 @@ pub const ZigConsoleClient = struct { this.addForNewLine(printable.len); if (printable.len == 0) { - writer.print(comptime Output.prettyFmt("[class]", enable_ansi_colors), .{}); + writer.print(comptime Output.prettyFmt("<cyan>[class]<r>", enable_ansi_colors), .{}); } else { - writer.print(comptime Output.prettyFmt("[class <cyan>{}<r>]", enable_ansi_colors), .{printable}); + writer.print(comptime Output.prettyFmt("<cyan>[class {}]<r>", enable_ansi_colors), .{printable}); } }, .Function => { @@ -2106,7 +2103,7 @@ pub const ZigConsoleClient = struct { if (printable.len == 0) { writer.print(comptime Output.prettyFmt("<cyan>[Function]<r>", enable_ansi_colors), .{}); } else { - writer.print(comptime Output.prettyFmt("<cyan>[Function<d>:<r> <cyan>{}]<r>", enable_ansi_colors), .{printable}); + writer.print(comptime Output.prettyFmt("<cyan>[Function: {}]<r>", enable_ansi_colors), .{printable}); } }, .Getter => { @@ -2802,7 +2799,7 @@ pub const ZigConsoleClient = struct { } if (iter.i == 0) { - if (value.isClass(this.globalThis) and !value.isCallable(this.globalThis.vm())) + if (value.isClass(this.globalThis)) this.printAs(.Class, Writer, writer_, value, jsType, enable_ansi_colors) else if (value.isCallable(this.globalThis.vm())) this.printAs(.Function, Writer, writer_, value, jsType, enable_ansi_colors) diff --git a/src/bun.js/test/pretty_format.zig b/src/bun.js/test/pretty_format.zig index 4a245c3bb..a6c6aa631 100644 --- a/src/bun.js/test/pretty_format.zig +++ b/src/bun.js/test/pretty_format.zig @@ -423,23 +423,20 @@ pub const JestPrettyFormat = struct { // If we check an Object has a method table and it does not // it will crash - const callable = js_type != .Object and value.isCallable(globalThis.vm()); + if (js_type != .Object and value.isCallable(globalThis.vm())) { + if (value.isClass(globalThis)) { + return .{ + .tag = .Class, + .cell = js_type, + }; + } - if (value.isClass(globalThis) and !callable) { return .{ - .tag = .Object, - .cell = js_type, - }; - } - - if (callable and js_type == .JSFunction) { - return .{ - .tag = .Function, - .cell = js_type, - }; - } else if (callable and js_type == .InternalFunction) { - return .{ - .tag = .Object, + // TODO: we print InternalFunction as Object because we have a lot of + // callable namespaces and printing the contents of it is better than [Function: namespace] + // ideally, we would print [Function: namespace] { ... } on all functions, internal and js. + // what we'll do later is rid of .Function and .Class and handle the prefix in the .Object formatter + .tag = if (js_type == .InternalFunction) .Object else .Function, .cell = js_type, }; } @@ -750,7 +747,7 @@ pub const JestPrettyFormat = struct { parent: JSValue, const enable_ansi_colors = enable_ansi_colors_; pub fn handleFirstProperty(this: *@This(), globalThis: *JSC.JSGlobalObject, value: JSValue) void { - if (!value.jsType().isFunction() and !value.isClass(globalThis)) { + if (!value.jsType().isFunction()) { var writer = WrappedWriter(Writer){ .ctx = this.writer, .failed = false, @@ -1126,13 +1123,20 @@ pub const JestPrettyFormat = struct { this.addForNewLine(printable.len); if (printable.len == 0) { - writer.print(comptime Output.prettyFmt("[class]", enable_ansi_colors), .{}); + writer.print(comptime Output.prettyFmt("<cyan>[class]<r>", enable_ansi_colors), .{}); } else { - writer.print(comptime Output.prettyFmt("[class <cyan>{}<r>]", enable_ansi_colors), .{printable}); + writer.print(comptime Output.prettyFmt("<cyan>[class {}]<r>", enable_ansi_colors), .{printable}); } }, .Function => { - writer.writeAll("[Function]"); + var printable = ZigString.init(&name_buf); + value.getNameProperty(this.globalThis, &printable); + + if (printable.len == 0) { + writer.print(comptime Output.prettyFmt("<cyan>[Function]<r>", enable_ansi_colors), .{}); + } else { + writer.print(comptime Output.prettyFmt("<cyan>[Function: {}]<r>", enable_ansi_colors), .{printable}); + } }, .Array => { const len = @truncate(u32, value.getLength(this.globalThis)); diff --git a/test/js/web/console/console-log.expected.txt b/test/js/web/console/console-log.expected.txt index 97191c8be..332322665 100644 --- a/test/js/web/console/console-log.expected.txt +++ b/test/js/web/console/console-log.expected.txt @@ -1,4 +1,6 @@ Hello World! +0 +-0 123 -123 123.567 @@ -7,6 +9,8 @@ true false null undefined +Infinity +-Infinity Symbol(Symbol Description) 2000-06-27T02:24:34.304Z [ 123, 456, 789 ] @@ -29,7 +33,9 @@ Symbol(Symbol Description) } Promise { <pending> } [Function] -[Function: Foo] +[Function] +[class Foo] +[class] {} [Function: foooo] /FooRegex/ diff --git a/test/js/web/console/console-log.js b/test/js/web/console/console-log.js index e23a3e9cb..4db40aaac 100644 --- a/test/js/web/console/console-log.js +++ b/test/js/web/console/console-log.js @@ -1,4 +1,6 @@ console.log("Hello World!"); +console.log(0); +console.log(-0); console.log(123); console.log(-123); console.log(123.567); @@ -7,6 +9,8 @@ console.log(true); console.log(false); console.log(null); console.log(undefined); +console.log(Infinity); +console.log(-Infinity); console.log(Symbol("Symbol Description")); console.log(new Date(Math.pow(2, 34) * 56)); console.log([123, 456, 789]); @@ -27,7 +31,9 @@ console.log(new Promise(() => {})); class Foo {} console.log(() => {}); +console.log(function () {}); console.log(Foo); +console.log(class {}); console.log(new Foo()); console.log(function foooo() {}); |