Mark FOO in "var { x: FOO }˝ as a binding, not as a reference (#9492)

This commit is contained in:
Nicolò Ribaudo
2019-02-27 00:17:11 +01:00
committed by GitHub
parent 43eed1ac92
commit 5c8cc0d536
6 changed files with 95 additions and 16 deletions

View File

@@ -3,7 +3,22 @@ import getBindingIdentifiers from "../retrievers/getBindingIdentifiers";
/**
* Check if the input `node` is a binding identifier.
*/
export default function isBinding(node: Object, parent: Object): boolean {
export default function isBinding(
node: Object,
parent: Object,
grandparent?: Object,
): boolean {
if (
grandparent &&
node.type === "Identifier" &&
parent.type === "ObjectProperty" &&
grandparent.type === "ObjectExpression"
) {
// We need to special-case this, because getBindingIdentifiers
// has an ObjectProperty->value entry for destructuring patterns.
return false;
}
const keys = getBindingIdentifiers.keys[parent.type];
if (keys) {
for (let i = 0; i < keys.length; i++) {

View File

@@ -2,7 +2,11 @@
/**
* Check if the input `node` is a reference to a bound variable.
*/
export default function isReferenced(node: Object, parent: Object): boolean {
export default function isReferenced(
node: Object,
parent: Object,
grandparent?: Object,
): boolean {
switch (parent.type) {
// yes: PARENT[NODE]
// yes: NODE.child
@@ -37,6 +41,7 @@ export default function isReferenced(node: Object, parent: Object): boolean {
// yes: { [NODE]: "" }
// no: { NODE: "" }
// depends: { NODE }
// depends: { key: NODE }
case "ObjectProperty":
// no: class { NODE = value; }
// yes: class { [NODE] = value; }
@@ -51,7 +56,10 @@ export default function isReferenced(node: Object, parent: Object): boolean {
if (parent.key === node) {
return !!parent.computed;
}
return parent.value === node;
if (parent.value === node) {
return !grandparent || grandparent.type !== "ObjectPattern";
}
return true;
// no: class NODE {}
// yes: class Foo extends NODE {}

View File

@@ -121,6 +121,40 @@ describe("validators", function() {
expect(t.isReferenced(node, parent)).toBe(true);
});
it("returns true if node id a value of ObjectProperty of an expression", function() {
const node = t.identifier("a");
const parent = t.objectProperty(t.identifier("key"), node);
const grandparent = t.objectExpression([parent]);
expect(t.isReferenced(node, parent, grandparent)).toBe(true);
});
it("returns false if node id a value of ObjectProperty of a pattern", function() {
const node = t.identifier("a");
const parent = t.objectProperty(t.identifier("key"), node);
const grandparent = t.objectPattern([parent]);
expect(t.isReferenced(node, parent, grandparent)).toBe(false);
});
});
describe("isBinding", function() {
it("returns false if node id a value of ObjectProperty of an expression", function() {
const node = t.identifier("a");
const parent = t.objectProperty(t.identifier("key"), node);
const grandparent = t.objectExpression([parent]);
expect(t.isBinding(node, parent, grandparent)).toBe(false);
});
it("returns true if node id a value of ObjectProperty of a pattern", function() {
const node = t.identifier("a");
const parent = t.objectProperty(t.identifier("key"), node);
const grandparent = t.objectPattern([parent]);
expect(t.isBinding(node, parent, grandparent)).toBe(true);
});
});
describe("isType", function() {