Skip to content
Closed
Prev Previous commit
Next Next commit
refactor: categorize variable hoisting by var & let
  • Loading branch information
ejose19 committed Jul 5, 2021
commit 79e59cf5d8781f0a88e3b043bc91399bcd36f9af
109 changes: 61 additions & 48 deletions lib/internal/repl/await.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,17 @@ const parser = require('internal/deps/acorn/acorn/dist/acorn').Parser;
const walk = require('internal/deps/acorn/acorn-walk/dist/walk');
const { Recoverable } = require('internal/repl');

function isTopLevelDeclaration(state) {
return state.ancestors[state.ancestors.length - 2] === state.body;
}

const noop = FunctionPrototype;
const visitorsWithoutAncestors = {
ClassDeclaration(node, state, c) {
state.prepend(node, `${node.id.name}=`);
state.prepend(state.root.body[0], `let ${node.id.name}; `);
if (isTopLevelDeclaration(state)) {
state.prepend(node, `${node.id.name}=`);
state.prepend(state.wrapper, `let ${node.id.name}; `);
}

walk.base.ClassDeclaration(node, state, c);
},
Expand All @@ -37,8 +43,10 @@ const visitorsWithoutAncestors = {
walk.base.ForOfStatement(node, state, c);
},
FunctionDeclaration(node, state, c) {
state.prepend(node, `${node.id.name}=`);
state.prepend(state.root.body[0], `let ${node.id.name}; `);
if (isTopLevelDeclaration(state)) {
state.prepend(node, `${node.id.name}=`);
state.prepend(state.wrapper, `let ${node.id.name}; `);
}
},
FunctionExpression: noop,
ArrowFunctionExpression: noop,
Expand All @@ -52,57 +60,62 @@ const visitorsWithoutAncestors = {
walk.base.ReturnStatement(node, state, c);
},
VariableDeclaration(node, state, c) {
if (node.declarations.length === 1) {
state.replace(node.start, node.start + node.kind.length, 'void');
} else {
state.replace(node.start, node.start + node.kind.length, 'void (');
}
const variableKind = node.kind;
if (variableKind === 'var' || isTopLevelDeclaration(state)) {
if (node.declarations.length === 1) {
state.replace(node.start, node.start + node.kind.length, 'void');
} else {
state.replace(node.start, node.start + node.kind.length, 'void (');
}

ArrayPrototypeForEach(node.declarations, (decl) => {
state.prepend(decl, '(');
state.append(decl, decl.init ? ')' : '=undefined)');
});
ArrayPrototypeForEach(node.declarations, (decl) => {
state.prepend(decl, '(');
state.append(decl, decl.init ? ')' : '=undefined)');
});

if (node.declarations.length !== 1) {
state.append(node.declarations[node.declarations.length - 1], ')');
}
if (node.declarations.length !== 1) {
state.append(node.declarations[node.declarations.length - 1], ')');
}

const variableIdentifiersToHoist = [];
function registerVariableDeclarationIdentifiers(node) {
switch (node.type) {
case 'Identifier':
ArrayPrototypePush(variableIdentifiersToHoist, node.name);
break;
case 'ObjectPattern':
ArrayPrototypeForEach(
node.properties,
(property) => {
const variableIdentifiersToHoist = [
['var', []],
['let', []],
];
function registerVariableDeclarationIdentifiers(node) {
switch (node.type) {
case 'Identifier':
ArrayPrototypePush(
variableIdentifiersToHoist[variableKind === 'var' ? 0 : 1][1],
node.name
);
break;
case 'ObjectPattern':
ArrayPrototypeForEach(node.properties, (property) => {
registerVariableDeclarationIdentifiers(property.value);
}
);
break;
case 'ArrayPattern':
ArrayPrototypeForEach(
node.elements,
(element) => {
});
break;
case 'ArrayPattern':
ArrayPrototypeForEach(node.elements, (element) => {
registerVariableDeclarationIdentifiers(element);
}
);
break;
});
break;
}
}
}

ArrayPrototypeForEach(
node.declarations,
(decl) => {
ArrayPrototypeForEach(node.declarations, (decl) => {
registerVariableDeclarationIdentifiers(decl.id);
}
);

if (variableIdentifiersToHoist.length > 0) {
state.prepend(
state.root.body[0],
'let ' + ArrayPrototypeJoin(variableIdentifiersToHoist, ', ') + '; '
});

ArrayPrototypeForEach(
variableIdentifiersToHoist,
({ 0: kind, 1: identifiers }) => {
if (identifiers.length > 0) {
state.prepend(
state.wrapper,
`${kind} ${ArrayPrototypeJoin(identifiers, ', ')}; `
);
}
}
);
}

Expand Down Expand Up @@ -163,7 +176,7 @@ function processTopLevelAwait(src) {
}
const body = root.body[0].expression.callee.body;
const state = {
root,
wrapper: root.body[0],
body,
ancestors: [],
replace(from, to, str) {
Expand Down