Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 56 additions & 57 deletions src/browser/chrome/scripts/parser.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const esprima = require('esprima');
const estraverse = require('estraverse');
const escodegen = require('escodegen');
const _ = require('lodash');

// declare functions to insert
function useReducerReplacement() {
Expand All @@ -18,7 +17,7 @@ function useReducerReplacement() {
});
return newState;
}
return dispatcher.useReducer(reducerWithTracker, initialArg, init);
return dispatcher.useReducer(reducerWithTracker, initialState, initialAction);
}

function commitAllHostEffectsReplacement() {
Expand All @@ -35,27 +34,27 @@ function commitAllHostEffectsReplacement() {
}
recordEffect();

let {effectTag} = nextEffect;
const { effectTag } = nextEffect;

if (effectTag & ContentReset) {
commitResetTextContent(nextEffect);
}

if (effectTag & Ref) {
let current$$1 = nextEffect.alternate;
const current$$1 = nextEffect.alternate;
if (current$$1 !== null) {
commitDetachRef(current$$1);
}
}

let primaryEffectTag = effectTag & (Placement | Update | Deletion);
const primaryEffectTag = effectTag & (Placement | Update | Deletion);
switch (primaryEffectTag) {
case Placement:
{
// editbyme
timeTravelLList.append({
primaryEffectTag: 'PLACEMENT',
effect: _.cloneDeep(nextEffect),
primaryEffectTag: 'PLACEMENT',
effect: _.cloneDeep(nextEffect),
});

commitPlacement(nextEffect);
Expand All @@ -67,7 +66,7 @@ function commitAllHostEffectsReplacement() {
{
commitPlacement(nextEffect);
nextEffect.effectTag &= ~Placement;
let _current = nextEffect.alternate;
const _current = nextEffect.alternate;
commitWork(_current, nextEffect);
break;
}
Expand All @@ -80,7 +79,7 @@ function commitAllHostEffectsReplacement() {
current: _.cloneDeep(nextEffect.alternate),
});

let _current2 = nextEffect.alternate;
const _current2 = nextEffect.alternate;
commitWork(_current2, nextEffect);
break;
}
Expand All @@ -103,20 +102,21 @@ function commitAllHostEffectsReplacement() {
resetCurrentFiber();
}
}
// regex method signatures
const uRsig = new RegExp(/\b(useReducer)\b\(reducer, initialArg, init\)/);
const cAHEsig = new RegExp(/\b(function)\b\s\b(commitAllHostEffects)\b\(\)/, 'g');

// get replacer method bodies
// method names
const USEREDUCER = 'useReducer';
const COMMITALLHOSTEFFECTS = 'commitAllHostEffects';
// library key inside of bundle
const reactLibraryPath = './node_modules/react/cjs/react.development.js';
const reactDOMLibraryPath = './node_modules/react-dom/cjs/react-dom.development.js';
// get replacer method
let injectableUseReducer = esprima.parseScript(useReducerReplacement.toString());
let injectableUseReducerString = escodegen.generate(injectableUseReducer.body[0].body);

let injectableCommitAllHostEffects = esprima.parseScript(commitAllHostEffectsReplacement.toString());
let injectableCommitAllHostEffectsString = escodegen.generate(injectableCommitAllHostEffects.body[0].body);

// traverse ast to find method and replace body with our node's body
function traverseTree(replacementNode, functionName, ast) {
console.log('traverse called');
console.log('unbundled traverse called');
estraverse.replace(ast, {
enter(node) {
if (node.type === 'FunctionDeclaration') {
Expand All @@ -128,55 +128,54 @@ function traverseTree(replacementNode, functionName, ast) {
},
});
}
function stringParser(string, newBody, methodSig) {
let stack = [];
const foundMethod = methodSig.test(string);
let oldBody = '';
let output;
for (let i = methodSig.lastIndex; i < string.length; i++) {
if (foundMethod) {
if (string[i] === '{') {
stack.push(string[i]);
}
if (stack.length > 0 && stack[stack.length - 1] === '{' && string[i] === '}') {
stack.pop();
oldBody += string[i];
output = string.replace(oldBody, newBody);
break;
}
if (stack.length > 0) {
oldBody += string[i];

function traverseBundledTree(replacementNode, functionName, ast, library) {
estraverse.traverse(ast, {
enter(node) {
if (node.key && node.key.value === library) {
if (node.value.body.body[1].type === 'ExpressionStatement') {
if (node.value.body.body[1].expression.callee.name === 'eval') {
// create new ast
const reactLib = esprima.parseScript(node.value.body.body[1].expression.arguments[0].value);
estraverse.traverse(reactLib, {
enter(libNode) {
if (libNode.type === 'FunctionDeclaration') {
if (libNode.id.name === functionName) {
libNode.body = replacementNode.body[0].body;
console.log('From parser. REPLACING body!', libNode.id.name);
}
}
},
});
node.value.body.body[1].expression.arguments[0].value = escodegen.generate(reactLib);
node.value.body.body[1].expression.arguments[0].raw = JSON.stringify(escodegen.generate(reactLib));
console.log('arguments replaced');
}
}
}
}
}
return output;
},
});
}

const parseAndGenerate = (codeString) => {
if (codeString.search('react') !== -1) {
let ast;
try {
ast = esprima.parseModule(codeString);
} catch (error) {
// esprima throws parsing error webpack devtool setting generates code
console.log('unable to use esprima parser');
codeString = stringParser(codeString, injectableUseReducerString, uRsig);
codeString = stringParser(codeString, injectableCommitAllHostEffectsString, cAHEsig);
return codeString;
const ast = esprima.parseModule(codeString);
// Webpack bundle is wrapped in function call
if (ast.body[0].expression.type === 'CallExpression') {
traverseBundledTree(injectableUseReducer, USEREDUCER, ast, reactLibraryPath);
traverseBundledTree(injectableCommitAllHostEffects, COMMITALLHOSTEFFECTS, ast, reactDOMLibraryPath);
} else {
// parse react-dom code
injectableCommitAllHostEffects = esprima.parseScript(commitAllHostEffectsReplacement.toString());
traverseTree(injectableCommitAllHostEffects, 'commitAllHostEffects', ast);

// parse react code
injectableUseReducer = esprima.parseScript(useReducerReplacement.toString());
traverseTree(injectableUseReducer, 'useReducer', ast);
}
// parse react-dom code
injectableCommitAllHostEffects = esprima.parseScript(commitAllHostEffectsReplacement.toString());
traverseTree(injectableCommitAllHostEffects, 'commitAllHostEffects', ast);

// parse react code
injectableUseReducer = esprima.parseScript(useReducerReplacement.toString());
traverseTree(injectableUseReducer, 'useReducer', ast);

const code = escodegen.generate(ast);
console.log('returning code.');
return code;
}
console.log('returning string.');
return codeString;
};

module.exports = parseAndGenerate;