From fd832cef9e6712abccdca43669629d0865061619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Thu, 6 May 2021 23:21:03 +0200 Subject: [PATCH 1/3] Support objects from other contexts in `t.valueToNode` --- .../babel-types/src/converters/valueToNode.ts | 8 +++++-- packages/babel-types/test/regressions.js | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/packages/babel-types/src/converters/valueToNode.ts b/packages/babel-types/src/converters/valueToNode.ts index 07978efa4544..f60086697b99 100644 --- a/packages/babel-types/src/converters/valueToNode.ts +++ b/packages/babel-types/src/converters/valueToNode.ts @@ -40,11 +40,15 @@ function isRegExp(value): value is RegExp { } function isPlainObject(value): value is object { - if (typeof value !== "object" || value === null) { + if ( + typeof value !== "object" || + value === null || + Object.prototype.toString.call(value) !== "[object Object]" + ) { return false; } const proto = Object.getPrototypeOf(value); - return proto === null || proto === Object.prototype; + return proto === null || Object.getPrototypeOf(proto) === null; } function valueToNode(value: unknown): t.Expression { diff --git a/packages/babel-types/test/regressions.js b/packages/babel-types/test/regressions.js index ca2e250ceec7..22d1b81c58e7 100644 --- a/packages/babel-types/test/regressions.js +++ b/packages/babel-types/test/regressions.js @@ -1,4 +1,5 @@ import * as t from "../lib"; +import * as vm from "vm"; describe("regressions", () => { const babel7 = process.env.BABEL_TYPES_8_BREAKING ? it.skip : it; @@ -8,4 +9,24 @@ describe("regressions", () => { t.file(t.program([]), [{ type: "Line" }]); }).not.toThrow(); }); + + it(".valueToNode works with objects from different contexts", () => { + const context = {}; + const script = new vm.Script(`this.obj = { foo: 2 }`); + script.runInNewContext(context); + + expect(t.valueToNode(context.obj)).toEqual({ + properties: [ + { + computed: false, + decorators: null, + key: { name: "foo", type: "Identifier" }, + shorthand: false, + type: "ObjectProperty", + value: { type: "NumericLiteral", value: 2 }, + }, + ], + type: "ObjectExpression", + }); + }); }); From a256a2cb2b491d0b9491b25f0f56a4cdcef81a58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Thu, 6 May 2021 23:27:23 +0200 Subject: [PATCH 2/3] Add comment --- packages/babel-types/src/converters/valueToNode.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/babel-types/src/converters/valueToNode.ts b/packages/babel-types/src/converters/valueToNode.ts index f60086697b99..6eb52b873e7a 100644 --- a/packages/babel-types/src/converters/valueToNode.ts +++ b/packages/babel-types/src/converters/valueToNode.ts @@ -48,6 +48,9 @@ function isPlainObject(value): value is object { return false; } const proto = Object.getPrototypeOf(value); + // Object.prototype's __proto__ is null. Every other class's __proto__.__proto__ is + // not null by default. We cannot check if proto === Object.prototype because it + // could come from another realm. return proto === null || Object.getPrototypeOf(proto) === null; } From 943cd77e874f9801b53b3079d96985a9b0d8b14e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 7 May 2021 10:42:29 +0200 Subject: [PATCH 3/3] Fix test on Babel 8 --- packages/babel-types/test/regressions.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/babel-types/test/regressions.js b/packages/babel-types/test/regressions.js index 22d1b81c58e7..d28899b090d7 100644 --- a/packages/babel-types/test/regressions.js +++ b/packages/babel-types/test/regressions.js @@ -15,11 +15,10 @@ describe("regressions", () => { const script = new vm.Script(`this.obj = { foo: 2 }`); script.runInNewContext(context); - expect(t.valueToNode(context.obj)).toEqual({ + expect(t.valueToNode(context.obj)).toMatchObject({ properties: [ { computed: false, - decorators: null, key: { name: "foo", type: "Identifier" }, shorthand: false, type: "ObjectProperty",