Skip to content

Commit da2aeb0

Browse files
committed
update a bit
1 parent 155ee6a commit da2aeb0

File tree

2 files changed

+2325
-508
lines changed

2 files changed

+2325
-508
lines changed

lib/rules/html-indent.js

Lines changed: 65 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ function isComment (token) {
155155
* @returns {boolean} `false` if the token is a comment.
156156
*/
157157
function isNotComment (token) {
158-
return token != null && !token.type.endsWith('Comment')
158+
return token != null && token.type !== 'Block' && token.type !== 'Line' && token.type !== 'Shebang' && !token.type.startsWith('Comment')
159159
}
160160

161161
/**
@@ -218,12 +218,12 @@ function create (context) {
218218
* Process the given node list.
219219
* The first node is offsetted from the given left token.
220220
* Rest nodes are adjusted to the first node.
221-
* @param {NodeList} nodeList The node to process.
221+
* @param {Node[]} nodeList The node to process.
222222
* @param {boolean} canParenthized If `true` then the node can be parenthized.
223223
* @returns {void}
224224
*/
225225
function processNodeList (nodeList, leftToken, rightToken, offset) {
226-
let t
226+
let t, u
227227

228228
if (nodeList.length >= 1) {
229229
let lastToken = leftToken
@@ -232,31 +232,49 @@ function create (context) {
232232
for (let i = 0; i < nodeList.length; ++i) {
233233
const node = nodeList[i]
234234
if (node == null) {
235+
// Holes of an array.
235236
continue
236237
}
237238

239+
// Get the first token of the node. If it's parenthesized then get the outermost left parenthesis.
238240
let elementFirstToken = template.getFirstToken(node)
241+
let elementLastToken = template.getLastToken(node)
239242
t = elementFirstToken
240-
while ((t = template.getTokenBefore(t)) != null && isLeftParen(t) && t.range[0] >= lastToken.range[1]) {
243+
u = elementLastToken
244+
while ((t = template.getTokenBefore(t)) != null && (u = template.getTokenAfter(u)) != null && isLeftParen(t) && isRightParen(u) && t.range[0] >= lastToken.range[1]) {
241245
elementFirstToken = t
246+
elementLastToken = u
242247
}
243248

249+
// Collect related tokens.
250+
// Commas between this and the previous, and the first token of this node.
244251
t = lastToken
245-
while ((t = template.getTokenAfter(t)) != null && t.range[1] <= elementFirstToken.range[0]) {
246-
alignTokens.push(t)
252+
while ((u = template.getTokenAfter(t)) != null && u.range[1] <= elementFirstToken.range[0]) {
253+
// This offset is smaller than the content, so it causes unintentional unindent.
254+
// E.g.
255+
// var obj = {
256+
// key:
257+
// value, // ← this comma is the same offset as `key`. It should avoid.
258+
// }
259+
if (u.loc.start.line !== t.loc.end.line) {
260+
alignTokens.push(u)
261+
}
262+
t = u
247263
}
248264
alignTokens.push(elementFirstToken)
249265

250-
lastToken = template.getLastToken(node)
266+
lastToken = elementLastToken
251267
}
252268

269+
// Check trailing commas.
253270
if (rightToken != null) {
254271
let t = lastToken
255272
while ((t = template.getTokenAfter(t)) != null && t.range[1] <= rightToken.range[0]) {
256273
alignTokens.push(t)
257274
}
258275
}
259276

277+
// Set offsets.
260278
const baseToken = alignTokens.shift()
261279
if (baseToken != null) {
262280
setOffset(baseToken, offset, leftToken)
@@ -465,19 +483,19 @@ function create (context) {
465483
}
466484

467485
// Debug log
468-
console.log('line', line, '=', indents[line], 'from:')
469-
for (const token of tokens) {
470-
const offsetInfo = offsets.get(token)
471-
if (offsetInfo == null) {
472-
console.log(' ', JSON.stringify(sourceCode.getText(token)), 'is unknown.')
473-
} else if (offsetInfo.offset === 0) {
474-
console.log(' ', JSON.stringify(sourceCode.getText(token)), 'is the same as', JSON.stringify(sourceCode.getText(offsetInfo.baseToken)), '(line', offsetInfo.baseToken.loc.start.line, ')')
475-
} else if (offsetInfo.offset === EXACT) {
476-
console.log(' ', JSON.stringify(sourceCode.getText(token)), 'is the exactly same as', JSON.stringify(sourceCode.getText(offsetInfo.baseToken)), '(line', offsetInfo.baseToken.loc.start.line, ')')
477-
} else {
478-
console.log(' ', JSON.stringify(sourceCode.getText(token)), 'is', offsetInfo.offset, 'offset from', JSON.stringify(sourceCode.getText(offsetInfo.baseToken)), '(line', offsetInfo.baseToken.loc.start.line, ')')
479-
}
480-
}
486+
// console.log('line', line, '=', indents[line], 'from:')
487+
// for (const token of tokens) {
488+
// const offsetInfo = offsets.get(token)
489+
// if (offsetInfo == null) {
490+
// console.log(' ', JSON.stringify(sourceCode.getText(token)), 'is unknown.')
491+
// } else if (offsetInfo.offset === 0) {
492+
// console.log(' ', JSON.stringify(sourceCode.getText(token)), 'is the same as', JSON.stringify(sourceCode.getText(offsetInfo.baseToken)), '(line', offsetInfo.baseToken.loc.start.line, ')')
493+
// } else if (offsetInfo.offset === EXACT) {
494+
// console.log(' ', JSON.stringify(sourceCode.getText(token)), 'is the exactly same as', JSON.stringify(sourceCode.getText(offsetInfo.baseToken)), '(line', offsetInfo.baseToken.loc.start.line, ')')
495+
// } else {
496+
// console.log(' ', JSON.stringify(sourceCode.getText(token)), 'is', offsetInfo.offset, 'offset from', JSON.stringify(sourceCode.getText(offsetInfo.baseToken)), '(line', offsetInfo.baseToken.loc.start.line, ')')
497+
// }
498+
// }
481499

482500
if (expectedIndent === Number.MAX_SAFE_INTEGER) {
483501
return
@@ -666,19 +684,18 @@ function create (context) {
666684
},
667685

668686
ConditionalExpression (node) {
669-
const headToken = getChainHeadToken(node)
687+
const firstToken = template.getFirstToken(node)
670688
const questionToken = template.getTokenAfter(node.test, isNotRightParen)
671689
const consequentToken = template.getTokenAfter(questionToken)
672690
const colonToken = template.getTokenAfter(node.consequent, isNotRightParen)
673691
const alternateToken = template.getTokenAfter(colonToken)
674692
const isFlat = (node.test.loc.end.line === node.consequent.loc.start.line)
675693

676694
if (isFlat) {
677-
setOffset([questionToken, consequentToken, colonToken, alternateToken], 0, headToken)
695+
setOffset([questionToken, consequentToken, colonToken, alternateToken], 0, firstToken)
678696
} else {
679-
setOffset([questionToken, colonToken], 1, headToken)
680-
setOffset(consequentToken, 1, questionToken)
681-
setOffset(alternateToken, 1, colonToken)
697+
setOffset([questionToken, colonToken], 1, firstToken)
698+
setOffset([consequentToken, alternateToken], 1, questionToken)
682699
}
683700
},
684701

@@ -707,8 +724,8 @@ function create (context) {
707724

708725
setOffset(leftParenToken, 1, forToken)
709726
setOffset(leftToken, 1, leftParenToken)
710-
setOffset(inToken, 1, leftParenToken)
711-
setOffset(rightToken, 1, inToken)
727+
setOffset(inToken, 1, leftToken)
728+
setOffset(rightToken, 1, leftToken)
712729
setOffset(rightParenToken, 0, leftParenToken)
713730
processMaybeBlock(node.body, forToken)
714731
},
@@ -733,7 +750,7 @@ function create (context) {
733750
const bodyToken = template.getFirstToken(node.body)
734751

735752
processNodeList(node.params, leftToken, rightToken, 1)
736-
setOffset(bodyToken, 0, firstToken)
753+
setOffset(bodyToken, 0, template.getFirstToken(node.parent))
737754
} else {
738755
// Normal functions.
739756
const functionToken = node.async ? template.getTokenAfter(firstToken) : firstToken
@@ -744,15 +761,15 @@ function create (context) {
744761
const bodyToken = template.getFirstToken(node.body)
745762

746763
if (node.async) {
747-
setOffset(functionToken, 1, firstToken)
764+
setOffset(functionToken, 0, firstToken)
748765
}
749766
if (node.generator) {
750-
setOffset(starToken, 1, functionToken)
767+
setOffset(starToken, 1, firstToken)
751768
}
752769
if (node.id != null) {
753-
setOffset(idToken, 1, starToken || functionToken)
770+
setOffset(idToken, 1, firstToken)
754771
}
755-
setOffset(leftToken, 1, idToken || starToken || functionToken)
772+
setOffset(leftToken, 1, firstToken)
756773
processNodeList(node.params, leftToken, rightToken, 1)
757774
setOffset(bodyToken, 0, firstToken)
758775
}
@@ -797,8 +814,7 @@ function create (context) {
797814
const dotToken = template.getTokenBefore(node.property)
798815
const propertyToken = template.getTokenAfter(dotToken)
799816

800-
setOffset(dotToken, 1, objectToken)
801-
setOffset(propertyToken, 1, dotToken)
817+
setOffset([dotToken, propertyToken], 1, objectToken)
802818
}
803819
},
804820

@@ -808,7 +824,7 @@ function create (context) {
808824
const hasPrefix = prefixTokens.length >= 1
809825

810826
for (let i = 1; i < prefixTokens.length; ++i) {
811-
setOffset(prefixTokens[i], 1, prefixTokens[i - 1])
827+
setOffset(prefixTokens[i], 0, prefixTokens[i - 1])
812828
}
813829

814830
let lastKeyToken = null
@@ -818,15 +834,15 @@ function create (context) {
818834
const keyRightToken = lastKeyToken = template.getTokenAfter(node.key, isRightBracket)
819835

820836
if (hasPrefix) {
821-
setOffset(keyLeftToken, 1, last(prefixTokens))
837+
setOffset(keyLeftToken, 0, last(prefixTokens))
822838
}
823839
setOffset(keyToken, 1, keyLeftToken)
824840
setOffset(keyRightToken, 0, keyLeftToken)
825841
} else {
826842
const idToken = lastKeyToken = template.getFirstToken(node.key)
827843

828844
if (hasPrefix) {
829-
setOffset(idToken, 1, last(prefixTokens))
845+
setOffset(idToken, 0, last(prefixTokens))
830846
}
831847
}
832848

@@ -838,8 +854,7 @@ function create (context) {
838854
const colonToken = template.getTokenAfter(lastKeyToken)
839855
const valueToken = template.getTokenAfter(colonToken)
840856

841-
setOffset(colonToken, 1, lastKeyToken)
842-
setOffset(valueToken, 1, colonToken)
857+
setOffset([colonToken, valueToken], 1, lastKeyToken)
843858
}
844859
},
845860

@@ -1033,7 +1048,7 @@ function create (context) {
10331048
const indents = []
10341049
let comments = []
10351050
let tokensOnSameLine = []
1036-
let shouldSkip = false
1051+
let isBesideMultilineToken = false
10371052

10381053
// Set the base indent.
10391054
{
@@ -1042,25 +1057,29 @@ function create (context) {
10421057
setOffset(firstToken, 0, firstToken)
10431058
}
10441059

1045-
// Validate indentations of tokens.
1060+
// Validate indentation of tokens.
10461061
for (const token of template.getTokens(node, { includeComments: true, filter: isNotWhitespace })) {
1047-
if (tokensOnSameLine.length === 0 || last(tokensOnSameLine).loc.start.line === token.loc.start.line) {
1062+
if (tokensOnSameLine.length === 0 || tokensOnSameLine[0].loc.start.line === token.loc.start.line) {
1063+
// This is on the same line (or the first token).
10481064
tokensOnSameLine.push(token)
10491065
} else if (tokensOnSameLine.every(isComment)) {
1066+
// New line is detected, but the all tokens of the previous line are comment.
1067+
// Comment lines are adjusted to the next code line.
10501068
comments.push(tokensOnSameLine[0])
1051-
shouldSkip = (last(tokensOnSameLine).loc.end.line === token.loc.start.line)
1069+
isBesideMultilineToken = last(tokensOnSameLine).loc.end.line === token.loc.start.line
10521070
tokensOnSameLine = [token]
10531071
} else {
1054-
if (!shouldSkip) {
1072+
// New line is detected, so validate the tokens.
1073+
if (!isBesideMultilineToken) {
10551074
validate(tokensOnSameLine, comments, indents)
10561075
}
1057-
shouldSkip = (last(tokensOnSameLine).loc.end.line === token.loc.start.line)
1076+
isBesideMultilineToken = last(tokensOnSameLine).loc.end.line === token.loc.start.line
10581077
tokensOnSameLine = [token]
10591078
comments = []
10601079
}
10611080
}
10621081
if (tokensOnSameLine.length >= 1 && tokensOnSameLine.some(isNotComment)) {
1063-
validate(tokensOnSameLine, [], indents)
1082+
validate(tokensOnSameLine, comments, indents)
10641083
}
10651084
}
10661085
})

0 commit comments

Comments
 (0)