Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions packages/vite/src/node/__tests__/__snapshots__/utils.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,62 @@ exports[`generateCodeFrames > invalid start > end 1`] = `
"
`;

exports[`generateCodeFrames > long line (center) 1`] = `
"
1 | ...aaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccccccccccccccc...
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 | short line
3 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
"
`;

exports[`generateCodeFrames > long line (end) 1`] = `
"
1 | ...bbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 | short line
3 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
"
`;

exports[`generateCodeFrames > long line (multiline 1) 1`] = `
"
1 | ...bbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
| ^^^^^^^^^^
2 | short line
| ^^^^^^
3 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
"
`;

exports[`generateCodeFrames > long line (multiline 2) 1`] = `
"
1 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
2 | short line
| ^^^^^
3 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
"
`;

exports[`generateCodeFrames > long line (start) 1`] = `
"
1 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 | short line
3 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
"
`;

exports[`generateCodeFrames > long line (whole) 1`] = `
"
1 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 | short line
3 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
"
`;

exports[`generateCodeFrames > range 1`] = `
"
1 | import foo from './foo'
Expand Down
66 changes: 66 additions & 0 deletions packages/vite/src/node/__tests__/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,72 @@ foo()
test('supports more than 1000 lines', () => {
expectSnapshot(generateCodeFrame(veryLongSource, { line: 1200, column: 0 }))
})

test('long line (start)', () => {
const longLine = 'a'.repeat(60) + 'b'.repeat(60) + 'c'.repeat(60)
const src = `${longLine}\nshort line\n${longLine}`
const frame = generateCodeFrame(
src,
{ line: 1, column: 0 },
{ line: 1, column: 30 },
)
expectSnapshot(frame)
})

test('long line (center)', () => {
const longLine = 'a'.repeat(60) + 'b'.repeat(60) + 'c'.repeat(60)
const src = `${longLine}\nshort line\n${longLine}`
const frame = generateCodeFrame(
src,
{ line: 1, column: 90 },
{ line: 1, column: 120 },
)
expectSnapshot(frame)
})

test('long line (end)', () => {
const longLine = 'a'.repeat(60) + 'b'.repeat(60) + 'c'.repeat(60)
const src = `${longLine}\nshort line\n${longLine}`
const frame = generateCodeFrame(
src,
{ line: 1, column: 150 },
{ line: 1, column: 180 },
)
expectSnapshot(frame)
})

test('long line (whole)', () => {
const longLine = 'a'.repeat(60) + 'b'.repeat(60) + 'c'.repeat(60)
const src = `${longLine}\nshort line\n${longLine}`
const frame = generateCodeFrame(
src,
{ line: 1, column: 0 },
{ line: 1, column: 180 },
)
expectSnapshot(frame)
})

test('long line (multiline 1)', () => {
const longLine = 'a'.repeat(60) + 'b'.repeat(60) + 'c'.repeat(60)
const src = `${longLine}\nshort line\n${longLine}`
const frame = generateCodeFrame(
src,
{ line: 1, column: 170 },
{ line: 2, column: 5 },
)
expectSnapshot(frame)
})

test('long line (multiline 2)', () => {
const longLine = 'a'.repeat(60) + 'b'.repeat(60) + 'c'.repeat(60)
const src = `${longLine}\nshort line\n${longLine}`
const frame = generateCodeFrame(
src,
{ line: 2, column: 5 },
{ line: 3, column: 30 },
)
expectSnapshot(frame)
})
})

describe('getHash', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/node/plugins/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ function handleParseError(
warnings[parseError.code] ??=
`Unable to parse HTML; ${parseError.message}\n` +
` at ${parseError.loc.file}:${parseError.loc.line}:${parseError.loc.column}\n` +
`${parseError.frame.length > 300 ? '[this code frame is omitted as the content was too long] ' : parseError.frame}`
parseError.frame
}

/**
Expand Down
46 changes: 35 additions & 11 deletions packages/vite/src/node/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,8 @@ export function numberToPos(source: string, offset: number | Pos): Pos {
}
}

const MAX_DISPLAY_LEN = 120

export function generateCodeFrame(
source: string,
start: number | Pos = 0,
Expand All @@ -522,28 +524,50 @@ export function generateCodeFrame(
for (let j = i - range; j <= i + range || end > count; j++) {
if (j < 0 || j >= lines.length) continue
const line = j + 1
const lineLength = lines[j].length
const pad = Math.max(start - (count - lineLength), 0)
const underlineLength = Math.max(
1,
end > count ? lineLength - pad : end - start,
)

let displayLine = lines[j]
let underlinePad = pad
if (lineLength > MAX_DISPLAY_LEN) {
let startIdx = 0
if (j === i) {
if (underlineLength > MAX_DISPLAY_LEN) {
startIdx = pad
} else {
const center = pad + Math.floor(underlineLength / 2)
startIdx = Math.max(0, center - Math.floor(MAX_DISPLAY_LEN / 2))
}
underlinePad = Math.max(0, pad - startIdx) + (startIdx > 0 ? 3 : 0)
}
const prefix = startIdx > 0 ? '...' : ''
const suffix = lineLength - startIdx > MAX_DISPLAY_LEN ? '...' : ''
const sliceLen = MAX_DISPLAY_LEN - prefix.length - suffix.length
displayLine =
prefix + displayLine.slice(startIdx, startIdx + sliceLen) + suffix
}
res.push(
`${line}${' '.repeat(lineNumberWidth - String(line).length)}| ${
lines[j]
}`,
`${line}${' '.repeat(lineNumberWidth - String(line).length)}| ${displayLine}`,
)
const lineLength = lines[j].length
if (j === i) {
// push underline
const pad = Math.max(start - (count - lineLength), 0)
const length = Math.max(
1,
end > count ? lineLength - pad : end - start,
const underline = '^'.repeat(
Math.min(underlineLength, MAX_DISPLAY_LEN),
)
res.push(
`${' '.repeat(lineNumberWidth)}| ` +
' '.repeat(pad) +
'^'.repeat(length),
' '.repeat(underlinePad) +
underline,
)
} else if (j > i) {
if (end > count) {
const length = Math.max(Math.min(end - count, lineLength), 1)
res.push(`${' '.repeat(lineNumberWidth)}| ` + '^'.repeat(length))
const underline = '^'.repeat(Math.min(length, MAX_DISPLAY_LEN))
res.push(`${' '.repeat(lineNumberWidth)}| ` + underline)
}
count += lineLength + 1
}
Expand Down
Loading