index.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. 'use strict';
  2. var estraverse = require('estraverse');
  3. var Syntax = estraverse.Syntax;
  4. /**
  5. * Change `assert` to `power-assert` destructively.
  6. *
  7. * @param {Object} ast
  8. * @return {Object}
  9. */
  10. function empowerAssert(ast) {
  11. estraverse.traverse(ast, {
  12. enter: enter
  13. });
  14. return ast;
  15. }
  16. /**
  17. * @param {Object} node
  18. * @param {Object} parent
  19. */
  20. function enter(node, parent) {
  21. if (node.type === Syntax.AssignmentExpression) {
  22. if (node.operator !== '=') {
  23. return;
  24. }
  25. if (!isIdentifier(node.left, 'assert')) {
  26. return;
  27. }
  28. if (replaceAssertIfMatch(node.right)) {
  29. return;
  30. }
  31. }
  32. if (node.type === Syntax.VariableDeclarator) {
  33. if (!isIdentifier(node.id, 'assert')) {
  34. return;
  35. }
  36. if (replaceAssertIfMatch(node.init)) {
  37. return;
  38. }
  39. }
  40. if (node.type === Syntax.ImportDeclaration) {
  41. var source = node.source;
  42. if (!source || source.type !== Syntax.Literal || source.value !== 'assert') {
  43. return;
  44. }
  45. changeAssertToPowerAssert(source);
  46. }
  47. }
  48. /**
  49. * @param {Object} node
  50. * @return {boolean} true if `assert` is replaced to `power-assert`.
  51. */
  52. function replaceAssertIfMatch(node) {
  53. var target;
  54. if (node === null) {
  55. return false;
  56. } else if (node.type === Syntax.CallExpression) {
  57. target = node;
  58. } else if (node.type === Syntax.MemberExpression) {
  59. target = node.object;
  60. } else {
  61. return false;
  62. }
  63. if (isRequireAssert(target)) {
  64. changeAssertToPowerAssert(target.arguments[0]);
  65. return true;
  66. }
  67. return false;
  68. }
  69. /**
  70. * @param {Object} node A Literal node.
  71. */
  72. function changeAssertToPowerAssert(node) {
  73. node.value = 'power-assert';
  74. }
  75. /**
  76. * @param {Object} node A CallExpression node.
  77. * @return {boolean} true if the node is `require('assert')`.
  78. */
  79. function isRequireAssert(node) {
  80. if (!node || node.type !== Syntax.CallExpression) {
  81. return false;
  82. }
  83. if (!isIdentifier(node.callee, 'require')) {
  84. return false;
  85. }
  86. var arg = node.arguments[0];
  87. if (!arg || arg.type !== Syntax.Literal || arg.value !== 'assert') {
  88. return false;
  89. }
  90. return true;
  91. }
  92. /**
  93. * @param {Object} node
  94. * @param {string} name
  95. * @return {boolean}
  96. */
  97. function isIdentifier(node, name) {
  98. return node &&
  99. node.type === Syntax.Identifier &&
  100. node.name === name;
  101. }
  102. module.exports = empowerAssert;
  103. empowerAssert.enter = enter;