eslint-plugin-vue
Advanced tools
Comparing version 4.0.0-beta.2 to 4.0.0-beta.3
@@ -202,2 +202,22 @@ /** | ||
/** | ||
* Check whether a given token is a closing token which triggers unindent. | ||
* @param {Token} token The token to check. | ||
* @returns {boolean} `true` if the token is a closing token. | ||
*/ | ||
function isClosingToken (token) { | ||
return token != null && ( | ||
token.type === 'HTMLEndTagOpen' || | ||
token.type === 'VExpressionEnd' || | ||
( | ||
token.type === 'Punctuator' && | ||
( | ||
token.value === ')' || | ||
token.value === '}' || | ||
token.value === ']' | ||
) | ||
) | ||
) | ||
} | ||
/** | ||
* Creates AST event handlers for html-indent. | ||
@@ -392,2 +412,51 @@ * | ||
/** | ||
* Check whether a given token is the first token of: | ||
* | ||
* - ExpressionStatement | ||
* - VExpressionContainer | ||
* - A parameter of CallExpression/NewExpression | ||
* - An element of ArrayExpression | ||
* - An expression of SequenceExpression | ||
* | ||
* @param {Token} token The token to check. | ||
* @param {Node} belongingNode The node that the token is belonging to. | ||
* @returns {boolean} `true` if the token is the first token of an element. | ||
*/ | ||
function isBeginningOfElement (token, belongingNode) { | ||
let node = belongingNode | ||
while (node != null) { | ||
const parent = node.parent | ||
const t = parent && parent.type | ||
if (t != null && (t.endsWith('Statement') || t.endsWith('Declaration'))) { | ||
return parent.range[0] === token.range[0] | ||
} | ||
if (t === 'VExpressionContainer') { | ||
return node.range[0] === token.range[0] | ||
} | ||
if (t === 'CallExpression' || t === 'NewExpression') { | ||
const openParen = template.getTokenAfter(parent.callee, isNotRightParen) | ||
return parent.arguments.some(param => | ||
getFirstAndLastTokens(param, openParen.range[1]).firstToken.range[0] === token.range[0] | ||
) | ||
} | ||
if (t === 'ArrayExpression') { | ||
return parent.elements.some(element => | ||
element != null && | ||
getFirstAndLastTokens(element).firstToken.range[0] === token.range[0] | ||
) | ||
} | ||
if (t === 'SequenceExpression') { | ||
return parent.expressions.some(expr => | ||
getFirstAndLastTokens(expr).firstToken.range[0] === token.range[0] | ||
) | ||
} | ||
node = parent | ||
} | ||
return false | ||
} | ||
/** | ||
* Ignore all tokens of the given node. | ||
@@ -509,5 +578,6 @@ * @param {Node} node The node to ignore. | ||
* @param {number} expectedIndent The expected indentation. | ||
* @param {number|undefined} optionalExpectedIndent The optional expected indentation. | ||
* @returns {void} | ||
*/ | ||
function validateCore (token, expectedIndent) { | ||
function validateCore (token, expectedIndent, optionalExpectedIndent) { | ||
const line = token.loc.start.line | ||
@@ -536,3 +606,3 @@ const actualIndent = token.loc.start.column | ||
if (actualIndent !== expectedIndent) { | ||
if (actualIndent !== expectedIndent && (optionalExpectedIndent === undefined || actualIndent !== optionalExpectedIndent)) { | ||
context.report({ | ||
@@ -560,5 +630,6 @@ loc: { | ||
* @param {Token[]} comments The comments which are on the immediately previous lines of the tokens. | ||
* @param {Token|null} lastToken The last validated token. Comments can adjust to the token. | ||
* @returns {void} | ||
*/ | ||
function validate (tokens, comments) { | ||
function validate (tokens, comments, lastToken) { | ||
// Calculate and save expected indentation. | ||
@@ -612,5 +683,13 @@ const firstToken = tokens[0] | ||
// Calculate the expected indents for comments. | ||
// It allows the same indent level with the previous line. | ||
const lastOffsetInfo = offsets.get(lastToken) | ||
const lastExpectedIndent = lastOffsetInfo && lastOffsetInfo.expectedIndent | ||
const commentExpectedIndents = (typeof lastExpectedIndent === 'number' && isClosingToken(firstToken)) | ||
? { primary: lastExpectedIndent, secondary: expectedIndent } | ||
: { primary: expectedIndent, secondary: undefined } | ||
// Validate. | ||
for (const comment of comments) { | ||
validateCore(comment, expectedIndent) | ||
validateCore(comment, commentExpectedIndents.primary, commentExpectedIndents.secondary) | ||
} | ||
@@ -731,4 +810,10 @@ validateCore(firstToken, expectedIndent) | ||
const rightToken = template.getTokenAfter(opToken) | ||
const prevToken = template.getTokenBefore(leftToken) | ||
const shouldIndent = ( | ||
prevToken == null || | ||
prevToken.loc.end.line === leftToken.loc.start.line || | ||
isBeginningOfElement(leftToken, node) | ||
) | ||
setOffset([opToken, rightToken], 1, leftToken) | ||
setOffset([opToken, rightToken], shouldIndent ? 1 : 0, leftToken) | ||
}, | ||
@@ -1152,2 +1237,3 @@ | ||
let first = true | ||
let lastValidatedToken = null | ||
@@ -1179,3 +1265,4 @@ // Validate indentation of tokens. | ||
validate(tokensOnSameLine, comments) | ||
validate(tokensOnSameLine, comments, lastValidatedToken) | ||
lastValidatedToken = tokensOnSameLine[0] | ||
} | ||
@@ -1188,3 +1275,3 @@ isBesideMultilineToken = last(tokensOnSameLine).loc.end.line === token.loc.start.line | ||
if (tokensOnSameLine.length >= 1 && tokensOnSameLine.some(isNotComment)) { | ||
validate(tokensOnSameLine, comments) | ||
validate(tokensOnSameLine, comments, lastValidatedToken) | ||
} | ||
@@ -1191,0 +1278,0 @@ } |
@@ -54,3 +54,3 @@ /** | ||
}, | ||
fixable: 'code', // or "code" or "whitespace" | ||
fixable: 'code', // or "code" or "whitespace" | ||
schema: [ | ||
@@ -57,0 +57,0 @@ { |
@@ -26,7 +26,7 @@ /** | ||
return vIf.value.references.some(reference => | ||
element.variables.some(variable => | ||
variable.id.name === reference.id.name && | ||
variable.kind === 'v-for' | ||
) | ||
element.variables.some(variable => | ||
variable.id.name === reference.id.name && | ||
variable.kind === 'v-for' | ||
) | ||
) | ||
} | ||
@@ -33,0 +33,0 @@ |
@@ -52,3 +52,3 @@ /** | ||
}, | ||
fixable: null, // or "code" or "whitespace" | ||
fixable: null, // or "code" or "whitespace" | ||
schema: [ | ||
@@ -55,0 +55,0 @@ { |
@@ -17,3 +17,3 @@ /** | ||
}, | ||
fixable: 'whitespace', // or "code" or "whitespace" | ||
fixable: 'whitespace', // or "code" or "whitespace" | ||
schema: [] | ||
@@ -20,0 +20,0 @@ }, |
@@ -19,3 +19,3 @@ /** | ||
}, | ||
fixable: null, // or "code" or "whitespace" | ||
fixable: null, // or "code" or "whitespace" | ||
schema: [] | ||
@@ -22,0 +22,0 @@ }, |
@@ -86,3 +86,3 @@ /** | ||
}, | ||
fixable: null, // or "code" or "whitespace" | ||
fixable: null, // or "code" or "whitespace" | ||
schema: [ | ||
@@ -89,0 +89,0 @@ // fill in your schema |
@@ -49,3 +49,3 @@ /** | ||
}, | ||
fixable: null, // or "code" or "whitespace" | ||
fixable: null, // or "code" or "whitespace" | ||
schema: [] | ||
@@ -52,0 +52,0 @@ }, |
@@ -53,3 +53,3 @@ /** | ||
}, | ||
fixable: null, // or "code" or "whitespace" | ||
fixable: null, // or "code" or "whitespace" | ||
schema: [ | ||
@@ -56,0 +56,0 @@ { |
@@ -37,7 +37,7 @@ /** | ||
message: shorthand | ||
? "Unexpected 'v-bind' before ':'." | ||
: "Expected 'v-bind' before ':'.", | ||
? "Unexpected 'v-bind' before ':'." | ||
: "Expected 'v-bind' before ':'.", | ||
fix: (fixer) => shorthand | ||
? fixer.removeRange([node.range[0], node.range[0] + 6]) | ||
: fixer.insertTextBefore(node, 'v-bind') | ||
? fixer.removeRange([node.range[0], node.range[0] + 6]) | ||
: fixer.insertTextBefore(node, 'v-bind') | ||
}) | ||
@@ -44,0 +44,0 @@ } |
@@ -38,7 +38,7 @@ /** | ||
message: shorthand | ||
? "Expected '@' instead of 'v-on:'." | ||
: "Expected 'v-on:' instead of '@'.", | ||
? "Expected '@' instead of 'v-on:'." | ||
: "Expected 'v-on:' instead of '@'.", | ||
fix: (fixer) => shorthand | ||
? fixer.replaceTextRange([pos, pos + 5], '@') | ||
: fixer.replaceTextRange([pos, pos + 1], 'v-on:') | ||
? fixer.replaceTextRange([pos, pos + 5], '@') | ||
: fixer.replaceTextRange([pos, pos + 1], 'v-on:') | ||
}) | ||
@@ -45,0 +45,0 @@ } |
@@ -31,7 +31,7 @@ /** | ||
return references.some(reference => | ||
variables.some(variable => | ||
variable.id.name === reference.id.name && | ||
variables.some(variable => | ||
variable.id.name === reference.id.name && | ||
variable.kind === 'v-for' | ||
) | ||
) | ||
) | ||
} | ||
@@ -52,7 +52,7 @@ | ||
const usedInFor = childForRefs.some(cref => | ||
variables.some(variable => | ||
cref.id.name === variable.id.name && | ||
variable.kind === 'v-for' | ||
) | ||
variables.some(variable => | ||
cref.id.name === variable.id.name && | ||
variable.kind === 'v-for' | ||
) | ||
) | ||
// if parent iterator is used, skip other checks | ||
@@ -59,0 +59,0 @@ // iterator usage will be checked later by child v-for |
@@ -28,12 +28,12 @@ /** | ||
return ( | ||
name === 'input' || | ||
name === 'select' || | ||
name === 'textarea' || | ||
( | ||
name !== 'keep-alive' && | ||
name !== 'slot' && | ||
name !== 'transition' && | ||
name !== 'transition-group' && | ||
utils.isCustomComponent(node) | ||
) | ||
name === 'input' || | ||
name === 'select' || | ||
name === 'textarea' || | ||
( | ||
name !== 'keep-alive' && | ||
name !== 'slot' && | ||
name !== 'transition' && | ||
name !== 'transition-group' && | ||
utils.isCustomComponent(node) | ||
) | ||
) | ||
@@ -49,5 +49,5 @@ } | ||
return node != null && ( | ||
node.type === 'Identifier' || | ||
node.type === 'MemberExpression' | ||
) | ||
node.type === 'Identifier' || | ||
node.type === 'MemberExpression' | ||
) | ||
} | ||
@@ -54,0 +54,0 @@ |
@@ -38,3 +38,3 @@ /** | ||
}) | ||
return | ||
return {} | ||
} | ||
@@ -89,9 +89,9 @@ return context.parserServices.defineTemplateBodyVisitor(templateBodyVisitor, scriptVisitor) | ||
return node.startTag.attributes.some(a => | ||
!a.directive && | ||
a.key.name === name && | ||
( | ||
value === undefined || | ||
(a.value != null && a.value.value === value) | ||
) | ||
) | ||
!a.directive && | ||
a.key.name === name && | ||
( | ||
value === undefined || | ||
(a.value != null && a.value.value === value) | ||
) | ||
) | ||
}, | ||
@@ -109,6 +109,6 @@ | ||
return node.startTag.attributes.some(a => | ||
a.directive && | ||
a.key.name === name && | ||
(argument === undefined || a.key.argument === argument) | ||
) | ||
a.directive && | ||
a.key.name === name && | ||
(argument === undefined || a.key.argument === argument) | ||
) | ||
}, | ||
@@ -124,4 +124,4 @@ | ||
return ( | ||
node.value != null && | ||
(node.value.expression != null || node.value.syntaxError != null) | ||
node.value != null && | ||
(node.value.expression != null || node.value.syntaxError != null) | ||
) | ||
@@ -140,9 +140,9 @@ }, | ||
return node.startTag.attributes.find(a => | ||
!a.directive && | ||
a.key.name === name && | ||
( | ||
value === undefined || | ||
(a.value != null && a.value.value === value) | ||
) | ||
) | ||
!a.directive && | ||
a.key.name === name && | ||
( | ||
value === undefined || | ||
(a.value != null && a.value.value === value) | ||
) | ||
) | ||
}, | ||
@@ -160,6 +160,6 @@ | ||
return node.startTag.attributes.find(a => | ||
a.directive && | ||
a.key.name === name && | ||
(argument === undefined || a.key.argument === argument) | ||
) | ||
a.directive && | ||
a.key.name === name && | ||
(argument === undefined || a.key.argument === argument) | ||
) | ||
}, | ||
@@ -177,7 +177,7 @@ | ||
return ( | ||
prev != null && | ||
prev.startTag.attributes.some(a => | ||
a.directive && | ||
(a.key.name === 'if' || a.key.name === 'else-if') | ||
) | ||
prev != null && | ||
prev.startTag.attributes.some(a => | ||
a.directive && | ||
(a.key.name === 'if' || a.key.name === 'else-if') | ||
) | ||
) | ||
@@ -184,0 +184,0 @@ }, |
{ | ||
"name": "eslint-plugin-vue", | ||
"version": "4.0.0-beta.2", | ||
"version": "4.0.0-beta.3", | ||
"description": "Official ESLint plugin for Vue.js", | ||
@@ -53,5 +53,6 @@ "main": "lib/index.js", | ||
"chai": "^4.1.0", | ||
"eslint": "^3.19.0", | ||
"eslint": "^4.12.1", | ||
"eslint-plugin-eslint-plugin": "^0.8.0", | ||
"eslint-plugin-vue-libs": "^1.2.0", | ||
"eslint-plugin-html": "^4.0.1", | ||
"eslint-plugin-vue-libs": "^2.0.0", | ||
"mocha": "^3.2.0", | ||
@@ -58,0 +59,0 @@ "nyc": "^11.1.0" |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
200546
5496
9