diff options
| author | ruki <waruqi@gmail.com> | 2018-11-08 00:38:48 +0800 |
|---|---|---|
| committer | ruki <waruqi@gmail.com> | 2018-11-07 21:53:09 +0800 |
| commit | 26105034da4fcce7ac883c899d781f016559310d (patch) | |
| tree | c459a5dc4e3aa0972d9919033ece511ce76dd129 /node_modules/@babel/plugin-transform-block-scoping | |
| parent | 2c77f00f1a7ecb6c8192f9c16d3b2001b254a107 (diff) | |
| download | xmake-docs-26105034da4fcce7ac883c899d781f016559310d.tar.gz xmake-docs-26105034da4fcce7ac883c899d781f016559310d.zip | |
switch to vuepress
Diffstat (limited to 'node_modules/@babel/plugin-transform-block-scoping')
4 files changed, 968 insertions, 0 deletions
diff --git a/node_modules/@babel/plugin-transform-block-scoping/README.md b/node_modules/@babel/plugin-transform-block-scoping/README.md new file mode 100644 index 00000000..7c174e50 --- /dev/null +++ b/node_modules/@babel/plugin-transform-block-scoping/README.md @@ -0,0 +1,103 @@ +# @babel/plugin-transform-block-scoping + +> Compile ES2015 block scoping (const and let) to ES5 + +## Examples + +**In** + +```javascript +{ + let a = 3 +} + +let a = 3 +``` + +**Out** + +```javascript +{ + var _a = 3; +} + +var a = 3; +``` + +## Constant checks + +This plugin also validates all `const` variables. +Reassignment of constants is a runtime error and it will insert the necessary error code for those. + +## Installation + +```sh +npm install --save-dev @babel/plugin-transform-block-scoping +``` + +## Usage + +### Via `.babelrc` (Recommended) + +**.babelrc** + +Without options: + +```json +{ + "plugins": ["@babel/plugin-transform-block-scoping"] +} +``` + +With options: + +```json +{ + "plugins": [ + ["@babel/plugin-transform-block-scoping", { + "throwIfClosureRequired": true + }] + ] +} +``` + +### Via CLI + +```sh +babel --plugins @babel/plugin-transform-block-scoping script.js +``` + +### Via Node API + +```javascript +require("@babel/core").transform("code", { + plugins: ["@babel/plugin-transform-block-scoping"] +}); +``` + +## Options + +### `throwIfClosureRequired` +`boolean`, defaults to `false`. + +In cases such as the following it's impossible to rewrite let/const without adding an additional function and closure while transforming: + +```javascript +for (let i = 0; i < 5; i++) { + setTimeout(() => console.log(i), 1); +} +``` + +In extremely performance-sensitive code, this can be undesirable. If `"throwIfClosureRequired": true` is set, Babel throws when transforming these patterns instead of automatically adding an additional function. + +### `tdz` +`boolean`, defaults to `false`. + +By default this plugin will ignore the *temporal dead zone (TDZ)* for block-scoped variables. The following code will **not throw an error when transpiled with Babel, which is not spec compliant**: + +```javascript +i +let i; +``` + +If you need these errors you can tell Babel to try and find them by setting `"tdz": true` for this plugin. However, the current implementation might not get all edge cases right and its best to just avoid code like this in the first place. diff --git a/node_modules/@babel/plugin-transform-block-scoping/lib/index.js b/node_modules/@babel/plugin-transform-block-scoping/lib/index.js new file mode 100644 index 00000000..e70fe5a0 --- /dev/null +++ b/node_modules/@babel/plugin-transform-block-scoping/lib/index.js @@ -0,0 +1,747 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +function _helperPluginUtils() { + const data = require("@babel/helper-plugin-utils"); + + _helperPluginUtils = function _helperPluginUtils() { + return data; + }; + + return data; +} + +var _tdz = require("./tdz"); + +function _values() { + const data = _interopRequireDefault(require("lodash/values")); + + _values = function _values() { + return data; + }; + + return data; +} + +function _extend() { + const data = _interopRequireDefault(require("lodash/extend")); + + _extend = function _extend() { + return data; + }; + + return data; +} + +function _core() { + const data = require("@babel/core"); + + _core = function _core() { + return data; + }; + + return data; +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const DONE = new WeakSet(); + +var _default = (0, _helperPluginUtils().declare)((api, opts) => { + api.assertVersion(7); + const _opts$throwIfClosureR = opts.throwIfClosureRequired, + throwIfClosureRequired = _opts$throwIfClosureR === void 0 ? false : _opts$throwIfClosureR, + _opts$tdz = opts.tdz, + tdzEnabled = _opts$tdz === void 0 ? false : _opts$tdz; + + if (typeof throwIfClosureRequired !== "boolean") { + throw new Error(`.throwIfClosureRequired must be a boolean, or undefined`); + } + + if (typeof tdzEnabled !== "boolean") { + throw new Error(`.throwIfClosureRequired must be a boolean, or undefined`); + } + + return { + visitor: { + VariableDeclaration(path) { + const node = path.node, + parent = path.parent, + scope = path.scope; + if (!isBlockScoped(node)) return; + convertBlockScopedToVar(path, null, parent, scope, true); + + if (node._tdzThis) { + const nodes = [node]; + + for (let i = 0; i < node.declarations.length; i++) { + const decl = node.declarations[i]; + + if (decl.init) { + const assign = _core().types.assignmentExpression("=", decl.id, decl.init); + + assign._ignoreBlockScopingTDZ = true; + nodes.push(_core().types.expressionStatement(assign)); + } + + decl.init = this.addHelper("temporalUndefined"); + } + + node._blockHoist = 2; + + if (path.isCompletionRecord()) { + nodes.push(_core().types.expressionStatement(scope.buildUndefinedNode())); + } + + path.replaceWithMultiple(nodes); + } + }, + + Loop(path, state) { + const parent = path.parent, + scope = path.scope; + path.ensureBlock(); + const blockScoping = new BlockScoping(path, path.get("body"), parent, scope, throwIfClosureRequired, tdzEnabled, state); + const replace = blockScoping.run(); + if (replace) path.replaceWith(replace); + }, + + CatchClause(path, state) { + const parent = path.parent, + scope = path.scope; + const blockScoping = new BlockScoping(null, path.get("body"), parent, scope, throwIfClosureRequired, tdzEnabled, state); + blockScoping.run(); + }, + + "BlockStatement|SwitchStatement|Program"(path, state) { + if (!ignoreBlock(path)) { + const blockScoping = new BlockScoping(null, path, path.parent, path.scope, throwIfClosureRequired, tdzEnabled, state); + blockScoping.run(); + } + } + + } + }; +}); + +exports.default = _default; + +function ignoreBlock(path) { + return _core().types.isLoop(path.parent) || _core().types.isCatchClause(path.parent); +} + +const buildRetCheck = (0, _core().template)(` + if (typeof RETURN === "object") return RETURN.v; +`); + +function isBlockScoped(node) { + if (!_core().types.isVariableDeclaration(node)) return false; + if (node[_core().types.BLOCK_SCOPED_SYMBOL]) return true; + if (node.kind !== "let" && node.kind !== "const") return false; + return true; +} + +function isInLoop(path) { + const loopOrFunctionParent = path.find(path => path.isLoop() || path.isFunction()); + return loopOrFunctionParent && loopOrFunctionParent.isLoop(); +} + +function convertBlockScopedToVar(path, node, parent, scope, moveBindingsToParent = false) { + if (!node) { + node = path.node; + } + + if (isInLoop(path) && !_core().types.isFor(parent)) { + for (let i = 0; i < node.declarations.length; i++) { + const declar = node.declarations[i]; + declar.init = declar.init || scope.buildUndefinedNode(); + } + } + + node[_core().types.BLOCK_SCOPED_SYMBOL] = true; + node.kind = "var"; + + if (moveBindingsToParent) { + const parentScope = scope.getFunctionParent() || scope.getProgramParent(); + const ids = path.getBindingIdentifiers(); + + for (const name in ids) { + const binding = scope.getOwnBinding(name); + if (binding) binding.kind = "var"; + scope.moveBindingTo(name, parentScope); + } + } +} + +function isVar(node) { + return _core().types.isVariableDeclaration(node, { + kind: "var" + }) && !isBlockScoped(node); +} + +const letReferenceBlockVisitor = _core().traverse.visitors.merge([{ + Loop: { + enter(path, state) { + state.loopDepth++; + }, + + exit(path, state) { + state.loopDepth--; + } + + }, + + Function(path, state) { + if (state.loopDepth > 0) { + path.traverse(letReferenceFunctionVisitor, state); + } + + return path.skip(); + } + +}, _tdz.visitor]); + +const letReferenceFunctionVisitor = _core().traverse.visitors.merge([{ + ReferencedIdentifier(path, state) { + const ref = state.letReferences[path.node.name]; + if (!ref) return; + const localBinding = path.scope.getBindingIdentifier(path.node.name); + if (localBinding && localBinding !== ref) return; + state.closurify = true; + } + +}, _tdz.visitor]); + +const hoistVarDeclarationsVisitor = { + enter(path, self) { + const node = path.node, + parent = path.parent; + + if (path.isForStatement()) { + if (isVar(node.init, node)) { + const nodes = self.pushDeclar(node.init); + + if (nodes.length === 1) { + node.init = nodes[0]; + } else { + node.init = _core().types.sequenceExpression(nodes); + } + } + } else if (path.isFor()) { + if (isVar(node.left, node)) { + self.pushDeclar(node.left); + node.left = node.left.declarations[0].id; + } + } else if (isVar(node, parent)) { + path.replaceWithMultiple(self.pushDeclar(node).map(expr => _core().types.expressionStatement(expr))); + } else if (path.isFunction()) { + return path.skip(); + } + } + +}; +const loopLabelVisitor = { + LabeledStatement({ + node + }, state) { + state.innerLabels.push(node.label.name); + } + +}; +const continuationVisitor = { + enter(path, state) { + if (path.isAssignmentExpression() || path.isUpdateExpression()) { + const bindings = path.getBindingIdentifiers(); + + for (const name in bindings) { + if (state.outsideReferences[name] !== path.scope.getBindingIdentifier(name)) { + continue; + } + + state.reassignments[name] = true; + } + } else if (path.isReturnStatement()) { + state.returnStatements.push(path); + } + } + +}; + +function loopNodeTo(node) { + if (_core().types.isBreakStatement(node)) { + return "break"; + } else if (_core().types.isContinueStatement(node)) { + return "continue"; + } +} + +const loopVisitor = { + Loop(path, state) { + const oldIgnoreLabeless = state.ignoreLabeless; + state.ignoreLabeless = true; + path.traverse(loopVisitor, state); + state.ignoreLabeless = oldIgnoreLabeless; + path.skip(); + }, + + Function(path) { + path.skip(); + }, + + SwitchCase(path, state) { + const oldInSwitchCase = state.inSwitchCase; + state.inSwitchCase = true; + path.traverse(loopVisitor, state); + state.inSwitchCase = oldInSwitchCase; + path.skip(); + }, + + "BreakStatement|ContinueStatement|ReturnStatement"(path, state) { + const node = path.node, + parent = path.parent, + scope = path.scope; + if (node[this.LOOP_IGNORE]) return; + let replace; + let loopText = loopNodeTo(node); + + if (loopText) { + if (node.label) { + if (state.innerLabels.indexOf(node.label.name) >= 0) { + return; + } + + loopText = `${loopText}|${node.label.name}`; + } else { + if (state.ignoreLabeless) return; + if (_core().types.isBreakStatement(node) && _core().types.isSwitchCase(parent)) return; + } + + state.hasBreakContinue = true; + state.map[loopText] = node; + replace = _core().types.stringLiteral(loopText); + } + + if (path.isReturnStatement()) { + state.hasReturn = true; + replace = _core().types.objectExpression([_core().types.objectProperty(_core().types.identifier("v"), node.argument || scope.buildUndefinedNode())]); + } + + if (replace) { + replace = _core().types.returnStatement(replace); + replace[this.LOOP_IGNORE] = true; + path.skip(); + path.replaceWith(_core().types.inherits(replace, node)); + } + } + +}; + +class BlockScoping { + constructor(loopPath, blockPath, parent, scope, throwIfClosureRequired, tdzEnabled, state) { + this.parent = parent; + this.scope = scope; + this.state = state; + this.throwIfClosureRequired = throwIfClosureRequired; + this.tdzEnabled = tdzEnabled; + this.blockPath = blockPath; + this.block = blockPath.node; + this.outsideLetReferences = Object.create(null); + this.hasLetReferences = false; + this.letReferences = Object.create(null); + this.body = []; + + if (loopPath) { + this.loopParent = loopPath.parent; + this.loopLabel = _core().types.isLabeledStatement(this.loopParent) && this.loopParent.label; + this.loopPath = loopPath; + this.loop = loopPath.node; + } + } + + run() { + const block = this.block; + if (DONE.has(block)) return; + DONE.add(block); + const needsClosure = this.getLetReferences(); + this.checkConstants(); + + if (_core().types.isFunction(this.parent) || _core().types.isProgram(this.block)) { + this.updateScopeInfo(); + return; + } + + if (!this.hasLetReferences) return; + + if (needsClosure) { + this.wrapClosure(); + } else { + this.remap(); + } + + this.updateScopeInfo(needsClosure); + + if (this.loopLabel && !_core().types.isLabeledStatement(this.loopParent)) { + return _core().types.labeledStatement(this.loopLabel, this.loop); + } + } + + checkConstants() { + const scope = this.scope; + const state = this.state; + + for (const name in scope.bindings) { + const binding = scope.bindings[name]; + if (binding.kind !== "const") continue; + var _arr = binding.constantViolations; + + for (var _i = 0; _i < _arr.length; _i++) { + const violation = _arr[_i]; + const readOnlyError = state.addHelper("readOnlyError"); + + const throwNode = _core().types.callExpression(readOnlyError, [_core().types.stringLiteral(name)]); + + if (violation.isAssignmentExpression()) { + violation.get("right").replaceWith(_core().types.sequenceExpression([throwNode, violation.get("right").node])); + } else if (violation.isUpdateExpression()) { + violation.replaceWith(_core().types.sequenceExpression([throwNode, violation.node])); + } else if (violation.isForXStatement()) { + violation.ensureBlock(); + violation.node.body.body.unshift(_core().types.expressionStatement(throwNode)); + } + } + } + } + + updateScopeInfo(wrappedInClosure) { + const scope = this.scope; + const parentScope = scope.getFunctionParent() || scope.getProgramParent(); + const letRefs = this.letReferences; + + for (const key in letRefs) { + const ref = letRefs[key]; + const binding = scope.getBinding(ref.name); + if (!binding) continue; + + if (binding.kind === "let" || binding.kind === "const") { + binding.kind = "var"; + + if (wrappedInClosure) { + scope.removeBinding(ref.name); + } else { + scope.moveBindingTo(ref.name, parentScope); + } + } + } + } + + remap() { + const letRefs = this.letReferences; + const scope = this.scope; + + for (const key in letRefs) { + const ref = letRefs[key]; + + if (scope.parentHasBinding(key) || scope.hasGlobal(key)) { + if (scope.hasOwnBinding(key)) { + scope.rename(ref.name); + } + + if (this.blockPath.scope.hasOwnBinding(key)) { + this.blockPath.scope.rename(ref.name); + } + } + } + } + + wrapClosure() { + if (this.throwIfClosureRequired) { + throw this.blockPath.buildCodeFrameError("Compiling let/const in this block would add a closure " + "(throwIfClosureRequired)."); + } + + const block = this.block; + const outsideRefs = this.outsideLetReferences; + + if (this.loop) { + for (const name in outsideRefs) { + const id = outsideRefs[name]; + + if (this.scope.hasGlobal(id.name) || this.scope.parentHasBinding(id.name)) { + delete outsideRefs[id.name]; + delete this.letReferences[id.name]; + this.scope.rename(id.name); + this.letReferences[id.name] = id; + outsideRefs[id.name] = id; + } + } + } + + this.has = this.checkLoop(); + this.hoistVarDeclarations(); + const args = (0, _values().default)(outsideRefs).map(id => _core().types.cloneNode(id)); + const params = args.map(id => _core().types.cloneNode(id)); + const isSwitch = this.blockPath.isSwitchStatement(); + + const fn = _core().types.functionExpression(null, params, _core().types.blockStatement(isSwitch ? [block] : block.body)); + + this.addContinuations(fn); + + let call = _core().types.callExpression(_core().types.nullLiteral(), args); + + let basePath = ".callee"; + + const hasYield = _core().traverse.hasType(fn.body, "YieldExpression", _core().types.FUNCTION_TYPES); + + if (hasYield) { + fn.generator = true; + call = _core().types.yieldExpression(call, true); + basePath = ".argument" + basePath; + } + + const hasAsync = _core().traverse.hasType(fn.body, "AwaitExpression", _core().types.FUNCTION_TYPES); + + if (hasAsync) { + fn.async = true; + call = _core().types.awaitExpression(call); + basePath = ".argument" + basePath; + } + + let placeholderPath; + let index; + + if (this.has.hasReturn || this.has.hasBreakContinue) { + const ret = this.scope.generateUid("ret"); + this.body.push(_core().types.variableDeclaration("var", [_core().types.variableDeclarator(_core().types.identifier(ret), call)])); + placeholderPath = "declarations.0.init" + basePath; + index = this.body.length - 1; + this.buildHas(ret); + } else { + this.body.push(_core().types.expressionStatement(call)); + placeholderPath = "expression" + basePath; + index = this.body.length - 1; + } + + let callPath; + + if (isSwitch) { + const _this$blockPath = this.blockPath, + parentPath = _this$blockPath.parentPath, + listKey = _this$blockPath.listKey, + key = _this$blockPath.key; + this.blockPath.replaceWithMultiple(this.body); + callPath = parentPath.get(listKey)[key + index]; + } else { + block.body = this.body; + callPath = this.blockPath.get("body")[index]; + } + + const placeholder = callPath.get(placeholderPath); + let fnPath; + + if (this.loop) { + const loopId = this.scope.generateUid("loop"); + const p = this.loopPath.insertBefore(_core().types.variableDeclaration("var", [_core().types.variableDeclarator(_core().types.identifier(loopId), fn)])); + placeholder.replaceWith(_core().types.identifier(loopId)); + fnPath = p[0].get("declarations.0.init"); + } else { + placeholder.replaceWith(fn); + fnPath = placeholder; + } + + fnPath.unwrapFunctionEnvironment(); + } + + addContinuations(fn) { + const state = { + reassignments: {}, + returnStatements: [], + outsideReferences: this.outsideLetReferences + }; + this.scope.traverse(fn, continuationVisitor, state); + + for (let i = 0; i < fn.params.length; i++) { + const param = fn.params[i]; + if (!state.reassignments[param.name]) continue; + const paramName = param.name; + const newParamName = this.scope.generateUid(param.name); + fn.params[i] = _core().types.identifier(newParamName); + this.scope.rename(paramName, newParamName, fn); + state.returnStatements.forEach(returnStatement => { + returnStatement.insertBefore(_core().types.expressionStatement(_core().types.assignmentExpression("=", _core().types.identifier(paramName), _core().types.identifier(newParamName)))); + }); + fn.body.body.push(_core().types.expressionStatement(_core().types.assignmentExpression("=", _core().types.identifier(paramName), _core().types.identifier(newParamName)))); + } + } + + getLetReferences() { + const block = this.block; + let declarators = []; + + if (this.loop) { + const init = this.loop.left || this.loop.init; + + if (isBlockScoped(init)) { + declarators.push(init); + (0, _extend().default)(this.outsideLetReferences, _core().types.getBindingIdentifiers(init)); + } + } + + const addDeclarationsFromChild = (path, node) => { + node = node || path.node; + + if (_core().types.isClassDeclaration(node) || _core().types.isFunctionDeclaration(node) || isBlockScoped(node)) { + if (isBlockScoped(node)) { + convertBlockScopedToVar(path, node, block, this.scope); + } + + declarators = declarators.concat(node.declarations || node); + } + + if (_core().types.isLabeledStatement(node)) { + addDeclarationsFromChild(path.get("body"), node.body); + } + }; + + if (block.body) { + const declarPaths = this.blockPath.get("body"); + + for (let i = 0; i < block.body.length; i++) { + addDeclarationsFromChild(declarPaths[i]); + } + } + + if (block.cases) { + const declarPaths = this.blockPath.get("cases"); + + for (let i = 0; i < block.cases.length; i++) { + const consequents = block.cases[i].consequent; + + for (let j = 0; j < consequents.length; j++) { + const declar = consequents[j]; + addDeclarationsFromChild(declarPaths[i], declar); + } + } + } + + for (let i = 0; i < declarators.length; i++) { + const declar = declarators[i]; + + const keys = _core().types.getBindingIdentifiers(declar, false, true); + + (0, _extend().default)(this.letReferences, keys); + this.hasLetReferences = true; + } + + if (!this.hasLetReferences) return; + const state = { + letReferences: this.letReferences, + closurify: false, + loopDepth: 0, + tdzEnabled: this.tdzEnabled, + addHelper: name => this.addHelper(name) + }; + + if (isInLoop(this.blockPath)) { + state.loopDepth++; + } + + this.blockPath.traverse(letReferenceBlockVisitor, state); + return state.closurify; + } + + checkLoop() { + const state = { + hasBreakContinue: false, + ignoreLabeless: false, + inSwitchCase: false, + innerLabels: [], + hasReturn: false, + isLoop: !!this.loop, + map: {}, + LOOP_IGNORE: Symbol() + }; + this.blockPath.traverse(loopLabelVisitor, state); + this.blockPath.traverse(loopVisitor, state); + return state; + } + + hoistVarDeclarations() { + this.blockPath.traverse(hoistVarDeclarationsVisitor, this); + } + + pushDeclar(node) { + const declars = []; + + const names = _core().types.getBindingIdentifiers(node); + + for (const name in names) { + declars.push(_core().types.variableDeclarator(names[name])); + } + + this.body.push(_core().types.variableDeclaration(node.kind, declars)); + const replace = []; + + for (let i = 0; i < node.declarations.length; i++) { + const declar = node.declarations[i]; + if (!declar.init) continue; + + const expr = _core().types.assignmentExpression("=", _core().types.cloneNode(declar.id), _core().types.cloneNode(declar.init)); + + replace.push(_core().types.inherits(expr, declar)); + } + + return replace; + } + + buildHas(ret) { + const body = this.body; + let retCheck; + const has = this.has; + const cases = []; + + if (has.hasReturn) { + retCheck = buildRetCheck({ + RETURN: _core().types.identifier(ret) + }); + } + + if (has.hasBreakContinue) { + for (const key in has.map) { + cases.push(_core().types.switchCase(_core().types.stringLiteral(key), [has.map[key]])); + } + + if (has.hasReturn) { + cases.push(_core().types.switchCase(null, [retCheck])); + } + + if (cases.length === 1) { + const single = cases[0]; + body.push(_core().types.ifStatement(_core().types.binaryExpression("===", _core().types.identifier(ret), single.test), single.consequent[0])); + } else { + if (this.loop) { + for (let i = 0; i < cases.length; i++) { + const caseConsequent = cases[i].consequent[0]; + + if (_core().types.isBreakStatement(caseConsequent) && !caseConsequent.label) { + if (!this.loopLabel) { + this.loopLabel = this.scope.generateUidIdentifier("loop"); + } + + caseConsequent.label = _core().types.cloneNode(this.loopLabel); + } + } + } + + body.push(_core().types.switchStatement(_core().types.identifier(ret), cases)); + } + } else { + if (has.hasReturn) { + body.push(retCheck); + } + } + } + +}
\ No newline at end of file diff --git a/node_modules/@babel/plugin-transform-block-scoping/lib/tdz.js b/node_modules/@babel/plugin-transform-block-scoping/lib/tdz.js new file mode 100644 index 00000000..df5b4d41 --- /dev/null +++ b/node_modules/@babel/plugin-transform-block-scoping/lib/tdz.js @@ -0,0 +1,96 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.visitor = void 0; + +function _core() { + const data = require("@babel/core"); + + _core = function _core() { + return data; + }; + + return data; +} + +function getTDZStatus(refPath, bindingPath) { + const executionStatus = bindingPath._guessExecutionStatusRelativeTo(refPath); + + if (executionStatus === "before") { + return "inside"; + } else if (executionStatus === "after") { + return "outside"; + } else { + return "maybe"; + } +} + +function buildTDZAssert(node, state) { + return _core().types.callExpression(state.addHelper("temporalRef"), [node, _core().types.stringLiteral(node.name)]); +} + +function isReference(node, scope, state) { + const declared = state.letReferences[node.name]; + if (!declared) return false; + return scope.getBindingIdentifier(node.name) === declared; +} + +const visitor = { + ReferencedIdentifier(path, state) { + if (!state.tdzEnabled) return; + const node = path.node, + parent = path.parent, + scope = path.scope; + if (path.parentPath.isFor({ + left: node + })) return; + if (!isReference(node, scope, state)) return; + const bindingPath = scope.getBinding(node.name).path; + if (bindingPath.isFunctionDeclaration()) return; + const status = getTDZStatus(path, bindingPath); + if (status === "inside") return; + + if (status === "maybe") { + const assert = buildTDZAssert(node, state); + bindingPath.parent._tdzThis = true; + path.skip(); + + if (path.parentPath.isUpdateExpression()) { + if (parent._ignoreBlockScopingTDZ) return; + path.parentPath.replaceWith(_core().types.sequenceExpression([assert, parent])); + } else { + path.replaceWith(assert); + } + } else if (status === "outside") { + path.replaceWith(_core().types.throwStatement(_core().types.inherits(_core().types.newExpression(_core().types.identifier("ReferenceError"), [_core().types.stringLiteral(`${node.name} is not defined - temporal dead zone`)]), node))); + } + }, + + AssignmentExpression: { + exit(path, state) { + if (!state.tdzEnabled) return; + const node = path.node; + if (node._ignoreBlockScopingTDZ) return; + const nodes = []; + const ids = path.getBindingIdentifiers(); + + for (const name in ids) { + const id = ids[name]; + + if (isReference(id, path.scope, state)) { + nodes.push(buildTDZAssert(id, state)); + } + } + + if (nodes.length) { + node._ignoreBlockScopingTDZ = true; + nodes.push(node); + path.replaceWithMultiple(nodes.map(_core().types.expressionStatement)); + } + } + + } +}; +exports.visitor = visitor;
\ No newline at end of file diff --git a/node_modules/@babel/plugin-transform-block-scoping/package.json b/node_modules/@babel/plugin-transform-block-scoping/package.json new file mode 100644 index 00000000..c23da85b --- /dev/null +++ b/node_modules/@babel/plugin-transform-block-scoping/package.json @@ -0,0 +1,22 @@ +{ + "name": "@babel/plugin-transform-block-scoping", + "version": "7.0.0-beta.47", + "description": "Compile ES2015 block scoping (const and let) to ES5", + "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-block-scoping", + "license": "MIT", + "main": "lib/index.js", + "dependencies": { + "@babel/helper-plugin-utils": "7.0.0-beta.47", + "lodash": "^4.17.5" + }, + "keywords": [ + "babel-plugin" + ], + "peerDependencies": { + "@babel/core": "7.0.0-beta.47" + }, + "devDependencies": { + "@babel/core": "7.0.0-beta.47", + "@babel/helper-plugin-test-runner": "7.0.0-beta.47" + } +} |
