Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi

| | Rule ID | Description |
|:---|:--------|:------------|
| | [comment-directive](./docs/rules/comment-directive.md) | support comment-directives in `<template>` |
| | [jsx-uses-vars](./docs/rules/jsx-uses-vars.md) | prevent variables used in JSX to be marked as unused |


Expand Down
24 changes: 24 additions & 0 deletions docs/rules/comment-directive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# support comment-directives in `<template>` (comment-directive)

This rule supports the following comment directives in `<template>`:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sole purpose of this rule is to provide `eslint-disable` functionality in `<template>`.
It supports usage of the following comments:
...

Plus I think you should add quick information of how this works actually, because it might be a bit confusing for people to see a rule, that actually has nothing in common with any other rule :D


- `eslint-disable`
- `eslint-enable`
- `eslint-disable-line`
- `eslint-disable-next-line`

For example:

```html
<template>
<!-- eslint-disable-next-line vue/max-attributes-per-line -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should also add this information in README

<div a="1" b="2" c="3" d="4">
</div>
</template>
```

This rule doesn't make any warning.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't throw


## Further reading

- [Disabling rules with inline comments](https://eslint.org/docs/user-guide/configuring#disabling-rules-with-inline-comments)
1 change: 1 addition & 0 deletions lib/base-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
* in order to update it's content execute "npm run update"
*/
module.exports = {
"vue/comment-directive": "error",
"vue/jsx-uses-vars": "error"
}
1 change: 1 addition & 0 deletions lib/essential-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* in order to update it's content execute "npm run update"
*/
module.exports = {
"vue/comment-directive": "error",
"vue/jsx-uses-vars": "error",
"vue/no-async-in-computed-properties": "error",
"vue/no-dupe-keys": "error",
Expand Down
4 changes: 3 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ const configs = requireAll({
dirname: resolve(__dirname, 'config'),
filter: /^([\w\-]+)\.js$/
})
const processor = require('./processor')

module.exports = {
rules,
configs
configs,
processors: { '.vue': processor }
}
60 changes: 60 additions & 0 deletions lib/processor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* @author Toru Nagashima <https://github.com/mysticatea>
*/
'use strict'

module.exports = {
preprocess (code) {
return [code]
},

postprocess (messages) {
const state = {
block: {
disableAll: false,
disableRules: new Set()
},
line: {
disableAll: false,
disableRules: new Set()
}
}

// Filter messages which are in disabled area.
return messages[0].filter(message => {
if (message.ruleId === 'vue/comment-directive') {
const rules = message.message.split(' ')
const type = rules.shift()
const group = rules.shift()
switch (type) {
case '--':
state[group].disableAll = true
break
case '++':
state[group].disableAll = false
break
case '-':
for (const rule of rules) {
state[group].disableRules.add(rule)
}
break
case '+':
for (const rule of rules) {
state[group].disableRules.delete(rule)
}
break
}
return false
} else {
return !(
state.block.disableAll ||
state.line.disableAll ||
state.block.disableRules.has(message.ruleId) ||
state.line.disableRules.has(message.ruleId)
)
}
})
},

supportsAutofix: true
}
1 change: 1 addition & 0 deletions lib/recommended-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
module.exports = {
"vue/attribute-hyphenation": "error",
"vue/comment-directive": "error",
"vue/html-end-tags": "error",
"vue/html-indent": "error",
"vue/html-quotes": "error",
Expand Down
132 changes: 132 additions & 0 deletions lib/rules/comment-directive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/**
* @author Toru Nagashima <https://github.com/mysticatea>
*/

'use strict'

// -----------------------------------------------------------------------------
// Helpers
// -----------------------------------------------------------------------------

const COMMENT_DIRECTIVE_B = /^\s*(eslint-(?:en|dis)able)\s*(?:(\S|\S[\s\S]*\S)\s*)?$/
const COMMENT_DIRECTIVE_L = /^\s*(eslint-disable(?:-next)?-line)\s*(?:(\S|\S[\s\S]*\S)\s*)?$/

/**
* Parse a given comment.
* @param {RegExp} pattern The RegExp pattern to parse.
* @param {string} comment The comment value to parse.
* @returns {({type:string,rules:string[]})|null} The parsing result.
*/
function parse (pattern, comment) {
const match = pattern.exec(comment)
if (match == null) {
return null
}

const type = match[1]
const rules = (match[2] || '')
.split(',')
.map(s => s.trim())
.filter(Boolean)

return { type, rules }
}

/**
* Enable rules.
* @param {RuleContext} context The rule context.
* @param {{line:number,column:number}} loc The location information to enable.
* @param {string} group The group to enable.
* @param {string[]} rules The rule IDs to enable.
* @returns {void}
*/
function enable (context, loc, group, rules) {
if (rules.length === 0) {
context.report({ loc, message: '++ {{group}}', data: { group }})
} else {
context.report({ loc, message: '+ {{group}} {{rules}}', data: { group, rules: rules.join(' ') }})
}
}

/**
* Disable rules.
* @param {RuleContext} context The rule context.
* @param {{line:number,column:number}} loc The location information to disable.
* @param {string} group The group to disable.
* @param {string[]} rules The rule IDs to disable.
* @returns {void}
*/
function disable (context, loc, group, rules) {
if (rules.length === 0) {
context.report({ loc, message: '-- {{group}}', data: { group }})
} else {
context.report({ loc, message: '- {{group}} {{rules}}', data: { group, rules: rules.join(' ') }})
}
}

/**
* Process a given comment token.
* If the comment is `eslint-disable` or `eslint-enable` then it reports the comment.
* @param {RuleContext} context The rule context.
* @param {Token} comment The comment token to process.
* @returns {void}
*/
function processBlock (context, comment) {
const parsed = parse(COMMENT_DIRECTIVE_B, comment.value)
if (parsed != null) {
if (parsed.type === 'eslint-disable') {
disable(context, comment.loc.start, 'block', parsed.rules)
} else {
enable(context, comment.loc.start, 'block', parsed.rules)
}
}
}

/**
* Process a given comment token.
* If the comment is `eslint-disable-line` or `eslint-disable-next-line` then it reports the comment.
* @param {RuleContext} context The rule context.
* @param {Token} comment The comment token to process.
* @returns {void}
*/
function processLine (context, comment) {
const parsed = parse(COMMENT_DIRECTIVE_L, comment.value)
if (parsed != null && comment.loc.start.line === comment.loc.end.line) {
const line = comment.loc.start.line + (parsed.type === 'eslint-disable-line' ? 0 : 1)
const column = -1
disable(context, { line, column }, 'line', parsed.rules)
enable(context, { line: line + 1, column }, 'line', parsed.rules)
}
}

/**
* The implementation of `vue/comment-directive` rule.
* @param {Program} node The program node to parse.
* @returns {Object} The visitor of this rule.
*/
function create (context) {
return {
Program (node) {
const comments = (node.templateBody && node.templateBody.comments) || []
for (const comment of comments) {
processBlock(context, comment)
processLine(context, comment)
}
}
}
}

// -----------------------------------------------------------------------------
// Rule Definition
// -----------------------------------------------------------------------------

module.exports = {
meta: {
docs: {
description: 'support comment-directives in `<template>`', // eslint-disable-line consistent-docs-description
category: 'base'
},
schema: []
},
create
}
1 change: 1 addition & 0 deletions lib/strongly-recommended-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
module.exports = {
"vue/attribute-hyphenation": "error",
"vue/comment-directive": "error",
"vue/html-end-tags": "error",
"vue/html-indent": "error",
"vue/html-self-closing": "error",
Expand Down
Loading