Skip to content

Commit ac7709f

Browse files
authored
chore: dedupe getLocator calls (#11600)
...by introducing global compiler state that is reset between iterations
1 parent 5cb432b commit ac7709f

File tree

11 files changed

+50
-86
lines changed

11 files changed

+50
-86
lines changed

packages/svelte/scripts/process-messages/templates/compile-warnings.js

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,7 @@
1-
import { getLocator } from 'locate-character';
1+
import { filename, locator, warnings } from './state.js';
22

33
/** @typedef {{ start?: number, end?: number }} NodeLike */
44

5-
/** @type {import('#compiler').Warning[]} */
6-
let warnings = [];
7-
8-
/** @type {string | undefined} */
9-
let filename;
10-
11-
let locator = getLocator('', { offsetLine: 1 });
12-
13-
/**
14-
* @param {{
15-
* source: string;
16-
* filename: string | undefined;
17-
* }} options
18-
* @returns {import('#compiler').Warning[]}
19-
*/
20-
export function reset_warnings(options) {
21-
filename = options.filename;
22-
locator = getLocator(options.source, { offsetLine: 1 });
23-
24-
return (warnings = []);
25-
}
26-
275
/**
286
* @param {null | NodeLike} node
297
* @param {string} code

packages/svelte/src/compiler/index.js

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { getLocator } from 'locate-character';
21
import { walk as zimmerframe_walk } from 'zimmerframe';
32
import { CompileError } from './errors.js';
43
import { convert } from './legacy.js';
@@ -8,7 +7,7 @@ import { remove_typescript_nodes } from './phases/1-parse/remove_typescript_node
87
import { analyze_component, analyze_module } from './phases/2-analyze/index.js';
98
import { transform_component, transform_module } from './phases/3-transform/index.js';
109
import { validate_component_options, validate_module_options } from './validate-options.js';
11-
import { reset_warnings } from './warnings.js';
10+
import * as state from './state.js';
1211
export { default as preprocess } from './preprocess/index.js';
1312

1413
/**
@@ -21,7 +20,8 @@ export { default as preprocess } from './preprocess/index.js';
2120
*/
2221
export function compile(source, options) {
2322
try {
24-
const warnings = reset_warnings({ source, filename: options.filename });
23+
state.reset({ source, filename: options.filename });
24+
2525
const validated = validate_component_options(options, '');
2626
let parsed = _parse(source);
2727

@@ -44,9 +44,7 @@ export function compile(source, options) {
4444
}
4545

4646
const analysis = analyze_component(parsed, source, combined_options);
47-
4847
const result = transform_component(analysis, source, combined_options);
49-
result.warnings = warnings;
5048
result.ast = to_public_ast(source, parsed, options.modernAst);
5149
return result;
5250
} catch (e) {
@@ -68,11 +66,11 @@ export function compile(source, options) {
6866
*/
6967
export function compileModule(source, options) {
7068
try {
71-
const warnings = reset_warnings({ source, filename: options.filename });
69+
state.reset({ source, filename: options.filename });
70+
7271
const validated = validate_module_options(options, '');
7372
const analysis = analyze_module(parse_acorn(source, false), validated);
7473
const result = transform_module(analysis, source, validated);
75-
result.warnings = warnings;
7674
return result;
7775
} catch (e) {
7876
if (e instanceof CompileError) {
@@ -92,10 +90,8 @@ function handle_compile_error(error, filename, source) {
9290
error.filename = filename;
9391

9492
if (error.position) {
95-
// TODO this is reused with warnings — DRY out
96-
const locator = getLocator(source, { offsetLine: 1 });
97-
const start = locator(error.position[0]);
98-
const end = locator(error.position[1]);
93+
const start = state.locator(error.position[0]);
94+
const end = state.locator(error.position[1]);
9995

10096
error.start = start;
10197
error.end = end;
@@ -142,6 +138,8 @@ function handle_compile_error(error, filename, source) {
142138
* @returns {import('#compiler').Root | import('./types/legacy-nodes.js').LegacyRoot}
143139
*/
144140
export function parse(source, options = {}) {
141+
state.reset({ source, filename: options.filename });
142+
145143
/** @type {import('#compiler').Root} */
146144
let ast;
147145
try {

packages/svelte/src/compiler/migrate/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { parse } from '../phases/1-parse/index.js';
44
import { analyze_component } from '../phases/2-analyze/index.js';
55
import { validate_component_options } from '../validate-options.js';
66
import { get_rune } from '../phases/scope.js';
7-
import { reset_warnings } from '../warnings.js';
7+
import { reset } from '../state.js';
88
import { extract_identifiers } from '../utils/ast.js';
99
import { regex_is_valid_identifier } from '../phases/patterns.js';
1010

@@ -17,7 +17,7 @@ import { regex_is_valid_identifier } from '../phases/patterns.js';
1717
*/
1818
export function migrate(source) {
1919
try {
20-
reset_warnings({ source, filename: 'migrate.svelte' });
20+
reset({ source, filename: 'migrate.svelte' });
2121

2222
let parsed = parse(source);
2323

packages/svelte/src/compiler/phases/1-parse/index.js

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import full_char_code_at from './utils/full_char_code_at.js';
77
import * as e from '../../errors.js';
88
import { create_fragment } from './utils/create.js';
99
import read_options from './read/options.js';
10-
import { getLocator } from 'locate-character';
10+
import { locator } from '../../state.js';
1111

1212
const regex_position_indicator = / \(\d+:\d+\)$/;
1313

@@ -42,16 +42,13 @@ export class Parser {
4242
/** @type {LastAutoClosedTag | undefined} */
4343
last_auto_closed_tag;
4444

45-
locate;
46-
4745
/** @param {string} template */
4846
constructor(template) {
4947
if (typeof template !== 'string') {
5048
throw new TypeError('Template must be a string');
5149
}
5250

5351
this.template = template.trimEnd();
54-
this.locate = getLocator(this.template, { offsetLine: 1 });
5552

5653
let match_lang;
5754

@@ -137,18 +134,6 @@ export class Parser {
137134
}
138135
}
139136

140-
/**
141-
* offset -> line/column
142-
* @param {number} start
143-
* @param {number} end
144-
*/
145-
get_location(start, end) {
146-
return {
147-
start: /** @type {import('locate-character').Location_1} */ (this.locate(start)),
148-
end: /** @type {import('locate-character').Location_1} */ (this.locate(end))
149-
};
150-
}
151-
152137
current() {
153138
return this.stack[this.stack.length - 1];
154139
}

packages/svelte/src/compiler/phases/1-parse/read/context.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
import { parse_expression_at } from '../acorn.js';
1111
import { regex_not_newline_characters } from '../../patterns.js';
1212
import * as e from '../../../errors.js';
13+
import { locator } from '../../../state.js';
1314

1415
/**
1516
* @param {import('../index.js').Parser} parser
@@ -29,7 +30,10 @@ export default function read_pattern(parser, optional_allowed = false) {
2930
type: 'Identifier',
3031
name,
3132
start,
32-
loc: parser.get_location(start, parser.index),
33+
loc: {
34+
start: /** @type {import('locate-character').Location} */ (locator(start)),
35+
end: /** @type {import('locate-character').Location} */ (locator(parser.index))
36+
},
3337
end: parser.index,
3438
typeAnnotation: annotation
3539
};

packages/svelte/src/compiler/phases/3-transform/client/transform-client.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { javascript_visitors_runes } from './visitors/javascript-runes.js';
88
import { javascript_visitors_legacy } from './visitors/javascript-legacy.js';
99
import { serialize_get_binding } from './utils.js';
1010
import { render_stylesheet } from '../css/index.js';
11-
import { getLocator } from 'locate-character';
1211

1312
/**
1413
* This function ensures visitor sets don't accidentally clobber each other
@@ -48,7 +47,6 @@ export function client_component(source, analysis, options) {
4847
scopes: analysis.template.scopes,
4948
hoisted: [b.import_all('$', 'svelte/internal/client')],
5049
node: /** @type {any} */ (null), // populated by the root node
51-
source_locator: getLocator(source, { offsetLine: 1 }),
5250
// these should be set by create_block - if they're called outside, it's a bug
5351
get before_init() {
5452
/** @type {any[]} */

packages/svelte/src/compiler/phases/3-transform/client/types.d.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@ export interface ComponentClientTransformState extends ClientTransformState {
3333
readonly options: ValidatedCompileOptions;
3434
readonly hoisted: Array<Statement | ModuleDeclaration>;
3535
readonly events: Set<string>;
36-
readonly source_locator: (
37-
search: string | number,
38-
index?: number | undefined
39-
) => Location | undefined;
4036

4137
/** Stuff that happens before the render effect(s) */
4238
readonly before_init: Statement[];

packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import { regex_is_valid_identifier } from '../../../patterns.js';
3838
import { javascript_visitors_runes } from './javascript-runes.js';
3939
import { sanitize_template_string } from '../../../../utils/sanitize_template_string.js';
4040
import { walk } from 'zimmerframe';
41+
import { locator } from '../../../../state.js';
4142

4243
/**
4344
* @param {import('#compiler').RegularElement | import('#compiler').SvelteElement} element
@@ -1841,7 +1842,7 @@ export const template_visitors = {
18411842
let location = [-1, -1];
18421843

18431844
if (context.state.options.dev) {
1844-
const loc = context.state.source_locator(node.start);
1845+
const loc = locator(node.start);
18451846
if (loc) {
18461847
location[0] = loc.line;
18471848
location[1] = loc.column;
@@ -2192,7 +2193,7 @@ export const template_visitors = {
21922193
})
21932194
);
21942195

2195-
const location = context.state.options.dev && context.state.source_locator(node.start);
2196+
const location = context.state.options.dev && locator(node.start);
21962197

21972198
context.state.init.push(
21982199
b.stmt(

packages/svelte/src/compiler/phases/3-transform/index.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { print } from 'esrap';
22
import { VERSION } from '../../../version.js';
33
import { server_component, server_module } from './server/transform-server.js';
44
import { client_component, client_module } from './client/transform-client.js';
5-
import { getLocator } from 'locate-character';
65
import { render_stylesheet } from './css/index.js';
76
import { merge_with_preprocessor_map, get_source_name } from '../../utils/mapped_code.js';
7+
import * as state from '../../state.js';
88

99
/**
1010
* @param {import('../types').ComponentAnalysis} analysis
@@ -17,7 +17,7 @@ export function transform_component(analysis, source, options) {
1717
return {
1818
js: /** @type {any} */ (null),
1919
css: null,
20-
warnings: /** @type {any} */ (null), // set afterwards
20+
warnings: state.warnings, // set afterwards
2121
metadata: {
2222
runes: analysis.runes
2323
},
@@ -46,7 +46,7 @@ export function transform_component(analysis, source, options) {
4646
return {
4747
js,
4848
css,
49-
warnings: /** @type {any} */ (null), // set afterwards. TODO apply preprocessor sourcemap
49+
warnings: state.warnings, // set afterwards. TODO apply preprocessor sourcemap
5050
metadata: {
5151
runes: analysis.runes
5252
},
@@ -65,7 +65,7 @@ export function transform_module(analysis, source, options) {
6565
return {
6666
js: /** @type {any} */ (null),
6767
css: null,
68-
warnings: /** @type {any} */ (null), // set afterwards
68+
warnings: state.warnings, // set afterwards
6969
metadata: {
7070
runes: true
7171
},
@@ -94,7 +94,7 @@ export function transform_module(analysis, source, options) {
9494
metadata: {
9595
runes: true
9696
},
97-
warnings: /** @type {any} */ (null), // set afterwards
97+
warnings: state.warnings, // set afterwards
9898
ast: /** @type {any} */ (null) // set afterwards
9999
};
100100
}

packages/svelte/src/compiler/state.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { getLocator } from 'locate-character';
2+
3+
/** @typedef {{ start?: number, end?: number }} NodeLike */
4+
5+
/** @type {import('#compiler').Warning[]} */
6+
export let warnings = [];
7+
8+
/** @type {string | undefined} */
9+
export let filename;
10+
11+
export let locator = getLocator('', { offsetLine: 1 });
12+
13+
/**
14+
* @param {{
15+
* source: string;
16+
* filename: string | undefined;
17+
* }} options
18+
*/
19+
export function reset(options) {
20+
filename = options.filename;
21+
locator = getLocator(options.source, { offsetLine: 1 });
22+
warnings = [];
23+
}

packages/svelte/src/compiler/warnings.js

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,8 @@
11
/* This file is generated by scripts/process-messages/index.js. Do not edit! */
22

3-
import { getLocator } from 'locate-character';
3+
import { filename, locator, warnings } from './state.js';
44

55
/** @typedef {{ start?: number, end?: number }} NodeLike */
6-
/** @type {import('#compiler').Warning[]} */
7-
let warnings = [];
8-
/** @type {string | undefined} */
9-
let filename;
10-
let locator = getLocator('', { offsetLine: 1 });
11-
12-
/**
13-
* @param {{
14-
* source: string;
15-
* filename: string | undefined;
16-
* }} options
17-
* @returns {import('#compiler').Warning[]}
18-
*/
19-
export function reset_warnings(options) {
20-
filename = options.filename;
21-
locator = getLocator(options.source, { offsetLine: 1 });
22-
return warnings = [];
23-
}
24-
256
/**
267
* @param {null | NodeLike} node
278
* @param {string} code

0 commit comments

Comments
 (0)