Skip to content

Commit 1559577

Browse files
authored
feat: support long lines in generateCodeFrame (#20640)
1 parent f691f57 commit 1559577

File tree

4 files changed

+160
-12
lines changed

4 files changed

+160
-12
lines changed

packages/vite/src/node/__tests__/__snapshots__/utils.spec.ts.snap

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,62 @@ exports[`generateCodeFrames > invalid start > end 1`] = `
6060
"
6161
`;
6262

63+
exports[`generateCodeFrames > long line (center) 1`] = `
64+
"
65+
1 | ...aaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccccccccccccccc...
66+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
67+
2 | short line
68+
3 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
69+
"
70+
`;
71+
72+
exports[`generateCodeFrames > long line (end) 1`] = `
73+
"
74+
1 | ...bbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
75+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
76+
2 | short line
77+
3 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
78+
"
79+
`;
80+
81+
exports[`generateCodeFrames > long line (multiline 1) 1`] = `
82+
"
83+
1 | ...bbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
84+
| ^^^^^^^^^^
85+
2 | short line
86+
| ^^^^^^
87+
3 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
88+
"
89+
`;
90+
91+
exports[`generateCodeFrames > long line (multiline 2) 1`] = `
92+
"
93+
1 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
94+
2 | short line
95+
| ^^^^^
96+
3 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
97+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
98+
"
99+
`;
100+
101+
exports[`generateCodeFrames > long line (start) 1`] = `
102+
"
103+
1 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
104+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
105+
2 | short line
106+
3 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
107+
"
108+
`;
109+
110+
exports[`generateCodeFrames > long line (whole) 1`] = `
111+
"
112+
1 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
113+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
114+
2 | short line
115+
3 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
116+
"
117+
`;
118+
63119
exports[`generateCodeFrames > range 1`] = `
64120
"
65121
1 | import foo from './foo'

packages/vite/src/node/__tests__/utils.spec.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,72 @@ foo()
347347
test('supports more than 1000 lines', () => {
348348
expectSnapshot(generateCodeFrame(veryLongSource, { line: 1200, column: 0 }))
349349
})
350+
351+
test('long line (start)', () => {
352+
const longLine = 'a'.repeat(60) + 'b'.repeat(60) + 'c'.repeat(60)
353+
const src = `${longLine}\nshort line\n${longLine}`
354+
const frame = generateCodeFrame(
355+
src,
356+
{ line: 1, column: 0 },
357+
{ line: 1, column: 30 },
358+
)
359+
expectSnapshot(frame)
360+
})
361+
362+
test('long line (center)', () => {
363+
const longLine = 'a'.repeat(60) + 'b'.repeat(60) + 'c'.repeat(60)
364+
const src = `${longLine}\nshort line\n${longLine}`
365+
const frame = generateCodeFrame(
366+
src,
367+
{ line: 1, column: 90 },
368+
{ line: 1, column: 120 },
369+
)
370+
expectSnapshot(frame)
371+
})
372+
373+
test('long line (end)', () => {
374+
const longLine = 'a'.repeat(60) + 'b'.repeat(60) + 'c'.repeat(60)
375+
const src = `${longLine}\nshort line\n${longLine}`
376+
const frame = generateCodeFrame(
377+
src,
378+
{ line: 1, column: 150 },
379+
{ line: 1, column: 180 },
380+
)
381+
expectSnapshot(frame)
382+
})
383+
384+
test('long line (whole)', () => {
385+
const longLine = 'a'.repeat(60) + 'b'.repeat(60) + 'c'.repeat(60)
386+
const src = `${longLine}\nshort line\n${longLine}`
387+
const frame = generateCodeFrame(
388+
src,
389+
{ line: 1, column: 0 },
390+
{ line: 1, column: 180 },
391+
)
392+
expectSnapshot(frame)
393+
})
394+
395+
test('long line (multiline 1)', () => {
396+
const longLine = 'a'.repeat(60) + 'b'.repeat(60) + 'c'.repeat(60)
397+
const src = `${longLine}\nshort line\n${longLine}`
398+
const frame = generateCodeFrame(
399+
src,
400+
{ line: 1, column: 170 },
401+
{ line: 2, column: 5 },
402+
)
403+
expectSnapshot(frame)
404+
})
405+
406+
test('long line (multiline 2)', () => {
407+
const longLine = 'a'.repeat(60) + 'b'.repeat(60) + 'c'.repeat(60)
408+
const src = `${longLine}\nshort line\n${longLine}`
409+
const frame = generateCodeFrame(
410+
src,
411+
{ line: 2, column: 5 },
412+
{ line: 3, column: 30 },
413+
)
414+
expectSnapshot(frame)
415+
})
350416
})
351417

352418
describe('getHash', () => {

packages/vite/src/node/plugins/html.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ function handleParseError(
336336
warnings[parseError.code] ??=
337337
`Unable to parse HTML; ${parseError.message}\n` +
338338
` at ${parseError.loc.file}:${parseError.loc.line}:${parseError.loc.column}\n` +
339-
`${parseError.frame.length > 300 ? '[this code frame is omitted as the content was too long] ' : parseError.frame}`
339+
parseError.frame
340340
}
341341

342342
/**

packages/vite/src/node/utils.ts

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,9 @@ export function numberToPos(source: string, offset: number | Pos): Pos {
498498
}
499499
}
500500

501+
const MAX_DISPLAY_LEN = 120
502+
const ELLIPSIS = '...'
503+
501504
export function generateCodeFrame(
502505
source: string,
503506
start: number | Pos = 0,
@@ -522,28 +525,51 @@ export function generateCodeFrame(
522525
for (let j = i - range; j <= i + range || end > count; j++) {
523526
if (j < 0 || j >= lines.length) continue
524527
const line = j + 1
528+
const lineLength = lines[j].length
529+
const pad = Math.max(start - (count - lineLength), 0)
530+
const underlineLength = Math.max(
531+
1,
532+
end > count ? lineLength - pad : end - start,
533+
)
534+
535+
let displayLine = lines[j]
536+
let underlinePad = pad
537+
if (lineLength > MAX_DISPLAY_LEN) {
538+
let startIdx = 0
539+
if (j === i) {
540+
if (underlineLength > MAX_DISPLAY_LEN) {
541+
startIdx = pad
542+
} else {
543+
const center = pad + Math.floor(underlineLength / 2)
544+
startIdx = Math.max(0, center - Math.floor(MAX_DISPLAY_LEN / 2))
545+
}
546+
underlinePad =
547+
Math.max(0, pad - startIdx) + (startIdx > 0 ? ELLIPSIS.length : 0)
548+
}
549+
const prefix = startIdx > 0 ? ELLIPSIS : ''
550+
const suffix = lineLength - startIdx > MAX_DISPLAY_LEN ? ELLIPSIS : ''
551+
const sliceLen = MAX_DISPLAY_LEN - prefix.length - suffix.length
552+
displayLine =
553+
prefix + displayLine.slice(startIdx, startIdx + sliceLen) + suffix
554+
}
525555
res.push(
526-
`${line}${' '.repeat(lineNumberWidth - String(line).length)}| ${
527-
lines[j]
528-
}`,
556+
`${line}${' '.repeat(lineNumberWidth - String(line).length)}| ${displayLine}`,
529557
)
530-
const lineLength = lines[j].length
531558
if (j === i) {
532559
// push underline
533-
const pad = Math.max(start - (count - lineLength), 0)
534-
const length = Math.max(
535-
1,
536-
end > count ? lineLength - pad : end - start,
560+
const underline = '^'.repeat(
561+
Math.min(underlineLength, MAX_DISPLAY_LEN),
537562
)
538563
res.push(
539564
`${' '.repeat(lineNumberWidth)}| ` +
540-
' '.repeat(pad) +
541-
'^'.repeat(length),
565+
' '.repeat(underlinePad) +
566+
underline,
542567
)
543568
} else if (j > i) {
544569
if (end > count) {
545570
const length = Math.max(Math.min(end - count, lineLength), 1)
546-
res.push(`${' '.repeat(lineNumberWidth)}| ` + '^'.repeat(length))
571+
const underline = '^'.repeat(Math.min(length, MAX_DISPLAY_LEN))
572+
res.push(`${' '.repeat(lineNumberWidth)}| ` + underline)
547573
}
548574
count += lineLength + 1
549575
}

0 commit comments

Comments
 (0)