diff --git a/.eslintrc.js b/.eslintrc.js index f45e3ef28..97e2e03f9 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -48,10 +48,6 @@ module.exports = { 'tests/lib/rules/require-direct-export.js', 'lib/utils/index.js', 'tests/lib/utils/vue-component.js', - // https://github.com/vuejs/eslint-plugin-vue/pull/1017 - 'lib/utils/indent-common.js', - 'tests/lib/rules/html-indent.js', - 'tests/lib/rules/script-indent.js', // https://github.com/vuejs/eslint-plugin-vue/pull/982 'lib/rules/attributes-order.js', 'tests/lib/rules/attributes-order.js', diff --git a/lib/utils/indent-common.js b/lib/utils/indent-common.js index a69d7a5d2..97d285274 100644 --- a/lib/utils/indent-common.js +++ b/lib/utils/indent-common.js @@ -14,11 +14,98 @@ const assert = require('assert') // Helpers // ------------------------------------------------------------------------------ -const KNOWN_NODES = new Set(['ArrayExpression', 'ArrayPattern', 'ArrowFunctionExpression', 'AssignmentExpression', 'AssignmentPattern', 'AwaitExpression', 'BinaryExpression', 'BlockStatement', 'BreakStatement', 'CallExpression', 'CatchClause', 'ClassBody', 'ClassDeclaration', 'ClassExpression', 'ConditionalExpression', 'ContinueStatement', 'DebuggerStatement', 'DoWhileStatement', 'EmptyStatement', 'ExperimentalRestProperty', 'ExperimentalSpreadProperty', 'ExportAllDeclaration', 'ExportDefaultDeclaration', 'ExportNamedDeclaration', 'ExportSpecifier', 'ExpressionStatement', 'ForInStatement', 'ForOfStatement', 'ForStatement', 'FunctionDeclaration', 'FunctionExpression', 'Identifier', 'IfStatement', 'ImportDeclaration', 'ImportDefaultSpecifier', 'ImportNamespaceSpecifier', 'ImportSpecifier', 'LabeledStatement', 'Literal', 'LogicalExpression', 'MemberExpression', 'MetaProperty', 'MethodDefinition', 'NewExpression', 'ObjectExpression', 'ObjectPattern', 'Program', 'Property', 'RestElement', 'ReturnStatement', 'SequenceExpression', 'SpreadElement', 'Super', 'SwitchCase', 'SwitchStatement', 'TaggedTemplateExpression', 'TemplateElement', 'TemplateLiteral', 'ThisExpression', 'ThrowStatement', 'TryStatement', 'UnaryExpression', 'UpdateExpression', 'VariableDeclaration', 'VariableDeclarator', 'WhileStatement', 'WithStatement', 'YieldExpression', 'VAttribute', 'VDirectiveKey', 'VDocumentFragment', 'VElement', 'VEndTag', 'VExpressionContainer', 'VFilter', 'VFilterSequenceExpression', 'VForExpression', 'VIdentifier', 'VLiteral', 'VOnExpression', 'VSlotScopeExpression', 'VStartTag', 'VText']) +const KNOWN_NODES = new Set([ + 'ArrayExpression', + 'ArrayPattern', + 'ArrowFunctionExpression', + 'AssignmentExpression', + 'AssignmentPattern', + 'AwaitExpression', + 'BinaryExpression', + 'BlockStatement', + 'BreakStatement', + 'CallExpression', + 'CatchClause', + 'ClassBody', + 'ClassDeclaration', + 'ClassExpression', + 'ConditionalExpression', + 'ContinueStatement', + 'DebuggerStatement', + 'DoWhileStatement', + 'EmptyStatement', + 'ExperimentalRestProperty', + 'ExperimentalSpreadProperty', + 'ExportAllDeclaration', + 'ExportDefaultDeclaration', + 'ExportNamedDeclaration', + 'ExportSpecifier', + 'ExpressionStatement', + 'ForInStatement', + 'ForOfStatement', + 'ForStatement', + 'FunctionDeclaration', + 'FunctionExpression', + 'Identifier', + 'IfStatement', + 'ImportDeclaration', + 'ImportDefaultSpecifier', + 'ImportNamespaceSpecifier', + 'ImportSpecifier', + 'LabeledStatement', + 'Literal', + 'LogicalExpression', + 'MemberExpression', + 'MetaProperty', + 'MethodDefinition', + 'NewExpression', + 'ObjectExpression', + 'ObjectPattern', + 'Program', + 'Property', + 'RestElement', + 'ReturnStatement', + 'SequenceExpression', + 'SpreadElement', + 'Super', + 'SwitchCase', + 'SwitchStatement', + 'TaggedTemplateExpression', + 'TemplateElement', + 'TemplateLiteral', + 'ThisExpression', + 'ThrowStatement', + 'TryStatement', + 'UnaryExpression', + 'UpdateExpression', + 'VariableDeclaration', + 'VariableDeclarator', + 'WhileStatement', + 'WithStatement', + 'YieldExpression', + 'VAttribute', + 'VDirectiveKey', + 'VDocumentFragment', + 'VElement', + 'VEndTag', + 'VExpressionContainer', + 'VFilter', + 'VFilterSequenceExpression', + 'VForExpression', + 'VIdentifier', + 'VLiteral', + 'VOnExpression', + 'VSlotScopeExpression', + 'VStartTag', + 'VText' +]) const LT_CHAR = /[\r\n\u2028\u2029]/ const LINES = /[^\r\n\u2028\u2029]+(?:$|\r\n|[\r\n\u2028\u2029])/g const BLOCK_COMMENT_PREFIX = /^\s*\*/ -const ITERATION_OPTS = Object.freeze({ includeComments: true, filter: isNotWhitespace }) +const ITERATION_OPTS = Object.freeze({ + includeComments: true, + filter: isNotWhitespace +}) const PREFORMATTED_ELEMENT_NAMES = ['pre', 'textarea'] /** @@ -42,21 +129,24 @@ const PREFORMATTED_ELEMENT_NAMES = ['pre', 'textarea'] * @param {Object} defaultOptions The default value of options. * @returns {IndentOptions} Normalized options. */ -function parseOptions (type, options, defaultOptions) { - const ret = Object.assign({ - indentChar: ' ', - indentSize: 2, - baseIndent: 0, - attribute: 1, - closeBracket: { - startTag: 0, - endTag: 0, - selfClosingTag: 0 +function parseOptions(type, options, defaultOptions) { + const ret = Object.assign( + { + indentChar: ' ', + indentSize: 2, + baseIndent: 0, + attribute: 1, + closeBracket: { + startTag: 0, + endTag: 0, + selfClosingTag: 0 + }, + switchCase: 0, + alignAttributesVertically: true, + ignores: [] }, - switchCase: 0, - alignAttributesVertically: true, - ignores: [] - }, defaultOptions) + defaultOptions + ) if (Number.isSafeInteger(type)) { ret.indentSize = type @@ -107,7 +197,7 @@ function parseOptions (type, options, defaultOptions) { * @param {Token} token The token to check. * @returns {boolean} `true` if the token is an arrow. */ -function isArrow (token) { +function isArrow(token) { return token != null && token.type === 'Punctuator' && token.value === '=>' } @@ -116,7 +206,7 @@ function isArrow (token) { * @param {Token} token The token to check. * @returns {boolean} `true` if the token is a left parenthesis. */ -function isLeftParen (token) { +function isLeftParen(token) { return token != null && token.type === 'Punctuator' && token.value === '(' } @@ -125,7 +215,7 @@ function isLeftParen (token) { * @param {Token} token The token to check. * @returns {boolean} `false` if the token is a left parenthesis. */ -function isNotLeftParen (token) { +function isNotLeftParen(token) { return token != null && (token.type !== 'Punctuator' || token.value !== '(') } @@ -134,7 +224,7 @@ function isNotLeftParen (token) { * @param {Token} token The token to check. * @returns {boolean} `true` if the token is a right parenthesis. */ -function isRightParen (token) { +function isRightParen(token) { return token != null && token.type === 'Punctuator' && token.value === ')' } @@ -143,7 +233,7 @@ function isRightParen (token) { * @param {Token} token The token to check. * @returns {boolean} `false` if the token is a right parenthesis. */ -function isNotRightParen (token) { +function isNotRightParen(token) { return token != null && (token.type !== 'Punctuator' || token.value !== ')') } @@ -152,7 +242,7 @@ function isNotRightParen (token) { * @param {Token} token The token to check. * @returns {boolean} `true` if the token is a left brace. */ -function isLeftBrace (token) { +function isLeftBrace(token) { return token != null && token.type === 'Punctuator' && token.value === '{' } @@ -161,7 +251,7 @@ function isLeftBrace (token) { * @param {Token} token The token to check. * @returns {boolean} `true` if the token is a right brace. */ -function isRightBrace (token) { +function isRightBrace(token) { return token != null && token.type === 'Punctuator' && token.value === '}' } @@ -170,7 +260,7 @@ function isRightBrace (token) { * @param {Token} token The token to check. * @returns {boolean} `true` if the token is a left bracket. */ -function isLeftBracket (token) { +function isLeftBracket(token) { return token != null && token.type === 'Punctuator' && token.value === '[' } @@ -179,7 +269,7 @@ function isLeftBracket (token) { * @param {Token} token The token to check. * @returns {boolean} `true` if the token is a right bracket. */ -function isRightBracket (token) { +function isRightBracket(token) { return token != null && token.type === 'Punctuator' && token.value === ']' } @@ -188,7 +278,7 @@ function isRightBracket (token) { * @param {Token} token The token to check. * @returns {boolean} `true` if the token is a semicolon. */ -function isSemicolon (token) { +function isSemicolon(token) { return token != null && token.type === 'Punctuator' && token.value === ';' } @@ -197,7 +287,7 @@ function isSemicolon (token) { * @param {Token} token The token to check. * @returns {boolean} `true` if the token is a comma. */ -function isComma (token) { +function isComma(token) { return token != null && token.type === 'Punctuator' && token.value === ',' } @@ -206,7 +296,7 @@ function isComma (token) { * @param {Token} token The token to check. * @returns {boolean} `true` if the token is a whitespace. */ -function isNotWhitespace (token) { +function isNotWhitespace(token) { return token != null && token.type !== 'HTMLWhitespace' } @@ -215,8 +305,14 @@ function isNotWhitespace (token) { * @param {Token} token The token to check. * @returns {boolean} `true` if the token is a comment. */ -function isComment (token) { - return token != null && (token.type === 'Block' || token.type === 'Line' || token.type === 'Shebang' || token.type.endsWith('Comment')) +function isComment(token) { + return ( + token != null && + (token.type === 'Block' || + token.type === 'Line' || + token.type === 'Shebang' || + token.type.endsWith('Comment')) + ) } /** @@ -224,8 +320,14 @@ function isComment (token) { * @param {Token} token The token to check. * @returns {boolean} `false` if the token is a comment. */ -function isNotComment (token) { - return token != null && token.type !== 'Block' && token.type !== 'Line' && token.type !== 'Shebang' && !token.type.endsWith('Comment') +function isNotComment(token) { + return ( + token != null && + token.type !== 'Block' && + token.type !== 'Line' && + token.type !== 'Shebang' && + !token.type.endsWith('Comment') + ) } /** @@ -233,7 +335,7 @@ function isNotComment (token) { * @param {Node} node The node to check. * @returns {boolean} `false` if the token is empty text node. */ -function isNotEmptyTextNode (node) { +function isNotEmptyTextNode(node) { return !(node.type === 'VText' && node.value.trim() === '') } @@ -242,7 +344,7 @@ function isNotEmptyTextNode (node) { * @param {Token} token The token to check. * @returns {boolean} `true` if the token is a pipe operator. */ -function isPipeOperator (token) { +function isPipeOperator(token) { return token != null && token.type === 'Punctuator' && token.value === '|' } @@ -251,7 +353,7 @@ function isPipeOperator (token) { * @param {Array} xs The array to get the last element. * @returns {any|undefined} The last element or undefined. */ -function last (xs) { +function last(xs) { return xs.length === 0 ? undefined : xs[xs.length - 1] } @@ -262,7 +364,7 @@ function last (xs) { * @param {Node[]} nodes The array of nodes. * @returns {boolean} `true` if the node is at the beginning of line. */ -function isBeginningOfLine (node, index, nodes) { +function isBeginningOfLine(node, index, nodes) { if (node != null) { for (let i = index - 1; i >= 0; --i) { const prevNode = nodes[i] @@ -281,18 +383,13 @@ function isBeginningOfLine (node, index, nodes) { * @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 === ']' - ) - ) +function isClosingToken(token) { + return ( + token != null && + (token.type === 'HTMLEndTagOpen' || + token.type === 'VExpressionEnd' || + (token.type === 'Punctuator' && + (token.value === ')' || token.value === '}' || token.value === ']'))) ) } @@ -304,10 +401,18 @@ function isClosingToken (token) { * @param {Object} defaultOptions The default value of options. * @returns {object} AST event handlers. */ -module.exports.defineVisitor = function create (context, tokenStore, defaultOptions) { +module.exports.defineVisitor = function create( + context, + tokenStore, + defaultOptions +) { if (!context.getFilename().endsWith('.vue')) return {} - const options = parseOptions(context.options[0], context.options[1] || {}, defaultOptions) + const options = parseOptions( + context.options[0], + context.options[1] || {}, + defaultOptions + ) const sourceCode = context.getSourceCode() const offsets = new Map() const ignoreTokens = new Set() @@ -320,7 +425,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {boolean} [trivial=false] The flag for trivial tokens. * @returns {void} */ - function setOffset (token, offset, baseToken) { + function setOffset(token, offset, baseToken) { assert(baseToken != null, "'baseToken' should not be null or undefined.") if (Array.isArray(token)) { @@ -347,7 +452,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {Token} token The token to set. * @returns {void} */ - function setBaseline (token) { + function setBaseline(token) { const offsetInfo = offsets.get(token) if (offsetInfo != null) { offsetInfo.baseline = true @@ -359,20 +464,26 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {Node} node The node to set. * @returns {void} */ - function setPreformattedTokens (node) { - const endToken = (node.endTag && tokenStore.getFirstToken(node.endTag)) || tokenStore.getTokenAfter(node) + function setPreformattedTokens(node) { + const endToken = + (node.endTag && tokenStore.getFirstToken(node.endTag)) || + tokenStore.getTokenAfter(node) const option = { includeComments: true, - filter: token => token != null && ( - token.type === 'HTMLText' || - token.type === 'HTMLRCDataText' || - token.type === 'HTMLTagOpen' || - token.type === 'HTMLEndTagOpen' || - token.type === 'HTMLComment' - ) + filter: (token) => + token != null && + (token.type === 'HTMLText' || + token.type === 'HTMLRCDataText' || + token.type === 'HTMLTagOpen' || + token.type === 'HTMLEndTagOpen' || + token.type === 'HTMLComment') } - for (const token of tokenStore.getTokensBetween(node.startTag, endToken, option)) { + for (const token of tokenStore.getTokensBetween( + node.startTag, + endToken, + option + )) { ignoreTokens.add(token) } ignoreTokens.add(endToken) @@ -385,7 +496,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {number} [borderOffset] The least offset of the first token. Defailt is 0. This value is used to prevent false positive in the following case: `(a) => {}` The parentheses are enclosing the whole parameter part rather than the first parameter, but this offset parameter is needed to distinguish. * @returns {{firstToken:Token,lastToken:Token}} The gotten tokens. */ - function getFirstAndLastTokens (node, borderOffset) { + function getFirstAndLastTokens(node, borderOffset) { borderOffset |= 0 let firstToken = tokenStore.getFirstToken(node) @@ -393,7 +504,13 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti // Get the outermost left parenthesis if it's parenthesized. let t, u - while ((t = tokenStore.getTokenBefore(firstToken)) != null && (u = tokenStore.getTokenAfter(lastToken)) != null && isLeftParen(t) && isRightParen(u) && t.range[0] >= borderOffset) { + while ( + (t = tokenStore.getTokenBefore(firstToken)) != null && + (u = tokenStore.getTokenAfter(lastToken)) != null && + isLeftParen(t) && + isRightParen(u) && + t.range[0] >= borderOffset + ) { firstToken = t lastToken = u } @@ -412,7 +529,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {boolean} [alignVertically=true] The flag to align vertically. If `false`, this doesn't align vertically even if the first node is not at beginning of line. * @returns {void} */ - function processNodeList (nodeList, left, right, offset, alignVertically) { + function processNodeList(nodeList, left, right, offset, alignVertically) { let t const leftToken = (left && tokenStore.getFirstToken(left)) || left const rightToken = (right && tokenStore.getFirstToken(right)) || right @@ -429,7 +546,10 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti // Holes of an array. continue } - const elementTokens = getFirstAndLastTokens(node, lastToken != null ? lastToken.range[1] : 0) + const elementTokens = getFirstAndLastTokens( + node, + lastToken != null ? lastToken.range[1] : 0 + ) // Collect comma/comment tokens between the last token of the previous node and the first token of this node. if (lastToken != null) { @@ -508,7 +628,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {Token} baseToken The base token. * @returns {void} */ - function processMaybeBlock (node, baseToken) { + function processMaybeBlock(node, baseToken) { const firstToken = getFirstAndLastTokens(node).firstToken setOffset(firstToken, isLeftBrace(firstToken) ? 0 : 1, baseToken) } @@ -518,7 +638,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * The prefix includes `async`, `get`, `set`, `static`, and `*`. * @param {Property|MethodDefinition} node The property node to collect prefix tokens. */ - function getPrefixTokens (node) { + function getPrefixTokens(node) { const prefixes = [] let token = tokenStore.getFirstToken(node) @@ -538,7 +658,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {Node} node The start node to find the head. * @returns {Token} The head token of the chain. */ - function getChainHeadToken (node) { + function getChainHeadToken(node) { const type = node.type while (node.parent.type === type) { const prevToken = tokenStore.getTokenBefore(node) @@ -564,7 +684,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @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) { + function isBeginningOfElement(token, belongingNode) { let node = belongingNode while (node != null) { @@ -585,20 +705,28 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti return true } if (t === 'CallExpression' || t === 'NewExpression') { - const openParen = tokenStore.getTokenAfter(parent.callee, isNotRightParen) - return parent.arguments.some(param => - getFirstAndLastTokens(param, openParen.range[1]).firstToken.range[0] === token.range[0] + const openParen = tokenStore.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] + 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] + return parent.expressions.some( + (expr) => + getFirstAndLastTokens(expr).firstToken.range[0] === token.range[0] ) } @@ -614,13 +742,18 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {number} expectedIndent The number of expected indent. * @returns {void} */ - function processTopLevelNode (node, expectedIndent) { + function processTopLevelNode(node, expectedIndent) { const token = tokenStore.getFirstToken(node) const offsetInfo = offsets.get(token) if (offsetInfo != null) { offsetInfo.expectedIndent = expectedIndent } else { - offsets.set(token, { baseToken: null, offset: 0, baseline: false, expectedIndent }) + offsets.set(token, { + baseToken: null, + offset: 0, + baseline: false, + expectedIndent + }) } } @@ -629,7 +762,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {Node} node The node to ignore. * @returns {void} */ - function ignore (node) { + function ignore(node) { for (const token of tokenStore.getTokens(node)) { offsets.delete(token) ignoreTokens.add(token) @@ -641,7 +774,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {Object} visitor The visitor to define functions to ignore nodes. * @returns {Object} The visitor. */ - function processIgnores (visitor) { + function processIgnores(visitor) { for (const ignorePattern of options.ignores) { const key = `${ignorePattern}:exit` @@ -665,7 +798,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {Token[]} tokens Tokens which are on the same line. * @returns {object|null} Correct indentation. If it failed to calculate then `null`. */ - function getExpectedIndents (tokens) { + function getExpectedIndents(tokens) { const expectedIndents = [] for (let i = 0; i < tokens.length; ++i) { @@ -677,8 +810,15 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti expectedIndents.push(offsetInfo.expectedIndent) } else { const baseOffsetInfo = offsets.get(offsetInfo.baseToken) - if (baseOffsetInfo != null && baseOffsetInfo.expectedIndent != null && (i === 0 || !baseOffsetInfo.baseline)) { - expectedIndents.push(baseOffsetInfo.expectedIndent + (offsetInfo.offset * options.indentSize)) + if ( + baseOffsetInfo != null && + baseOffsetInfo.expectedIndent != null && + (i === 0 || !baseOffsetInfo.baseline) + ) { + expectedIndents.push( + baseOffsetInfo.expectedIndent + + offsetInfo.offset * options.indentSize + ) if (baseOffsetInfo.baseline) { break } @@ -701,7 +841,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {Token} firstToken The first token on a line. * @returns {string} The text of indentation part. */ - function getIndentText (firstToken) { + function getIndentText(firstToken) { const text = sourceCode.text let i = firstToken.range[0] - 1 @@ -719,25 +859,27 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {number} expectedIndent The number of expected indentation. * @returns {Function} The defined function. */ - function defineFix (token, actualIndent, expectedIndent) { + function defineFix(token, actualIndent, expectedIndent) { if (token.type === 'Block' && token.loc.start.line !== token.loc.end.line) { // Fix indentation in multiline block comments. const lines = sourceCode.getText(token).match(LINES) const firstLine = lines.shift() - if (lines.every(l => BLOCK_COMMENT_PREFIX.test(l))) { - return fixer => { + if (lines.every((l) => BLOCK_COMMENT_PREFIX.test(l))) { + return (fixer) => { const range = [token.range[0] - actualIndent, token.range[1]] const indent = options.indentChar.repeat(expectedIndent) return fixer.replaceTextRange( range, - `${indent}${firstLine}${lines.map(l => l.replace(BLOCK_COMMENT_PREFIX, `${indent} *`)).join('')}` + `${indent}${firstLine}${lines + .map((l) => l.replace(BLOCK_COMMENT_PREFIX, `${indent} *`)) + .join('')}` ) } } } - return fixer => { + return (fixer) => { const range = [token.range[0] - actualIndent, token.range[0]] const indent = options.indentChar.repeat(expectedIndent) return fixer.replaceTextRange(range, indent) @@ -751,7 +893,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {number[]|undefined} optionalExpectedIndents The optional expected indentation. * @returns {void} */ - function validateCore (token, expectedIndent, optionalExpectedIndents) { + function validateCore(token, expectedIndent, optionalExpectedIndents) { const line = token.loc.start.line const indentText = getIndentText(token) @@ -763,7 +905,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } const actualIndent = token.loc.start.column - const unit = (options.indentChar === '\t' ? 'tab' : 'space') + const unit = options.indentChar === '\t' ? 'tab' : 'space' for (let i = 0; i < indentText.length; ++i) { if (indentText[i] !== options.indentChar) { @@ -772,7 +914,8 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti start: { line, column: i }, end: { line, column: i + 1 } }, - message: 'Expected {{expected}} character, but found {{actual}} character.', + message: + 'Expected {{expected}} character, but found {{actual}} character.', data: { expected: JSON.stringify(options.indentChar), actual: JSON.stringify(indentText[i]) @@ -783,19 +926,24 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } } - if (actualIndent !== expectedIndent && (optionalExpectedIndents == null || !optionalExpectedIndents.includes(actualIndent))) { + if ( + actualIndent !== expectedIndent && + (optionalExpectedIndents == null || + !optionalExpectedIndents.includes(actualIndent)) + ) { context.report({ loc: { start: { line, column: 0 }, end: { line, column: actualIndent } }, - message: 'Expected indentation of {{expectedIndent}} {{unit}}{{expectedIndentPlural}} but found {{actualIndent}} {{unit}}{{actualIndentPlural}}.', + message: + 'Expected indentation of {{expectedIndent}} {{unit}}{{expectedIndentPlural}} but found {{actualIndent}} {{unit}}{{actualIndentPlural}}.', data: { expectedIndent, actualIndent, unit, - expectedIndentPlural: (expectedIndent === 1) ? '' : 's', - actualIndentPlural: (actualIndent === 1) ? '' : 's' + expectedIndentPlural: expectedIndent === 1 ? '' : 's', + actualIndentPlural: actualIndent === 1 ? '' : 's' }, fix: defineFix(token, actualIndent, expectedIndent) }) @@ -809,7 +957,11 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {number|undefined} lastExpectedIndent The expected indent of the last token. * @returns {number[]} */ - function getCommentExpectedIndents (nextToken, nextExpectedIndent, lastExpectedIndent) { + function getCommentExpectedIndents( + nextToken, + nextExpectedIndent, + lastExpectedIndent + ) { if (typeof lastExpectedIndent === 'number' && isClosingToken(nextToken)) { if (nextExpectedIndent === lastExpectedIndent) { // For solo comment. E.g., @@ -842,7 +994,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {Token|null} lastToken The last validated token. Comments can adjust to the token. * @returns {void} */ - function validate (tokens, comments, lastToken) { + function validate(tokens, comments, lastToken) { // Calculate and save expected indentation. const firstToken = tokens[0] const actualIndent = firstToken.loc.start.column @@ -876,16 +1028,22 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti if (offsetInfo.baseline) { // This is a baseline token, so the expected indent is the column of this token. if (options.indentChar === ' ') { - offsetInfo.expectedIndent = Math.max(0, token.loc.start.column + expectedBaseIndent - actualIndent) + offsetInfo.expectedIndent = Math.max( + 0, + token.loc.start.column + expectedBaseIndent - actualIndent + ) } else { // In hard-tabs mode, it cannot align tokens strictly, so use one additional offset. // But the additional offset isn't needed if it's at the beginning of the line. - offsetInfo.expectedIndent = expectedBaseIndent + (token === tokens[0] ? 0 : 1) + offsetInfo.expectedIndent = + expectedBaseIndent + (token === tokens[0] ? 0 : 1) } baseline.add(token) } else if (baseline.has(offsetInfo.baseToken)) { // The base token is a baseline token on this line, so inherit it. - offsetInfo.expectedIndent = offsets.get(offsetInfo.baseToken).expectedIndent + offsetInfo.expectedIndent = offsets.get( + offsetInfo.baseToken + ).expectedIndent baseline.add(token) } else { // Otherwise, set the expected indent of this line. @@ -903,17 +1061,24 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti // It allows the same indent level with the previous line. const lastOffsetInfo = offsets.get(lastToken) const lastExpectedIndent = lastOffsetInfo && lastOffsetInfo.expectedIndent - const commentOptionalExpectedIndents = getCommentExpectedIndents(firstToken, expectedIndent, lastExpectedIndent) + const commentOptionalExpectedIndents = getCommentExpectedIndents( + firstToken, + expectedIndent, + lastExpectedIndent + ) // Validate. for (const comment of comments) { const commentExpectedIndents = getExpectedIndents([comment]) - const commentExpectedIndent = - commentExpectedIndents - ? commentExpectedIndents.expectedIndent - : commentOptionalExpectedIndents[0] - - validateCore(comment, commentExpectedIndent, commentOptionalExpectedIndents) + const commentExpectedIndent = commentExpectedIndents + ? commentExpectedIndents.expectedIndent + : commentOptionalExpectedIndents[0] + + validateCore( + comment, + commentExpectedIndent, + commentOptionalExpectedIndents + ) } validateCore(firstToken, expectedIndent) } @@ -923,7 +1088,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti // ------------------------------------------------------------------------------ return processIgnores({ - VAttribute (node) { + VAttribute(node) { const keyToken = tokenStore.getFirstToken(node) const eqToken = tokenStore.getTokenAfter(node.key) @@ -937,11 +1102,17 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - VElement (node) { + VElement(node) { if (!PREFORMATTED_ELEMENT_NAMES.includes(node.name)) { const isTopLevel = node.parent.type !== 'VElement' const offset = isTopLevel ? options.baseIndent : 1 - processNodeList(node.children.filter(isNotEmptyTextNode), node.startTag, node.endTag, offset, false) + processNodeList( + node.children.filter(isNotEmptyTextNode), + node.startTag, + node.endTag, + offset, + false + ) } else { const startTagToken = tokenStore.getFirstToken(node) const endTagToken = node.endTag && tokenStore.getFirstToken(node.endTag) @@ -950,7 +1121,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - VEndTag (node) { + VEndTag(node) { const element = node.parent const startTagOpenToken = tokenStore.getFirstToken(element.startTag) const closeToken = tokenStore.getLastToken(node) @@ -960,8 +1131,11 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - VExpressionContainer (node) { - if (node.expression != null && node.range[0] !== node.expression.range[0]) { + VExpressionContainer(node) { + if ( + node.expression != null && + node.range[0] !== node.expression.range[0] + ) { const startQuoteToken = tokenStore.getFirstToken(node) const endQuoteToken = tokenStore.getLastToken(node) const childToken = tokenStore.getTokenAfter(startQuoteToken) @@ -971,7 +1145,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - VFilter (node) { + VFilter(node) { const idToken = tokenStore.getFirstToken(node) const lastToken = tokenStore.getLastToken(node) if (isRightParen(lastToken)) { @@ -981,7 +1155,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - VFilterSequenceExpression (node) { + VFilterSequenceExpression(node) { if (node.filters.length === 0) { return } @@ -999,7 +1173,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti setOffset(tokens, 1, firstToken) }, - VForExpression (node) { + VForExpression(node) { const firstToken = tokenStore.getFirstToken(node) const lastOfLeft = last(node.left) || firstToken const inToken = tokenStore.getTokenAfter(lastOfLeft, isNotRightParen) @@ -1013,11 +1187,11 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti setOffset(rightToken, 1, inToken) }, - VOnExpression (node) { + VOnExpression(node) { processNodeList(node.body, null, null, 0) }, - VStartTag (node) { + VStartTag(node) { const openToken = tokenStore.getFirstToken(node) const closeToken = tokenStore.getLastToken(node) @@ -1029,14 +1203,15 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti options.alignAttributesVertically ) if (closeToken != null && closeToken.type.endsWith('TagClose')) { - const offset = closeToken.type !== 'HTMLSelfClosingTagClose' - ? options.closeBracket.startTag - : options.closeBracket.selfClosingTag + const offset = + closeToken.type !== 'HTMLSelfClosingTagClose' + ? options.closeBracket.startTag + : options.closeBracket.selfClosingTag setOffset(closeToken, offset, openToken) } }, - VText (node) { + VText(node) { const tokens = tokenStore.getTokens(node, isNotWhitespace) const firstTokenInfo = offsets.get(tokenStore.getFirstToken(node)) @@ -1045,11 +1220,16 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - 'ArrayExpression, ArrayPattern' (node) { - processNodeList(node.elements, tokenStore.getFirstToken(node), tokenStore.getLastToken(node), 1) + 'ArrayExpression, ArrayPattern'(node) { + processNodeList( + node.elements, + tokenStore.getFirstToken(node), + tokenStore.getLastToken(node), + 1 + ) }, - ArrowFunctionExpression (node) { + ArrowFunctionExpression(node) { const firstToken = tokenStore.getFirstToken(node) const secondToken = tokenStore.getTokenAfter(firstToken) const leftToken = node.async ? secondToken : firstToken @@ -1059,7 +1239,10 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti setOffset(secondToken, 1, firstToken) } if (isLeftParen(leftToken)) { - const rightToken = tokenStore.getTokenAfter(last(node.params) || leftToken, isRightParen) + const rightToken = tokenStore.getTokenAfter( + last(node.params) || leftToken, + isRightParen + ) processNodeList(node.params, leftToken, rightToken, 1) } @@ -1067,32 +1250,38 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti processMaybeBlock(node.body, firstToken) }, - 'AssignmentExpression, AssignmentPattern, BinaryExpression, LogicalExpression' (node) { + 'AssignmentExpression, AssignmentPattern, BinaryExpression, LogicalExpression'( + node + ) { const leftToken = getChainHeadToken(node) const opToken = tokenStore.getTokenAfter(node.left, isNotRightParen) const rightToken = tokenStore.getTokenAfter(opToken) const prevToken = tokenStore.getTokenBefore(leftToken) - const shouldIndent = ( + const shouldIndent = prevToken == null || prevToken.loc.end.line === leftToken.loc.start.line || isBeginningOfElement(leftToken, node) - ) setOffset([opToken, rightToken], shouldIndent ? 1 : 0, leftToken) }, - 'AwaitExpression, RestElement, SpreadElement, UnaryExpression' (node) { + 'AwaitExpression, RestElement, SpreadElement, UnaryExpression'(node) { const firstToken = tokenStore.getFirstToken(node) const nextToken = tokenStore.getTokenAfter(firstToken) setOffset(nextToken, 1, firstToken) }, - 'BlockStatement, ClassBody' (node) { - processNodeList(node.body, tokenStore.getFirstToken(node), tokenStore.getLastToken(node), 1) + 'BlockStatement, ClassBody'(node) { + processNodeList( + node.body, + tokenStore.getFirstToken(node), + tokenStore.getLastToken(node), + 1 + ) }, - 'BreakStatement, ContinueStatement, ReturnStatement, ThrowStatement' (node) { + 'BreakStatement, ContinueStatement, ReturnStatement, ThrowStatement'(node) { if (node.argument != null || node.label != null) { const firstToken = tokenStore.getFirstToken(node) const nextToken = tokenStore.getTokenAfter(firstToken) @@ -1101,7 +1290,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - CallExpression (node) { + CallExpression(node) { const firstToken = tokenStore.getFirstToken(node) const rightToken = tokenStore.getLastToken(node) const leftToken = tokenStore.getTokenAfter(node.callee, isLeftParen) @@ -1110,7 +1299,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti processNodeList(node.arguments, leftToken, rightToken, 1) }, - CatchClause (node) { + CatchClause(node) { const firstToken = tokenStore.getFirstToken(node) const bodyToken = tokenStore.getFirstToken(node.body) @@ -1124,7 +1313,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti setOffset(bodyToken, 0, firstToken) }, - 'ClassDeclaration, ClassExpression' (node) { + 'ClassDeclaration, ClassExpression'(node) { const firstToken = tokenStore.getFirstToken(node) const bodyToken = tokenStore.getFirstToken(node.body) @@ -1140,12 +1329,15 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti setOffset(bodyToken, 0, firstToken) }, - ConditionalExpression (node) { + ConditionalExpression(node) { const prevToken = tokenStore.getTokenBefore(node) const firstToken = tokenStore.getFirstToken(node) const questionToken = tokenStore.getTokenAfter(node.test, isNotRightParen) const consequentToken = tokenStore.getTokenAfter(questionToken) - const colonToken = tokenStore.getTokenAfter(node.consequent, isNotRightParen) + const colonToken = tokenStore.getTokenAfter( + node.consequent, + isNotRightParen + ) const alternateToken = tokenStore.getTokenAfter(colonToken) const isFlat = prevToken && @@ -1153,20 +1345,26 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti node.test.loc.end.line === node.consequent.loc.start.line if (isFlat) { - setOffset([questionToken, consequentToken, colonToken, alternateToken], 0, firstToken) + setOffset( + [questionToken, consequentToken, colonToken, alternateToken], + 0, + firstToken + ) } else { setOffset([questionToken, colonToken], 1, firstToken) setOffset([consequentToken, alternateToken], 1, questionToken) } }, - DoWhileStatement (node) { + DoWhileStatement(node) { const doToken = tokenStore.getFirstToken(node) const whileToken = tokenStore.getTokenAfter(node.body, isNotRightParen) const leftToken = tokenStore.getTokenAfter(whileToken) const testToken = tokenStore.getTokenAfter(leftToken) const lastToken = tokenStore.getLastToken(node) - const rightToken = isSemicolon(lastToken) ? tokenStore.getTokenBefore(lastToken) : lastToken + const rightToken = isSemicolon(lastToken) + ? tokenStore.getTokenBefore(lastToken) + : lastToken processMaybeBlock(node.body, doToken) setOffset(whileToken, 0, doToken) @@ -1175,7 +1373,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti setOffset(rightToken, 0, leftToken) }, - ExportAllDeclaration (node) { + ExportAllDeclaration(node) { const tokens = tokenStore.getTokens(node) const firstToken = tokens.shift() if (isSemicolon(last(tokens))) { @@ -1184,14 +1382,15 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti setOffset(tokens, 1, firstToken) }, - ExportDefaultDeclaration (node) { + ExportDefaultDeclaration(node) { const exportToken = tokenStore.getFirstToken(node) const defaultToken = tokenStore.getFirstToken(node, 1) - const declarationToken = getFirstAndLastTokens(node.declaration).firstToken + const declarationToken = getFirstAndLastTokens(node.declaration) + .firstToken setOffset([defaultToken, declarationToken], 1, exportToken) }, - ExportNamedDeclaration (node) { + ExportNamedDeclaration(node) { const exportToken = tokenStore.getFirstToken(node) if (node.declaration) { // export var foo = 1; @@ -1205,7 +1404,10 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti processNodeList(node.specifiers, leftParenToken, rightParenToken, 1) const maybeFromToken = tokenStore.getTokenAfter(rightParenToken) - if (maybeFromToken != null && sourceCode.getText(maybeFromToken) === 'from') { + if ( + maybeFromToken != null && + sourceCode.getText(maybeFromToken) === 'from' + ) { const fromToken = maybeFromToken const nameToken = tokenStore.getTokenAfter(fromToken) setOffset([fromToken, nameToken], 1, exportToken) @@ -1213,19 +1415,22 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - ExportSpecifier (node) { + ExportSpecifier(node) { const tokens = tokenStore.getTokens(node) const firstToken = tokens.shift() setOffset(tokens, 1, firstToken) }, - 'ForInStatement, ForOfStatement' (node) { + 'ForInStatement, ForOfStatement'(node) { const forToken = tokenStore.getFirstToken(node) const leftParenToken = tokenStore.getTokenAfter(forToken) const leftToken = tokenStore.getTokenAfter(leftParenToken) const inToken = tokenStore.getTokenAfter(leftToken, isNotRightParen) const rightToken = tokenStore.getTokenAfter(inToken) - const rightParenToken = tokenStore.getTokenBefore(node.body, isNotLeftParen) + const rightParenToken = tokenStore.getTokenBefore( + node.body, + isNotLeftParen + ) setOffset(leftParenToken, 1, forToken) setOffset(leftToken, 1, leftParenToken) @@ -1235,33 +1440,53 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti processMaybeBlock(node.body, forToken) }, - ForStatement (node) { + ForStatement(node) { const forToken = tokenStore.getFirstToken(node) const leftParenToken = tokenStore.getTokenAfter(forToken) - const rightParenToken = tokenStore.getTokenBefore(node.body, isNotLeftParen) + const rightParenToken = tokenStore.getTokenBefore( + node.body, + isNotLeftParen + ) setOffset(leftParenToken, 1, forToken) - processNodeList([node.init, node.test, node.update], leftParenToken, rightParenToken, 1) + processNodeList( + [node.init, node.test, node.update], + leftParenToken, + rightParenToken, + 1 + ) processMaybeBlock(node.body, forToken) }, - 'FunctionDeclaration, FunctionExpression' (node) { + 'FunctionDeclaration, FunctionExpression'(node) { const firstToken = tokenStore.getFirstToken(node) if (isLeftParen(firstToken)) { // Methods. const leftToken = firstToken - const rightToken = tokenStore.getTokenAfter(last(node.params) || leftToken, isRightParen) + const rightToken = tokenStore.getTokenAfter( + last(node.params) || leftToken, + isRightParen + ) const bodyToken = tokenStore.getFirstToken(node.body) processNodeList(node.params, leftToken, rightToken, 1) setOffset(bodyToken, 0, tokenStore.getFirstToken(node.parent)) } else { // Normal functions. - const functionToken = node.async ? tokenStore.getTokenAfter(firstToken) : firstToken - const starToken = node.generator ? tokenStore.getTokenAfter(functionToken) : null + const functionToken = node.async + ? tokenStore.getTokenAfter(firstToken) + : firstToken + const starToken = node.generator + ? tokenStore.getTokenAfter(functionToken) + : null const idToken = node.id && tokenStore.getFirstToken(node.id) - const leftToken = tokenStore.getTokenAfter(idToken || starToken || functionToken) - const rightToken = tokenStore.getTokenAfter(last(node.params) || leftToken, isRightParen) + const leftToken = tokenStore.getTokenAfter( + idToken || starToken || functionToken + ) + const rightToken = tokenStore.getTokenAfter( + last(node.params) || leftToken, + isRightParen + ) const bodyToken = tokenStore.getFirstToken(node.body) if (node.async) { @@ -1279,24 +1504,30 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - IfStatement (node) { + IfStatement(node) { const ifToken = tokenStore.getFirstToken(node) const ifLeftParenToken = tokenStore.getTokenAfter(ifToken) - const ifRightParenToken = tokenStore.getTokenBefore(node.consequent, isRightParen) + const ifRightParenToken = tokenStore.getTokenBefore( + node.consequent, + isRightParen + ) setOffset(ifLeftParenToken, 1, ifToken) setOffset(ifRightParenToken, 0, ifLeftParenToken) processMaybeBlock(node.consequent, ifToken) if (node.alternate != null) { - const elseToken = tokenStore.getTokenAfter(node.consequent, isNotRightParen) + const elseToken = tokenStore.getTokenAfter( + node.consequent, + isNotRightParen + ) setOffset(elseToken, 0, ifToken) processMaybeBlock(node.alternate, elseToken) } }, - ImportDeclaration (node) { + ImportDeclaration(node) { const firstSpecifier = node.specifiers[0] const secondSpecifier = node.specifiers[1] const importToken = tokenStore.getFirstToken(node) @@ -1322,7 +1553,10 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti tokens.push(tokenStore.getLastToken(node, hasSemi ? 1 : 0)) } } else if (firstSpecifier.type === 'ImportDefaultSpecifier') { - if (secondSpecifier && secondSpecifier.type === 'ImportNamespaceSpecifier') { + if ( + secondSpecifier && + secondSpecifier.type === 'ImportNamespaceSpecifier' + ) { // There is a pattern: // import Foo, * as foo from "foo" tokens.push( @@ -1381,7 +1615,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti setOffset(tokens, 1, importToken) }, - ImportSpecifier (node) { + ImportSpecifier(node) { if (node.local.range[0] !== node.imported.range[0]) { const tokens = tokenStore.getTokens(node) const firstToken = tokens.shift() @@ -1389,13 +1623,13 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - ImportNamespaceSpecifier (node) { + ImportNamespaceSpecifier(node) { const tokens = tokenStore.getTokens(node) const firstToken = tokens.shift() setOffset(tokens, 1, firstToken) }, - LabeledStatement (node) { + LabeledStatement(node) { const labelToken = tokenStore.getFirstToken(node) const colonToken = tokenStore.getTokenAfter(labelToken) const bodyToken = tokenStore.getTokenAfter(colonToken) @@ -1403,12 +1637,18 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti setOffset([colonToken, bodyToken], 1, labelToken) }, - 'MemberExpression, MetaProperty' (node) { + 'MemberExpression, MetaProperty'(node) { const objectToken = tokenStore.getFirstToken(node) if (node.computed) { - const leftBracketToken = tokenStore.getTokenBefore(node.property, isLeftBracket) + const leftBracketToken = tokenStore.getTokenBefore( + node.property, + isLeftBracket + ) const propertyToken = tokenStore.getTokenAfter(leftBracketToken) - const rightBracketToken = tokenStore.getTokenAfter(node.property, isRightBracket) + const rightBracketToken = tokenStore.getTokenAfter( + node.property, + isRightBracket + ) setOffset(leftBracketToken, 1, objectToken) setOffset(propertyToken, 1, leftBracketToken) @@ -1421,8 +1661,8 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - 'MethodDefinition, Property' (node) { - const isMethod = (node.type === 'MethodDefinition' || node.method === true) + 'MethodDefinition, Property'(node) { + const isMethod = node.type === 'MethodDefinition' || node.method === true const prefixTokens = getPrefixTokens(node) const hasPrefix = prefixTokens.length >= 1 @@ -1434,7 +1674,10 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti if (node.computed) { const keyLeftToken = tokenStore.getFirstToken(node, isLeftBracket) const keyToken = tokenStore.getTokenAfter(keyLeftToken) - const keyRightToken = lastKeyToken = tokenStore.getTokenAfter(node.key, isRightBracket) + const keyRightToken = (lastKeyToken = tokenStore.getTokenAfter( + node.key, + isRightBracket + )) if (hasPrefix) { setOffset(keyLeftToken, 0, last(prefixTokens)) @@ -1442,7 +1685,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti setOffset(keyToken, 1, keyLeftToken) setOffset(keyRightToken, 0, keyLeftToken) } else { - const idToken = lastKeyToken = tokenStore.getFirstToken(node.key) + const idToken = (lastKeyToken = tokenStore.getFirstToken(node.key)) if (hasPrefix) { setOffset(idToken, 0, last(prefixTokens)) @@ -1461,7 +1704,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - NewExpression (node) { + NewExpression(node) { const newToken = tokenStore.getFirstToken(node) const calleeToken = tokenStore.getTokenAfter(newToken) const rightToken = tokenStore.getLastToken(node) @@ -1476,15 +1719,20 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - 'ObjectExpression, ObjectPattern' (node) { - processNodeList(node.properties, tokenStore.getFirstToken(node), tokenStore.getLastToken(node), 1) + 'ObjectExpression, ObjectPattern'(node) { + processNodeList( + node.properties, + tokenStore.getFirstToken(node), + tokenStore.getLastToken(node), + 1 + ) }, - SequenceExpression (node) { + SequenceExpression(node) { processNodeList(node.expressions, null, null, 0) }, - SwitchCase (node) { + SwitchCase(node) { const caseToken = tokenStore.getFirstToken(node) if (node.test != null) { @@ -1498,7 +1746,10 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti setOffset(colonToken, 1, caseToken) } - if (node.consequent.length === 1 && node.consequent[0].type === 'BlockStatement') { + if ( + node.consequent.length === 1 && + node.consequent[0].type === 'BlockStatement' + ) { setOffset(tokenStore.getFirstToken(node.consequent[0]), 0, caseToken) } else if (node.consequent.length >= 1) { setOffset(tokenStore.getFirstToken(node.consequent[0]), 1, caseToken) @@ -1506,11 +1757,14 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - SwitchStatement (node) { + SwitchStatement(node) { const switchToken = tokenStore.getFirstToken(node) const leftParenToken = tokenStore.getTokenAfter(switchToken) const discriminantToken = tokenStore.getTokenAfter(leftParenToken) - const leftBraceToken = tokenStore.getTokenAfter(node.discriminant, isLeftBrace) + const leftBraceToken = tokenStore.getTokenAfter( + node.discriminant, + isLeftBrace + ) const rightParenToken = tokenStore.getTokenBefore(leftBraceToken) const rightBraceToken = tokenStore.getLastToken(node) @@ -1518,26 +1772,35 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti setOffset(discriminantToken, 1, leftParenToken) setOffset(rightParenToken, 0, leftParenToken) setOffset(leftBraceToken, 0, switchToken) - processNodeList(node.cases, leftBraceToken, rightBraceToken, options.switchCase) + processNodeList( + node.cases, + leftBraceToken, + rightBraceToken, + options.switchCase + ) }, - TaggedTemplateExpression (node) { + TaggedTemplateExpression(node) { const tagTokens = getFirstAndLastTokens(node.tag, node.range[0]) const quasiToken = tokenStore.getTokenAfter(tagTokens.lastToken) setOffset(quasiToken, 1, tagTokens.firstToken) }, - TemplateLiteral (node) { + TemplateLiteral(node) { const firstToken = tokenStore.getFirstToken(node) - const quasiTokens = node.quasis.slice(1).map(n => tokenStore.getFirstToken(n)) - const expressionToken = node.quasis.slice(0, -1).map(n => tokenStore.getTokenAfter(n)) + const quasiTokens = node.quasis + .slice(1) + .map((n) => tokenStore.getFirstToken(n)) + const expressionToken = node.quasis + .slice(0, -1) + .map((n) => tokenStore.getTokenAfter(n)) setOffset(quasiTokens, 0, firstToken) setOffset(expressionToken, 1, firstToken) }, - TryStatement (node) { + TryStatement(node) { const tryToken = tokenStore.getFirstToken(node) const tryBlockToken = tokenStore.getFirstToken(node.block) @@ -1557,18 +1820,23 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - UpdateExpression (node) { + UpdateExpression(node) { const firstToken = tokenStore.getFirstToken(node) const nextToken = tokenStore.getTokenAfter(firstToken) setOffset(nextToken, 1, firstToken) }, - VariableDeclaration (node) { - processNodeList(node.declarations, tokenStore.getFirstToken(node), null, 1) + VariableDeclaration(node) { + processNodeList( + node.declarations, + tokenStore.getFirstToken(node), + null, + 1 + ) }, - VariableDeclarator (node) { + VariableDeclarator(node) { if (node.init != null) { const idToken = tokenStore.getFirstToken(node) const eqToken = tokenStore.getTokenAfter(node.id) @@ -1578,7 +1846,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } }, - 'WhileStatement, WithStatement' (node) { + 'WhileStatement, WithStatement'(node) { const firstToken = tokenStore.getFirstToken(node) const leftParenToken = tokenStore.getTokenAfter(firstToken) const rightParenToken = tokenStore.getTokenBefore(node.body, isRightParen) @@ -1588,7 +1856,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti processMaybeBlock(node.body, firstToken) }, - YieldExpression (node) { + YieldExpression(node) { if (node.argument != null) { const yieldToken = tokenStore.getFirstToken(node) @@ -1600,7 +1868,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti }, // Process semicolons. - ':statement' (node) { + ':statement'(node) { const firstToken = tokenStore.getFirstToken(node) const lastToken = tokenStore.getLastToken(node) if (isSemicolon(lastToken) && firstToken !== lastToken) { @@ -1613,14 +1881,18 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti // ;[1,2,3].forEach(f) const info = offsets.get(firstToken) const prevToken = tokenStore.getTokenBefore(firstToken) - if (info != null && isSemicolon(prevToken) && prevToken.loc.end.line === firstToken.loc.start.line) { + if ( + info != null && + isSemicolon(prevToken) && + prevToken.loc.end.line === firstToken.loc.start.line + ) { offsets.set(prevToken, info) } }, // Process parentheses. // `:expression` does not match with MetaProperty and TemplateLiteral as a bug: https://github.com/estools/esquery/pull/59 - ':expression, MetaProperty, TemplateLiteral' (node) { + ':expression, MetaProperty, TemplateLiteral'(node) { let leftToken = tokenStore.getTokenBefore(node) let rightToken = tokenStore.getTokenAfter(node) let firstToken = tokenStore.getFirstToken(node) @@ -1636,33 +1908,33 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti }, // Ignore tokens of unknown nodes. - '*:exit' (node) { + '*:exit'(node) { if (!KNOWN_NODES.has(node.type)) { ignore(node) } }, // Top-level process. - Program (node) { + Program(node) { const firstToken = node.tokens[0] - const isScriptTag = ( + const isScriptTag = firstToken != null && firstToken.type === 'Punctuator' && firstToken.value === ' ` - }, + }, - // Comments - { - filename: 'test.vue', - code: unIndent` + // Comments + { + filename: 'test.vue', + code: unIndent` ` - }, - { - filename: 'test.vue', - code: unIndent` + }, + { + filename: 'test.vue', + code: unIndent` ` - }, - { - filename: 'test.vue', - code: unIndent` + }, + { + filename: 'test.vue', + code: unIndent` ` - }, + }, - // Ignores files other than .vue - { - filename: 'test.js', - code: unIndent` + // Ignores files other than .vue + { + filename: 'test.js', + code: unIndent` ` - }, + }, - // Ignores - { - filename: 'test.vue', - code: unIndent` + // Ignores + { + filename: 'test.vue', + code: unIndent` `, - options: [4, { - // Ignore all :D - ignores: ['*'] - }] - } - ], + options: [ + 4, + { + // Ignore all :D + ignores: ['*'] + } + ] + } + ], - // Invalid - [ - // TemplateLiteral - { - filename: 'test.vue', - code: unIndent` + // Invalid + [ + // TemplateLiteral + { + filename: 'test.vue', + code: unIndent` `, - output: unIndent` + output: unIndent` `, - options: [4], - errors: [ - { message: 'Expected indentation of 0 spaces but found 2 spaces.', line: 2 } - ] - }, + options: [4], + errors: [ + { + message: 'Expected indentation of 0 spaces but found 2 spaces.', + line: 2 + } + ] + }, - // A mix of spaces and tabs. - { - filename: 'test.vue', - code: unIndent` + // A mix of spaces and tabs. + { + filename: 'test.vue', + code: unIndent` `, - output: unIndent` + output: unIndent` `, - errors: [ - { message: 'Expected " " character, but found "\\t" character.', line: 3 } - ] - }, - { - filename: 'test.vue', - code: unIndent` + errors: [ + { + message: 'Expected " " character, but found "\\t" character.', + line: 3 + } + ] + }, + { + filename: 'test.vue', + code: unIndent` `, - output: unIndent` + output: unIndent` `, - options: ['tab'], - errors: [ - { message: 'Expected "\\t" character, but found " " character.', line: 3 }, - { message: 'Expected "\\t" character, but found " " character.', line: 4 } - ] - } - ] -)) + options: ['tab'], + errors: [ + { + message: 'Expected "\\t" character, but found " " character.', + line: 3 + }, + { + message: 'Expected "\\t" character, but found " " character.', + line: 4 + } + ] + } + ] + ) +)