Skip to content

Commit 40be734

Browse files
committed
put locations on template, instead of on the side
1 parent af78465 commit 40be734

File tree

11 files changed

+45
-64
lines changed

11 files changed

+45
-64
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,7 @@ export function client_component(analysis, options) {
170170
update: /** @type {any} */ (null),
171171
expressions: /** @type {any} */ (null),
172172
after_update: /** @type {any} */ (null),
173-
template: /** @type {any} */ (null),
174-
locations: /** @type {any} */ (null)
173+
template: /** @type {any} */ (null)
175174
};
176175

177176
const module = /** @type {ESTree.Program} */ (

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

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
/** @import { ComponentClientTransformState } from '../types.js' */
1+
/** @import { Location } from 'locate-character' */
22
/** @import { Namespace } from '#compiler' */
3-
/** @import { SourceLocation } from '#shared' */
4-
import { dev } from '../../../../state.js';
3+
/** @import { ComponentClientTransformState } from '../types.js' */
4+
/** @import { Node } from './types.js' */
5+
import { dev, locator } from '../../../../state.js';
56
import * as b from '../../../../utils/builders.js';
67
import { template_to_functions } from './to-functions.js';
78
import { template_to_string } from './to-string.js';
@@ -28,20 +29,27 @@ function get_template_function(namespace, state) {
2829
}
2930

3031
/**
31-
* @param {SourceLocation[]} locations
32+
* @param {Node[]} nodes
3233
*/
33-
function build_locations(locations) {
34-
return b.array(
35-
locations.map((loc) => {
36-
const expression = b.array([b.literal(loc[0]), b.literal(loc[1])]);
34+
function build_locations(nodes) {
35+
const array = b.array([]);
3736

38-
if (loc.length === 3) {
39-
expression.elements.push(build_locations(loc[2]));
40-
}
37+
for (const node of nodes) {
38+
if (node.type !== 'element') continue;
4139

42-
return expression;
43-
})
44-
);
40+
const { line, column } = /** @type {Location} */ (locator(node.start));
41+
42+
const expression = b.array([b.literal(line), b.literal(column)]);
43+
const children = build_locations(node.children);
44+
45+
if (children.elements.length > 0) {
46+
expression.elements.push(children);
47+
}
48+
49+
array.elements.push(expression);
50+
}
51+
52+
return array;
4553
}
4654

4755
/**
@@ -66,7 +74,7 @@ export function transform_template(state, namespace, flags) {
6674
'$.add_locations',
6775
call,
6876
b.member(b.id(state.analysis.name), '$.FILENAME', true),
69-
build_locations(state.locations)
77+
build_locations(state.template.nodes)
7078
);
7179
}
7280

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,17 @@ export class Template {
2222

2323
#fragment = this.nodes;
2424

25-
/** @param {string} name */
26-
create_element(name) {
25+
/**
26+
* @param {string} name
27+
* @param {number} start
28+
*/
29+
create_element(name, start) {
2730
this.#element = {
2831
type: 'element',
2932
name,
3033
attributes: {},
31-
children: []
34+
children: [],
35+
start
3236
};
3337

3438
this.#fragment.push(this.#element);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ export interface Element {
55
name: string;
66
attributes: Record<string, string | undefined>;
77
children: Node[];
8+
/** used for populating __svelte_meta */
9+
start: number;
810
}
911

1012
export interface Text {

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,14 @@ import type {
33
Statement,
44
LabeledStatement,
55
Identifier,
6-
PrivateIdentifier,
76
Expression,
87
AssignmentExpression,
98
UpdateExpression,
109
VariableDeclaration
1110
} from 'estree';
12-
import type { AST, Namespace, StateField, ValidatedCompileOptions } from '#compiler';
11+
import type { AST, Namespace, ValidatedCompileOptions } from '#compiler';
1312
import type { TransformState } from '../types.js';
1413
import type { ComponentAnalysis } from '../../types.js';
15-
import type { SourceLocation } from '#shared';
1614
import type { Template } from './transform-template/template.js';
1715

1816
export interface ClientTransformState extends TransformState {
@@ -55,7 +53,6 @@ export interface ComponentClientTransformState extends ClientTransformState {
5553
readonly expressions: Expression[];
5654
/** The HTML template string */
5755
readonly template: Template;
58-
readonly locations: SourceLocation[];
5956
readonly metadata: {
6057
namespace: Namespace;
6158
bound_contenteditable: boolean;

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ export function Fragment(node, context) {
6767
expressions: [],
6868
after_update: [],
6969
template: new Template(),
70-
locations: [],
7170
transform: { ...context.state.transform },
7271
metadata: {
7372
namespace,

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

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
/** @import { ArrayExpression, Expression, ExpressionStatement, Identifier, MemberExpression, ObjectExpression } from 'estree' */
22
/** @import { AST } from '#compiler' */
3-
/** @import { SourceLocation } from '#shared' */
43
/** @import { ComponentClientTransformState, ComponentContext } from '../types' */
54
/** @import { Scope } from '../../../scope' */
65
import {
76
cannot_be_set_statically,
87
is_boolean_attribute,
98
is_dom_property,
10-
is_load_error_element,
11-
is_void
9+
is_load_error_element
1210
} from '../../../../../utils.js';
13-
import { escape_html } from '../../../../../escaping.js';
14-
import { dev, is_ignored, locator } from '../../../../state.js';
11+
import { is_ignored } from '../../../../state.js';
1512
import { is_event_attribute, is_text_attribute } from '../../../../utils/ast.js';
1613
import * as b from '#compiler/builders';
1714
import { is_custom_element_node } from '../../../nodes.js';
@@ -39,20 +36,9 @@ import { visit_event_attribute } from './shared/events.js';
3936
* @param {ComponentContext} context
4037
*/
4138
export function RegularElement(node, context) {
42-
/** @type {SourceLocation} */
43-
let location = [-1, -1];
44-
45-
if (dev) {
46-
const loc = locator(node.start);
47-
if (loc) {
48-
location[0] = loc.line;
49-
location[1] = loc.column;
50-
context.state.locations.push(location);
51-
}
52-
}
39+
context.state.template.create_element(node.name, node.start);
5340

5441
if (node.name === 'noscript') {
55-
context.state.template.create_element('noscript');
5642
return;
5743
}
5844

@@ -68,8 +54,6 @@ export function RegularElement(node, context) {
6854

6955
context.state.template.contains_script_tag ||= node.name === 'script';
7056

71-
context.state.template.create_element(node.name);
72-
7357
/** @type {Array<AST.Attribute | AST.SpreadAttribute>} */
7458
const attributes = [];
7559

@@ -345,7 +329,6 @@ export function RegularElement(node, context) {
345329
const state = {
346330
...context.state,
347331
metadata,
348-
locations: [],
349332
scope: /** @type {Scope} */ (context.state.scopes.get(node.fragment)),
350333
preserve_whitespace:
351334
context.state.preserve_whitespace || node.name === 'pre' || node.name === 'textarea'
@@ -439,10 +422,6 @@ export function RegularElement(node, context) {
439422
context.state.update.push(b.stmt(b.assignment('=', dir, dir)));
440423
}
441424

442-
if (state.locations.length > 0) {
443-
// @ts-expect-error
444-
location.push(state.locations);
445-
}
446425
context.state.template.pop_element();
447426
}
448427

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

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/** @import { BlockStatement, Expression, ExpressionStatement, Identifier, MemberExpression, Pattern, Property, SequenceExpression, Statement } from 'estree' */
22
/** @import { AST } from '#compiler' */
33
/** @import { ComponentContext } from '../../types.js' */
4-
import { dev, is_ignored, locator } from '../../../../../state.js';
4+
import { dev, is_ignored } from '../../../../../state.js';
55
import { get_attribute_chunks, object } from '../../../../../utils/ast.js';
66
import * as b from '#compiler/builders';
77
import { build_bind_this, memoize_expression, validate_binding } from '../shared/utils.js';
@@ -440,19 +440,12 @@ export function build_component(node, component_name, context, anchor = context.
440440
}
441441

442442
if (Object.keys(custom_css_props).length > 0) {
443-
if (dev) {
444-
const loc = locator(node.start);
445-
if (loc) {
446-
context.state.locations.push([loc.line, loc.column]);
447-
}
448-
}
449-
450443
if (context.state.metadata.namespace === 'svg') {
451444
// this boils down to <g><!></g>
452-
context.state.template.create_element('g');
445+
context.state.template.create_element('g', node.start);
453446
} else {
454447
// this boils down to <svelte-css-wrapper style='display: contents'><!></svelte-css-wrapper>
455-
context.state.template.create_element('svelte-css-wrapper');
448+
context.state.template.create_element('svelte-css-wrapper', node.start);
456449
context.state.template.set_prop('style', 'display: contents');
457450
}
458451

packages/svelte/src/internal/client/dev/elements.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @import { SourceLocation } from '#shared' */
1+
/** @import { SourceLocation } from '#client' */
22
import { HYDRATION_END, HYDRATION_START, HYDRATION_START_ELSE } from '../../../constants.js';
33
import { hydrating } from '../dom/hydration.js';
44

packages/svelte/src/internal/client/types.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,8 @@ export type ProxyStateObject<T = Record<string | symbol, any>> = T & {
183183
[STATE_SYMBOL]: T;
184184
};
185185

186+
export type SourceLocation =
187+
| [line: number, column: number]
188+
| [line: number, column: number, SourceLocation[]];
189+
186190
export * from './reactivity/types';

0 commit comments

Comments
 (0)