From 17011cb29f0db4887b79590f6940400e19af26be Mon Sep 17 00:00:00 2001 From: Kia Date: Sun, 17 Mar 2019 13:00:17 -0400 Subject: [PATCH 1/3] returns our code in function. Issue parsing string because argument is not being replaced as a node literal. --- src/browser/chrome/scripts/parser.js | 101 ++++++++++++++++++--------- 1 file changed, 68 insertions(+), 33 deletions(-) diff --git a/src/browser/chrome/scripts/parser.js b/src/browser/chrome/scripts/parser.js index 8ee3d2d..f7f6939 100644 --- a/src/browser/chrome/scripts/parser.js +++ b/src/browser/chrome/scripts/parser.js @@ -35,27 +35,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); @@ -67,7 +67,7 @@ function commitAllHostEffectsReplacement() { { commitPlacement(nextEffect); nextEffect.effectTag &= ~Placement; - let _current = nextEffect.alternate; + const _current = nextEffect.alternate; commitWork(_current, nextEffect); break; } @@ -80,7 +80,7 @@ function commitAllHostEffectsReplacement() { current: _.cloneDeep(nextEffect.alternate), }); - let _current2 = nextEffect.alternate; + const _current2 = nextEffect.alternate; commitWork(_current2, nextEffect); break; } @@ -106,17 +106,22 @@ function commitAllHostEffectsReplacement() { // 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); +const injectableUseReducerString = escodegen.generate(injectableUseReducer.body[0].body); let injectableCommitAllHostEffects = esprima.parseScript(commitAllHostEffectsReplacement.toString()); -let injectableCommitAllHostEffectsString = escodegen.generate(injectableCommitAllHostEffects.body[0].body); +const 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') { @@ -129,7 +134,7 @@ function traverseTree(replacementNode, functionName, ast) { }); } function stringParser(string, newBody, methodSig) { - let stack = []; + const stack = []; const foundMethod = methodSig.test(string); let oldBody = ''; let output; @@ -151,32 +156,62 @@ function stringParser(string, newBody, methodSig) { } return output; } +function traverseBundledTree(replacementNode, functionName, ast, library) { + estraverse.replace(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, { range: true, tokens: true, comment: true }); + const reactLib = esprima.parseScript(node.value.body.body[1].expression.arguments[0].value); + estraverse.replace(reactLib, { + enter(libNode) { + if (libNode.type === 'FunctionDeclaration') { + if (libNode.id.name === functionName) { + libNode.body = replacementNode.body[0].body; + console.log('From parser. REPLACING!', libNode.id.name); + // return libNode; + } + } + }, + }); + // reactLib = escodegen.attachComments(reactLib, reactLib.comments, reactLib.tokens); + node.value.body.body[1].expression.arguments = escodegen.generate(reactLib); + console.log('generated'); + // node.value.body.body[1].expression.arguments[0].value = escodegen.generate(reactLib, { comment: true }); + // node.value.body.body[1].expression.arguments[0].value = stringParser(node.value.body.body[1].expression.arguments[0].value, replacementNode, functionName); + } + } + } + }, + }); +} + 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') { + // if (ast.body[0].expression.arguments[0].properties[6].key.value ==='./node_modules/react/cjs/react.development.js'){ + // const reactLib = esprima.parseModule(ast.body[0].expression.arguments[0].properties[6].value.body.body[1].expression.arguments[0].value); + // .value at end is a string + traverseBundledTree(injectableUseReducer, USEREDUCER, ast, reactLibraryPath); + traverseBundledTree(injectableCommitAllHostEffects, COMMITALLHOSTEFFECTS, ast, reactDOMLibraryPath); + // traverseBundledTree(injectableUseReducerString, uRsig, ast, reactLibraryPath); + // traverseBundledTree(injectableCommitAllHostEffectsString, cAHEsig, 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; From 2a4fff66dbef6497f78506a22864b245cb41811b Mon Sep 17 00:00:00 2001 From: Kia Date: Sun, 17 Mar 2019 18:16:17 -0400 Subject: [PATCH 2/3] The methods are replaced but getting the lodash error. --- src/browser/chrome/scripts/parser.js | 52 +++++----------------------- 1 file changed, 8 insertions(+), 44 deletions(-) diff --git a/src/browser/chrome/scripts/parser.js b/src/browser/chrome/scripts/parser.js index f7f6939..ebea577 100644 --- a/src/browser/chrome/scripts/parser.js +++ b/src/browser/chrome/scripts/parser.js @@ -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() { @@ -103,9 +102,7 @@ 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'); + // method names const USEREDUCER = 'useReducer'; const COMMITALLHOSTEFFECTS = 'commitAllHostEffects'; @@ -114,10 +111,8 @@ 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()); -const injectableUseReducerString = escodegen.generate(injectableUseReducer.body[0].body); let injectableCommitAllHostEffects = esprima.parseScript(commitAllHostEffectsReplacement.toString()); -const 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) { @@ -133,54 +128,28 @@ function traverseTree(replacementNode, functionName, ast) { }, }); } -function stringParser(string, newBody, methodSig) { - const 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]; - } - } - } - return output; -} + function traverseBundledTree(replacementNode, functionName, ast, library) { - estraverse.replace(ast, { + 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, { range: true, tokens: true, comment: true }); const reactLib = esprima.parseScript(node.value.body.body[1].expression.arguments[0].value); - estraverse.replace(reactLib, { + 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!', libNode.id.name); - // return libNode; + console.log('From parser. REPLACING body!', libNode.id.name); } } }, }); - // reactLib = escodegen.attachComments(reactLib, reactLib.comments, reactLib.tokens); - node.value.body.body[1].expression.arguments = escodegen.generate(reactLib); - console.log('generated'); - // node.value.body.body[1].expression.arguments[0].value = escodegen.generate(reactLib, { comment: true }); - // node.value.body.body[1].expression.arguments[0].value = stringParser(node.value.body.body[1].expression.arguments[0].value, replacementNode, functionName); + 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'); } } } @@ -193,13 +162,8 @@ const parseAndGenerate = (codeString) => { const ast = esprima.parseModule(codeString); // Webpack bundle is wrapped in function call if (ast.body[0].expression.type === 'CallExpression') { - // if (ast.body[0].expression.arguments[0].properties[6].key.value ==='./node_modules/react/cjs/react.development.js'){ - // const reactLib = esprima.parseModule(ast.body[0].expression.arguments[0].properties[6].value.body.body[1].expression.arguments[0].value); - // .value at end is a string traverseBundledTree(injectableUseReducer, USEREDUCER, ast, reactLibraryPath); traverseBundledTree(injectableCommitAllHostEffects, COMMITALLHOSTEFFECTS, ast, reactDOMLibraryPath); - // traverseBundledTree(injectableUseReducerString, uRsig, ast, reactLibraryPath); - // traverseBundledTree(injectableCommitAllHostEffectsString, cAHEsig, ast, reactDOMLibraryPath); } else { // parse react-dom code injectableCommitAllHostEffects = esprima.parseScript(commitAllHostEffectsReplacement.toString()); From a03fd7fbe693cb7082283ebd0c0e14a666011f3f Mon Sep 17 00:00:00 2001 From: Kia Date: Tue, 19 Mar 2019 21:09:06 -0400 Subject: [PATCH 3/3] Updated useReducer arguments --- src/browser/chrome/scripts/parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/chrome/scripts/parser.js b/src/browser/chrome/scripts/parser.js index ebea577..1a74618 100644 --- a/src/browser/chrome/scripts/parser.js +++ b/src/browser/chrome/scripts/parser.js @@ -17,7 +17,7 @@ function useReducerReplacement() { }); return newState; } - return dispatcher.useReducer(reducerWithTracker, initialArg, init); + return dispatcher.useReducer(reducerWithTracker, initialState, initialAction); } function commitAllHostEffectsReplacement() {