0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-02-01 20:25:12 -05:00

Support custom inspection of objects (#2791)

This commit is contained in:
Kitson Kelly 2019-08-20 01:35:43 +10:00 committed by Ryan Dahl
parent 4faab6a74b
commit f0a235563e
4 changed files with 35 additions and 7 deletions

View file

@ -326,7 +326,9 @@ function createObjectString(
value: {}, value: {},
...args: [ConsoleContext, number, number] ...args: [ConsoleContext, number, number]
): string { ): 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); return String(value.stack);
} else if (Array.isArray(value)) { } else if (Array.isArray(value)) {
return createArrayString(value, ...args); 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 * `inspect()` converts input into string that has the same format
* as printed by `console.log(...)`; * as printed by `console.log(...)`;

View file

@ -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 // Some of these APIs aren't exposed in the types and so we have to cast to any
// in order to "trick" TypeScript. // in order to "trick" TypeScript.
// eslint-disable-next-line @typescript-eslint/no-explicit-any const {
const { Console, stringifyArgs, inspect, write, stdout } = Deno as any; Console,
customInspect,
stringifyArgs,
inspect,
write,
stdout
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} = Deno as any;
function stringify(...args: unknown[]): string { function stringify(...args: unknown[]): string {
return stringifyArgs(args).replace(/\n$/, ""); 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 { test(function consoleTestWithIntegerFormatSpecifier(): void {
assertEquals(stringify("%i"), "%i"); assertEquals(stringify("%i"), "%i");
assertEquals(stringify("%i", 42.0), "42"); assertEquals(stringify("%i", 42.0), "42");

View file

@ -79,7 +79,7 @@ export {
ProcessStatus, ProcessStatus,
Signal Signal
} from "./process"; } from "./process";
export { inspect } from "./console"; export { inspect, customInspect } from "./console";
export { build, platform, OperatingSystem, Arch } from "./build"; export { build, platform, OperatingSystem, Arch } from "./build";
export { version } from "./version"; export { version } from "./version";
export const args: string[] = []; export const args: string[] = [];

View file

@ -1,6 +1,6 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. // 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 // 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 // is evaluated in. We use this file to automatically build the runtime type
// library. // library.
@ -12,7 +12,7 @@ import * as blob from "./blob";
import * as consoleTypes from "./console"; import * as consoleTypes from "./console";
import * as csprng from "./get_random_values"; import * as csprng from "./get_random_values";
import * as customEvent from "./custom_event"; import * as customEvent from "./custom_event";
import * as deno from "./deno"; import * as Deno from "./deno";
import * as domTypes from "./dom_types"; import * as domTypes from "./dom_types";
import * as domFile from "./dom_file"; import * as domFile from "./dom_file";
import * as event from "./event"; import * as event from "./event";
@ -62,6 +62,10 @@ declare global {
interface ErrorConstructor { interface ErrorConstructor {
prepareStackTrace(error: Error, structuredStackTrace: CallSite[]): string; prepareStackTrace(error: Error, structuredStackTrace: CallSite[]): string;
} }
interface Object {
[consoleTypes.customInspect]?(): string;
}
} }
// A self reference to the global object. // 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 // This is the Deno namespace, it is handled differently from other window
// properties when building the runtime type library, as the whole module // properties when building the runtime type library, as the whole module
// is flattened into a single namespace. // is flattened into a single namespace.
window.Deno = deno; window.Deno = Deno;
Object.freeze(window.Deno); Object.freeze(window.Deno);
// Globally available functions and object instances. // Globally available functions and object instances.