Skip to content

Commit de7472e

Browse files
Merge pull request #67 from kiacolbert/parser2
Parser2
2 parents 9ad875a + a03fd7f commit de7472e

File tree

1 file changed

+56
-57
lines changed

1 file changed

+56
-57
lines changed
Lines changed: 56 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
const esprima = require('esprima');
22
const estraverse = require('estraverse');
33
const escodegen = require('escodegen');
4-
const _ = require('lodash');
54

65
// declare functions to insert
76
function useReducerReplacement() {
@@ -18,7 +17,7 @@ function useReducerReplacement() {
1817
});
1918
return newState;
2019
}
21-
return dispatcher.useReducer(reducerWithTracker, initialArg, init);
20+
return dispatcher.useReducer(reducerWithTracker, initialState, initialAction);
2221
}
2322

2423
function commitAllHostEffectsReplacement() {
@@ -35,27 +34,27 @@ function commitAllHostEffectsReplacement() {
3534
}
3635
recordEffect();
3736

38-
let {effectTag} = nextEffect;
37+
const { effectTag } = nextEffect;
3938

4039
if (effectTag & ContentReset) {
4140
commitResetTextContent(nextEffect);
4241
}
4342

4443
if (effectTag & Ref) {
45-
let current$$1 = nextEffect.alternate;
44+
const current$$1 = nextEffect.alternate;
4645
if (current$$1 !== null) {
4746
commitDetachRef(current$$1);
4847
}
4948
}
5049

51-
let primaryEffectTag = effectTag & (Placement | Update | Deletion);
50+
const primaryEffectTag = effectTag & (Placement | Update | Deletion);
5251
switch (primaryEffectTag) {
5352
case Placement:
5453
{
5554
// editbyme
5655
timeTravelLList.append({
57-
primaryEffectTag: 'PLACEMENT',
58-
effect: _.cloneDeep(nextEffect),
56+
primaryEffectTag: 'PLACEMENT',
57+
effect: _.cloneDeep(nextEffect),
5958
});
6059

6160
commitPlacement(nextEffect);
@@ -67,7 +66,7 @@ function commitAllHostEffectsReplacement() {
6766
{
6867
commitPlacement(nextEffect);
6968
nextEffect.effectTag &= ~Placement;
70-
let _current = nextEffect.alternate;
69+
const _current = nextEffect.alternate;
7170
commitWork(_current, nextEffect);
7271
break;
7372
}
@@ -80,7 +79,7 @@ function commitAllHostEffectsReplacement() {
8079
current: _.cloneDeep(nextEffect.alternate),
8180
});
8281

83-
let _current2 = nextEffect.alternate;
82+
const _current2 = nextEffect.alternate;
8483
commitWork(_current2, nextEffect);
8584
break;
8685
}
@@ -103,20 +102,21 @@ function commitAllHostEffectsReplacement() {
103102
resetCurrentFiber();
104103
}
105104
}
106-
// regex method signatures
107-
const uRsig = new RegExp(/\b(useReducer)\b\(reducer, initialArg, init\)/);
108-
const cAHEsig = new RegExp(/\b(function)\b\s\b(commitAllHostEffects)\b\(\)/, 'g');
109105

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

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

117117
// traverse ast to find method and replace body with our node's body
118118
function traverseTree(replacementNode, functionName, ast) {
119-
console.log('traverse called');
119+
console.log('unbundled traverse called');
120120
estraverse.replace(ast, {
121121
enter(node) {
122122
if (node.type === 'FunctionDeclaration') {
@@ -128,55 +128,54 @@ function traverseTree(replacementNode, functionName, ast) {
128128
},
129129
});
130130
}
131-
function stringParser(string, newBody, methodSig) {
132-
let stack = [];
133-
const foundMethod = methodSig.test(string);
134-
let oldBody = '';
135-
let output;
136-
for (let i = methodSig.lastIndex; i < string.length; i++) {
137-
if (foundMethod) {
138-
if (string[i] === '{') {
139-
stack.push(string[i]);
140-
}
141-
if (stack.length > 0 && stack[stack.length - 1] === '{' && string[i] === '}') {
142-
stack.pop();
143-
oldBody += string[i];
144-
output = string.replace(oldBody, newBody);
145-
break;
146-
}
147-
if (stack.length > 0) {
148-
oldBody += string[i];
131+
132+
function traverseBundledTree(replacementNode, functionName, ast, library) {
133+
estraverse.traverse(ast, {
134+
enter(node) {
135+
if (node.key && node.key.value === library) {
136+
if (node.value.body.body[1].type === 'ExpressionStatement') {
137+
if (node.value.body.body[1].expression.callee.name === 'eval') {
138+
// create new ast
139+
const reactLib = esprima.parseScript(node.value.body.body[1].expression.arguments[0].value);
140+
estraverse.traverse(reactLib, {
141+
enter(libNode) {
142+
if (libNode.type === 'FunctionDeclaration') {
143+
if (libNode.id.name === functionName) {
144+
libNode.body = replacementNode.body[0].body;
145+
console.log('From parser. REPLACING body!', libNode.id.name);
146+
}
147+
}
148+
},
149+
});
150+
node.value.body.body[1].expression.arguments[0].value = escodegen.generate(reactLib);
151+
node.value.body.body[1].expression.arguments[0].raw = JSON.stringify(escodegen.generate(reactLib));
152+
console.log('arguments replaced');
153+
}
154+
}
149155
}
150-
}
151-
}
152-
return output;
156+
},
157+
});
153158
}
159+
154160
const parseAndGenerate = (codeString) => {
155161
if (codeString.search('react') !== -1) {
156-
let ast;
157-
try {
158-
ast = esprima.parseModule(codeString);
159-
} catch (error) {
160-
// esprima throws parsing error webpack devtool setting generates code
161-
console.log('unable to use esprima parser');
162-
codeString = stringParser(codeString, injectableUseReducerString, uRsig);
163-
codeString = stringParser(codeString, injectableCommitAllHostEffectsString, cAHEsig);
164-
return codeString;
162+
const ast = esprima.parseModule(codeString);
163+
// Webpack bundle is wrapped in function call
164+
if (ast.body[0].expression.type === 'CallExpression') {
165+
traverseBundledTree(injectableUseReducer, USEREDUCER, ast, reactLibraryPath);
166+
traverseBundledTree(injectableCommitAllHostEffects, COMMITALLHOSTEFFECTS, ast, reactDOMLibraryPath);
167+
} else {
168+
// parse react-dom code
169+
injectableCommitAllHostEffects = esprima.parseScript(commitAllHostEffectsReplacement.toString());
170+
traverseTree(injectableCommitAllHostEffects, 'commitAllHostEffects', ast);
171+
172+
// parse react code
173+
injectableUseReducer = esprima.parseScript(useReducerReplacement.toString());
174+
traverseTree(injectableUseReducer, 'useReducer', ast);
165175
}
166-
// parse react-dom code
167-
injectableCommitAllHostEffects = esprima.parseScript(commitAllHostEffectsReplacement.toString());
168-
traverseTree(injectableCommitAllHostEffects, 'commitAllHostEffects', ast);
169-
170-
// parse react code
171-
injectableUseReducer = esprima.parseScript(useReducerReplacement.toString());
172-
traverseTree(injectableUseReducer, 'useReducer', ast);
173-
174176
const code = escodegen.generate(ast);
175177
console.log('returning code.');
176178
return code;
177179
}
178-
console.log('returning string.');
179-
return codeString;
180180
};
181-
182181
module.exports = parseAndGenerate;

0 commit comments

Comments
 (0)