diff options
author | Kitson Kelly <me@kitsonkelly.com> | 2019-08-20 01:35:43 +1000 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2019-08-19 11:35:43 -0400 |
commit | f0a235563e1eb748f4030d19af3f9a5ac59d2550 (patch) | |
tree | b6753890b2baf6224c9facceb86d5ccf9f52ad44 | |
parent | 4faab6a74b0f583bba5ebcc877c6ea1407d360e3 (diff) |
Support custom inspection of objects (#2791)
-rw-r--r-- | js/console.ts | 9 | ||||
-rw-r--r-- | js/console_test.ts | 21 | ||||
-rw-r--r-- | js/deno.ts | 2 | ||||
-rw-r--r-- | js/globals.ts | 10 |
4 files changed, 35 insertions, 7 deletions
diff --git a/js/console.ts b/js/console.ts index 002be6e2f..ed2543a9d 100644 --- a/js/console.ts +++ b/js/console.ts @@ -326,7 +326,9 @@ function createObjectString( value: {}, ...args: [ConsoleContext, number, number] ): string { - if (value instanceof Error) { + if (customInspect in value && typeof value[customInspect] === "function") { + return String(value[customInspect]!()); + } else if (value instanceof Error) { return String(value.stack); } else if (Array.isArray(value)) { return createArrayString(value, ...args); @@ -752,6 +754,11 @@ export class Console { } } +/** A symbol which can be used as a key for a custom method which will be called + * when `Deno.inspect()` is called, or when the object is logged to the console. + */ +export const customInspect = Symbol.for("Deno.customInspect"); + /** * `inspect()` converts input into string that has the same format * as printed by `console.log(...)`; diff --git a/js/console_test.ts b/js/console_test.ts index 8070ee0f0..a2f9280a1 100644 --- a/js/console_test.ts +++ b/js/console_test.ts @@ -3,8 +3,15 @@ import { assert, assertEquals, test } from "./test_util.ts"; // Some of these APIs aren't exposed in the types and so we have to cast to any // in order to "trick" TypeScript. -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const { Console, stringifyArgs, inspect, write, stdout } = Deno as any; +const { + Console, + customInspect, + stringifyArgs, + inspect, + write, + stdout + // eslint-disable-next-line @typescript-eslint/no-explicit-any +} = Deno as any; function stringify(...args: unknown[]): string { return stringifyArgs(args).replace(/\n$/, ""); @@ -173,6 +180,16 @@ test(function consoleTestStringifyWithDepth(): void { ); }); +test(function consoleTestWithCustomInspector(): void { + class A { + [customInspect](): string { + return "b"; + } + } + + assertEquals(stringify(new A()), "b"); +}); + test(function consoleTestWithIntegerFormatSpecifier(): void { assertEquals(stringify("%i"), "%i"); assertEquals(stringify("%i", 42.0), "42"); diff --git a/js/deno.ts b/js/deno.ts index 8dc4fd791..65a93c467 100644 --- a/js/deno.ts +++ b/js/deno.ts @@ -79,7 +79,7 @@ export { ProcessStatus, Signal } from "./process"; -export { inspect } from "./console"; +export { inspect, customInspect } from "./console"; export { build, platform, OperatingSystem, Arch } from "./build"; export { version } from "./version"; export const args: string[] = []; diff --git a/js/globals.ts b/js/globals.ts index 92e4662aa..93495ff18 100644 --- a/js/globals.ts +++ b/js/globals.ts @@ -1,6 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. // This is a "special" module, in that it define the global runtime scope of -// Deno, and therefore it defines a lot of the runtime environemnt that code +// Deno, and therefore it defines a lot of the runtime environment that code // is evaluated in. We use this file to automatically build the runtime type // library. @@ -12,7 +12,7 @@ import * as blob from "./blob"; import * as consoleTypes from "./console"; import * as csprng from "./get_random_values"; import * as customEvent from "./custom_event"; -import * as deno from "./deno"; +import * as Deno from "./deno"; import * as domTypes from "./dom_types"; import * as domFile from "./dom_file"; import * as event from "./event"; @@ -62,6 +62,10 @@ declare global { interface ErrorConstructor { prepareStackTrace(error: Error, structuredStackTrace: CallSite[]): string; } + + interface Object { + [consoleTypes.customInspect]?(): string; + } } // A self reference to the global object. @@ -70,7 +74,7 @@ window.window = window; // This is the Deno namespace, it is handled differently from other window // properties when building the runtime type library, as the whole module // is flattened into a single namespace. -window.Deno = deno; +window.Deno = Deno; Object.freeze(window.Deno); // Globally available functions and object instances. |