123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- 'use strict'
- const utils = require('../utils')
- function isComma(node) {
- return node.type === 'Punctuator' && node.value === ','
- }
- function* iterateBetweenTokens(sourceCode, pre, cur) {
- yield sourceCode.getLastToken(pre)
- yield* sourceCode.getTokensBetween(pre, cur, {
- includeComments: true
- })
- yield sourceCode.getFirstToken(cur)
- }
- function hasEmptyLine(sourceCode, pre, cur) {
-
- let preToken = null
- for (const token of iterateBetweenTokens(sourceCode, pre, cur)) {
- if (preToken && token.loc.start.line - preToken.loc.end.line >= 2) {
- return true
- }
- preToken = token
- }
- return false
- }
- module.exports = {
- meta: {
- type: 'layout',
- docs: {
- description:
- 'enforce new lines between multi-line properties in Vue components',
- categories: undefined,
- url: 'https://eslint.vuejs.org/rules/new-line-between-multi-line-property.html'
- },
- fixable: 'whitespace',
- schema: [
- {
- type: 'object',
- properties: {
-
- minLineOfMultilineProperty: {
- type: 'number',
- minimum: 2
- }
- },
- additionalProperties: false
- }
- ]
- },
-
- create(context) {
- let minLineOfMultilineProperty = 2
- if (
- context.options &&
- context.options[0] &&
- context.options[0].minLineOfMultilineProperty
- ) {
- minLineOfMultilineProperty = context.options[0].minLineOfMultilineProperty
- }
-
- const callStack = []
- const sourceCode = context.getSourceCode()
- return Object.assign(
- utils.defineVueVisitor(context, {
- CallExpression(node) {
- callStack.push(node)
- },
- 'CallExpression:exit'() {
- callStack.pop()
- },
-
- ObjectExpression(node) {
- if (callStack.length) {
- return
- }
- const properties = node.properties
- for (let i = 1; i < properties.length; i++) {
- const cur = properties[i]
- const pre = properties[i - 1]
- const lineCountOfPreProperty =
- pre.loc.end.line - pre.loc.start.line + 1
- if (lineCountOfPreProperty < minLineOfMultilineProperty) {
- continue
- }
- if (hasEmptyLine(sourceCode, pre, cur)) {
- continue
- }
- context.report({
- node: pre,
- loc: {
- start: pre.loc.end,
- end: cur.loc.start
- },
- message:
- 'Enforce new lines between multi-line properties in Vue components.',
- fix(fixer) {
-
- let preToken = null
- for (const token of iterateBetweenTokens(
- sourceCode,
- pre,
- cur
- )) {
- if (
- preToken &&
- preToken.loc.end.line < token.loc.start.line
- ) {
- return fixer.insertTextAfter(preToken, '\n')
- }
- preToken = token
- }
- const commaToken = sourceCode.getTokenAfter(pre, isComma)
- return fixer.insertTextAfter(commaToken || pre, '\n\n')
- }
- })
- }
- }
- })
- )
- }
- }
|