Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new
vue/require-prop-comment
rule (#2019)
* require-prop-comment * add type arg * add jsdoc type * edit rule * npm run update运行结果 * npm run update edit * Modify according to the requirements during consolidation * edit test * delete only one check * delete template * edit md * Lint * Improve docs * Only check last preceding comment * Use message IDs * Rename unlimited → any * Fix docs * edit rules * edit schema type * update readme.md * add rules * add rules Co-authored-by: Flo Edelmann <florian-edelmann@online.de>
- Loading branch information
1 parent
2bdcc51
commit bf5829c
Showing
5 changed files
with
538 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
--- | ||
pageClass: rule-details | ||
sidebarDepth: 0 | ||
title: vue/require-prop-comment | ||
description: require props to have a comment | ||
--- | ||
# vue/require-prop-comment | ||
|
||
> require props to have a comment | ||
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge> | ||
|
||
## :book: Rule Details | ||
|
||
This rule enforces that every prop has a comment that documents it. | ||
|
||
<eslint-code-block :rules="{'vue/require-prop-comment': ['error']}"> | ||
|
||
```vue | ||
<script> | ||
export default defineComponent({ | ||
props: { | ||
// ✓ GOOD | ||
/** JSDoc comment */ | ||
a: Number, | ||
// ✗ BAD | ||
// line comment | ||
b: Number, | ||
/* block comment */ | ||
c: Number, | ||
d: Number, | ||
} | ||
}) | ||
</script> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
## :wrench: Options | ||
|
||
```json | ||
{ | ||
"vue/require-prop-comment": ["error", { | ||
"type": "JSDoc" | ||
}] | ||
} | ||
``` | ||
|
||
- `type` ... Type of comment. Default is `"JSDoc"` | ||
- `"JSDoc"` ... Only JSDoc comment are allowed. | ||
- `"line"` ... Only line comment are allowed. | ||
- `"block"` ... Only block comment are allowed. | ||
- `"any"` ... All comment types are allowed. | ||
|
||
### `"type": "block"` | ||
|
||
<eslint-code-block :rules="{'vue/require-prop-comment': ['error', {type: 'block'}]}"> | ||
|
||
```vue | ||
<script setup> | ||
// ✓ GOOD | ||
const goodProps = defineProps({ | ||
/* block comment */ | ||
a: Number, | ||
}) | ||
// ✗ BAD | ||
const badProps = defineProps({ | ||
/** JSDoc comment */ | ||
b: Number, | ||
// line comment | ||
c: Number, | ||
d: Number, | ||
}) | ||
</script> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
### `"type": "line"` | ||
|
||
<eslint-code-block :rules="{'vue/require-prop-comment': ['error', {type: 'line'}]}"> | ||
|
||
```vue | ||
<script setup> | ||
// ✓ GOOD | ||
const goodProps = defineProps({ | ||
// line comment | ||
a: Number, | ||
}) | ||
// ✗ BAD | ||
const badProps = defineProps({ | ||
/** JSDoc comment */ | ||
b: Number, | ||
/* block comment */ | ||
c: Number, | ||
d: Number, | ||
}) | ||
</script> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
### `"type": "any"` | ||
|
||
<eslint-code-block :rules="{'vue/require-prop-comment': ['error', {type: 'any'}]}"> | ||
|
||
```vue | ||
<script setup> | ||
// ✓ GOOD | ||
const goodProps = defineProps({ | ||
/** JSDoc comment */ | ||
a: Number, | ||
/* block comment */ | ||
b: Number, | ||
// line comment | ||
c: Number, | ||
}) | ||
// ✗ BAD | ||
const badProps = defineProps({ | ||
d: Number, | ||
}) | ||
</script> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
## :mag: Implementation | ||
|
||
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/require-prop-comment.js) | ||
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/require-prop-comment.js) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/** | ||
* @author CZB | ||
* See LICENSE file in root directory for full license. | ||
*/ | ||
'use strict' | ||
|
||
const utils = require('../utils') | ||
|
||
module.exports = { | ||
meta: { | ||
type: 'suggestion', | ||
docs: { | ||
description: 'require props to have a comment', | ||
categories: undefined, | ||
url: 'https://eslint.vuejs.org/rules/require-prop-comment.html' | ||
}, | ||
fixable: null, | ||
schema: [ | ||
{ | ||
type: 'object', | ||
properties: { | ||
type: { enum: ['JSDoc', 'line', 'block', 'any'] } | ||
}, | ||
additionalProperties: false | ||
} | ||
], | ||
messages: { | ||
requireAnyComment: 'The "{{name}}" property should have a comment.', | ||
requireLineComment: 'The "{{name}}" property should have a line comment.', | ||
requireBlockComment: | ||
'The "{{name}}" property should have a block comment.', | ||
requireJSDocComment: | ||
'The "{{name}}" property should have a JSDoc comment.' | ||
} | ||
}, | ||
/** @param {RuleContext} context */ | ||
create(context) { | ||
/** @type {{type?: "JSDoc" | "line" | "block" | "any"}|undefined} */ | ||
const schema = context.options[0] | ||
const type = (schema && schema.type) || 'JSDoc' | ||
|
||
const sourceCode = context.getSourceCode() | ||
|
||
/** @param {Comment | undefined} comment */ | ||
const verifyBlock = (comment) => | ||
comment && comment.type === 'Block' && comment.value.charAt(0) !== '*' | ||
? undefined | ||
: 'requireBlockComment' | ||
|
||
/** @param {Comment | undefined} comment */ | ||
const verifyLine = (comment) => | ||
comment && comment.type === 'Line' ? undefined : 'requireLineComment' | ||
|
||
/** @param {Comment | undefined} comment */ | ||
const verifyAny = (comment) => (comment ? undefined : 'requireAnyComment') | ||
|
||
/** @param {Comment | undefined} comment */ | ||
const verifyJSDoc = (comment) => | ||
comment && comment.type === 'Block' && comment.value.charAt(0) === '*' | ||
? undefined | ||
: 'requireJSDocComment' | ||
|
||
/** | ||
* @param {import('../utils').ComponentProp[]} props | ||
*/ | ||
function verifyProps(props) { | ||
for (const prop of props) { | ||
if (!prop.propName) { | ||
continue | ||
} | ||
|
||
const precedingComments = sourceCode.getCommentsBefore(prop.node) | ||
const lastPrecedingComment = | ||
precedingComments.length > 0 | ||
? precedingComments[precedingComments.length - 1] | ||
: undefined | ||
|
||
/** @type {string|undefined} */ | ||
let messageId | ||
|
||
switch (type) { | ||
case 'block': | ||
messageId = verifyBlock(lastPrecedingComment) | ||
break | ||
case 'line': | ||
messageId = verifyLine(lastPrecedingComment) | ||
break | ||
case 'any': | ||
messageId = verifyAny(lastPrecedingComment) | ||
break | ||
default: | ||
messageId = verifyJSDoc(lastPrecedingComment) | ||
break | ||
} | ||
|
||
if (!messageId) { | ||
continue | ||
} | ||
|
||
context.report({ | ||
node: prop.node, | ||
messageId, | ||
data: { | ||
name: prop.propName | ||
} | ||
}) | ||
} | ||
} | ||
|
||
return utils.compositingVisitors( | ||
utils.defineScriptSetupVisitor(context, { | ||
onDefinePropsEnter(_node, props) { | ||
verifyProps(props) | ||
} | ||
}), | ||
utils.defineVueVisitor(context, { | ||
onVueObjectEnter(node) { | ||
verifyProps(utils.getComponentPropsFromOptions(node)) | ||
} | ||
}) | ||
) | ||
} | ||
} |
Oops, something went wrong.