提交 f0a23556 编写于 作者: K Kitson Kelly 提交者: Ryan Dahl

Support custom inspection of objects (#2791)

上级 4faab6a7
......@@ -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(...)`;
......
......@@ -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");
......
......@@ -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[] = [];
......
// 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.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册