comment-directive.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /**
  2. * @author Toru Nagashima <https://github.com/mysticatea>
  3. */
  4. /* eslint-disable eslint-plugin/report-message-format, consistent-docs-description */
  5. 'use strict'
  6. // -----------------------------------------------------------------------------
  7. // Helpers
  8. // -----------------------------------------------------------------------------
  9. const COMMENT_DIRECTIVE_B = /^\s*(eslint-(?:en|dis)able)(?:\s+(\S|\S[\s\S]*\S))?\s*$/
  10. const COMMENT_DIRECTIVE_L = /^\s*(eslint-disable(?:-next)?-line)(?:\s+(\S|\S[\s\S]*\S))?\s*$/
  11. /**
  12. * Parse a given comment.
  13. * @param {RegExp} pattern The RegExp pattern to parse.
  14. * @param {string} comment The comment value to parse.
  15. * @returns {({type:string,rules:string[]})|null} The parsing result.
  16. */
  17. function parse (pattern, comment) {
  18. const match = pattern.exec(comment)
  19. if (match == null) {
  20. return null
  21. }
  22. const type = match[1]
  23. const rules = (match[2] || '')
  24. .split(',')
  25. .map(s => s.trim())
  26. .filter(Boolean)
  27. return { type, rules }
  28. }
  29. /**
  30. * Enable rules.
  31. * @param {RuleContext} context The rule context.
  32. * @param {{line:number,column:number}} loc The location information to enable.
  33. * @param {string} group The group to enable.
  34. * @param {string[]} rules The rule IDs to enable.
  35. * @returns {void}
  36. */
  37. function enable (context, loc, group, rules) {
  38. if (rules.length === 0) {
  39. context.report({ loc, message: '++ {{group}}', data: { group }})
  40. } else {
  41. context.report({ loc, message: '+ {{group}} {{rules}}', data: { group, rules: rules.join(' ') }})
  42. }
  43. }
  44. /**
  45. * Disable rules.
  46. * @param {RuleContext} context The rule context.
  47. * @param {{line:number,column:number}} loc The location information to disable.
  48. * @param {string} group The group to disable.
  49. * @param {string[]} rules The rule IDs to disable.
  50. * @returns {void}
  51. */
  52. function disable (context, loc, group, rules) {
  53. if (rules.length === 0) {
  54. context.report({ loc, message: '-- {{group}}', data: { group }})
  55. } else {
  56. context.report({ loc, message: '- {{group}} {{rules}}', data: { group, rules: rules.join(' ') }})
  57. }
  58. }
  59. /**
  60. * Process a given comment token.
  61. * If the comment is `eslint-disable` or `eslint-enable` then it reports the comment.
  62. * @param {RuleContext} context The rule context.
  63. * @param {Token} comment The comment token to process.
  64. * @returns {void}
  65. */
  66. function processBlock (context, comment) {
  67. const parsed = parse(COMMENT_DIRECTIVE_B, comment.value)
  68. if (parsed != null) {
  69. if (parsed.type === 'eslint-disable') {
  70. disable(context, comment.loc.start, 'block', parsed.rules)
  71. } else {
  72. enable(context, comment.loc.start, 'block', parsed.rules)
  73. }
  74. }
  75. }
  76. /**
  77. * Process a given comment token.
  78. * If the comment is `eslint-disable-line` or `eslint-disable-next-line` then it reports the comment.
  79. * @param {RuleContext} context The rule context.
  80. * @param {Token} comment The comment token to process.
  81. * @returns {void}
  82. */
  83. function processLine (context, comment) {
  84. const parsed = parse(COMMENT_DIRECTIVE_L, comment.value)
  85. if (parsed != null && comment.loc.start.line === comment.loc.end.line) {
  86. const line = comment.loc.start.line + (parsed.type === 'eslint-disable-line' ? 0 : 1)
  87. const column = -1
  88. disable(context, { line, column }, 'line', parsed.rules)
  89. enable(context, { line: line + 1, column }, 'line', parsed.rules)
  90. }
  91. }
  92. // -----------------------------------------------------------------------------
  93. // Rule Definition
  94. // -----------------------------------------------------------------------------
  95. module.exports = {
  96. meta: {
  97. type: 'problem',
  98. docs: {
  99. description: 'support comment-directives in `<template>`',
  100. category: 'base',
  101. url: 'https://eslint.vuejs.org/rules/comment-directive.html'
  102. },
  103. schema: []
  104. },
  105. create (context) {
  106. return {
  107. Program (node) {
  108. if (!node.templateBody) {
  109. return
  110. }
  111. // Send directives to the post-process.
  112. for (const comment of node.templateBody.comments) {
  113. processBlock(context, comment)
  114. processLine(context, comment)
  115. }
  116. // Send a clear mark to the post-process.
  117. context.report({
  118. loc: node.templateBody.loc.end,
  119. message: 'clear'
  120. })
  121. }
  122. }
  123. }
  124. }