Skip to content

Commit 53db1d4

Browse files
authored
fix: crash with template expression in no-trailing-spaces (#337)
* fix: crash with template expression in no-trailing-spaces * Update no-trailing-spaces.test.js
1 parent 390a69b commit 53db1d4

File tree

2 files changed

+129
-18
lines changed

2 files changed

+129
-18
lines changed

packages/eslint-plugin/lib/rules/no-trailing-spaces.js

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,29 +44,32 @@ module.exports = {
4444
/**
4545
* @param {string} source
4646
* @param {string[]} lines
47-
* @param {number} rangeOffset
47+
* @param {Object} offset
48+
* @param {number} offset.range
49+
* @param {number} offset.line
50+
* @param {number} offset.column
4851
* @param {((CommentContent | Text)['parts'][number])[]} tokens
4952
*/
50-
function check(source, lines, rangeOffset, tokens) {
51-
let rangeIndex = rangeOffset;
53+
function check(source, lines, offset, tokens) {
5254
const lineBreaks = source.match(/\r\n|[\r\n\u2028\u2029]/gu);
55+
5356
lines.forEach((line, index) => {
54-
const lineNumber = index + 1;
57+
const lineNumber = index + offset.line;
5558
const match = line.match(/[ \t\u00a0\u2000-\u200b\u3000]+$/);
5659
const lineBreakLength =
5760
lineBreaks && lineBreaks[index] ? lineBreaks[index].length : 1;
5861
const lineLength = line.length + lineBreakLength;
59-
62+
const columnOffset = index === 0 ? offset.column : 0;
6063
if (match) {
6164
if (typeof match.index === "number" && match.index > 0) {
6265
const loc = {
6366
start: {
6467
line: lineNumber,
65-
column: match.index,
68+
column: match.index + columnOffset,
6669
},
6770
end: {
6871
line: lineNumber,
69-
column: lineLength - lineBreakLength,
72+
column: lineLength - lineBreakLength + columnOffset,
7073
},
7174
};
7275
const start = sourceCode.getIndexFromLoc(loc.start);
@@ -80,21 +83,26 @@ module.exports = {
8083
messageId: MESSAGE_IDS.TRAILING_SPACE,
8184
loc,
8285
fix(fixer) {
83-
return fixer.removeRange([
84-
rangeIndex + loc.start.column,
85-
rangeIndex + loc.end.column,
86-
]);
86+
return fixer.removeRange([start, end]);
8787
},
8888
});
8989
}
9090
}
91-
rangeIndex += lineLength;
9291
});
9392
}
9493

9594
return {
9695
Document() {
97-
check(sourceCode.getText(), sourceCode.getLines(), 0, []);
96+
check(
97+
sourceCode.getText(),
98+
sourceCode.getLines(),
99+
{
100+
range: 0,
101+
line: 1,
102+
column: 0,
103+
},
104+
[]
105+
);
98106
},
99107
TaggedTemplateExpression(node) {
100108
if (shouldCheckTaggedTemplateExpression(node, context)) {
@@ -107,8 +115,11 @@ module.exports = {
107115
check(
108116
html,
109117
lines,
110-
// @ts-ignore
111-
node.quasi.range[0] + 1,
118+
{
119+
range: node.quasi.range[0] + 1,
120+
line: node.quasi.loc.start.line,
121+
column: node.quasi.loc.start.column + 1,
122+
},
112123
getTemplateTokens(tokens)
113124
);
114125
}
@@ -120,8 +131,11 @@ module.exports = {
120131
check(
121132
html,
122133
lines,
123-
// @ts-ignore
124-
node.range[0] + 1,
134+
{
135+
range: node.range[0] + 1,
136+
line: node.loc.start.line,
137+
column: node.loc.start.column + 1,
138+
},
125139
getTemplateTokens(tokens)
126140
);
127141
}

packages/eslint-plugin/tests/rules/no-trailing-spaces.test.js

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ ruleTester.run("no-tailing-spaces", rule, {
2626
errors: [
2727
{
2828
messageId: "trailingSpace",
29+
column: 12,
30+
endColumn: 14,
31+
line: 1,
2932
},
3033
],
3134
},
@@ -35,6 +38,9 @@ ruleTester.run("no-tailing-spaces", rule, {
3538
errors: [
3639
{
3740
messageId: "trailingSpace",
41+
column: 12,
42+
endColumn: 14,
43+
line: 1,
3844
},
3945
],
4046
},
@@ -44,6 +50,9 @@ ruleTester.run("no-tailing-spaces", rule, {
4450
errors: [
4551
{
4652
messageId: "trailingSpace",
53+
column: 6,
54+
endColumn: 8,
55+
line: 1,
4756
},
4857
],
4958
},
@@ -77,6 +86,94 @@ templateRuleTester.run("[template] no-tailing-spaces", rule, {
7786
})()}
7887
</div>\``,
7988
},
89+
{
90+
code: `html\`<div>
91+
\${(() => {
92+
93+
})() }
94+
</div>\``,
95+
},
96+
{
97+
code: `
98+
html\`<div>
99+
</div>\``,
100+
},
101+
],
102+
invalid: [
103+
{
104+
code: `
105+
html\`<div>
106+
</div>\``,
107+
output: `
108+
html\`<div>
109+
</div>\``,
110+
errors: [
111+
{
112+
messageId: "trailingSpace",
113+
},
114+
],
115+
},
116+
{
117+
code: "html`<div> \n text\n </div>`",
118+
output: "html`<div>\n text\n </div>`",
119+
errors: [
120+
{
121+
messageId: "trailingSpace",
122+
line: 1,
123+
column: 11,
124+
endColumn: 13,
125+
},
126+
],
127+
},
128+
{
129+
code: "html`<div>\n text\n </div> `",
130+
output: "html`<div>\n text\n </div>`",
131+
errors: [
132+
{
133+
messageId: "trailingSpace",
134+
line: 3,
135+
column: 9,
136+
endColumn: 12,
137+
},
138+
],
139+
},
140+
{
141+
code: `html\`<div id=\${foo}
142+
>
143+
text
144+
</div>\``,
145+
output: `html\`<div id=\${foo}
146+
>
147+
text
148+
</div>\``,
149+
errors: [
150+
{
151+
messageId: "trailingSpace",
152+
line: 1,
153+
column: 20,
154+
endColumn: 23,
155+
},
156+
],
157+
},
158+
{
159+
code: `
160+
html\`<div id=\${foo}
161+
>
162+
text
163+
</div>\``,
164+
output: `
165+
html\`<div id=\${foo}
166+
>
167+
text
168+
</div>\``,
169+
errors: [
170+
{
171+
messageId: "trailingSpace",
172+
line: 2,
173+
column: 20,
174+
endColumn: 23,
175+
},
176+
],
177+
},
80178
],
81-
invalid: [],
82179
});

0 commit comments

Comments
 (0)