unreachableBranchTransformer.js 1.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. var booleanCondition = require('esmangle-evaluator').booleanCondition;
  2. var recast = require('recast');
  3. var types = recast.types;
  4. var b = types.builders;
  5. var VISITOR_METHODS = {
  6. visitLogicalExpression: visitLogicalExp,
  7. visitIfStatement: visitCondition,
  8. visitConditionalExpression: visitCondition
  9. };
  10. module.exports = function(branch) {
  11. recast.visit(branch, VISITOR_METHODS);
  12. return branch;
  13. };
  14. /**
  15. * "||" and "&&"
  16. */
  17. function visitLogicalExp(path) {
  18. var leftEval = booleanCondition(path.node.left);
  19. if (typeof leftEval !== 'boolean') {
  20. // console.log('___ %s ___', path.node.operator);
  21. this.traverse(path);
  22. return;
  23. }
  24. if (leftEval === true && path.node.operator === '||') {
  25. // console.log('true || ___');
  26. path.replace(b.literal(true));
  27. recast.visit(path, VISITOR_METHODS);
  28. return false;
  29. }
  30. if (leftEval === true && path.node.operator === '&&') {
  31. // console.log('true && ___');
  32. path.replace(path.node.right);
  33. recast.visit(path, VISITOR_METHODS);
  34. return false;
  35. }
  36. if (leftEval === false && path.node.operator === '&&') {
  37. // console.log('false && ___');
  38. path.replace(b.literal(false));
  39. recast.visit(path, VISITOR_METHODS);
  40. return false;
  41. }
  42. if (leftEval === false && path.node.operator === '||') {
  43. // console.log('false || ___');
  44. path.replace(path.node.right);
  45. recast.visit(path, VISITOR_METHODS);
  46. return false;
  47. }
  48. }
  49. /**
  50. * "if" and ternary "?"
  51. */
  52. function visitCondition(path) {
  53. var testEval = booleanCondition(path.node.test);
  54. if (typeof testEval !== 'boolean') {
  55. // console.log('if/? ___');
  56. this.traverse(path);
  57. return;
  58. }
  59. if (testEval === true) {
  60. // console.log('if/? (true)');
  61. path.replace(path.value.consequent);
  62. recast.visit(path, VISITOR_METHODS);
  63. return false;
  64. }
  65. if (testEval === false) {
  66. // console.log('if/? (false)');
  67. path.replace(path.value.alternate);
  68. recast.visit(path, VISITOR_METHODS);
  69. return false;
  70. }
  71. }