[babel-types] Fix isNodesEquivalent() behavior for TemplateElements (#8165)

Fixes #8163

The `isNodesEquivalent()` algorithm incorrectly assumes that any object properties must themselves be AST nodes, which is not the case here, causing the error.
This commit is contained in:
Tim Kendrick
2018-07-06 13:45:25 +01:00
committed by Henry Zhu
parent 663c96db04
commit e9184ed05e
2 changed files with 22 additions and 1 deletions

View File

@@ -1,5 +1,5 @@
// @flow
import { NODE_FIELDS } from "../definitions";
import { NODE_FIELDS, VISITOR_KEYS } from "../definitions";
/**
* Check if two nodes are equivalent
@@ -19,6 +19,7 @@ export default function isNodesEquivalent(a: any, b: any): boolean {
}
const fields = Object.keys(NODE_FIELDS[a.type] || a.type);
const visitorKeys = VISITOR_KEYS[a.type];
for (const field of fields) {
if (typeof a[field] !== typeof b[field]) {
@@ -41,6 +42,18 @@ export default function isNodesEquivalent(a: any, b: any): boolean {
continue;
}
if (
typeof a[field] === "object" &&
(!visitorKeys || !visitorKeys.includes(field))
) {
for (const key in a[field]) {
if (a[field][key] !== b[field][key]) {
return false;
}
}
continue;
}
if (!isNodesEquivalent(a[field], b[field])) {
return false;
}

View File

@@ -26,6 +26,14 @@ describe("validators", function() {
expect(t.isNodesEquivalent(parse(program), parse(program2))).toBe(false);
});
it("should handle nodes with object properties", function() {
const original = t.templateElement({ raw: "\\'a", cooked: "'a" }, true);
const identical = t.templateElement({ raw: "\\'a", cooked: "'a" }, true);
const different = t.templateElement({ raw: "'a", cooked: "'a" }, true);
expect(t.isNodesEquivalent(original, identical)).toBe(true);
expect(t.isNodesEquivalent(original, different)).toBe(false);
});
it("rejects 'await' as an identifier", function() {
expect(t.isValidIdentifier("await")).toBe(false);
});