jsx-quotes.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /**
  2. * @fileoverview A rule to ensure consistent quotes used in jsx syntax.
  3. * @author Mathias Schreck <https://github.com/lo1tuma>
  4. * @deprecated in ESLint v8.53.0
  5. */
  6. "use strict";
  7. //------------------------------------------------------------------------------
  8. // Requirements
  9. //------------------------------------------------------------------------------
  10. const astUtils = require("./utils/ast-utils");
  11. //------------------------------------------------------------------------------
  12. // Constants
  13. //------------------------------------------------------------------------------
  14. const QUOTE_SETTINGS = {
  15. "prefer-double": {
  16. quote: '"',
  17. description: "singlequote",
  18. convert(str) {
  19. return str.replace(/'/gu, '"');
  20. },
  21. },
  22. "prefer-single": {
  23. quote: "'",
  24. description: "doublequote",
  25. convert(str) {
  26. return str.replace(/"/gu, "'");
  27. },
  28. },
  29. };
  30. //------------------------------------------------------------------------------
  31. // Rule Definition
  32. //------------------------------------------------------------------------------
  33. /** @type {import('../types').Rule.RuleModule} */
  34. module.exports = {
  35. meta: {
  36. deprecated: {
  37. message: "Formatting rules are being moved out of ESLint core.",
  38. url: "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
  39. deprecatedSince: "8.53.0",
  40. availableUntil: "11.0.0",
  41. replacedBy: [
  42. {
  43. message:
  44. "ESLint Stylistic now maintains deprecated stylistic core rules.",
  45. url: "https://eslint.style/guide/migration",
  46. plugin: {
  47. name: "@stylistic/eslint-plugin",
  48. url: "https://eslint.style",
  49. },
  50. rule: {
  51. name: "jsx-quotes",
  52. url: "https://eslint.style/rules/jsx-quotes",
  53. },
  54. },
  55. ],
  56. },
  57. type: "layout",
  58. docs: {
  59. description:
  60. "Enforce the consistent use of either double or single quotes in JSX attributes",
  61. recommended: false,
  62. url: "https://eslint.org/docs/latest/rules/jsx-quotes",
  63. },
  64. fixable: "whitespace",
  65. schema: [
  66. {
  67. enum: ["prefer-single", "prefer-double"],
  68. },
  69. ],
  70. messages: {
  71. unexpected: "Unexpected usage of {{description}}.",
  72. },
  73. },
  74. create(context) {
  75. const quoteOption = context.options[0] || "prefer-double",
  76. setting = QUOTE_SETTINGS[quoteOption];
  77. /**
  78. * Checks if the given string literal node uses the expected quotes
  79. * @param {ASTNode} node A string literal node.
  80. * @returns {boolean} Whether or not the string literal used the expected quotes.
  81. * @public
  82. */
  83. function usesExpectedQuotes(node) {
  84. return (
  85. node.value.includes(setting.quote) ||
  86. astUtils.isSurroundedBy(node.raw, setting.quote)
  87. );
  88. }
  89. return {
  90. JSXAttribute(node) {
  91. const attributeValue = node.value;
  92. if (
  93. attributeValue &&
  94. astUtils.isStringLiteral(attributeValue) &&
  95. !usesExpectedQuotes(attributeValue)
  96. ) {
  97. context.report({
  98. node: attributeValue,
  99. messageId: "unexpected",
  100. data: {
  101. description: setting.description,
  102. },
  103. fix(fixer) {
  104. return fixer.replaceText(
  105. attributeValue,
  106. setting.convert(attributeValue.raw),
  107. );
  108. },
  109. });
  110. }
  111. },
  112. };
  113. },
  114. };