test.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. const parser = require('@babel/parser');
  2. const traverse = require('@babel/traverse').default;
  3. const fs = require('fs');
  4. const code = `
  5. let state = 0, x = 5;
  6. while (1) {
  7. switch (state) {
  8. case 0:
  9. console.log('执行块 0 操作')
  10. state = 1;
  11. break;
  12. case 1:
  13. state = (x > 0) ? 2 : 3;
  14. console.log('执行块 1 操作')
  15. break;
  16. case 2:
  17. console.log('执行块 2 操作')
  18. state = 4;
  19. break;
  20. case 3:
  21. console.log('执行块 3 操作')
  22. state = 4;
  23. break;
  24. case 4:
  25. console.log('程序执行完毕');
  26. }
  27. }
  28. `;
  29. const ast = parser.parse(code, { sourceType: 'module' });
  30. let initialState = null;
  31. let switchCases = {};
  32. traverse(ast, {
  33. VariableDeclarator(path) {
  34. if (path.node.id.name === 'state') {
  35. initialState = path.node.init.value;
  36. }
  37. },
  38. SwitchCase(path) {
  39. const test = path.node.test.value;
  40. const body = path.node.consequent;
  41. let logs = [];
  42. let nextState = null;
  43. body.forEach(node => {
  44. if (
  45. node.type === 'ExpressionStatement' &&
  46. node.expression.type === 'CallExpression' &&
  47. node.expression.callee.object.name === 'console'
  48. ) {
  49. logs.push(node.expression.arguments[0].value);
  50. }
  51. if (
  52. node.type === 'ExpressionStatement' &&
  53. node.expression.type === 'AssignmentExpression' &&
  54. node.expression.left.name === 'state'
  55. ) {
  56. nextState = node.expression.right;
  57. }
  58. });
  59. switchCases[test] = { logs, nextState };
  60. }
  61. });
  62. function formatNextState(nextState) {
  63. if (nextState.type === 'ConditionalExpression') {
  64. return `if (${generateCode(nextState.test)}) {
  65. ${switchCases[nextState.consequent.value].logs.map(log => `console.log('${log}')`).join('\n ')}
  66. } else {
  67. ${switchCases[nextState.alternate.value].logs.map(log => `console.log('${log}')`).join('\n ')}
  68. }`;
  69. } else if (nextState.type === 'NumericLiteral') {
  70. const logs = switchCases[nextState.value]?.logs || [];
  71. return logs.map(log => `console.log('${log}')`).join('\n');
  72. } else {
  73. return '// 未识别的跳转';
  74. }
  75. }
  76. function generateCode(node) {
  77. if (node.type === 'BinaryExpression') {
  78. return `${node.left.name} ${node.operator} ${node.right.value}`;
  79. }
  80. return '// 未识别表达式';
  81. }
  82. // 🌳 生成结构化代码
  83. let outputCode = '';
  84. outputCode += switchCases[0].logs.map(log => `console.log('${log}')`).join('\n') + '\n';
  85. outputCode += formatNextState(switchCases[1].nextState) + '\n';
  86. outputCode += switchCases[4].logs.map(log => `console.log('${log}')`).join('\n');
  87. console.log('\n✅ 结构化还原后的代码:\n');
  88. console.log(outputCode);