UNPKG

babel-core

Version:

A compiler for writing next generation JavaScript

115 lines (86 loc) 2.58 kB
"use strict"; exports.__esModule = true; // istanbul ignore next function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } } var _types = require("../../../types"); var t = _interopRequireWildcard(_types); /** * [Please add a description.] */ function buildAssert(node, file) { return t.callExpression(file.addHelper("temporal-assert-defined"), [node, t.literal(node.name), file.addHelper("temporal-undefined")]); } /** * [Please add a description.] */ function references(node, scope, state) { var declared = state.letRefs[node.name]; if (!declared) return false; // declared node is different in this scope return scope.getBindingIdentifier(node.name) === declared; } /** * [Please add a description.] */ var refVisitor = { /** * [Please add a description.] */ ReferencedIdentifier: function ReferencedIdentifier(node, parent, scope, state) { if (t.isFor(parent) && parent.left === node) return; if (!references(node, scope, state)) return; var assert = buildAssert(node, state.file); this.skip(); if (t.isUpdateExpression(parent)) { if (parent._ignoreBlockScopingTDZ) return; this.parentPath.replaceWith(t.sequenceExpression([assert, parent])); } else { return t.logicalExpression("&&", assert, node); } }, /** * [Please add a description.] */ AssignmentExpression: { exit: function exit(node, parent, scope, state) { if (node._ignoreBlockScopingTDZ) return; var nodes = []; var ids = this.getBindingIdentifiers(); for (var name in ids) { var id = ids[name]; if (references(id, scope, state)) { nodes.push(buildAssert(id, state.file)); } } if (nodes.length) { node._ignoreBlockScopingTDZ = true; nodes.push(node); return nodes.map(t.expressionStatement); } } } }; var metadata = { optional: true, group: "builtin-advanced" }; exports.metadata = metadata; /** * [Please add a description.] */ var visitor = { /** * [Please add a description.] */ "Program|Loop|BlockStatement": { exit: function exit(node, parent, scope, file) { var letRefs = node._letReferences; if (!letRefs) return; this.traverse(refVisitor, { letRefs: letRefs, file: file }); } } }; exports.visitor = visitor;