Skip to content

Commit 9a12b7c

Browse files
Merge pull request #28 from kiacolbert/ep
Parser for libraries wrapped in eval()s
2 parents f2a9a7c + 0664c7b commit 9a12b7c

File tree

1 file changed

+46
-23
lines changed

1 file changed

+46
-23
lines changed

src/browser/chrome/scripts/parser.js

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// function parser() {
21
const esprima = require('esprima');
32
const estraverse = require('estraverse');
43
const escodegen = require('escodegen');
@@ -49,45 +48,30 @@ function commitAllHostEffectsReplacement() {
4948
}
5049
}
5150

52-
// The following switch statement is only concerned about placement,
53-
// updates, and deletions. To avoid needing to add a case for every
54-
// possible bitmap value, we remove the secondary effects from the
55-
// effect tag and switch on that value.
5651
let primaryEffectTag = effectTag & (Placement | Update | Deletion);
5752
switch (primaryEffectTag) {
5853
case Placement:
5954
{
60-
// editbyme
6155
timeTravelTracker.push({
6256
primaryEffectTag: 'PLACEMENT',
6357
effect: _.cloneDeep(nextEffect),
6458
});
6559

6660
commitPlacement(nextEffect);
67-
// Clear the "placement" from effect tag so that we know that this is inserted, before
68-
// any life-cycles like componentDidMount gets called.
69-
// TODO: findDOMNode doesn't rely on this any more but isMounted
70-
// does and isMounted is deprecated anyway so we should be able
71-
// to kill this.
61+
7262
nextEffect.effectTag &= ~Placement;
7363
break;
7464
}
7565
case PlacementAndUpdate:
7666
{
77-
// Placement
7867
commitPlacement(nextEffect);
79-
// Clear the "placement" from effect tag so that we know that this is inserted, before
80-
// any life-cycles like componentDidMount gets called.
8168
nextEffect.effectTag &= ~Placement;
82-
83-
// Update
8469
let _current = nextEffect.alternate;
8570
commitWork(_current, nextEffect);
8671
break;
8772
}
8873
case Update:
8974
{
90-
// editbyme
9175
timeTravelTracker.push({
9276
primaryEffectTag: 'UPDATE',
9377
effect: _.cloneDeep(nextEffect),
@@ -100,7 +84,6 @@ function commitAllHostEffectsReplacement() {
10084
}
10185
case Deletion:
10286
{
103-
// editbyme
10487
timeTravelTracker.push({
10588
primaryEffectTag: 'DELETION',
10689
effect: _.cloneDeep(nextEffect),
@@ -117,6 +100,16 @@ function commitAllHostEffectsReplacement() {
117100
resetCurrentFiber();
118101
}
119102
}
103+
// regex method signatures
104+
const uRsig = new RegExp(/\b(useReducer)\b\(reducer, initialArg, init\)/);
105+
const cAHEsig = new RegExp(/\b(function)\b\s\b(commitAllHostEffects)\b\(\)/, 'g');
106+
107+
// get replacer method bodies
108+
let injectableUseReducer = esprima.parseScript(useReducerReplacement.toString());
109+
let injectableUseReducerString = escodegen.generate(injectableUseReducer.body[0].body);
110+
111+
let injectableCommitAllHostEffects = esprima.parseScript(commitAllHostEffectsReplacement.toString());
112+
let injectableCommitAllHostEffectsString = escodegen.generate(injectableCommitAllHostEffects.body[0].body);
120113

121114
// traverse ast to find method and replace body with our node's body
122115
function traverseTree(replacementNode, functionName, ast) {
@@ -132,17 +125,47 @@ function traverseTree(replacementNode, functionName, ast) {
132125
},
133126
});
134127
}
135-
128+
function stringParser(string, newBody, methodSig) {
129+
let stack = [];
130+
const foundMethod = methodSig.test(string);
131+
let oldBody = '';
132+
let output;
133+
for (let i = methodSig.lastIndex; i < string.length; i++) {
134+
if (foundMethod) {
135+
if (string[i] === '{') {
136+
stack.push(string[i]);
137+
}
138+
if (stack.length > 0 && stack[stack.length - 1] === '{' && string[i] === '}') {
139+
stack.pop();
140+
oldBody += string[i];
141+
output = string.replace(oldBody, newBody);
142+
break;
143+
}
144+
if (stack.length > 0) {
145+
oldBody += string[i];
146+
}
147+
}
148+
}
149+
return output;
150+
}
136151
const parseAndGenerate = (codeString) => {
137152
if (codeString.search('react') !== -1) {
138-
const ast = esprima.parseModule(codeString);
139-
153+
let ast;
154+
try {
155+
ast = esprima.parseModule(codeString);
156+
} catch (error) {
157+
// esprima throws parsing error webpack devtool setting generates code
158+
console.log('unable to use esprima parser');
159+
codeString = stringParser(codeString, injectableUseReducerString, uRsig);
160+
codeString = stringParser(codeString, injectableCommitAllHostEffectsString, cAHEsig);
161+
return codeString;
162+
}
140163
// parse react-dom code
141-
const injectableCommitAllHostEffects = esprima.parseScript(commitAllHostEffectsReplacement.toString());
164+
injectableCommitAllHostEffects = esprima.parseScript(commitAllHostEffectsReplacement.toString());
142165
traverseTree(injectableCommitAllHostEffects, 'commitAllHostEffects', ast);
143166

144167
// parse react code
145-
const injectableUseReducer = esprima.parseScript(useReducerReplacement.toString());
168+
injectableUseReducer = esprima.parseScript(useReducerReplacement.toString());
146169
traverseTree(injectableUseReducer, 'useReducer', ast);
147170

148171
const code = escodegen.generate(ast);

0 commit comments

Comments
 (0)