Skip to content

Commit

Permalink
use estree-walker
Browse files Browse the repository at this point in the history
  • Loading branch information
habibrosyad committed Aug 10, 2020
1 parent 1a81532 commit 0beee4e
Showing 1 changed file with 29 additions and 39 deletions.
68 changes: 29 additions & 39 deletions src/compiler/compile/nodes/shared/Context.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { x } from 'code-red';
import { Node, Identifier } from 'estree';
import { walk } from 'estree-walker';
import is_reference from 'is-reference';

export interface Context {
key: Identifier;
Expand Down Expand Up @@ -27,13 +29,7 @@ export function unpack_destructuring(contexts: Context[], node: Node, modifier:
} else if (element && element.type === 'AssignmentPattern') {
const n = contexts.length;

unpack_destructuring(contexts, element.left, node => {
const alternate = JSON.parse(JSON.stringify(element.right));

update_reference(contexts.slice(0, n), node, alternate);

return x`${modifier(node)}[${i}] !== undefined ? ${modifier(node)}[${i}] : ${alternate.replacement || alternate}` as Node;
});
unpack_destructuring(contexts, element.left, node => x`${modifier(node)}[${i}] !== undefined ? ${modifier(node)}[${i}] : ${update_reference(contexts, n, element.right, node)}` as Node);
} else {
unpack_destructuring(contexts, element, node => x`${modifier(node)}[${i}]` as Node);
}
Expand All @@ -56,13 +52,7 @@ export function unpack_destructuring(contexts: Context[], node: Node, modifier:
if (value.type === 'AssignmentPattern') {
const n = contexts.length;

unpack_destructuring(contexts, value.left, node => {
const alternate = JSON.parse(JSON.stringify(value.right));

update_reference(contexts.slice(0, n), node, alternate);

return x`${modifier(node)}.${key.name} !== undefined ? ${modifier(node)}.${key.name} : ${alternate.replacement || alternate}` as Node;
});
unpack_destructuring(contexts, value.left, node => x`${modifier(node)}.${key.name} !== undefined ? ${modifier(node)}.${key.name} : ${update_reference(contexts, n, value.right, node)}` as Node);
} else {
unpack_destructuring(contexts, value, node => x`${modifier(node)}.${key.name}` as Node);
}
Expand All @@ -71,36 +61,36 @@ export function unpack_destructuring(contexts: Context[], node: Node, modifier:
}
}

function update_reference(contexts: Context[], node: Node, parent: any, property?: any) {
const current_node = (property !== undefined && parent[property] || parent);
function update_reference(contexts: Context[], n: number, info, replacement: Node): Node {
if (!n) return info;

if (!current_node || !contexts.length) return;
let copy = JSON.parse(JSON.stringify(info)) as Node;
const replace = (node: Identifier, callback: (node: Node, context: any) => void, context?: any) => {
for (let i = 0; i < n; i++) {
const { key, modifier } = contexts[i];

if (current_node.type === 'Identifier') {
contexts.forEach((context) => {
const { key, modifier } = context;
if (node.name === key.name) {
callback(modifier(replacement), context);
break;
}
}
};

if (copy.type === 'Identifier') {
replace(copy, (node: Node, _context: any) => copy = node);
} else {
walk(copy, {
enter(node, parent: Node) {
if (!['Identifier', 'BinaryExpression', 'CallExpression', 'MemberExpression'].includes(node.type)) {
return this.skip();
}

if (current_node.name === key.name) {
const replacement = modifier(node);

if (property === undefined) {
current_node.replacement = replacement;
} else {
parent[property] = replacement;
if (is_reference(node, parent)) {
replace(node as Identifier, (node: Node, context: any) => context && context.replace(node), this);
}
}
});
} else if (current_node.type === 'BinaryExpression') {
update_reference(contexts, node, current_node, 'left');
update_reference(contexts, node, current_node, 'right');
} else if (current_node.type === 'CallExpression') {
for (let i = 0; i < current_node.arguments.length; i += 1) {
update_reference(contexts, node, current_node.arguments, i);
}

update_reference(contexts, node, current_node, 'callee');
} else if (current_node.type === 'MemberExpression') {
update_reference(contexts, node, current_node, 'object');
update_reference(contexts, node, current_node, 'property');
}

return copy;
}

0 comments on commit 0beee4e

Please sign in to comment.