diff --git a/lib/utils/indent-common.js b/lib/utils/indent-common.js index a4dee6f21..c8c867250 100644 --- a/lib/utils/indent-common.js +++ b/lib/utils/indent-common.js @@ -18,7 +18,6 @@ const KNOWN_NODES = new Set(['ArrayExpression', 'ArrayPattern', 'ArrowFunctionEx 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 TRIVIAL_PUNCTUATOR = /^[(){}[\],;]$/ /** * Normalize options. @@ -245,21 +244,6 @@ function isClosingToken (token) { ) } -/** - * Check whether a given token is trivial or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is trivial. - */ -function isTrivialToken (token) { - return token != null && ( - (token.type === 'Punctuator' && TRIVIAL_PUNCTUATOR.test(token.value)) || - token.type === 'HTMLTagOpen' || - token.type === 'HTMLEndTagOpen' || - token.type === 'HTMLTagClose' || - token.type === 'HTMLSelfClosingTagClose' - ) -} - /** * Creates AST event handlers for html-indent. * @@ -564,24 +548,22 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti /** * Calculate correct indentation of the line of the given tokens. * @param {Token[]} tokens Tokens which are on the same line. - * @returns {number} Correct indentation. If it failed to calculate then `Number.MAX_SAFE_INTEGER`. + * @returns {object|null} Correct indentation. If it failed to calculate then `null`. */ - function getExpectedIndent (tokens) { - const trivial = isTrivialToken(tokens[0]) - let expectedIndent = Number.MAX_SAFE_INTEGER + function getExpectedIndents (tokens) { + const expectedIndents = [] for (let i = 0; i < tokens.length; ++i) { const token = tokens[i] const offsetInfo = offsets.get(token) - // If the first token is not trivial then ignore trivial following tokens. - if (offsetInfo != null && (trivial || !isTrivialToken(token))) { + if (offsetInfo != null) { if (offsetInfo.expectedIndent != null) { - expectedIndent = Math.min(expectedIndent, offsetInfo.expectedIndent) + expectedIndents.push(offsetInfo.expectedIndent) } else { const baseOffsetInfo = offsets.get(offsetInfo.baseToken) if (baseOffsetInfo != null && baseOffsetInfo.expectedIndent != null && (i === 0 || !baseOffsetInfo.baseline)) { - expectedIndent = Math.min(expectedIndent, baseOffsetInfo.expectedIndent + offsetInfo.offset * options.indentSize) + expectedIndents.push(baseOffsetInfo.expectedIndent + offsetInfo.offset * options.indentSize) if (baseOffsetInfo.baseline) { break } @@ -589,8 +571,14 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti } } } + if (!expectedIndents.length) { + return null + } - return expectedIndent + return { + expectedIndent: expectedIndents[0], + expectedBaseIndent: expectedIndents.reduce((a, b) => Math.min(a, b)) + } } /** @@ -746,11 +734,14 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti // Calculate and save expected indentation. const firstToken = tokens[0] const actualIndent = firstToken.loc.start.column - const expectedIndent = getExpectedIndent(tokens) - if (expectedIndent === Number.MAX_SAFE_INTEGER) { + const expectedIndents = getExpectedIndents(tokens) + if (!expectedIndents) { return } + const expectedBaseIndent = expectedIndents.expectedBaseIndent + const expectedIndent = expectedIndents.expectedIndent + // Debug log // console.log('line', firstToken.loc.start.line, '=', { actualIndent, expectedIndent }, 'from:') // for (const token of tokens) { @@ -773,11 +764,11 @@ 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 + expectedIndent - 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 = expectedIndent + (token === tokens[0] ? 0 : 1) + offsetInfo.expectedIndent = expectedBaseIndent + (token === tokens[0] ? 0 : 1) } baseline.add(token) } else if (baseline.has(offsetInfo.baseToken)) { @@ -786,7 +777,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti baseline.add(token) } else { // Otherwise, set the expected indent of this line. - offsetInfo.expectedIndent = expectedIndent + offsetInfo.expectedIndent = expectedBaseIndent } } } diff --git a/tests/fixtures/script-indent/array-expression-03.vue b/tests/fixtures/script-indent/array-expression-03.vue new file mode 100644 index 000000000..0e15d8aad --- /dev/null +++ b/tests/fixtures/script-indent/array-expression-03.vue @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/tests/fixtures/script-indent/array-expression-04.vue b/tests/fixtures/script-indent/array-expression-04.vue new file mode 100644 index 000000000..1530c24b5 --- /dev/null +++ b/tests/fixtures/script-indent/array-expression-04.vue @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/tests/fixtures/script-indent/indent-valid-fixture-01.vue b/tests/fixtures/script-indent/indent-valid-fixture-01.vue new file mode 100644 index 000000000..c1423bf9b --- /dev/null +++ b/tests/fixtures/script-indent/indent-valid-fixture-01.vue @@ -0,0 +1,541 @@ + + + \ No newline at end of file diff --git a/tests/fixtures/script-indent/issue441.vue b/tests/fixtures/script-indent/issue441.vue new file mode 100644 index 000000000..a6738f2a3 --- /dev/null +++ b/tests/fixtures/script-indent/issue441.vue @@ -0,0 +1,10 @@ + + \ No newline at end of file diff --git a/tests/fixtures/script-indent/issue443.vue b/tests/fixtures/script-indent/issue443.vue new file mode 100644 index 000000000..4a8c356e7 --- /dev/null +++ b/tests/fixtures/script-indent/issue443.vue @@ -0,0 +1,27 @@ + + \ No newline at end of file diff --git a/tests/fixtures/script-indent/sequence-expression-04.vue b/tests/fixtures/script-indent/sequence-expression-04.vue new file mode 100644 index 000000000..f263bf523 --- /dev/null +++ b/tests/fixtures/script-indent/sequence-expression-04.vue @@ -0,0 +1,8 @@ + +