@babel/plugin-transform-block-scoping
Advanced tools
Comparing version 7.20.0 to 7.20.2
155
lib/index.js
@@ -7,11 +7,6 @@ "use strict"; | ||
exports.default = void 0; | ||
var _helperPluginUtils = require("@babel/helper-plugin-utils"); | ||
var _tdz = require("./tdz"); | ||
var _core = require("@babel/core"); | ||
const DONE = new WeakSet(); | ||
var _default = (0, _helperPluginUtils.declare)((api, opts) => { | ||
@@ -23,11 +18,8 @@ api.assertVersion(7); | ||
} = opts; | ||
if (typeof throwIfClosureRequired !== "boolean") { | ||
throw new Error(`.throwIfClosureRequired must be a boolean, or undefined`); | ||
} | ||
if (typeof tdzEnabled !== "boolean") { | ||
throw new Error(`.tdz must be a boolean, or undefined`); | ||
} | ||
return { | ||
@@ -47,8 +39,5 @@ name: "transform-block-scoping", | ||
const nodes = [node]; | ||
for (let i = 0; i < node.declarations.length; i++) { | ||
const decl = node.declarations[i]; | ||
const assign = _core.types.assignmentExpression("=", _core.types.cloneNode(decl.id), decl.init || scope.buildUndefinedNode()); | ||
assign._ignoreBlockScopingTDZ = true; | ||
@@ -60,11 +49,8 @@ nodes.push(_core.types.expressionStatement(assign)); | ||
node._blockHoist = 2; | ||
if (path.isCompletionRecord()) { | ||
nodes.push(_core.types.expressionStatement(scope.buildUndefinedNode())); | ||
} | ||
path.replaceWithMultiple(nodes); | ||
} | ||
}, | ||
Loop(path, state) { | ||
@@ -80,3 +66,2 @@ const { | ||
}, | ||
CatchClause(path, state) { | ||
@@ -90,3 +75,2 @@ const { | ||
}, | ||
"BlockStatement|SwitchStatement|Program"(path, state) { | ||
@@ -98,28 +82,21 @@ if (!ignoreBlock(path)) { | ||
} | ||
} | ||
}; | ||
}); | ||
exports.default = _default; | ||
function ignoreBlock(path) { | ||
return _core.types.isLoop(path.parent) || _core.types.isCatchClause(path.parent); | ||
} | ||
const buildRetCheck = _core.template.statement(` | ||
if (typeof RETURN === "object") return RETURN.v; | ||
`); | ||
function isBlockScoped(node) { | ||
if (!_core.types.isVariableDeclaration(node)) return false; | ||
if (node[_core.types.BLOCK_SCOPED_SYMBOL]) { | ||
if ( | ||
node[_core.types.BLOCK_SCOPED_SYMBOL]) { | ||
return true; | ||
} | ||
if (node.kind !== "let" && node.kind !== "const" && node.kind !== "using") { | ||
return false; | ||
} | ||
return true; | ||
@@ -132,3 +109,2 @@ } | ||
} | ||
function convertBlockScopedToVar(path, node, parent, scope, moveBindingsToParent = false) { | ||
@@ -151,3 +127,2 @@ if (!node) { | ||
const parentScope = scope.getFunctionParent() || scope.getProgramParent(); | ||
for (const name of Object.keys(path.getBindingIdentifiers())) { | ||
@@ -160,3 +135,2 @@ const binding = scope.getOwnBinding(name); | ||
} | ||
function isVar(node) { | ||
@@ -167,3 +141,13 @@ return _core.types.isVariableDeclaration(node, { | ||
} | ||
const letReferenceFunctionVisitor = _core.traverse.visitors.merge([{ | ||
ReferencedIdentifier(path, state) { | ||
const ref = state.letReferences.get(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 letReferenceBlockVisitor = _core.traverse.visitors.merge([{ | ||
@@ -174,9 +158,6 @@ Loop: { | ||
}, | ||
exit(path, state) { | ||
state.loopDepth--; | ||
} | ||
}, | ||
FunctionParent(path, state) { | ||
@@ -188,19 +169,5 @@ if (state.loopDepth > 0) { | ||
} | ||
return path.skip(); | ||
} | ||
}, _tdz.visitor]); | ||
const letReferenceFunctionVisitor = _core.traverse.visitors.merge([{ | ||
ReferencedIdentifier(path, state) { | ||
const ref = state.letReferences.get(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 = { | ||
@@ -212,6 +179,4 @@ enter(path, self) { | ||
} = path; | ||
if (isVar(node.init)) { | ||
const nodes = self.pushDeclar(node.init); | ||
if (nodes.length === 1) { | ||
@@ -227,3 +192,2 @@ node.init = nodes[0]; | ||
} = path; | ||
if (isVar(node.left)) { | ||
@@ -239,3 +203,2 @@ self.pushDeclar(node.left); | ||
} | ||
}; | ||
@@ -248,3 +211,2 @@ const loopLabelVisitor = { | ||
} | ||
}; | ||
@@ -258,3 +220,2 @@ const continuationVisitor = { | ||
} | ||
state.reassignments[name] = true; | ||
@@ -266,5 +227,3 @@ } | ||
} | ||
}; | ||
function loopNodeTo(node) { | ||
@@ -277,3 +236,2 @@ if (_core.types.isBreakStatement(node)) { | ||
} | ||
const loopVisitor = { | ||
@@ -287,7 +245,5 @@ Loop(path, state) { | ||
}, | ||
Function(path) { | ||
path.skip(); | ||
}, | ||
SwitchCase(path, state) { | ||
@@ -300,3 +256,2 @@ const oldInSwitchCase = state.inSwitchCase; | ||
}, | ||
"BreakStatement|ContinueStatement|ReturnStatement"(path, state) { | ||
@@ -310,3 +265,2 @@ const { | ||
let loopText = loopNodeTo(node); | ||
if (loopText) { | ||
@@ -316,3 +270,2 @@ if (_core.types.isReturnStatement(node)) { | ||
} | ||
if (node.label) { | ||
@@ -322,9 +275,8 @@ if (state.innerLabels.indexOf(node.label.name) >= 0) { | ||
} | ||
loopText = `${loopText}|${node.label.name}`; | ||
} else { | ||
if (state.ignoreLabeless) return; | ||
if (_core.types.isBreakStatement(node) && state.inSwitchCase) return; | ||
} | ||
state.hasBreakContinue = true; | ||
@@ -334,3 +286,2 @@ state.map.set(loopText, node); | ||
} | ||
if (_core.types.isReturnStatement(node)) { | ||
@@ -340,3 +291,2 @@ state.hasReturn = true; | ||
} | ||
if (replace) { | ||
@@ -349,5 +299,3 @@ replace = _core.types.returnStatement(replace); | ||
} | ||
}; | ||
function isStrict(path) { | ||
@@ -360,8 +308,7 @@ return !!path.find(({ | ||
} else if (!_core.types.isBlockStatement(node)) return false; | ||
return node.directives.some(directive => directive.value.value === "use strict"); | ||
}); | ||
} | ||
class BlockScoping { | ||
class BlockScoping { | ||
constructor(loopPath, blockPath, parent, scope, throwIfClosureRequired, tdzEnabled, state) { | ||
@@ -395,3 +342,2 @@ this.parent = void 0; | ||
this.body = []; | ||
if (loopPath) { | ||
@@ -418,3 +364,2 @@ this.loopParent = loopPath.parent; | ||
if (!this.hasLetReferences) return; | ||
if (needsClosure) { | ||
@@ -425,5 +370,3 @@ this.wrapClosure(); | ||
} | ||
this.updateScopeInfo(needsClosure); | ||
if (this.loopLabel && !_core.types.isLabeledStatement(this.loopParent)) { | ||
@@ -433,3 +376,2 @@ return _core.types.labeledStatement(this.loopLabel, this.loop); | ||
} | ||
checkConstants() { | ||
@@ -444,13 +386,9 @@ const constBindings = new Map(); | ||
} | ||
const { | ||
state | ||
} = this; | ||
for (const [name, binding] of constBindings) { | ||
for (const violation of binding.constantViolations) { | ||
const readOnlyError = state.addHelper("readOnlyError"); | ||
const throwNode = _core.types.callExpression(readOnlyError, [_core.types.stringLiteral(name)]); | ||
if (violation.isAssignmentExpression()) { | ||
@@ -460,9 +398,10 @@ const { | ||
} = violation.node; | ||
if (operator === "=") { | ||
violation.replaceWith(_core.types.sequenceExpression([violation.get("right").node, throwNode])); | ||
} else if (["&&=", "||=", "??="].includes(operator)) { | ||
violation.replaceWith(_core.types.logicalExpression(operator.slice(0, -1), violation.get("left").node, _core.types.sequenceExpression([violation.get("right").node, throwNode]))); | ||
violation.replaceWith(_core.types.logicalExpression( | ||
operator.slice(0, -1), violation.get("left").node, _core.types.sequenceExpression([violation.get("right").node, throwNode]))); | ||
} else { | ||
violation.replaceWith(_core.types.sequenceExpression([_core.types.binaryExpression(operator.slice(0, -1), violation.get("left").node, violation.get("right").node), throwNode])); | ||
violation.replaceWith(_core.types.sequenceExpression([_core.types.binaryExpression( | ||
operator.slice(0, -1), violation.get("left").node, violation.get("right").node), throwNode])); | ||
} | ||
@@ -479,3 +418,2 @@ } else if (violation.isUpdateExpression()) { | ||
} | ||
updateScopeInfo(wrappedInClosure) { | ||
@@ -485,3 +423,2 @@ const blockScope = this.blockPath.scope; | ||
const letRefs = this.letReferences; | ||
for (const key of letRefs.keys()) { | ||
@@ -491,6 +428,4 @@ const ref = letRefs.get(key); | ||
if (!binding) continue; | ||
if (binding.kind === "let" || binding.kind === "const") { | ||
binding.kind = "var"; | ||
if (wrappedInClosure) { | ||
@@ -506,3 +441,2 @@ if (blockScope.hasOwnBinding(ref.name)) { | ||
} | ||
remap() { | ||
@@ -519,13 +453,11 @@ const letRefs = this.letReferences; | ||
const binding = scope.getOwnBinding(key); | ||
if (binding) { | ||
const parentBinding = scope.parent.getOwnBinding(key); | ||
if (binding.kind === "hoisted" && !binding.path.node.async && !binding.path.node.generator && (!parentBinding || isVar(parentBinding.path.parent)) && !isStrict(binding.path.parentPath)) { | ||
if (binding.kind === "hoisted" && | ||
!binding.path.node.async && | ||
!binding.path.node.generator && (!parentBinding || isVar(parentBinding.path.parent)) && !isStrict(binding.path.parentPath)) { | ||
continue; | ||
} | ||
scope.rename(ref.name); | ||
} | ||
if (blockPathScope.hasOwnBinding(key)) { | ||
@@ -536,6 +468,4 @@ blockPathScope.rename(ref.name); | ||
} | ||
for (const key of outsideLetRefs.keys()) { | ||
const ref = letRefs.get(key); | ||
if (isInLoop(this.blockPath) && blockPathScope.hasOwnBinding(key)) { | ||
@@ -546,3 +476,2 @@ blockPathScope.rename(ref.name); | ||
} | ||
wrapClosure() { | ||
@@ -552,3 +481,2 @@ if (this.throwIfClosureRequired) { | ||
} | ||
const block = this.block; | ||
@@ -560,3 +488,2 @@ const outsideRefs = this.outsideLetReferences; | ||
const id = outsideRefs.get(name); | ||
if (this.scope.hasGlobal(id.name) || this.scope.parentHasBinding(id.name)) { | ||
@@ -573,3 +500,5 @@ outsideRefs.delete(id.name); | ||
this.has = this.checkLoop(); | ||
this.hoistVarDeclarations(); | ||
const args = Array.from(outsideRefs.values(), node => _core.types.cloneNode(node)); | ||
@@ -582,9 +511,6 @@ const params = args.map(id => _core.types.cloneNode(id)); | ||
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) { | ||
@@ -597,3 +523,2 @@ fn.generator = true; | ||
const hasAsync = _core.traverse.hasType(fn.body, "AwaitExpression", _core.types.FUNCTION_TYPES); | ||
if (hasAsync) { | ||
@@ -604,6 +529,4 @@ fn.async = true; | ||
} | ||
let placeholderPath; | ||
let index; | ||
if (this.has.hasReturn || this.has.hasBreakContinue) { | ||
@@ -620,5 +543,3 @@ const ret = this.scope.generateUid("ret"); | ||
} | ||
let callPath; | ||
if (isSwitch) { | ||
@@ -636,6 +557,4 @@ const { | ||
} | ||
const placeholder = callPath.get(placeholderPath); | ||
let fnPath; | ||
if (this.loop) { | ||
@@ -661,3 +580,2 @@ const loopId = this.scope.generateUid("loop"); | ||
this.scope.traverse(fn, continuationVisitor, state); | ||
for (let i = 0; i < fn.params.length; i++) { | ||
@@ -673,18 +591,14 @@ const param = fn.params[i]; | ||
}); | ||
fn.body.body.push(_core.types.expressionStatement(_core.types.assignmentExpression("=", _core.types.identifier(paramName), _core.types.identifier(newParamName)))); | ||
} | ||
} | ||
getLetReferences() { | ||
const block = this.block; | ||
const declarators = []; | ||
if (this.loop) { | ||
const init = this.loop.left || this.loop.init; | ||
if (isBlockScoped(init)) { | ||
declarators.push(init); | ||
const names = _core.types.getBindingIdentifiers(init); | ||
for (const name of Object.keys(names)) { | ||
@@ -695,3 +609,2 @@ this.outsideLetReferences.set(name, names[name]); | ||
} | ||
const addDeclarationsFromChild = (path, node) => { | ||
@@ -702,3 +615,2 @@ if (_core.types.isClassDeclaration(node) || _core.types.isFunctionDeclaration(node) || isBlockScoped(node)) { | ||
} | ||
if (node.type === "VariableDeclaration") { | ||
@@ -712,3 +624,2 @@ for (let i = 0; i < node.declarations.length; i++) { | ||
} | ||
if (_core.types.isLabeledStatement(node)) { | ||
@@ -718,9 +629,6 @@ addDeclarationsFromChild(path.get("body"), node.body); | ||
}; | ||
if (block.type === "SwitchStatement") { | ||
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++) { | ||
@@ -733,3 +641,2 @@ const declar = consequents[j]; | ||
const declarPaths = this.blockPath.get("body"); | ||
for (let i = 0; i < block.body.length; i++) { | ||
@@ -742,9 +649,6 @@ addDeclarationsFromChild(declarPaths[i], declarPaths[i].node); | ||
const declar = declarators[i]; | ||
const keys = _core.types.getBindingIdentifiers(declar, false, true); | ||
for (const key of Object.keys(keys)) { | ||
this.letReferences.set(key, keys[key]); | ||
} | ||
this.hasLetReferences = true; | ||
@@ -761,3 +665,2 @@ } | ||
}; | ||
if (isInLoop(this.blockPath)) { | ||
@@ -793,28 +696,19 @@ state.loopDepth++; | ||
const declars = []; | ||
const names = _core.types.getBindingIdentifiers(node); | ||
for (const name of Object.keys(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; | ||
const has = this.has; | ||
if (has.hasBreakContinue) { | ||
@@ -832,5 +726,4 @@ for (const key of has.map.keys()) { | ||
} | ||
} | ||
//# sourceMappingURL=index.js.map |
@@ -7,8 +7,5 @@ "use strict"; | ||
exports.visitor = void 0; | ||
var _core = require("@babel/core"); | ||
function getTDZStatus(refPath, bindingPath) { | ||
const executionStatus = bindingPath._guessExecutionStatusRelativeTo(refPath); | ||
if (executionStatus === "before") { | ||
@@ -22,13 +19,12 @@ return "outside"; | ||
} | ||
function buildTDZAssert(node, state) { | ||
return _core.types.callExpression(state.addHelper("temporalRef"), [node, _core.types.stringLiteral(node.name)]); | ||
return _core.types.callExpression(state.addHelper("temporalRef"), [ | ||
node, _core.types.stringLiteral(node.name)]); | ||
} | ||
function isReference(node, scope, state) { | ||
const declared = state.letReferences.get(node.name); | ||
if (!declared) return false; | ||
return scope.getBindingIdentifier(node.name) === declared; | ||
} | ||
const visitedMaybeTDZNodes = new WeakSet(); | ||
@@ -51,3 +47,2 @@ const visitor = { | ||
if (status === "outside") return; | ||
if (status === "maybe") { | ||
@@ -57,7 +52,6 @@ if (visitedMaybeTDZNodes.has(node)) { | ||
} | ||
visitedMaybeTDZNodes.add(node); | ||
const assert = buildTDZAssert(node, state); | ||
bindingPath.parent._tdzThis = true; | ||
if (path.parentPath.isUpdateExpression()) { | ||
@@ -73,3 +67,2 @@ if (parent._ignoreBlockScopingTDZ) return; | ||
}, | ||
AssignmentExpression: { | ||
@@ -81,9 +74,8 @@ exit(path, state) { | ||
} = path; | ||
if (node._ignoreBlockScopingTDZ) return; | ||
const nodes = []; | ||
const ids = path.getBindingIdentifiers(); | ||
for (const name of Object.keys(ids)) { | ||
const id = ids[name]; | ||
if (isReference(id, path.scope, state)) { | ||
@@ -93,3 +85,2 @@ nodes.push(id); | ||
} | ||
if (nodes.length) { | ||
@@ -101,3 +92,2 @@ node._ignoreBlockScopingTDZ = true; | ||
} | ||
} | ||
@@ -104,0 +94,0 @@ }; |
{ | ||
"name": "@babel/plugin-transform-block-scoping", | ||
"version": "7.20.0", | ||
"version": "7.20.2", | ||
"description": "Compile ES2015 block scoping (const and let) to ES5", | ||
@@ -17,3 +17,3 @@ "repository": { | ||
"dependencies": { | ||
"@babel/helper-plugin-utils": "^7.19.0" | ||
"@babel/helper-plugin-utils": "^7.20.2" | ||
}, | ||
@@ -27,5 +27,5 @@ "keywords": [ | ||
"devDependencies": { | ||
"@babel/core": "^7.19.6", | ||
"@babel/core": "^7.20.2", | ||
"@babel/helper-plugin-test-runner": "^7.18.6", | ||
"@babel/traverse": "^7.20.0" | ||
"@babel/traverse": "^7.20.1" | ||
}, | ||
@@ -32,0 +32,0 @@ "engines": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
94731
716