Skip to content

Commit 3f46901

Browse files
authored
perf(utils): improve performance of numberToPos (#20244)
1 parent 657c2fa commit 3f46901

File tree

3 files changed

+38
-16
lines changed

3 files changed

+38
-16
lines changed

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
isFileReadable,
1818
mergeWithDefaults,
1919
normalizePath,
20+
numberToPos,
2021
posToNumber,
2122
processSrcSetSync,
2223
resolveHostname,
@@ -245,6 +246,34 @@ describe('posToNumber', () => {
245246
})
246247
})
247248

249+
describe('numberToPos', () => {
250+
test('simple', () => {
251+
const actual = numberToPos('a\nb', 2)
252+
expect(actual).toEqual({ line: 2, column: 0 })
253+
})
254+
test('pass though pos', () => {
255+
const actual = numberToPos('a\nb', { line: 2, column: 0 })
256+
expect(actual).toEqual({ line: 2, column: 0 })
257+
})
258+
test('empty line', () => {
259+
const actual = numberToPos('a\n\nb', 3)
260+
expect(actual).toEqual({ line: 3, column: 0 })
261+
})
262+
test('middle of line', () => {
263+
const actual = numberToPos('abc\ndef', 5)
264+
expect(actual).toEqual({ line: 2, column: 1 })
265+
})
266+
test('end of line', () => {
267+
const actual = numberToPos('abc\ndef', 3)
268+
expect(actual).toEqual({ line: 1, column: 3 })
269+
})
270+
test('out of range', () => {
271+
expect(() => numberToPos('a\nb', 5)).toThrowError(
272+
'offset is longer than source length',
273+
)
274+
})
275+
})
276+
248277
describe('generateCodeFrames', () => {
249278
const source = `
250279
import foo from './foo'

packages/vite/src/node/ssr/__tests__/__snapshots__/ssrLoadModule.spec.ts.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ exports[`parse error 2`] = `
2626
2 | ",
2727
"id": "/fixtures/errors/syntax-error.js",
2828
"loc": {
29-
"column": 9,
29+
"column": 8,
3030
"file": "/fixtures/errors/syntax-error.js",
3131
"line": 1,
3232
},
3333
"message": "Parse failure: Expected ';', '}' or <eof>
34-
At file: /fixtures/errors/syntax-error.js:1:9",
34+
At file: /fixtures/errors/syntax-error.js:1:8",
3535
}
3636
`;
3737
@@ -61,11 +61,11 @@ exports[`parse error 4`] = `
6161
2 | ",
6262
"id": "/fixtures/errors/syntax-error.js",
6363
"loc": {
64-
"column": 9,
64+
"column": 8,
6565
"file": "/fixtures/errors/syntax-error.js",
6666
"line": 1,
6767
},
6868
"message": "Parse failure: Expected ';', '}' or <eof>
69-
At file: /fixtures/errors/syntax-error.js:1:9",
69+
At file: /fixtures/errors/syntax-error.js:1:8",
7070
}
7171
`;

packages/vite/src/node/utils.ts

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -493,19 +493,12 @@ export function numberToPos(source: string, offset: number | Pos): Pos {
493493
`offset is longer than source length! offset ${offset} > length ${source.length}`,
494494
)
495495
}
496-
const lines = source.split(splitRE)
497-
let counted = 0
498-
let line = 0
499-
let column = 0
500-
for (; line < lines.length; line++) {
501-
const lineLength = lines[line].length + 1
502-
if (counted + lineLength >= offset) {
503-
column = offset - counted + 1
504-
break
505-
}
506-
counted += lineLength
496+
497+
const lines = source.slice(0, offset).split(splitRE)
498+
return {
499+
line: lines.length,
500+
column: lines[lines.length - 1].length,
507501
}
508-
return { line: line + 1, column }
509502
}
510503

511504
export function generateCodeFrame(

0 commit comments

Comments
 (0)