1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-22 15:06:54 -05:00

feat(console): print proxy details (#7139)

This commit is contained in:
uki00a 2020-09-08 23:06:26 +09:00 committed by GitHub
parent 6ff9395532
commit ac455050ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 127 additions and 2 deletions

View file

@ -1952,6 +1952,8 @@ declare namespace Deno {
compact?: boolean;
/** The maximum number of iterable entries to print. Defaults to 100. */
iterableLimit?: number;
/** Show a Proxy's target and handler. Defaults to false. */
showProxy?: boolean;
}
/** Converts the input into a string that has the same format as printed by

View file

@ -154,6 +154,7 @@
trailingComma: false,
compact: true,
iterableLimit: 100,
showProxy: false,
};
const DEFAULT_INDENT = " "; // Default indent string
@ -400,6 +401,13 @@
level,
inspectOptions,
) {
const proxyDetails = Deno.core.getProxyDetails(value);
if (proxyDetails != null) {
return inspectOptions.showProxy
? inspectProxy(proxyDetails, ctx, level, inspectOptions)
: inspectValue(proxyDetails[0], ctx, level, inspectOptions);
}
switch (typeof value) {
case "string":
return value;
@ -657,7 +665,16 @@
return `Promise { ${str} }`;
}
// TODO: Proxy
function inspectProxy(
targetAndHandler,
ctx,
level,
inspectOptions,
) {
return `Proxy ${
inspectArray(targetAndHandler, ctx, level, inspectOptions)
}`;
}
function inspectRawObject(
value,

View file

@ -1367,3 +1367,50 @@ unitTest(function inspectIterableLimit(): void {
`Map { "a" => 1, "b" => 2, ... 1 more items }`,
);
});
unitTest(function inspectProxy(): void {
assertEquals(
Deno.inspect(
new Proxy([1, 2, 3], { get(): void {} }),
),
"[ 1, 2, 3 ]",
);
assertEquals(
Deno.inspect(
new Proxy({ key: "value" }, { get(): void {} }),
),
`{ key: "value" }`,
);
assertEquals(
Deno.inspect(new Proxy([1, 2, 3], { get(): void {} }), { showProxy: true }),
"Proxy [ [ 1, 2, 3 ], { get: [Function: get] } ]",
);
assertEquals(
Deno.inspect(
new Proxy({ a: 1 }, {
set(): boolean {
return false;
},
}),
{ showProxy: true },
),
"Proxy [ { a: 1 }, { set: [Function: set] } ]",
);
assertEquals(
Deno.inspect(
new Proxy([1, 2, 3, 4, 5, 6, 7], { get(): void {} }),
{ showProxy: true },
),
`Proxy [ [
1, 2, 3, 4,
5, 6, 7
], { get: [Function: get] } ]`,
);
assertEquals(
Deno.inspect(
new Proxy(function fn() {}, { get(): void {} }),
{ showProxy: true },
),
"Proxy [ [Function: fn], { get: [Function: get] } ]",
);
});

View file

@ -50,7 +50,10 @@ lazy_static! {
},
v8::ExternalReference {
function: get_promise_details.map_fn_to()
}
},
v8::ExternalReference {
function: get_proxy_details.map_fn_to()
},
]);
}
@ -181,6 +184,18 @@ pub fn initialize_context<'s>(
get_promise_details_val.into(),
);
let get_proxy_details_key =
v8::String::new(scope, "getProxyDetails").unwrap();
let get_proxy_details_tmpl =
v8::FunctionTemplate::new(scope, get_proxy_details);
let get_proxy_details_val =
get_proxy_details_tmpl.get_function(scope).unwrap();
core_val.set(
scope,
get_proxy_details_key.into(),
get_proxy_details_val.into(),
);
let shared_key = v8::String::new(scope, "shared").unwrap();
core_val.set_accessor(scope, shared_key.into(), shared_getter);
@ -797,6 +812,50 @@ fn get_promise_details(
}
}
// Based on https://github.com/nodejs/node/blob/1e470510ff74391d7d4ec382909ea8960d2d2fbc/src/node_util.cc
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
fn get_proxy_details(
scope: &mut v8::HandleScope,
args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue,
) {
// Return undefined if it's not a proxy.
let proxy = match v8::Local::<v8::Proxy>::try_from(args.get(0)) {
Ok(val) => val,
Err(_) => {
return;
}
};
let proxy_details = v8::Array::new(scope, 2);
let js_zero = v8::Integer::new(scope, 0);
let js_one = v8::Integer::new(scope, 1);
let target = proxy.get_target(scope);
let handler = proxy.get_handler(scope);
proxy_details.set(scope, js_zero.into(), target);
proxy_details.set(scope, js_one.into(), handler);
rv.set(proxy_details.into());
}
fn throw_type_error<'s>(
scope: &mut v8::HandleScope<'s>,
message: impl AsRef<str>,