summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/dts/lib.deno.ns.d.ts2
-rw-r--r--cli/rt/02_console.js19
-rw-r--r--cli/tests/unit/console_test.ts47
-rw-r--r--core/bindings.rs61
4 files changed, 127 insertions, 2 deletions
diff --git a/cli/dts/lib.deno.ns.d.ts b/cli/dts/lib.deno.ns.d.ts
index 15b390fd1..141e66a24 100644
--- a/cli/dts/lib.deno.ns.d.ts
+++ b/cli/dts/lib.deno.ns.d.ts
@@ -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
diff --git a/cli/rt/02_console.js b/cli/rt/02_console.js
index e3492772d..00ecd3aac 100644
--- a/cli/rt/02_console.js
+++ b/cli/rt/02_console.js
@@ -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,
diff --git a/cli/tests/unit/console_test.ts b/cli/tests/unit/console_test.ts
index 3d1ace6bd..384b5d2c8 100644
--- a/cli/tests/unit/console_test.ts
+++ b/cli/tests/unit/console_test.ts
@@ -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] } ]",
+ );
+});
diff --git a/core/bindings.rs b/core/bindings.rs
index 55cb080f6..0a755c298 100644
--- a/core/bindings.rs
+++ b/core/bindings.rs
@@ -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>,