You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
2.8 KiB
102 lines
2.8 KiB
1 month ago
|
"use strict";
|
||
|
|
||
|
Object.defineProperty(exports, "__esModule", {
|
||
|
value: true
|
||
|
});
|
||
|
exports.annexB33FunctionsVisitor = void 0;
|
||
|
exports.isVarScope = isVarScope;
|
||
|
var _core = require("@babel/core");
|
||
|
const annexB33FunctionsVisitor = exports.annexB33FunctionsVisitor = Object.assign({
|
||
|
VariableDeclaration(path) {
|
||
|
if (isStrict(path)) return;
|
||
|
if (path.node.kind !== "var") return;
|
||
|
const varScope = path.scope.getFunctionParent() || path.scope.getProgramParent();
|
||
|
varScope.path.traverse(functionsToVarVisitor, {
|
||
|
names: Object.keys(path.getBindingIdentifiers())
|
||
|
});
|
||
|
}
|
||
|
}, {
|
||
|
BlockStatement(path) {
|
||
|
if (isStrict(path)) return;
|
||
|
if (_core.types.isFunction(path.parent, {
|
||
|
body: path.node
|
||
|
})) return;
|
||
|
transformStatementList(path.get("body"));
|
||
|
},
|
||
|
SwitchCase(path) {
|
||
|
if (isStrict(path)) return;
|
||
|
transformStatementList(path.get("consequent"));
|
||
|
}
|
||
|
});
|
||
|
function transformStatementList(paths) {
|
||
|
outer: for (const path of paths) {
|
||
|
if (!path.isFunctionDeclaration()) continue;
|
||
|
if (path.node.async || path.node.generator) return;
|
||
|
const {
|
||
|
scope
|
||
|
} = path.parentPath;
|
||
|
if (isVarScope(scope)) return;
|
||
|
const {
|
||
|
name
|
||
|
} = path.node.id;
|
||
|
let currScope = scope;
|
||
|
do {
|
||
|
if (currScope.parent.hasOwnBinding(name)) continue outer;
|
||
|
currScope = currScope.parent;
|
||
|
} while (!isVarScope(currScope));
|
||
|
maybeTransformBlockScopedFunction(path);
|
||
|
}
|
||
|
}
|
||
|
function maybeTransformBlockScopedFunction(path) {
|
||
|
const {
|
||
|
node,
|
||
|
parentPath: {
|
||
|
scope
|
||
|
}
|
||
|
} = path;
|
||
|
const {
|
||
|
id
|
||
|
} = node;
|
||
|
scope.removeOwnBinding(id.name);
|
||
|
node.id = null;
|
||
|
const varNode = _core.types.variableDeclaration("var", [_core.types.variableDeclarator(id, _core.types.toExpression(node))]);
|
||
|
varNode._blockHoist = 2;
|
||
|
const [varPath] = path.replaceWith(varNode);
|
||
|
scope.registerDeclaration(varPath);
|
||
|
}
|
||
|
const functionsToVarVisitor = {
|
||
|
Scope(path, {
|
||
|
names
|
||
|
}) {
|
||
|
for (const name of names) {
|
||
|
const binding = path.scope.getOwnBinding(name);
|
||
|
if (binding && binding.kind === "hoisted") {
|
||
|
maybeTransformBlockScopedFunction(binding.path);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
"Expression|Declaration"(path) {
|
||
|
path.skip();
|
||
|
}
|
||
|
};
|
||
|
function isVarScope(scope) {
|
||
|
return scope.path.isFunctionParent() || scope.path.isProgram();
|
||
|
}
|
||
|
function isStrict(path) {
|
||
|
return !!path.find(({
|
||
|
node
|
||
|
}) => {
|
||
|
var _node$directives;
|
||
|
if (_core.types.isProgram(node)) {
|
||
|
if (node.sourceType === "module") return true;
|
||
|
} else if (_core.types.isClass(node)) {
|
||
|
return true;
|
||
|
} else if (!_core.types.isBlockStatement(node)) {
|
||
|
return false;
|
||
|
}
|
||
|
return (_node$directives = node.directives) == null ? void 0 : _node$directives.some(directive => directive.value.value === "use strict");
|
||
|
});
|
||
|
}
|
||
|
|
||
|
//# sourceMappingURL=annex-B_3_3.js.map
|