no-string-refs.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /**
  2. * @fileoverview Prevent string definitions for references and prevent referencing this.refs
  3. * @author Tom Hastjarjanto
  4. */
  5. 'use strict';
  6. const Components = require('../util/Components');
  7. const docsUrl = require('../util/docsUrl');
  8. // ------------------------------------------------------------------------------
  9. // Rule Definition
  10. // ------------------------------------------------------------------------------
  11. module.exports = {
  12. meta: {
  13. docs: {
  14. description: 'Prevent string definitions for references and prevent referencing this.refs',
  15. category: 'Best Practices',
  16. recommended: true,
  17. url: docsUrl('no-string-refs')
  18. },
  19. schema: []
  20. },
  21. create: Components.detect((context, components, utils) => {
  22. /**
  23. * Checks if we are using refs
  24. * @param {ASTNode} node The AST node being checked.
  25. * @returns {Boolean} True if we are using refs, false if not.
  26. */
  27. function isRefsUsage(node) {
  28. return Boolean(
  29. (
  30. utils.getParentES6Component() ||
  31. utils.getParentES5Component()
  32. ) &&
  33. node.object.type === 'ThisExpression' &&
  34. node.property.name === 'refs'
  35. );
  36. }
  37. /**
  38. * Checks if we are using a ref attribute
  39. * @param {ASTNode} node The AST node being checked.
  40. * @returns {Boolean} True if we are using a ref attribute, false if not.
  41. */
  42. function isRefAttribute(node) {
  43. return Boolean(
  44. node.type === 'JSXAttribute' &&
  45. node.name &&
  46. node.name.name === 'ref'
  47. );
  48. }
  49. /**
  50. * Checks if a node contains a string value
  51. * @param {ASTNode} node The AST node being checked.
  52. * @returns {Boolean} True if the node contains a string value, false if not.
  53. */
  54. function containsStringLiteral(node) {
  55. return Boolean(
  56. node.value &&
  57. node.value.type === 'Literal' &&
  58. typeof node.value.value === 'string'
  59. );
  60. }
  61. /**
  62. * Checks if a node contains a string value within a jsx expression
  63. * @param {ASTNode} node The AST node being checked.
  64. * @returns {Boolean} True if the node contains a string value within a jsx expression, false if not.
  65. */
  66. function containsStringExpressionContainer(node) {
  67. return Boolean(
  68. node.value &&
  69. node.value.type === 'JSXExpressionContainer' &&
  70. node.value.expression &&
  71. node.value.expression.type === 'Literal' &&
  72. typeof node.value.expression.value === 'string'
  73. );
  74. }
  75. return {
  76. MemberExpression: function(node) {
  77. if (isRefsUsage(node)) {
  78. context.report({
  79. node: node,
  80. message: 'Using this.refs is deprecated.'
  81. });
  82. }
  83. },
  84. JSXAttribute: function(node) {
  85. if (
  86. isRefAttribute(node) &&
  87. (containsStringLiteral(node) || containsStringExpressionContainer(node))
  88. ) {
  89. context.report({
  90. node: node,
  91. message: 'Using string literals in ref attributes is deprecated.'
  92. });
  93. }
  94. }
  95. };
  96. })
  97. };