| OLD | NEW |
| 1 // This script rewrites AST to be compatible with JavaScript 1.5 and decompiles | 1 // This script rewrites AST to be compatible with JavaScript 1.5 and decompiles |
| 2 // the modified tree then | 2 // the modified tree then |
| 3 | 3 |
| 4 include("../scripts/astDecompile.js"); | 4 include("../scripts/astDecompile.js"); |
| 5 include("../utils/beautify.js"); | 5 include("../utils/beautify.js"); |
| 6 | 6 |
| 7 let headerPrinted = false; | 7 let headerPrinted = false; |
| 8 | 8 |
| 9 // See https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API for | 9 // See https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API for |
| 10 // AST structure. | 10 // AST structure. |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 ast.consequent = ensureBlock(ast.consequent); | 313 ast.consequent = ensureBlock(ast.consequent); |
| 314 if (ast.alternate && ast.alternate.type != "IfStatement") | 314 if (ast.alternate && ast.alternate.type != "IfStatement") |
| 315 ast.alternate = ensureBlock(ast.alternate); | 315 ast.alternate = ensureBlock(ast.alternate); |
| 316 return ast; | 316 return ast; |
| 317 } | 317 } |
| 318 | 318 |
| 319 function modifyForInStatement(ast) | 319 function modifyForInStatement(ast) |
| 320 { | 320 { |
| 321 if (ast.each) | 321 if (ast.each) |
| 322 { | 322 { |
| 323 // Convert "for each" loops: | 323 print("Use for (.. of ..) instead of for each (..)!\n"); |
| 324 // for each (var foo in fooList) | 324 throw new Error("Use for (.. of ..) instead of for each (..)!"); |
| 325 // { | |
| 326 // ... | |
| 327 // } | |
| 328 // | |
| 329 // Change into: | |
| 330 // for (var _loopIndex44 = 0; _loopIndex44 < fooList.length; ++_loopIndex44) | |
| 331 // { | |
| 332 // var foo = fooList[_loopIndex44]; | |
| 333 // ... | |
| 334 // } | |
| 335 let loopIndex = Identifier("_loopIndex" + options.varIndex++); | |
| 336 | |
| 337 let block = ensureBlock(ast.body); | |
| 338 if (ast.left.type == "VariableDeclaration") | |
| 339 block.body.unshift(VariableDeclaration(ast.left.declarations[0].id, Member
(ast.right, loopIndex, true))); | |
| 340 else | |
| 341 block.body.unshift(Assignment(ast.left, Member(ast.right, loopIndex, true)
)); | |
| 342 | |
| 343 return { | |
| 344 type: "ForStatement", | |
| 345 init: VariableDeclaration(loopIndex, 0), | |
| 346 test: LogicalExpression(loopIndex, "<", Member(ast.right, "length", false)
), | |
| 347 update: IncExpression(loopIndex), | |
| 348 body: block | |
| 349 }; | |
| 350 } | 325 } |
| 351 | 326 |
| 352 // Make sure that the loop body is always wrapped in a block | 327 // Make sure that the loop body is always wrapped in a block |
| 353 ast.body = ensureBlock(ast.body); | 328 ast.body = ensureBlock(ast.body); |
| 354 | 329 |
| 355 return ast; | 330 return ast; |
| 356 } | 331 } |
| 357 | 332 |
| 333 function modifyForOfStatement(ast) |
| 334 { |
| 335 // Convert "for of" loops: |
| 336 // for (var foo of fooList) |
| 337 // { |
| 338 // ... |
| 339 // } |
| 340 // |
| 341 // Change into: |
| 342 // for (var _loopIndex44 = 0; _loopIndex44 < fooList.length; ++_loopIndex44) |
| 343 // { |
| 344 // var foo = fooList[_loopIndex44]; |
| 345 // ... |
| 346 // } |
| 347 let loopIndex = Identifier("_loopIndex" + options.varIndex++); |
| 348 |
| 349 let block = ensureBlock(ast.body); |
| 350 if (ast.left.type == "VariableDeclaration") |
| 351 block.body.unshift(VariableDeclaration(ast.left.declarations[0].id, Member(a
st.right, loopIndex, true))); |
| 352 else |
| 353 block.body.unshift(Assignment(ast.left, Member(ast.right, loopIndex, true)))
; |
| 354 |
| 355 return { |
| 356 type: "ForStatement", |
| 357 init: VariableDeclaration(loopIndex, 0), |
| 358 test: LogicalExpression(loopIndex, "<", Member(ast.right, "length", false)), |
| 359 update: IncExpression(loopIndex), |
| 360 body: block |
| 361 }; |
| 362 } |
| 363 |
| 358 function modifyLetStatement(ast) | 364 function modifyLetStatement(ast) |
| 359 { | 365 { |
| 360 if (ast.body.type == "ForStatement" && ast.body.init == null) | 366 if (ast.body.type == "ForStatement" && ast.body.init == null) |
| 361 { | 367 { |
| 362 // Convert back "for" loops written as "let" statements: | 368 // Convert back "for" loops written as "let" statements: |
| 363 // let (foo = 0) for (; foo < bar; ++foo) | 369 // let (foo = 0) for (; foo < bar; ++foo) |
| 364 // { | 370 // { |
| 365 // ... | 371 // ... |
| 366 // } | 372 // } |
| 367 // | 373 // |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 callee: Member(options.generatorVar, "push"), | 474 callee: Member(options.generatorVar, "push"), |
| 469 arguments: [ast.argument] | 475 arguments: [ast.argument] |
| 470 }; | 476 }; |
| 471 } | 477 } |
| 472 else | 478 else |
| 473 return null; | 479 return null; |
| 474 } | 480 } |
| 475 | 481 |
| 476 process_js = function(ast, filename, args) | 482 process_js = function(ast, filename, args) |
| 477 { | 483 { |
| 478 for each (let arg in args.split(/\s+/)) | 484 for (let arg of args.split(/\s+/)) |
| 479 { | 485 { |
| 480 let match = /^(\w+)\s*=\s*(.*)/.exec(arg); | 486 let match = /^(\w+)\s*=\s*(.*)/.exec(arg); |
| 481 if (match && typeof options[match[1]] == "boolean") | 487 if (match && typeof options[match[1]] == "boolean") |
| 482 options[match[1]] = (match[2] == "true"); | 488 options[match[1]] = (match[2] == "true"); |
| 483 else if (match && typeof options[match[1]] == "string") | 489 else if (match && typeof options[match[1]] == "string") |
| 484 options[match[1]] = match[2]; | 490 options[match[1]] = match[2]; |
| 485 } | 491 } |
| 486 | 492 |
| 487 if (!headerPrinted) | 493 if (!headerPrinted) |
| 488 { | 494 { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 let code = 'require.scopes["' + options.filename + '"] = (function() {\n' + | 543 let code = 'require.scopes["' + options.filename + '"] = (function() {\n' + |
| 538 'var exports = {};\n' + | 544 'var exports = {};\n' + |
| 539 decompileAST(ast) + | 545 decompileAST(ast) + |
| 540 'return exports;\n' + | 546 'return exports;\n' + |
| 541 '})();\n'; | 547 '})();\n'; |
| 542 _print(js_beautify(code, options)); | 548 _print(js_beautify(code, options)); |
| 543 } | 549 } |
| 544 else | 550 else |
| 545 _print(js_beautify(decompileAST(ast), options)); | 551 _print(js_beautify(decompileAST(ast), options)); |
| 546 } | 552 } |
| OLD | NEW |