Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve how lazy loading proxies are shown when inspected #615

Merged
merged 2 commits into from
May 28, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions packages/buidler-core/src/internal/util/lazy.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import util from "util";

import { BuidlerError } from "../core/errors";
import { ERRORS } from "../core/errors-list";

Expand Down Expand Up @@ -31,7 +33,12 @@ import { ERRORS } from "../core/errors-list";
export function lazyObject<T extends object>(objectCreator: () => T): T {
return createLazyProxy(
objectCreator,
() => ({}),
(getRealTarget) => ({
[util.inspect.custom]() {
const realTarget = getRealTarget();
return util.inspect(realTarget);
},
}),
(object) => {
if (object instanceof Function) {
throw new BuidlerError(ERRORS.GENERAL.UNSUPPORTED_OPERATION, {
Expand All @@ -51,9 +58,17 @@ export function lazyObject<T extends object>(objectCreator: () => T): T {
// tslint:disable-next-line ban-types
export function lazyFunction<T extends Function>(functionCreator: () => T): T {
return createLazyProxy(
// FIXME: this needs to be revised since TS >= 3.7.x fails without the cast
functionCreator as () => any,
() => function () {},
functionCreator,
(getRealTarget) => {
function dummyTarget() {}

(dummyTarget as any)[util.inspect.custom] = function () {
const realTarget = getRealTarget();
return util.inspect(realTarget);
};

return dummyTarget;
},
(object) => {
if (!(object instanceof Function)) {
throw new BuidlerError(ERRORS.GENERAL.UNSUPPORTED_OPERATION, {
Expand All @@ -67,13 +82,13 @@ export function lazyFunction<T extends Function>(functionCreator: () => T): T {

function createLazyProxy<ActualT extends GuardT, GuardT extends object>(
targetCreator: () => ActualT,
dummyTargetCreator: () => GuardT,
dummyTargetCreator: (getRealTarget: () => ActualT) => GuardT,
validator: (target: any) => void
): ActualT {
let realTarget: ActualT | undefined;

// tslint:disable-next-line
const dummyTarget: ActualT = dummyTargetCreator() as any;
const dummyTarget: ActualT = dummyTargetCreator(getRealTarget) as any;

function getRealTarget(): ActualT {
if (realTarget === undefined) {
Expand Down Expand Up @@ -134,6 +149,13 @@ function createLazyProxy<ActualT extends GuardT, GuardT extends object>(
// before: https://github.com/ethereum/web3.js/blob/8574bd3bf11a2e9cf4bcf8850cab13e1db56653f/packages/web3-core-requestmanager/src/givenProvider.js#L41
//
// We just return `undefined` in that case, to not enter into the loop.
//
// **SUPER IMPORTANT NOTE:** Removing this is very tempting, I know. This
// is a horrible hack. The most obvious approach for doing so is to
// remove the `global` elements that trigger this crazy behavior right
// before doing our `require("web3")`, and restore them afterwards.
// **THIS IS NOT ENOUGH** Users, and libraries (!!!!), will have their own
// `require`s that we can't control and will trigger the same bug.
const stack = new Error().stack;
if (
stack !== undefined &&
Expand Down