You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
3.4 KiB
124 lines
3.4 KiB
/** |
|
* @author CZB |
|
* See LICENSE file in root directory for full license. |
|
*/ |
|
'use strict' |
|
|
|
const utils = require('../utils') |
|
const { isBlockComment, isJSDocComment } = require('../utils/comments.js') |
|
|
|
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 && isBlockComment(comment) ? 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 && isJSDocComment(comment) ? undefined : 'requireJSDocComment' |
|
|
|
/** |
|
* @param {import('../utils').ComponentProp[]} props |
|
*/ |
|
function verifyProps(props) { |
|
for (const prop of props) { |
|
if (!prop.propName || prop.type === 'infer-type') { |
|
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)) |
|
} |
|
}) |
|
) |
|
} |
|
}
|
|
|