eslint-plugin-vue
Advanced tools
Comparing version 4.0.0-beta.1 to 4.0.0-beta.2
@@ -32,34 +32,8 @@ /** | ||
create (context) { | ||
const options = context.options[0] | ||
const optSpaces = options !== 'never' | ||
const template = context.parserServices.getTemplateBodyTokenStore && context.parserServices.getTemplateBodyTokenStore() | ||
const options = context.options[0] || 'always' | ||
const template = | ||
context.parserServices.getTemplateBodyTokenStore && | ||
context.parserServices.getTemplateBodyTokenStore() | ||
// ---------------------------------------------------------------------- | ||
// Helpers | ||
// ---------------------------------------------------------------------- | ||
function checkTokens (leftToken, rightToken) { | ||
if (leftToken.loc.end.line === rightToken.loc.start.line) { | ||
const spaces = rightToken.loc.start.column - leftToken.loc.end.column | ||
const noSpacesFound = spaces === 0 | ||
if (optSpaces === noSpacesFound) { | ||
context.report({ | ||
node: rightToken, | ||
loc: { | ||
start: leftToken.loc.end, | ||
end: rightToken.loc.start | ||
}, | ||
message: 'Found {{spaces}} whitespaces, {{type}} expected.', | ||
data: { | ||
spaces: spaces === 0 ? 'none' : spaces, | ||
type: optSpaces ? '1' : 'none' | ||
}, | ||
fix: (fixer) => fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], optSpaces ? ' ' : '') | ||
}) | ||
} | ||
} | ||
} | ||
// ---------------------------------------------------------------------- | ||
// Public | ||
@@ -70,17 +44,53 @@ // ---------------------------------------------------------------------- | ||
'VExpressionContainer[expression!=null]' (node) { | ||
const tokens = template.getTokens(node, { | ||
includeComments: true, | ||
filter: token => token.type !== 'HTMLWhitespace' // When there is only whitespace between ignore it | ||
}) | ||
const openBrace = template.getFirstToken(node) | ||
const closeBrace = template.getLastToken(node) | ||
const startToken = tokens.shift() | ||
if (!startToken || startToken.type !== 'VExpressionStart') return | ||
const endToken = tokens.pop() | ||
if (!endToken || endToken.type !== 'VExpressionEnd') return | ||
if ( | ||
!openBrace || | ||
!closeBrace || | ||
openBrace.type !== 'VExpressionStart' || | ||
closeBrace.type !== 'VExpressionEnd' | ||
) { | ||
return | ||
} | ||
if (tokens.length > 0) { | ||
checkTokens(startToken, tokens[0]) | ||
checkTokens(tokens[tokens.length - 1], endToken) | ||
const firstToken = template.getTokenAfter(openBrace, { includeComments: true }) | ||
const lastToken = template.getTokenBefore(closeBrace, { includeComments: true }) | ||
if (options === 'always') { | ||
if (openBrace.range[1] === firstToken.range[0]) { | ||
context.report({ | ||
node: openBrace, | ||
message: "Expected 1 space after '{{', but not found.", | ||
fix: (fixer) => fixer.insertTextAfter(openBrace, ' ') | ||
}) | ||
} | ||
if (closeBrace.range[0] === lastToken.range[1]) { | ||
context.report({ | ||
node: closeBrace, | ||
message: "Expected 1 space before '}}', but not found.", | ||
fix: (fixer) => fixer.insertTextBefore(closeBrace, ' ') | ||
}) | ||
} | ||
} else { | ||
checkTokens(startToken, endToken) | ||
if (openBrace.range[1] !== firstToken.range[0]) { | ||
context.report({ | ||
loc: { | ||
start: openBrace.loc.start, | ||
end: firstToken.loc.start | ||
}, | ||
message: "Expected no space after '{{', but found.", | ||
fix: (fixer) => fixer.removeRange([openBrace.range[1], firstToken.range[0]]) | ||
}) | ||
} | ||
if (closeBrace.range[0] !== lastToken.range[1]) { | ||
context.report({ | ||
loc: { | ||
start: lastToken.loc.end, | ||
end: closeBrace.loc.end | ||
}, | ||
message: "Expected no space before '}}', but found.", | ||
fix: (fixer) => fixer.removeRange([lastToken.range[1], closeBrace.range[0]]) | ||
}) | ||
} | ||
} | ||
@@ -87,0 +97,0 @@ } |
@@ -9,6 +9,29 @@ /** | ||
function isOpenParen (token) { | ||
return token.type === 'Punctuator' && token.value === '(' | ||
} | ||
function isCloseParen (token) { | ||
return token.type === 'Punctuator' && token.value === ')' | ||
} | ||
function getFirstAndLastTokens (node, sourceCode) { | ||
let first = sourceCode.getFirstToken(node) | ||
let last = sourceCode.getLastToken(node) | ||
// If the value enclosed by parentheses, update the 'first' and 'last' by the parentheses. | ||
while (true) { | ||
const prev = sourceCode.getTokenBefore(first) | ||
const next = sourceCode.getTokenAfter(last) | ||
if (isOpenParen(prev) && isCloseParen(next)) { | ||
first = prev | ||
last = next | ||
} else { | ||
return { first, last } | ||
} | ||
} | ||
} | ||
function create (context) { | ||
// ---------------------------------------------------------------------- | ||
// Public | ||
// ---------------------------------------------------------------------- | ||
const sourceCode = context.getSourceCode() | ||
@@ -25,6 +48,20 @@ return utils.executeOnVueComponent(context, (obj) => { | ||
) | ||
.forEach(cp => { | ||
.forEach(p => { | ||
context.report({ | ||
node: cp.value, | ||
message: '`data` property in component must be a function' | ||
node: p, | ||
message: '`data` property in component must be a function', | ||
fix (fixer) { | ||
const tokens = getFirstAndLastTokens(p.value, sourceCode) | ||
// If we can upgrade requirements to `eslint@>4.1.0`, this code can be replaced by: | ||
// return [ | ||
// fixer.insertTextBefore(tokens.first, 'function() {\nreturn '), | ||
// fixer.insertTextAfter(tokens.last, ';\n}') | ||
// ] | ||
// See: https://eslint.org/blog/2017/06/eslint-v4.1.0-released#applying-multiple-autofixes-simultaneously | ||
const range = [tokens.first.range[0], tokens.last.range[1]] | ||
const valueText = sourceCode.text.slice(range[0], range[1]) | ||
const replacement = `function() {\nreturn ${valueText};\n}` | ||
return fixer.replaceTextRange(range, replacement) | ||
} | ||
}) | ||
@@ -45,3 +82,3 @@ }) | ||
}, | ||
fixable: null, // or "code" or "whitespace" | ||
fixable: 'code', | ||
schema: [] | ||
@@ -48,0 +85,0 @@ }, |
{ | ||
"name": "eslint-plugin-vue", | ||
"version": "4.0.0-beta.1", | ||
"version": "4.0.0-beta.2", | ||
"description": "Official ESLint plugin for Vue.js", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
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
197562
5415