Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: scripts/astDecompile.js

Issue 29350140: Issue 4353 - Remove non standard for each syntax (Closed)
Patch Set: Created Aug. 24, 2016, 11:08 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | scripts/decompile.js » ('j') | scripts/decompile.js » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 let global = this; 1 let global = this;
2 function decompileAST(ast) { 2 function decompileAST(ast) {
3 let func = global["decompile" + ast.type]; 3 let func = global["decompile" + ast.type];
4 if (!func) 4 if (!func)
5 throw "Unknown type " + ast.type; 5 throw "Unknown type " + ast.type;
6 return func(ast); 6 return func(ast);
7 } 7 }
8 8
9 function decompileProgram(ast) { 9 function decompileProgram(ast) {
10 return [decompileAST(stmt) for each (stmt in ast.body)].join('\n'); 10 return ast.body.map(decompileAST).join('\n');
11 } 11 }
12 12
13 /* Statements */ 13 /* Statements */
14 function decompileEmptyStatement(ast) { 14 function decompileEmptyStatement(ast) {
15 return ";" 15 return ";"
16 } 16 }
17 function decompileBlockStatement(ast) { 17 function decompileBlockStatement(ast) {
18 return '{\n' + [decompileAST(stmt) for each (stmt in ast.body)].join('\n') + 18 return '{\n' + ast.body.map(decompileAST).join('\n') + '\n}\n';
19 '\n}\n';
20 } 19 }
21 20
22 function decompileExpressionStatement(ast) { 21 function decompileExpressionStatement(ast) {
23 return decompileAST(ast.expression) + ";"; 22 return decompileAST(ast.expression) + ";";
24 } 23 }
25 24
26 function decompileIfStatement(ast) { 25 function decompileIfStatement(ast) {
27 let str = "if (" + decompileAST(ast.test) + ")\n"; 26 let str = "if (" + decompileAST(ast.test) + ")\n";
28 str += decompileAST(ast.consequent); 27 str += decompileAST(ast.consequent);
29 if (ast.alternate) 28 if (ast.alternate)
(...skipping 13 matching lines...) Expand all
43 return "continue" + (ast.label ? " " + ast.label.name : "") + ";"; 42 return "continue" + (ast.label ? " " + ast.label.name : "") + ";";
44 } 43 }
45 44
46 function decompileWithStatement(ast) { 45 function decompileWithStatement(ast) {
47 return "with (" + decompileAST(ast.object) + ") " + decompileAST(ast.body); 46 return "with (" + decompileAST(ast.object) + ") " + decompileAST(ast.body);
48 } 47 }
49 48
50 function decompileSwitchStatement(ast) { 49 function decompileSwitchStatement(ast) {
51 let str = "switch (" + decompileAST(ast.discriminant) + ") {\n"; 50 let str = "switch (" + decompileAST(ast.discriminant) + ") {\n";
52 let cases = []; 51 let cases = [];
53 for each (let scase in ast.cases) { 52 for (let scase of ast.cases) {
54 let casestr = scase.test ? "case " + decompileAST(scase.test) : "default"; 53 let casestr = scase.test ? "case " + decompileAST(scase.test) : "default";
55 casestr += ":\n"; 54 casestr += ":\n";
56 casestr += [decompileAST(stmt) for each (stmt in scase.consequent)] 55 casestr += scase.consequent.map(decompileAST).join('\n');
57 .join('\n');
58 cases.push(casestr); 56 cases.push(casestr);
59 } 57 }
60 str += cases.join('\n') + '\n}\n'; 58 str += cases.join('\n') + '\n}\n';
61 return str; 59 return str;
62 } 60 }
63 61
64 function decompileReturnStatement(ast) { 62 function decompileReturnStatement(ast) {
65 return "return" + (ast.argument ? " " + decompileAST(ast.argument) : 63 return "return" + (ast.argument ? " " + decompileAST(ast.argument) :
66 "") + ";"; 64 "") + ";";
67 } 65 }
68 66
69 function decompileThrowStatement(ast) { 67 function decompileThrowStatement(ast) {
70 return "throw " + decompileAST(ast.argument) + ";"; 68 return "throw " + decompileAST(ast.argument) + ";";
71 } 69 }
72 70
73 function decompileTryStatement(ast) { 71 function decompileTryStatement(ast) {
74 let str = "try " + decompileAST(ast.block); 72 let str = "try " + decompileAST(ast.block);
75 73
76 let handlers = []; 74 let handlers = [];
77 if (ast.handler && "type" in ast.handler) 75 if (ast.handler && "type" in ast.handler)
78 handlers.push(ast.handler); 76 handlers.push(ast.handler);
79 else if (ast.handlers) 77 else if (ast.handlers)
80 handlers = ast.handlers; 78 handlers = ast.handlers;
81 79
82 let handler_strs = []; 80 let handler_strs = [];
83 for each (let handler in handlers) { 81 for (let handler of handlers) {
84 let handler_str = "catch (" + decompileAST(handler.param); 82 let handler_str = "catch (" + decompileAST(handler.param);
85 if (handler.guard) 83 if (handler.guard)
86 handler_str += " if " + decompileAST(handler.guard); 84 handler_str += " if " + decompileAST(handler.guard);
87 handler_str += ") " + decompileAST(handler.body); 85 handler_str += ") " + decompileAST(handler.body);
88 handler_strs.push(handler_str); 86 handler_strs.push(handler_str);
89 } 87 }
90 str += handler_strs.join(""); 88 str += handler_strs.join("");
91 if (ast.finalizer) 89 if (ast.finalizer)
92 str += " finally " + decompileAST(ast.finalizer); 90 str += " finally " + decompileAST(ast.finalizer);
93 return str; 91 return str;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 str += decompileVariableDeclaration(ast.left, true); 138 str += decompileVariableDeclaration(ast.left, true);
141 else 139 else
142 str += decompileAST(ast.left); 140 str += decompileAST(ast.left);
143 str += " of " + decompileExpr(ast.right, ast) + ") "; 141 str += " of " + decompileExpr(ast.right, ast) + ") ";
144 str += decompileAST(ast.body); 142 str += decompileAST(ast.body);
145 return str; 143 return str;
146 } 144 }
147 145
148 function decompileLetStatement(ast) { 146 function decompileLetStatement(ast) {
149 let str = "let ("; 147 let str = "let (";
150 str += [d ? decompileAST(d) : ' ' for each (d in ast.head)].join(', '); 148 str += ast.head.map(d => d ? decompileAST(d) : ' ').join(', ');
151 str += ") " + decompileAST(ast.body); 149 str += ") " + decompileAST(ast.body);
152 return str; 150 return str;
153 } 151 }
154 152
155 function decompileDebuggerStatement(ast) { 153 function decompileDebuggerStatement(ast) {
156 return "debugger;"; 154 return "debugger;";
157 } 155 }
158 156
159 function decompileFunctionDeclaration(ast, init, name_ast) { 157 function decompileFunctionDeclaration(ast, init, name_ast) {
160 let str = (init ? init : "function") + " "; 158 let str = (init ? init : "function") + " ";
161 if (ast.id) 159 if (ast.id)
162 str += ast.id.name; 160 str += ast.id.name;
163 else if (name_ast) 161 else if (name_ast)
164 str += decompileAST(name_ast); 162 str += decompileAST(name_ast);
165 str += "("; 163 str += "(";
166 str += [decompileAST(param) for each (param in ast.params)].join(', '); 164 str += ast.params.map(decompileAST).join(', ');
167 str += ") " + decompileAST(ast.body); 165 str += ") " + decompileAST(ast.body);
168 return str; 166 return str;
169 } 167 }
170 168
171 function decompileVariableDeclaration(ast, excludeSemi) { 169 function decompileVariableDeclaration(ast, excludeSemi) {
172 let inits = []; 170 let inits = [];
173 for each (let initializer in ast.declarations) { 171 for (let initializer of ast.declarations) {
174 inits.push(decompileAST(initializer)); 172 inits.push(decompileAST(initializer));
175 } 173 }
176 return ast.kind + " " + inits.join(', ') + (excludeSemi ? "" : ";"); 174 return ast.kind + " " + inits.join(', ') + (excludeSemi ? "" : ";");
177 } 175 }
178 176
179 function decompileVariableDeclarator(ast) { 177 function decompileVariableDeclarator(ast) {
180 if (ast.init) 178 if (ast.init)
181 return decompileAST(ast.id) + " = " + decompileAST(ast.init); 179 return decompileAST(ast.id) + " = " + decompileAST(ast.init);
182 return decompileAST(ast.id); 180 return decompileAST(ast.id);
183 } 181 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 else 218 else
221 return decompileAST(expr); 219 return decompileAST(expr);
222 } 220 }
223 221
224 function decompileThisExpression(ast) { 222 function decompileThisExpression(ast) {
225 return "this"; 223 return "this";
226 } 224 }
227 225
228 function decompileArrayExpression(ast) { 226 function decompileArrayExpression(ast) {
229 if (ast.elements) 227 if (ast.elements)
230 return "[" + [el ? decompileAST(el) : "" for each (el in ast.elements)]. 228 return "[" + ast.elements.map(el => el ? decompileAST(el) : "").
231 join(", ") + "]"; 229 join(", ") + "]";
232 return "[]"; 230 return "[]";
233 } 231 }
234 232
235 function decompileObjectExpression(ast) { 233 function decompileObjectExpression(ast) {
236 let props = []; 234 let props = [];
237 for each (let prop in ast.properties) { 235 for (let prop of ast.properties) {
238 if (prop.kind == "init") 236 if (prop.kind == "init")
239 props.push(decompileAST(prop.key) + ": " + decompileAST(prop.value)); 237 props.push(decompileAST(prop.key) + ": " + decompileAST(prop.value));
240 else if (prop.kind == "get" || prop.kind == "set") 238 else if (prop.kind == "get" || prop.kind == "set")
241 props.push(decompileFunctionDeclaration(prop.value, prop.kind, prop.key)); 239 props.push(decompileFunctionDeclaration(prop.value, prop.kind, prop.key));
242 else 240 else
243 throw "Unknown kind " + prop.kind; 241 throw "Unknown kind " + prop.kind;
244 } 242 }
245 return "{\n" + props.join(",\n") + "}"; 243 return "{\n" + props.join(",\n") + "}";
246 } 244 }
247 245
248 function decompileFunctionExpression(ast) { 246 function decompileFunctionExpression(ast) {
249 return decompileFunctionDeclaration(ast); 247 return decompileFunctionDeclaration(ast);
250 } 248 }
251 249
252 function decompileArrowExpression(ast) { 250 function decompileArrowExpression(ast) {
253 let str = "(" + ast.params.map(decompileAST).join(", ") + ")"; 251 let str = "(" + ast.params.map(decompileAST).join(", ") + ")";
254 str += " => " + decompileAST(ast.body); 252 str += " => " + decompileAST(ast.body);
255 return str; 253 return str;
256 } 254 }
257 255
258 function decompileSequenceExpression(ast) { 256 function decompileSequenceExpression(ast) {
259 return "(" + [decompileExpr(e, ast) for each (e in ast.expressions)].join(", " ) + ")"; 257 return "(" + ast.expressions.map(e => decompileExpr(e, ast)).join(", ") + ")";
260 } 258 }
261 259
262 function decompileUnaryExpression(ast) { 260 function decompileUnaryExpression(ast) {
263 if (ast.prefix) 261 if (ast.prefix)
264 return ast.operator + " " + decompileExpr(ast.argument, ast); 262 return ast.operator + " " + decompileExpr(ast.argument, ast);
265 throw "ER, wtf?"; 263 throw "ER, wtf?";
266 } 264 }
267 265
268 function decompileBinaryExpression(ast) { 266 function decompileBinaryExpression(ast) {
269 return decompileExpr(ast.left, ast) + " " + ast.operator + 267 return decompileExpr(ast.left, ast) + " " + ast.operator +
(...skipping 21 matching lines...) Expand all
291 289
292 function decompileConditionalExpression(ast) { 290 function decompileConditionalExpression(ast) {
293 return decompileExpr(ast.test, ast) + " ? " + 291 return decompileExpr(ast.test, ast) + " ? " +
294 decompileExpr(ast.consequent, ast) + " : " + 292 decompileExpr(ast.consequent, ast) + " : " +
295 decompileExpr(ast.alternate, ast); 293 decompileExpr(ast.alternate, ast);
296 } 294 }
297 295
298 function decompileNewExpression(ast) { 296 function decompileNewExpression(ast) {
299 let str = "new " + decompileAST(ast.callee, ast) + "("; 297 let str = "new " + decompileAST(ast.callee, ast) + "(";
300 if (ast.arguments) 298 if (ast.arguments)
301 str += [decompileAST(arg) for each (arg in ast.arguments)].join(", "); 299 str += ast.arguments.map(decompileAST).join(", ");
302 str += ")"; 300 str += ")";
303 return str; 301 return str;
304 } 302 }
305 303
306 function decompileCallExpression(ast) { 304 function decompileCallExpression(ast) {
307 return decompileExpr(ast.callee, ast) + "(" + 305 return decompileExpr(ast.callee, ast) + "(" +
308 [decompileAST(param) for each (param in ast.arguments)] + ")"; 306 ast.arguments.map(decompileAST) + ")";
309 } 307 }
310 308
311 function decompileMemberExpression(ast) { 309 function decompileMemberExpression(ast) {
312 function isIdentifier(ast2) { 310 function isIdentifier(ast2) {
313 let val = decompileAST(ast2); 311 let val = decompileAST(ast2);
314 if (val.length == 0) return false; 312 if (val.length == 0) return false;
315 if (!(val[0] == '_' || val[0] == '$' || 313 if (!(val[0] == '_' || val[0] == '$' ||
316 (val[0] >= 'a' && val[0] <= 'z') || (val[0] >= 'A' && val[0] <= 'Z'))) 314 (val[0] >= 'a' && val[0] <= 'z') || (val[0] >= 'A' && val[0] <= 'Z')))
317 return false; 315 return false;
318 for (let i = 1; i < val.length; i++) { 316 for (let i = 1; i < val.length; i++) {
(...skipping 11 matching lines...) Expand all
330 '["' + sanitize(decompileAST(ast.property), '"') + '"]' : 328 '["' + sanitize(decompileAST(ast.property), '"') + '"]' :
331 '.' + ast.property.name); 329 '.' + ast.property.name);
332 } 330 }
333 331
334 function decompileYieldExpression(ast) { 332 function decompileYieldExpression(ast) {
335 return "yield" + (ast.argument ? " " + decompileAST(ast.argument) : ""); 333 return "yield" + (ast.argument ? " " + decompileAST(ast.argument) : "");
336 } 334 }
337 335
338 function decompileComprehensionExpression(ast, paren) { 336 function decompileComprehensionExpression(ast, paren) {
339 let str = (paren ? paren.l : "[") + decompileAST(ast.body); 337 let str = (paren ? paren.l : "[") + decompileAST(ast.body);
340 for each (let block in ast.blocks) { 338 for (let block of ast.blocks) {
341 str += (block.each ? " for each " : " for ") 339 str += (block.each ? " for each " : " for ");
342 str += "(" + decompileAST(block.left) + " in "; 340 str += "(" + decompileAST(block.left) + " in ";
343 str += decompileAST(block.right) + ")"; 341 str += decompileAST(block.right) + ")";
344 } 342 }
345 if (ast.filter) 343 if (ast.filter)
346 str += " if (" + decompileAST(ast.filter) + ")"; 344 str += " if (" + decompileAST(ast.filter) + ")";
347 return str + (paren ? paren.r : "]"); 345 return str + (paren ? paren.r : "]");
348 } 346 }
349 347
350 function decompileGeneratorExpression(ast) { 348 function decompileGeneratorExpression(ast) {
351 return decompileComprehensionExpression(ast, {l: "(", r: ")"}); 349 return decompileComprehensionExpression(ast, {l: "(", r: ")"});
352 } 350 }
353 351
354 function decompileGraphExpression(ast) { 352 function decompileGraphExpression(ast) {
355 return "#" + ast.index + "=" + decompileAST(ast.expression); 353 return "#" + ast.index + "=" + decompileAST(ast.expression);
356 } 354 }
357 355
358 function decompileGraphIndexExpression(ast) { 356 function decompileGraphIndexExpression(ast) {
359 return "#" + ast.index; 357 return "#" + ast.index;
360 } 358 }
361 359
362 function decompileLetExpression(ast) { 360 function decompileLetExpression(ast) {
363 return decompileLetStatement(ast); 361 return decompileLetStatement(ast);
364 } 362 }
365 363
366 /* Patterns */ 364 /* Patterns */
367 365
368 function decompileObjectPattern(ast) { 366 function decompileObjectPattern(ast) {
369 let str = "{"; 367 let str = "{";
370 str += [decompileAST(p.key) + ": " + decompileAST(p.value) 368 str += ast.properties.map(p => decompileAST(p.key) + ": " +
371 for each (p in ast.properties)].join(', '); 369 decompileAST(p.value)).join(', ');
372 return str + "}"; 370 return str + "}";
373 } 371 }
374 372
375 function decompileArrayPattern(ast) { 373 function decompileArrayPattern(ast) {
376 return "[" + 374 return "[" + ast.elements.map(e => e ? decompileAST(e) : ' ').join(', ') + "]" ;
377 [e ? decompileAST(e) : ' ' for each (e in ast.elements)].join(', ') + "]";
378 } 375 }
379 376
380 function decompileIdentifier(ast) { return ast.name; } 377 function decompileIdentifier(ast) { return ast.name; }
381 378
382 function sanitize(str, q) { 379 function sanitize(str, q) {
383 function replace(x) { 380 function replace(x) {
384 if (x == q) return '\\' + q; 381 if (x == q) return '\\' + q;
385 if (x == '\\') return '\\\\'; 382 if (x == '\\') return '\\\\';
386 if (x == '\b') return '\\b'; 383 if (x == '\b') return '\\b';
387 if (x == '\f') return '\\f'; 384 if (x == '\f') return '\\f';
388 if (x == '\n') return '\\n'; 385 if (x == '\n') return '\\n';
389 if (x == '\r') return '\\r'; 386 if (x == '\r') return '\\r';
390 if (x == '\t') return '\\t'; 387 if (x == '\t') return '\\t';
391 if (x == '\v') return '\\v'; 388 if (x == '\v') return '\\v';
392 let val = x.charCodeAt(0) 389 let val = x.charCodeAt(0);
393 if (x < ' ') return '\\x' + (val - val % 16) / 16 + (val % 16); 390 if (x < ' ') return '\\x' + (val - val % 16) / 16 + (val % 16);
394 return x; 391 return x;
395 } 392 }
396 return [replace(x) for each (x in str)].join(''); 393 let result = "";
394 for (let char of str)
395 result += replace(char);
396 return result;
397 } 397 }
398 398
399 function decompileLiteral(ast) { 399 function decompileLiteral(ast) {
400 if (typeof ast.value == "string") 400 if (typeof ast.value == "string")
401 return '"' + sanitize(ast.value, '"') + '"'; 401 return '"' + sanitize(ast.value, '"') + '"';
402 if (ast.value === null) 402 if (ast.value === null)
403 return "null"; 403 return "null";
404 return ast.value; 404 return ast.value;
405 } 405 }
406 406
(...skipping 28 matching lines...) Expand all
435 435
436 function decompileXMLAttributeSelector(ast) { 436 function decompileXMLAttributeSelector(ast) {
437 return "@" + decompileAST(ast.attribute); 437 return "@" + decompileAST(ast.attribute);
438 } 438 }
439 439
440 function decompileXMLFilterExpression(ast) { 440 function decompileXMLFilterExpression(ast) {
441 return decompileAST(ast.left) + ".(" + decompileAST(ast.right) + ")"; 441 return decompileAST(ast.left) + ".(" + decompileAST(ast.right) + ")";
442 } 442 }
443 443
444 function decompileXMLElement(ast) { 444 function decompileXMLElement(ast) {
445 return [decompileAST(xml) for each (xml in ast.contents)].join(''); 445 return ast.contents.map(decompileAST).join('');
446 } 446 }
447 447
448 function decompileXMLList(ast) { 448 function decompileXMLList(ast) {
449 return "<>" + [decompileAST(xml) for each (xml in ast.contents)].join("") + "< />"; 449 return "<>" + ast.contents.map(decompileAST).join("") + "</>";
Wladimir Palant 2016/08/24 14:21:50 Nit: You've added unnecessary whitespace here.
kzar 2016/08/24 14:43:20 Done.
450 } 450 }
451 451
452 function decompileXMLEscape(ast) { 452 function decompileXMLEscape(ast) {
453 return "{" + decompileAST(ast.expression) + "}"; 453 return "{" + decompileAST(ast.expression) + "}";
454 } 454 }
455 455
456 function decompileXMLText(ast) { 456 function decompileXMLText(ast) {
457 return ast.text; 457 return ast.text;
458 } 458 }
459 459
460 function tagJoin(strings) { 460 function tagJoin(strings) {
461 let str = strings[0]; 461 let str = strings[0];
462 for (let i = 1; i < strings.length; i++) 462 for (let i = 1; i < strings.length; i++)
463 str += (i % 2 ? ' ' : '=') + strings[i]; 463 str += (i % 2 ? ' ' : '=') + strings[i];
464 return str; 464 return str;
465 } 465 }
466 466
467 function decompileXMLStartTag(ast) { 467 function decompileXMLStartTag(ast) {
468 return "<" + tagJoin([decompileAST(xml) for each (xml in ast.contents)]) + ">" ; 468 return "<" + tagJoin(ast.contents.map(decompileAST)) + ">";
469 } 469 }
470 470
471 function decompileXMLEndTag(ast) { 471 function decompileXMLEndTag(ast) {
472 return "</" + tagJoin([decompileAST(xml) for each (xml in ast.contents)]) + "> "; 472 return "</" + tagJoin(ast.contents.map(decompileAST)) + ">";
473 } 473 }
474 474
475 function decompileXMLPointTag(ast) { 475 function decompileXMLPointTag(ast) {
476 return "<" + tagJoin([decompileAST(xml) for each (xml in ast.contents)]) + "/> "; 476 return "<" + tagJoin(ast.contents.map(decompileAST)) + "/>";
477 } 477 }
478 478
479 function decompileXMLName(ast) { 479 function decompileXMLName(ast) {
480 if (typeof ast.contents == "string") 480 if (typeof ast.contents == "string")
481 return ast.contents + " "; 481 return ast.contents + " ";
482 return [decompileAST(xml) for each (xml in ast.contents)].join(''); 482 return ast.contents.map(decompileAST).join('');
483 } 483 }
484 484
485 function decompileXMLAttribute(ast) { 485 function decompileXMLAttribute(ast) {
486 return '"' + ast.value + '"'; 486 return '"' + ast.value + '"';
487 } 487 }
488 488
489 function decompileXMLCdata(ast) { 489 function decompileXMLCdata(ast) {
490 return "<![CDATA[" + ast.contents + "]]>"; 490 return "<![CDATA[" + ast.contents + "]]>";
491 } 491 }
492 492
493 function decompileXMLComment(ast) { 493 function decompileXMLComment(ast) {
494 return "<!--" + ast.comment + "-->"; 494 return "<!--" + ast.comment + "-->";
495 } 495 }
496 496
497 function decompileXMLProcessingInstruction(ast) { 497 function decompileXMLProcessingInstruction(ast) {
498 return "<?" + ast.target + (ast.contents ? " " + ast.contents : "") + "?>"; 498 return "<?" + ast.target + (ast.contents ? " " + ast.contents : "") + "?>";
499 } 499 }
Wladimir Palant 2016/08/24 14:21:50 It's probably better to just remove all functions
kzar 2016/08/24 14:43:20 Done.
500 500
501 function process_js(ast) { 501 function process_js(ast) {
502 _print(decompileAST(ast)); 502 _print(decompileAST(ast));
503 } 503 }
OLDNEW
« no previous file with comments | « no previous file | scripts/decompile.js » ('j') | scripts/decompile.js » ('J')

Powered by Google App Engine
This is Rietveld