require-macro-variable-name.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /**
  2. * @author ItMaga
  3. * See LICENSE file in root directory for full license.
  4. */
  5. 'use strict'
  6. const utils = require('../utils')
  7. const DEFAULT_OPTIONS = {
  8. defineProps: 'props',
  9. defineEmits: 'emit',
  10. defineSlots: 'slots',
  11. useSlots: 'slots',
  12. useAttrs: 'attrs'
  13. }
  14. module.exports = {
  15. meta: {
  16. type: 'suggestion',
  17. docs: {
  18. description: 'require a certain macro variable name',
  19. categories: undefined,
  20. url: 'https://eslint.vuejs.org/rules/require-macro-variable-name.html'
  21. },
  22. fixable: null,
  23. hasSuggestions: true,
  24. schema: [
  25. {
  26. type: 'object',
  27. properties: {
  28. defineProps: {
  29. type: 'string',
  30. default: DEFAULT_OPTIONS.defineProps
  31. },
  32. defineEmits: {
  33. type: 'string',
  34. default: DEFAULT_OPTIONS.defineEmits
  35. },
  36. defineSlots: {
  37. type: 'string',
  38. default: DEFAULT_OPTIONS.defineSlots
  39. },
  40. useSlots: {
  41. type: 'string',
  42. default: DEFAULT_OPTIONS.useSlots
  43. },
  44. useAttrs: {
  45. type: 'string',
  46. default: DEFAULT_OPTIONS.useAttrs
  47. }
  48. },
  49. additionalProperties: false
  50. }
  51. ],
  52. messages: {
  53. requireName:
  54. 'The variable name of "{{macroName}}" must be "{{variableName}}".',
  55. changeName: 'Change the variable name to "{{variableName}}".'
  56. }
  57. },
  58. /** @param {RuleContext} context */
  59. create(context) {
  60. const options = context.options[0] || DEFAULT_OPTIONS
  61. const relevantMacros = new Set([
  62. ...Object.keys(DEFAULT_OPTIONS),
  63. 'withDefaults'
  64. ])
  65. return utils.defineScriptSetupVisitor(context, {
  66. VariableDeclarator(node) {
  67. if (
  68. node.init &&
  69. node.init.type === 'CallExpression' &&
  70. node.init.callee.type === 'Identifier' &&
  71. relevantMacros.has(node.init.callee.name)
  72. ) {
  73. const macroName =
  74. node.init.callee.name === 'withDefaults'
  75. ? 'defineProps'
  76. : node.init.callee.name
  77. if (
  78. node.id.type === 'Identifier' &&
  79. node.id.name !== options[macroName]
  80. ) {
  81. context.report({
  82. node: node.id,
  83. loc: node.id.loc,
  84. messageId: 'requireName',
  85. data: {
  86. macroName,
  87. variableName: options[macroName]
  88. },
  89. suggest: [
  90. {
  91. messageId: 'changeName',
  92. data: {
  93. variableName: options[macroName]
  94. },
  95. fix(fixer) {
  96. return fixer.replaceText(node.id, options[macroName])
  97. }
  98. }
  99. ]
  100. })
  101. }
  102. }
  103. }
  104. })
  105. }
  106. }