first commit
This commit is contained in:
204
app_vue/node_modules/eslint-plugin-vue/lib/rules/no-extra-parens.js
generated
vendored
Normal file
204
app_vue/node_modules/eslint-plugin-vue/lib/rules/no-extra-parens.js
generated
vendored
Normal file
@ -0,0 +1,204 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { isParenthesized } = require('eslint-utils')
|
||||
const { wrapCoreRule } = require('../utils')
|
||||
const { getStyleVariablesContext } = require('../utils/style-variables')
|
||||
|
||||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories
|
||||
module.exports = wrapCoreRule('no-extra-parens', {
|
||||
skipDynamicArguments: true,
|
||||
applyDocument: true,
|
||||
create: createForVueSyntax
|
||||
})
|
||||
|
||||
/**
|
||||
* Check whether the given token is a left parenthesis.
|
||||
* @param {Token} token The token to check.
|
||||
* @returns {boolean} `true` if the token is a left parenthesis.
|
||||
*/
|
||||
function isLeftParen(token) {
|
||||
return token.type === 'Punctuator' && token.value === '('
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given token is a right parenthesis.
|
||||
* @param {Token} token The token to check.
|
||||
* @returns {boolean} `true` if the token is a right parenthesis.
|
||||
*/
|
||||
function isRightParen(token) {
|
||||
return token.type === 'Punctuator' && token.value === ')'
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given token is a left brace.
|
||||
* @param {Token} token The token to check.
|
||||
* @returns {boolean} `true` if the token is a left brace.
|
||||
*/
|
||||
function isLeftBrace(token) {
|
||||
return token.type === 'Punctuator' && token.value === '{'
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given token is a right brace.
|
||||
* @param {Token} token The token to check.
|
||||
* @returns {boolean} `true` if the token is a right brace.
|
||||
*/
|
||||
function isRightBrace(token) {
|
||||
return token.type === 'Punctuator' && token.value === '}'
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given token is a left bracket.
|
||||
* @param {Token} token The token to check.
|
||||
* @returns {boolean} `true` if the token is a left bracket.
|
||||
*/
|
||||
function isLeftBracket(token) {
|
||||
return token.type === 'Punctuator' && token.value === '['
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given token is a right bracket.
|
||||
* @param {Token} token The token to check.
|
||||
* @returns {boolean} `true` if the token is a right bracket.
|
||||
*/
|
||||
function isRightBracket(token) {
|
||||
return token.type === 'Punctuator' && token.value === ']'
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a given expression node is an IIFE
|
||||
* @param {Expression} node The node to check
|
||||
* @returns {node is CallExpression & { callee: FunctionExpression } } `true` if the given node is an IIFE
|
||||
*/
|
||||
function isIIFE(node) {
|
||||
return (
|
||||
node.type === 'CallExpression' && node.callee.type === 'FunctionExpression'
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {RuleContext} context - The rule context.
|
||||
* @returns {TemplateListener} AST event handlers.
|
||||
*/
|
||||
function createForVueSyntax(context) {
|
||||
if (!context.parserServices.getTemplateBodyTokenStore) {
|
||||
return {}
|
||||
}
|
||||
const tokenStore = context.parserServices.getTemplateBodyTokenStore()
|
||||
|
||||
/**
|
||||
* Checks if the given node turns into a filter when unwraped.
|
||||
* @param {Expression} expression node to evaluate
|
||||
* @returns {boolean} `true` if the given node turns into a filter when unwraped.
|
||||
*/
|
||||
function isUnwrapChangeToFilter(expression) {
|
||||
let parenStack = null
|
||||
for (const token of tokenStore.getTokens(expression)) {
|
||||
if (!parenStack) {
|
||||
if (token.value === '|') {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
if (parenStack.isUpToken(token)) {
|
||||
parenStack = parenStack.upper
|
||||
continue
|
||||
}
|
||||
}
|
||||
if (isLeftParen(token)) {
|
||||
parenStack = { isUpToken: isRightParen, upper: parenStack }
|
||||
} else if (isLeftBracket(token)) {
|
||||
parenStack = { isUpToken: isRightBracket, upper: parenStack }
|
||||
} else if (isLeftBrace(token)) {
|
||||
parenStack = { isUpToken: isRightBrace, upper: parenStack }
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
/**
|
||||
* Checks if the given node is CSS v-bind() without quote.
|
||||
* @param {VExpressionContainer} node
|
||||
* @param {Expression} expression
|
||||
*/
|
||||
function isStyleVariableWithoutQuote(node, expression) {
|
||||
const styleVars = getStyleVariablesContext(context)
|
||||
if (!styleVars || !styleVars.vBinds.includes(node)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const vBindToken = tokenStore.getFirstToken(node)
|
||||
const tokens = tokenStore.getTokensBetween(vBindToken, expression)
|
||||
|
||||
return tokens.every(isLeftParen)
|
||||
}
|
||||
/**
|
||||
* @param {VExpressionContainer & { expression: Expression | VFilterSequenceExpression | null }} node
|
||||
*/
|
||||
function verify(node) {
|
||||
if (!node.expression) {
|
||||
return
|
||||
}
|
||||
|
||||
const expression =
|
||||
node.expression.type === 'VFilterSequenceExpression'
|
||||
? node.expression.expression
|
||||
: node.expression
|
||||
|
||||
if (!isParenthesized(expression, tokenStore)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!isParenthesized(2, expression, tokenStore)) {
|
||||
if (
|
||||
isIIFE(expression) &&
|
||||
!isParenthesized(expression.callee, tokenStore)
|
||||
) {
|
||||
return
|
||||
}
|
||||
if (isUnwrapChangeToFilter(expression)) {
|
||||
return
|
||||
}
|
||||
if (isStyleVariableWithoutQuote(node, expression)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
report(expression)
|
||||
}
|
||||
|
||||
/**
|
||||
* Report the node
|
||||
* @param {Expression} node node to evaluate
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function report(node) {
|
||||
const sourceCode = context.getSourceCode()
|
||||
const leftParenToken = tokenStore.getTokenBefore(node)
|
||||
const rightParenToken = tokenStore.getTokenAfter(node)
|
||||
|
||||
context.report({
|
||||
node,
|
||||
loc: leftParenToken.loc,
|
||||
messageId: 'unexpected',
|
||||
fix(fixer) {
|
||||
const parenthesizedSource = sourceCode.text.slice(
|
||||
leftParenToken.range[1],
|
||||
rightParenToken.range[0]
|
||||
)
|
||||
|
||||
return fixer.replaceTextRange(
|
||||
[leftParenToken.range[0], rightParenToken.range[1]],
|
||||
parenthesizedSource
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
"VAttribute[directive=true][key.name.name='bind'] > VExpressionContainer":
|
||||
verify,
|
||||
'VElement > VExpressionContainer': verify
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user