summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2020-03-11 15:49:53 +0100
committerGitHub <noreply@github.com>2020-03-11 15:49:53 +0100
commit2d1b39bef339edb19ae6be5fb2099e685cee93bb (patch)
tree4e1664f50e079e2f258d86cb0e4a1160fb6b3d7b
parent99a0c6df79b903e4fe72ce066787039bdede3868 (diff)
reorg: remove dispatch.ts, move signals, factor out web utils (#4316)
- moves signal definition from "cli/js/process.ts" to "cli/js/signals.ts" - removes "cli/js/dispatch.ts" - removes "cli/js/types.ts" - moves web specific utilities to "cli/js/web/util.ts"
-rw-r--r--cli/js/deno.ts4
-rw-r--r--cli/js/dispatch.ts23
-rw-r--r--cli/js/ops/os.ts3
-rw-r--r--cli/js/process.ts83
-rw-r--r--cli/js/runtime.ts15
-rw-r--r--cli/js/runtime_main.ts2
-rw-r--r--cli/js/signals.ts83
-rw-r--r--cli/js/types.ts2
-rw-r--r--cli/js/util.ts67
-rw-r--r--cli/js/web/console.ts3
-rw-r--r--cli/js/web/console_table.ts2
-rw-r--r--cli/js/web/custom_event.ts2
-rw-r--r--cli/js/web/dom_iterable.ts2
-rw-r--r--cli/js/web/event.ts2
-rw-r--r--cli/js/web/event_target.ts2
-rw-r--r--cli/js/web/fetch.ts8
-rw-r--r--cli/js/web/form_data.ts2
-rw-r--r--cli/js/web/headers.ts2
-rw-r--r--cli/js/web/url_search_params.ts2
-rw-r--r--cli/js/web/util.ts78
20 files changed, 188 insertions, 199 deletions
diff --git a/cli/js/deno.ts b/cli/js/deno.ts
index 4f56bb7d1..2ecd7680c 100644
--- a/cli/js/deno.ts
+++ b/cli/js/deno.ts
@@ -99,7 +99,7 @@ export {
} from "./permissions.ts";
export { openPlugin } from "./plugins.ts";
export { kill } from "./ops/process.ts";
-export { run, RunOptions, Process, ProcessStatus, Signal } from "./process.ts";
+export { run, RunOptions, Process, ProcessStatus } from "./process.ts";
export { readdirSync, readdir } from "./ops/fs/read_dir.ts";
export { readFileSync, readFile } from "./read_file.ts";
export { readlinkSync, readlink } from "./ops/fs/read_link.ts";
@@ -107,7 +107,7 @@ export { realpathSync, realpath } from "./ops/fs/realpath.ts";
export { removeSync, remove, RemoveOptions } from "./ops/fs/remove.ts";
export { renameSync, rename } from "./ops/fs/rename.ts";
export { resources, close } from "./ops/resources.ts";
-export { signal, signals, SignalStream } from "./signals.ts";
+export { signal, signals, Signal, SignalStream } from "./signals.ts";
export { statSync, lstatSync, stat, lstat } from "./ops/fs/stat.ts";
export { symlinkSync, symlink } from "./ops/fs/symlink.ts";
export { connectTLS, listenTLS } from "./tls.ts";
diff --git a/cli/js/dispatch.ts b/cli/js/dispatch.ts
deleted file mode 100644
index f3c92dbc6..000000000
--- a/cli/js/dispatch.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-import * as minimal from "./ops/dispatch_minimal.ts";
-import * as json from "./ops/dispatch_json.ts";
-import { AsyncHandler } from "./plugins.ts";
-
-const PLUGIN_ASYNC_HANDLER_MAP: Map<number, AsyncHandler> = new Map();
-
-export function setPluginAsyncHandler(
- opId: number,
- handler: AsyncHandler
-): void {
- PLUGIN_ASYNC_HANDLER_MAP.set(opId, handler);
-}
-
-export function getAsyncHandler(opName: string): (msg: Uint8Array) => void {
- switch (opName) {
- case "op_write":
- case "op_read":
- return minimal.asyncMsgFromRust;
- default:
- return json.asyncMsgFromRust;
- }
-}
diff --git a/cli/js/ops/os.ts b/cli/js/ops/os.ts
index 2d27f7ef5..5d3026283 100644
--- a/cli/js/ops/os.ts
+++ b/cli/js/ops/os.ts
@@ -1,7 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { sendSync } from "./dispatch_json.ts";
import { errors } from "../errors.ts";
-import * as util from "../util.ts";
/** Get the loadavg.
* Requires the `--allow-env` flag.
@@ -33,7 +32,7 @@ export function osRelease(): string {
/** Exit the Deno process with optional exit code. */
export function exit(code = 0): never {
sendSync("op_exit", { code });
- return util.unreachable();
+ throw new Error("Code not reachable");
}
function setEnv(key: string, value: string): void {
diff --git a/cli/js/process.ts b/cli/js/process.ts
index 6462086ee..7e17da5b6 100644
--- a/cli/js/process.ts
+++ b/cli/js/process.ts
@@ -3,7 +3,6 @@ import { File } from "./files.ts";
import { close } from "./ops/resources.ts";
import { ReadCloser, WriteCloser } from "./io.ts";
import { readAll } from "./buffer.ts";
-import { build } from "./build.ts";
import { kill, runStatus as runStatusOp, run as runOp } from "./ops/process.ts";
/** How to handle subprocess stdio.
@@ -161,85 +160,3 @@ export function run({
}) as RunResponse;
return new Process(res);
}
-
-// From `kill -l`
-enum LinuxSignal {
- SIGHUP = 1,
- SIGINT = 2,
- SIGQUIT = 3,
- SIGILL = 4,
- SIGTRAP = 5,
- SIGABRT = 6,
- SIGBUS = 7,
- SIGFPE = 8,
- SIGKILL = 9,
- SIGUSR1 = 10,
- SIGSEGV = 11,
- SIGUSR2 = 12,
- SIGPIPE = 13,
- SIGALRM = 14,
- SIGTERM = 15,
- SIGSTKFLT = 16,
- SIGCHLD = 17,
- SIGCONT = 18,
- SIGSTOP = 19,
- SIGTSTP = 20,
- SIGTTIN = 21,
- SIGTTOU = 22,
- SIGURG = 23,
- SIGXCPU = 24,
- SIGXFSZ = 25,
- SIGVTALRM = 26,
- SIGPROF = 27,
- SIGWINCH = 28,
- SIGIO = 29,
- SIGPWR = 30,
- SIGSYS = 31
-}
-
-// From `kill -l`
-enum MacOSSignal {
- SIGHUP = 1,
- SIGINT = 2,
- SIGQUIT = 3,
- SIGILL = 4,
- SIGTRAP = 5,
- SIGABRT = 6,
- SIGEMT = 7,
- SIGFPE = 8,
- SIGKILL = 9,
- SIGBUS = 10,
- SIGSEGV = 11,
- SIGSYS = 12,
- SIGPIPE = 13,
- SIGALRM = 14,
- SIGTERM = 15,
- SIGURG = 16,
- SIGSTOP = 17,
- SIGTSTP = 18,
- SIGCONT = 19,
- SIGCHLD = 20,
- SIGTTIN = 21,
- SIGTTOU = 22,
- SIGIO = 23,
- SIGXCPU = 24,
- SIGXFSZ = 25,
- SIGVTALRM = 26,
- SIGPROF = 27,
- SIGWINCH = 28,
- SIGINFO = 29,
- SIGUSR1 = 30,
- SIGUSR2 = 31
-}
-
-/** Signals numbers. This is platform dependent.
- */
-export const Signal: { [key: string]: number } = {};
-
-export function setSignals(): void {
- if (build.os === "mac") {
- Object.assign(Signal, MacOSSignal);
- } else {
- Object.assign(Signal, LinuxSignal);
- }
-}
diff --git a/cli/js/runtime.ts b/cli/js/runtime.ts
index 9a304379f..9d783dc7a 100644
--- a/cli/js/runtime.ts
+++ b/cli/js/runtime.ts
@@ -1,6 +1,7 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { core } from "./core.ts";
-import * as dispatch from "./dispatch.ts";
+import * as dispatchMinimal from "./ops/dispatch_minimal.ts";
+import * as dispatchJson from "./ops/dispatch_json.ts";
import { assert } from "./util.ts";
import * as util from "./util.ts";
import { setBuildInfo } from "./build.ts";
@@ -11,12 +12,22 @@ import { Start, start as startOp } from "./ops/runtime.ts";
export let OPS_CACHE: { [name: string]: number };
+function getAsyncHandler(opName: string): (msg: Uint8Array) => void {
+ switch (opName) {
+ case "op_write":
+ case "op_read":
+ return dispatchMinimal.asyncMsgFromRust;
+ default:
+ return dispatchJson.asyncMsgFromRust;
+ }
+}
+
// TODO(bartlomieju): temporary solution, must be fixed when moving
// dispatches to separate crates
export function initOps(): void {
OPS_CACHE = core.ops();
for (const [name, opId] of Object.entries(OPS_CACHE)) {
- core.setAsyncHandler(opId, dispatch.getAsyncHandler(name));
+ core.setAsyncHandler(opId, getAsyncHandler(name));
}
}
diff --git a/cli/js/runtime_main.ts b/cli/js/runtime_main.ts
index 84ee43d37..40987f33d 100644
--- a/cli/js/runtime_main.ts
+++ b/cli/js/runtime_main.ts
@@ -18,7 +18,7 @@ import {
eventTargetProperties
} from "./globals.ts";
import { internalObject } from "./internals.ts";
-import { setSignals } from "./process.ts";
+import { setSignals } from "./signals.ts";
import { replLoop } from "./repl.ts";
import * as runtime from "./runtime.ts";
import { symbols } from "./symbols.ts";
diff --git a/cli/js/signals.ts b/cli/js/signals.ts
index 2715cfa50..3295b9e80 100644
--- a/cli/js/signals.ts
+++ b/cli/js/signals.ts
@@ -1,8 +1,89 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-import { Signal } from "./process.ts";
import { bindSignal, pollSignal, unbindSignal } from "./ops/signal.ts";
import { build } from "./build.ts";
+// From `kill -l`
+enum LinuxSignal {
+ SIGHUP = 1,
+ SIGINT = 2,
+ SIGQUIT = 3,
+ SIGILL = 4,
+ SIGTRAP = 5,
+ SIGABRT = 6,
+ SIGBUS = 7,
+ SIGFPE = 8,
+ SIGKILL = 9,
+ SIGUSR1 = 10,
+ SIGSEGV = 11,
+ SIGUSR2 = 12,
+ SIGPIPE = 13,
+ SIGALRM = 14,
+ SIGTERM = 15,
+ SIGSTKFLT = 16,
+ SIGCHLD = 17,
+ SIGCONT = 18,
+ SIGSTOP = 19,
+ SIGTSTP = 20,
+ SIGTTIN = 21,
+ SIGTTOU = 22,
+ SIGURG = 23,
+ SIGXCPU = 24,
+ SIGXFSZ = 25,
+ SIGVTALRM = 26,
+ SIGPROF = 27,
+ SIGWINCH = 28,
+ SIGIO = 29,
+ SIGPWR = 30,
+ SIGSYS = 31
+}
+
+// From `kill -l`
+enum MacOSSignal {
+ SIGHUP = 1,
+ SIGINT = 2,
+ SIGQUIT = 3,
+ SIGILL = 4,
+ SIGTRAP = 5,
+ SIGABRT = 6,
+ SIGEMT = 7,
+ SIGFPE = 8,
+ SIGKILL = 9,
+ SIGBUS = 10,
+ SIGSEGV = 11,
+ SIGSYS = 12,
+ SIGPIPE = 13,
+ SIGALRM = 14,
+ SIGTERM = 15,
+ SIGURG = 16,
+ SIGSTOP = 17,
+ SIGTSTP = 18,
+ SIGCONT = 19,
+ SIGCHLD = 20,
+ SIGTTIN = 21,
+ SIGTTOU = 22,
+ SIGIO = 23,
+ SIGXCPU = 24,
+ SIGXFSZ = 25,
+ SIGVTALRM = 26,
+ SIGPROF = 27,
+ SIGWINCH = 28,
+ SIGINFO = 29,
+ SIGUSR1 = 30,
+ SIGUSR2 = 31
+}
+
+/** Signals numbers. This is platform dependent.
+ */
+export const Signal: { [key: string]: number } = {};
+
+export function setSignals(): void {
+ if (build.os === "mac") {
+ Object.assign(Signal, MacOSSignal);
+ } else {
+ Object.assign(Signal, LinuxSignal);
+ }
+}
+
/**
* Returns the stream of the given signal number. You can use it as an async
* iterator.
diff --git a/cli/js/types.ts b/cli/js/types.ts
deleted file mode 100644
index d13963090..000000000
--- a/cli/js/types.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-export type TypedArray = Uint8Array | Float32Array | Int32Array;
diff --git a/cli/js/util.ts b/cli/js/util.ts
index 9f0373721..3c67fa7f1 100644
--- a/cli/js/util.ts
+++ b/cli/js/util.ts
@@ -1,5 +1,4 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-import { TypedArray } from "./types.ts";
let logDebug = false;
let logSource = "JS";
@@ -81,30 +80,6 @@ export function notImplemented(): never {
}
// @internal
-export function unreachable(): never {
- throw new Error("Code not reachable");
-}
-
-const TypedArrayConstructor = Object.getPrototypeOf(Uint8Array);
-export function isTypedArray(x: unknown): x is TypedArray {
- return x instanceof TypedArrayConstructor;
-}
-
-// @internal
-export function requiredArguments(
- name: string,
- length: number,
- required: number
-): void {
- if (length < required) {
- const errMsg = `${name} requires at least ${required} argument${
- required === 1 ? "" : "s"
- }, but only ${length} present`;
- throw new TypeError(errMsg);
- }
-}
-
-// @internal
export function immutableDefine(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
o: any,
@@ -118,45 +93,3 @@ export function immutableDefine(
writable: false
});
}
-
-// Returns values from a WeakMap to emulate private properties in JavaScript
-export function getPrivateValue<
- K extends object,
- V extends object,
- W extends keyof V
->(instance: K, weakMap: WeakMap<K, V>, key: W): V[W] {
- if (weakMap.has(instance)) {
- return weakMap.get(instance)![key];
- }
- throw new TypeError("Illegal invocation");
-}
-
-/**
- * Determines whether an object has a property with the specified name.
- * Avoid calling prototype builtin `hasOwnProperty` for two reasons:
- *
- * 1. `hasOwnProperty` is defined on the object as something else:
- *
- * const options = {
- * ending: 'utf8',
- * hasOwnProperty: 'foo'
- * };
- * options.hasOwnProperty('ending') // throws a TypeError
- *
- * 2. The object doesn't inherit from `Object.prototype`:
- *
- * const options = Object.create(null);
- * options.ending = 'utf8';
- * options.hasOwnProperty('ending'); // throws a TypeError
- *
- * @param obj A Object.
- * @param v A property name.
- * @see https://eslint.org/docs/rules/no-prototype-builtins
- * @internal
- */
-export function hasOwnProperty<T>(obj: T, v: PropertyKey): boolean {
- if (obj == null) {
- return false;
- }
- return Object.prototype.hasOwnProperty.call(obj, v);
-}
diff --git a/cli/js/web/console.ts b/cli/js/web/console.ts
index 601d5fd09..8a34d62a1 100644
--- a/cli/js/web/console.ts
+++ b/cli/js/web/console.ts
@@ -1,6 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-import { isTypedArray } from "../util.ts";
-import { TypedArray } from "../types.ts";
+import { isTypedArray, TypedArray } from "./util.ts";
import { TextEncoder } from "./text_encoding.ts";
import { File, stdout } from "../files.ts";
import { cliTable } from "./console_table.ts";
diff --git a/cli/js/web/console_table.ts b/cli/js/web/console_table.ts
index 276d77f1d..7e698f712 100644
--- a/cli/js/web/console_table.ts
+++ b/cli/js/web/console_table.ts
@@ -2,7 +2,7 @@
// Forked from Node's lib/internal/cli_table.js
import { TextEncoder } from "./text_encoding.ts";
-import { hasOwnProperty } from "../util.ts";
+import { hasOwnProperty } from "./util.ts";
const encoder = new TextEncoder();
diff --git a/cli/js/web/custom_event.ts b/cli/js/web/custom_event.ts
index 6c8a3c19b..2d94df56d 100644
--- a/cli/js/web/custom_event.ts
+++ b/cli/js/web/custom_event.ts
@@ -1,7 +1,7 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import * as domTypes from "./dom_types.ts";
import * as event from "./event.ts";
-import { getPrivateValue, requiredArguments } from "../util.ts";
+import { getPrivateValue, requiredArguments } from "./util.ts";
// WeakMaps are recommended for private attributes (see MDN link below)
// https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Add-on_SDK/Guides/Contributor_s_Guide/Private_Properties#Using_WeakMaps
diff --git a/cli/js/web/dom_iterable.ts b/cli/js/web/dom_iterable.ts
index bd8e7d8cd..f365d555f 100644
--- a/cli/js/web/dom_iterable.ts
+++ b/cli/js/web/dom_iterable.ts
@@ -1,7 +1,7 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { DomIterable } from "./dom_types.ts";
-import { requiredArguments } from "../util.ts";
+import { requiredArguments } from "./util.ts";
import { exposeForTest } from "../internals.ts";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
diff --git a/cli/js/web/event.ts b/cli/js/web/event.ts
index e365fb6b2..a30e33447 100644
--- a/cli/js/web/event.ts
+++ b/cli/js/web/event.ts
@@ -1,6 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import * as domTypes from "./dom_types.ts";
-import { getPrivateValue, requiredArguments } from "../util.ts";
+import { getPrivateValue, requiredArguments } from "./util.ts";
// WeakMaps are recommended for private attributes (see MDN link below)
// https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Add-on_SDK/Guides/Contributor_s_Guide/Private_Properties#Using_WeakMaps
diff --git a/cli/js/web/event_target.ts b/cli/js/web/event_target.ts
index 09e80a731..03557526a 100644
--- a/cli/js/web/event_target.ts
+++ b/cli/js/web/event_target.ts
@@ -1,6 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import * as domTypes from "./dom_types.ts";
-import { hasOwnProperty, requiredArguments } from "../util.ts";
+import { hasOwnProperty, requiredArguments } from "./util.ts";
import {
getRoot,
isNode,
diff --git a/cli/js/web/fetch.ts b/cli/js/web/fetch.ts
index d9918ba14..daa926e51 100644
--- a/cli/js/web/fetch.ts
+++ b/cli/js/web/fetch.ts
@@ -1,10 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-import {
- assert,
- createResolvable,
- notImplemented,
- isTypedArray
-} from "../util.ts";
+import { assert, createResolvable, notImplemented } from "../util.ts";
+import { isTypedArray } from "./util.ts";
import * as domTypes from "./dom_types.ts";
import { TextDecoder, TextEncoder } from "./text_encoding.ts";
import { DenoBlob, bytesSymbol as blobBytesSymbol } from "./blob.ts";
diff --git a/cli/js/web/form_data.ts b/cli/js/web/form_data.ts
index 9c0590c32..461210b9d 100644
--- a/cli/js/web/form_data.ts
+++ b/cli/js/web/form_data.ts
@@ -3,7 +3,7 @@ import * as domTypes from "./dom_types.ts";
import * as blob from "./blob.ts";
import * as domFile from "./dom_file.ts";
import { DomIterableMixin } from "./dom_iterable.ts";
-import { requiredArguments } from "../util.ts";
+import { requiredArguments } from "./util.ts";
const dataSymbol = Symbol("data");
diff --git a/cli/js/web/headers.ts b/cli/js/web/headers.ts
index 652dd2de6..9ff594224 100644
--- a/cli/js/web/headers.ts
+++ b/cli/js/web/headers.ts
@@ -1,7 +1,7 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import * as domTypes from "./dom_types.ts";
import { DomIterableMixin } from "./dom_iterable.ts";
-import { requiredArguments } from "../util.ts";
+import { requiredArguments } from "./util.ts";
import { customInspect } from "./console.ts";
// From node-fetch
diff --git a/cli/js/web/url_search_params.ts b/cli/js/web/url_search_params.ts
index 2248a5388..ed93045da 100644
--- a/cli/js/web/url_search_params.ts
+++ b/cli/js/web/url_search_params.ts
@@ -1,6 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { URL } from "./url.ts";
-import { requiredArguments } from "../util.ts";
+import { requiredArguments } from "./util.ts";
// Returns whether o is iterable.
// @internal
diff --git a/cli/js/web/util.ts b/cli/js/web/util.ts
new file mode 100644
index 000000000..b0a050973
--- /dev/null
+++ b/cli/js/web/util.ts
@@ -0,0 +1,78 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+
+export type TypedArray = Uint8Array | Float32Array | Int32Array;
+const TypedArrayConstructor = Object.getPrototypeOf(Uint8Array);
+export function isTypedArray(x: unknown): x is TypedArray {
+ return x instanceof TypedArrayConstructor;
+}
+
+// @internal
+export function requiredArguments(
+ name: string,
+ length: number,
+ required: number
+): void {
+ if (length < required) {
+ const errMsg = `${name} requires at least ${required} argument${
+ required === 1 ? "" : "s"
+ }, but only ${length} present`;
+ throw new TypeError(errMsg);
+ }
+}
+
+// @internal
+export function immutableDefine(
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ o: any,
+ p: string | number | symbol,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ value: any
+): void {
+ Object.defineProperty(o, p, {
+ value,
+ configurable: false,
+ writable: false
+ });
+}
+
+// Returns values from a WeakMap to emulate private properties in JavaScript
+export function getPrivateValue<
+ K extends object,
+ V extends object,
+ W extends keyof V
+>(instance: K, weakMap: WeakMap<K, V>, key: W): V[W] {
+ if (weakMap.has(instance)) {
+ return weakMap.get(instance)![key];
+ }
+ throw new TypeError("Illegal invocation");
+}
+
+/**
+ * Determines whether an object has a property with the specified name.
+ * Avoid calling prototype builtin `hasOwnProperty` for two reasons:
+ *
+ * 1. `hasOwnProperty` is defined on the object as something else:
+ *
+ * const options = {
+ * ending: 'utf8',
+ * hasOwnProperty: 'foo'
+ * };
+ * options.hasOwnProperty('ending') // throws a TypeError
+ *
+ * 2. The object doesn't inherit from `Object.prototype`:
+ *
+ * const options = Object.create(null);
+ * options.ending = 'utf8';
+ * options.hasOwnProperty('ending'); // throws a TypeError
+ *
+ * @param obj A Object.
+ * @param v A property name.
+ * @see https://eslint.org/docs/rules/no-prototype-builtins
+ * @internal
+ */
+export function hasOwnProperty<T>(obj: T, v: PropertyKey): boolean {
+ if (obj == null) {
+ return false;
+ }
+ return Object.prototype.hasOwnProperty.call(obj, v);
+}