Skip to content

Commit

Permalink
Fix: html-indent about binary expressions (fixes #264) (#281)
Browse files Browse the repository at this point in the history
* Fix: html-indent about binary expressions (fixes #264)

* update logic
  • Loading branch information
mysticatea authored and michalsnik committed Dec 17, 2017
1 parent e6593a5 commit 345aaac
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 14 deletions.
57 changes: 56 additions & 1 deletion lib/rules/html-indent.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,55 @@ function create (context) {
return template.getFirstToken(node)
}

/**
* Check whether a given token is the first token of:
*
* - ExpressionStatement
* - VExpressionContainer
* - A parameter of CallExpression/NewExpression
* - An element of ArrayExpression
* - An expression of SequenceExpression
*
* @param {Token} token The token to check.
* @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) {
let node = belongingNode

while (node != null) {
const parent = node.parent
const t = parent && parent.type
if (t != null && (t.endsWith('Statement') || t.endsWith('Declaration'))) {
return parent.range[0] === token.range[0]
}
if (t === 'VExpressionContainer') {
return node.range[0] === token.range[0]
}
if (t === 'CallExpression' || t === 'NewExpression') {
const openParen = template.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]
)
}
if (t === 'SequenceExpression') {
return parent.expressions.some(expr =>
getFirstAndLastTokens(expr).firstToken.range[0] === token.range[0]
)
}

node = parent
}

return false
}

/**
* Ignore all tokens of the given node.
* @param {Node} node The node to ignore.
Expand Down Expand Up @@ -752,8 +801,14 @@ function create (context) {
const leftToken = getChainHeadToken(node)
const opToken = template.getTokenAfter(node.left, isNotRightParen)
const rightToken = template.getTokenAfter(opToken)
const prevToken = template.getTokenBefore(leftToken)
const shouldIndent = (
prevToken == null ||
prevToken.loc.end.line === leftToken.loc.start.line ||
isBeginningOfElement(leftToken, node)
)

setOffset([opToken, rightToken], 1, leftToken)
setOffset([opToken, rightToken], shouldIndent ? 1 : 0, leftToken)
},

'AwaitExpression, RestElement, SpreadElement, UnaryExpression' (node) {
Expand Down
146 changes: 133 additions & 13 deletions tests/lib/rules/html-indent.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,10 @@ tester.run('html-indent', rule, {
a
=
b
+
c
+
d
+
c
+
d
"
></div>
</template>
Expand Down Expand Up @@ -1347,7 +1347,127 @@ tester.run('html-indent', rule, {
// Ignore all :D
ignores: ['*']
}]
}
},

// https://github.com/vuejs/eslint-plugin-vue/issues/264
unIndent`
<template>
<div
:class="{
foo: (
a === b &&
c === d
)
}"
/>
</template>
`,
unIndent`
<template>
<div
:class="{
foo:
a === b &&
c === d
}"
/>
</template>
`,
unIndent`
<template>
<div
:class="{
foo: a === b &&
c === d
}"
/>
</template>
`,
unIndent`
<template>
<div
:class="
[
a
+
b,
c
+
d
]
"
/>
</template>
`,
unIndent`
<template>
<div
:class="
foo(
a
+
b,
c
+
d
)
"
/>
<div
:class="
new Foo(
a
+
b,
c
+
d
)
"
/>
</template>
`,
unIndent`
<template>
<div
:class="
a
+
b,
c
+
d
"
/>
</template>
`,
unIndent`
<template>
<div
:class="
foo(
a
+
b
)
"
/>
<div
:class="
foo(
(
a +
b
),
(
c +
d
)
)
"
/>
</template>
`
],

invalid: [
Expand Down Expand Up @@ -1819,10 +1939,10 @@ tester.run('html-indent', rule, {
a
=
b
+
c
+
d
+
c
+
d
"
></div>
</template>
Expand All @@ -1840,10 +1960,10 @@ tester.run('html-indent', rule, {
{ message: 'Expected indentation of 12 spaces but found 10 spaces.', line: 16 },
{ message: 'Expected indentation of 16 spaces but found 10 spaces.', line: 17 },
{ message: 'Expected indentation of 16 spaces but found 10 spaces.', line: 18 },
{ message: 'Expected indentation of 20 spaces but found 10 spaces.', line: 19 },
{ message: 'Expected indentation of 20 spaces but found 10 spaces.', line: 20 },
{ message: 'Expected indentation of 20 spaces but found 10 spaces.', line: 21 },
{ message: 'Expected indentation of 20 spaces but found 10 spaces.', line: 22 }
{ message: 'Expected indentation of 16 spaces but found 10 spaces.', line: 19 },
{ message: 'Expected indentation of 16 spaces but found 10 spaces.', line: 20 },
{ message: 'Expected indentation of 16 spaces but found 10 spaces.', line: 21 },
{ message: 'Expected indentation of 16 spaces but found 10 spaces.', line: 22 }
]
},

Expand Down

0 comments on commit 345aaac

Please sign in to comment.