summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKitson Kelly <me@kitsonkelly.com>2019-08-20 01:35:43 +1000
committerRyan Dahl <ry@tinyclouds.org>2019-08-19 11:35:43 -0400
commitf0a235563e1eb748f4030d19af3f9a5ac59d2550 (patch)
treeb6753890b2baf6224c9facceb86d5ccf9f52ad44
parent4faab6a74b0f583bba5ebcc877c6ea1407d360e3 (diff)
Support custom inspection of objects (#2791)
-rw-r--r--js/console.ts9
-rw-r--r--js/console_test.ts21
-rw-r--r--js/deno.ts2
-rw-r--r--js/globals.ts10
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.