diff --git a/lib/utils/indent-common.js b/lib/utils/indent-common.js index 1b93f2069..dfc89d57c 100644 --- a/lib/utils/indent-common.js +++ b/lib/utils/indent-common.js @@ -18,6 +18,7 @@ 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. @@ -244,6 +245,21 @@ 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. * @@ -262,6 +278,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @param {Token|Token[]} token The token to set. * @param {number} offset The offset of the tokens. * @param {Token} baseToken The token of the base offset. + * @param {boolean} [trivial=false] The flag for trivial tokens. * @returns {void} */ function setOffset (token, offset, baseToken) { @@ -352,9 +369,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti if (lastToken != null) { t = lastToken while ((t = tokenStore.getTokenAfter(t)) != null && t.range[1] <= elementTokens.firstToken.range[0]) { - if (lastToken.loc.end.line !== t.loc.start.line) { - alignTokens.push(t) - } + alignTokens.push(t) } } alignTokens.push(elementTokens.firstToken) @@ -550,13 +565,15 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti * @returns {number} Correct indentation. If it failed to calculate then `Number.MAX_SAFE_INTEGER`. */ function getExpectedIndent (tokens) { + const trivial = isTrivialToken(tokens[0]) let expectedIndent = Number.MAX_SAFE_INTEGER for (let i = 0; i < tokens.length; ++i) { const token = tokens[i] const offsetInfo = offsets.get(token) - if (offsetInfo != null) { + // If the first token is not trivial then ignore trivial following tokens. + if (offsetInfo != null && (trivial || !isTrivialToken(token))) { if (offsetInfo.expectedIndent != null) { expectedIndent = Math.min(expectedIndent, offsetInfo.expectedIndent) } else { @@ -1429,24 +1446,23 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti // Process semicolons. ':statement' (node) { const info = offsets.get(tokenStore.getFirstToken(node)) + const lastToken = tokenStore.getLastToken(node) if (info == null) { return } + if (isSemicolon(lastToken)) { + offsets.set(lastToken, info) + } // Set to the semicolon of the previous token for semicolon-free style. // E.g., // foo // ;[1,2,3].forEach(f) - const tokens = [ - tokenStore.getTokenBefore(node), - tokenStore.getLastToken(node) - ].filter(isSemicolon) - - // Set offsets if the semicolon is at beginning of line. - for (const token of tokens) { - const prevToken = tokenStore.getTokenBefore(token) - if (prevToken == null || token.loc.end.line !== prevToken.loc.start.line) { - offsets.set(token, info) + const prevToken = tokenStore.getTokenBefore(node) + if (isSemicolon(prevToken)) { + const prevPrevToken = tokenStore.getTokenBefore(prevToken) + if (prevPrevToken == null || prevToken.loc.end.line !== prevPrevToken.loc.start.line) { + offsets.set(prevToken, info) } } }, diff --git a/tests/fixtures/html-indent/v-start-tag-02.vue b/tests/fixtures/html-indent/v-start-tag-02.vue new file mode 100644 index 000000000..7ac1ee0da --- /dev/null +++ b/tests/fixtures/html-indent/v-start-tag-02.vue @@ -0,0 +1,5 @@ + + diff --git a/tests/fixtures/html-indent/v-start-tag-03.vue b/tests/fixtures/html-indent/v-start-tag-03.vue new file mode 100644 index 000000000..4a4d918aa --- /dev/null +++ b/tests/fixtures/html-indent/v-start-tag-03.vue @@ -0,0 +1,6 @@ + + diff --git a/tests/fixtures/html-indent/v-start-tag-04.vue b/tests/fixtures/html-indent/v-start-tag-04.vue new file mode 100644 index 000000000..69ac40a5d --- /dev/null +++ b/tests/fixtures/html-indent/v-start-tag-04.vue @@ -0,0 +1,7 @@ + + diff --git a/tests/fixtures/html-indent/v-start-tag-05.vue b/tests/fixtures/html-indent/v-start-tag-05.vue new file mode 100644 index 000000000..5d7d7155d --- /dev/null +++ b/tests/fixtures/html-indent/v-start-tag-05.vue @@ -0,0 +1,5 @@ + + diff --git a/tests/fixtures/script-indent/array-expression-02.vue b/tests/fixtures/script-indent/array-expression-02.vue new file mode 100644 index 000000000..d398bde99 --- /dev/null +++ b/tests/fixtures/script-indent/array-expression-02.vue @@ -0,0 +1,5 @@ + + diff --git a/tests/fixtures/script-indent/function-declaration-04.vue b/tests/fixtures/script-indent/function-declaration-04.vue new file mode 100644 index 000000000..d4ce7897b --- /dev/null +++ b/tests/fixtures/script-indent/function-declaration-04.vue @@ -0,0 +1,7 @@ + + diff --git a/tests/fixtures/script-indent/object-expression-03.vue b/tests/fixtures/script-indent/object-expression-03.vue new file mode 100644 index 000000000..f65063ecc --- /dev/null +++ b/tests/fixtures/script-indent/object-expression-03.vue @@ -0,0 +1,5 @@ + +