svelte 5.57.0 → 5.57.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compiler/index.js +1 -1
- package/package.json +8 -8
- package/src/compiler/phases/1-parse/acorn.js +36 -2
- package/src/compiler/phases/1-parse/index.js +23 -22
- package/src/compiler/phases/1-parse/read/context.js +3 -18
- package/src/compiler/phases/1-parse/read/expression.js +110 -2
- package/src/compiler/phases/1-parse/read/script.js +1 -1
- package/src/compiler/phases/1-parse/read/style.js +3 -5
- package/src/compiler/phases/1-parse/state/element.js +68 -40
- package/src/compiler/phases/1-parse/state/tag.js +6 -6
- package/src/compiler/phases/1-parse/utils/html.js +2 -0
- package/src/compiler/phases/1-parse/utils/whitespace.js +18 -0
- package/src/compiler/phases/2-analyze/css/css-prune.js +7 -6
- package/src/compiler/phases/2-analyze/index.js +1 -1
- package/src/compiler/phases/2-analyze/visitors/BindDirective.js +1 -1
- package/src/compiler/phases/2-analyze/visitors/ClassDeclaration.js +1 -1
- package/src/compiler/phases/2-analyze/visitors/FunctionDeclaration.js +1 -1
- package/src/compiler/phases/2-analyze/visitors/Identifier.js +1 -2
- package/src/compiler/phases/2-analyze/visitors/SvelteBody.js +1 -1
- package/src/compiler/phases/2-analyze/visitors/SvelteDocument.js +1 -1
- package/src/compiler/phases/2-analyze/visitors/SvelteWindow.js +1 -1
- package/src/compiler/phases/2-analyze/visitors/VariableDeclarator.js +2 -2
- package/src/compiler/phases/2-analyze/visitors/shared/a11y/constants.js +1 -1
- package/src/compiler/phases/2-analyze/visitors/shared/a11y/index.js +1 -1
- package/src/compiler/phases/2-analyze/visitors/shared/utils.js +0 -38
- package/src/compiler/phases/3-transform/client/utils.js +0 -38
- package/src/compiler/phases/3-transform/client/visitors/AssignmentExpression.js +2 -2
- package/src/compiler/phases/3-transform/client/visitors/CallExpression.js +1 -2
- package/src/compiler/phases/3-transform/client/visitors/VariableDeclaration.js +3 -8
- package/src/compiler/phases/3-transform/server/visitors/shared/element.js +8 -0
- package/src/compiler/phases/3-transform/utils.js +1 -1
- package/src/compiler/phases/nodes.js +30 -0
- package/src/compiler/phases/scope.js +77 -2
- package/src/compiler/state.js +9 -5
- package/src/compiler/utils/ast.js +2 -5
- package/src/compiler/utils/compile_diagnostic.js +1 -1
- package/src/compiler/utils/extract_svelte_ignore.js +1 -1
- package/src/compiler/utils/mapped_code.js +13 -1
- package/src/internal/client/constants.js +0 -9
- package/src/internal/client/dev/debug.js +0 -2
- package/src/internal/client/dom/elements/events.js +6 -1
- package/src/internal/client/errors.js +0 -16
- package/src/internal/client/proxy.js +12 -7
- package/src/internal/client/reactivity/batch.js +91 -71
- package/src/internal/client/reactivity/deriveds.js +0 -3
- package/src/internal/client/reactivity/sources.js +28 -16
- package/src/internal/client/reactivity/utils.js +2 -23
- package/src/internal/client/runtime.js +5 -9
- package/src/internal/server/context.js +9 -2
- package/src/internal/server/index.js +9 -2
- package/src/internal/server/renderer.js +101 -69
- package/src/internal/shared/errors.js +16 -0
- package/src/version.js +1 -1
- package/types/index.d.ts.map +1 -1
- package/src/compiler/phases/1-parse/utils/create.js +0 -16
- package/src/compiler/phases/2-analyze/visitors/shared/special-element.js +0 -16
- package/src/compiler/utils/push_array.js +0 -13
- /package/src/compiler/{phases/2-analyze/utils → utils}/check_graph_for_cycles.js +0 -0
- /package/src/compiler/{phases/1-parse/utils → utils}/fuzzymatch.js +0 -0
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
} from '../../utils/ast.js';
|
|
15
15
|
import * as b from '#compiler/builders';
|
|
16
16
|
import { Scope, ScopeRoot, create_scopes, get_rune, set_scope } from '../scope.js';
|
|
17
|
-
import check_graph_for_cycles from '
|
|
17
|
+
import check_graph_for_cycles from '../../utils/check_graph_for_cycles.js';
|
|
18
18
|
import { create_attribute, is_custom_element_node } from '../nodes.js';
|
|
19
19
|
import { analyze_css } from './css/css-analyze.js';
|
|
20
20
|
import { prune } from './css/css-prune.js';
|
|
@@ -9,7 +9,7 @@ import { validate_assignment } from './shared/utils.js';
|
|
|
9
9
|
import * as e from '../../../errors.js';
|
|
10
10
|
import * as w from '../../../warnings.js';
|
|
11
11
|
import { binding_properties } from '../../bindings.js';
|
|
12
|
-
import fuzzymatch from '
|
|
12
|
+
import fuzzymatch from '../../../utils/fuzzymatch.js';
|
|
13
13
|
import { is_content_editable_binding, is_svg } from '../../../../utils.js';
|
|
14
14
|
import { mark_subtree_dynamic } from './shared/fragment.js';
|
|
15
15
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** @import { ClassDeclaration } from 'estree' */
|
|
2
2
|
/** @import { Context } from '../types' */
|
|
3
3
|
import * as w from '../../../warnings.js';
|
|
4
|
-
import { validate_identifier_name } from '
|
|
4
|
+
import { validate_identifier_name } from '../../scope.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @param {ClassDeclaration} node
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** @import { FunctionDeclaration } from 'estree' */
|
|
2
2
|
/** @import { Context } from '../types' */
|
|
3
3
|
import { visit_function } from './shared/function.js';
|
|
4
|
-
import { validate_identifier_name } from '
|
|
4
|
+
import { validate_identifier_name } from '../../scope.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @param {FunctionDeclaration} node
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/** @import { Expression, Identifier } from 'estree' */
|
|
2
2
|
/** @import { Context } from '../types' */
|
|
3
3
|
import is_reference from 'is-reference';
|
|
4
|
-
import { should_proxy } from '../../
|
|
4
|
+
import { should_proxy, get_rune } from '../../scope.js';
|
|
5
5
|
import * as e from '../../../errors.js';
|
|
6
6
|
import * as w from '../../../warnings.js';
|
|
7
7
|
import { is_rune } from '../../../../utils.js';
|
|
8
8
|
import { mark_subtree_dynamic } from './shared/fragment.js';
|
|
9
|
-
import { get_rune } from '../../scope.js';
|
|
10
9
|
import { is_component_node } from '../../nodes.js';
|
|
11
10
|
|
|
12
11
|
/**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/** @import { Context } from '../types' */
|
|
3
3
|
import * as e from '../../../errors.js';
|
|
4
4
|
import { is_event_attribute } from '../../../utils/ast.js';
|
|
5
|
-
import { disallow_children } from '
|
|
5
|
+
import { disallow_children } from '../../nodes.js';
|
|
6
6
|
import { check_global_event_reference } from './shared/utils.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @import { AST } from '#compiler' */
|
|
2
2
|
/** @import { Context } from '../types' */
|
|
3
|
-
import { disallow_children } from '
|
|
3
|
+
import { disallow_children } from '../../nodes.js';
|
|
4
4
|
import * as e from '../../../errors.js';
|
|
5
5
|
import { is_event_attribute } from '../../../utils/ast.js';
|
|
6
6
|
import { check_global_event_reference } from './shared/utils.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @import { AST } from '#compiler' */
|
|
2
2
|
/** @import { Context } from '../types' */
|
|
3
|
-
import { disallow_children } from '
|
|
3
|
+
import { disallow_children } from '../../nodes.js';
|
|
4
4
|
import * as e from '../../../errors.js';
|
|
5
5
|
import { is_event_attribute } from '../../../utils/ast.js';
|
|
6
6
|
import { check_global_event_reference } from './shared/utils.js';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/** @import { Expression, Identifier, Literal, VariableDeclarator } from 'estree' */
|
|
2
2
|
/** @import { Binding } from '#compiler' */
|
|
3
3
|
/** @import { Context } from '../types' */
|
|
4
|
-
import { get_rune } from '../../scope.js';
|
|
5
|
-
import { ensure_no_module_import_conflict
|
|
4
|
+
import { get_rune, validate_identifier_name } from '../../scope.js';
|
|
5
|
+
import { ensure_no_module_import_conflict } from './shared/utils.js';
|
|
6
6
|
import * as e from '../../../errors.js';
|
|
7
7
|
import * as w from '../../../warnings.js';
|
|
8
8
|
import { extract_paths } from '../../../utils/ast.js';
|
|
@@ -4,7 +4,7 @@ import { roles as roles_map, elementRoles } from 'aria-query';
|
|
|
4
4
|
import { AXObjects, elementAXObjects } from 'axobject-query';
|
|
5
5
|
|
|
6
6
|
export const aria_attributes =
|
|
7
|
-
'activedescendant atomic autocomplete busy checked colcount colindex colspan controls current describedby description details disabled dropeffect errormessage expanded flowto grabbed haspopup hidden invalid keyshortcuts label labelledby level live modal multiline multiselectable orientation owns placeholder posinset pressed readonly relevant required roledescription rowcount rowindex rowspan selected setsize sort valuemax valuemin valuenow valuetext'.split(
|
|
7
|
+
'activedescendant atomic autocomplete braillelabel brailleroledescription busy checked colcount colindex colspan controls current describedby description details disabled dropeffect errormessage expanded flowto grabbed haspopup hidden invalid keyshortcuts label labelledby level live modal multiline multiselectable orientation owns placeholder posinset pressed readonly relevant required roledescription rowcount rowindex rowspan selected setsize sort valuemax valuemin valuenow valuetext'.split(
|
|
8
8
|
' '
|
|
9
9
|
);
|
|
10
10
|
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
import { is_event_attribute, is_text_attribute } from '../../../../../utils/ast.js';
|
|
46
46
|
import { list } from '../../../../../utils/string.js';
|
|
47
47
|
import { walk } from 'zimmerframe';
|
|
48
|
-
import fuzzymatch from '
|
|
48
|
+
import fuzzymatch from '../../../../../utils/fuzzymatch.js';
|
|
49
49
|
import { is_content_editable_binding } from '../../../../../../utils.js';
|
|
50
50
|
import * as w from '../../../../../warnings.js';
|
|
51
51
|
|
|
@@ -246,44 +246,6 @@ export function is_pure(node, context) {
|
|
|
246
246
|
return false;
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
-
/**
|
|
250
|
-
* Checks if the name is valid, which it is when it's not starting with (or is) a dollar sign or if it's a function parameter.
|
|
251
|
-
* The second argument is the depth of the scope, which is there for backwards compatibility reasons: In Svelte 4, you
|
|
252
|
-
* were allowed to define `$`-prefixed variables anywhere below the top level of components. Once legacy mode is gone, this
|
|
253
|
-
* argument can be removed / the call sites adjusted accordingly.
|
|
254
|
-
* @param {Binding | null} binding
|
|
255
|
-
* @param {number | undefined} [function_depth]
|
|
256
|
-
*/
|
|
257
|
-
export function validate_identifier_name(binding, function_depth) {
|
|
258
|
-
if (!binding) return;
|
|
259
|
-
|
|
260
|
-
const declaration_kind = binding.declaration_kind;
|
|
261
|
-
|
|
262
|
-
if (
|
|
263
|
-
declaration_kind !== 'synthetic' &&
|
|
264
|
-
declaration_kind !== 'param' &&
|
|
265
|
-
declaration_kind !== 'rest_param' &&
|
|
266
|
-
(!function_depth || function_depth <= 1)
|
|
267
|
-
) {
|
|
268
|
-
const node = binding.node;
|
|
269
|
-
|
|
270
|
-
if (node.name === '$') {
|
|
271
|
-
e.dollar_binding_invalid(node);
|
|
272
|
-
} else if (
|
|
273
|
-
node.name.startsWith('$') &&
|
|
274
|
-
// import type { $Type } from "" - these are normally already filtered out,
|
|
275
|
-
// but for the migration they aren't, and throwing here is preventing the migration to complete
|
|
276
|
-
// TODO -> once migration script is gone we can remove this check
|
|
277
|
-
!(
|
|
278
|
-
binding.initial?.type === 'ImportDeclaration' &&
|
|
279
|
-
/** @type {any} */ (binding.initial).importKind === 'type'
|
|
280
|
-
)
|
|
281
|
-
) {
|
|
282
|
-
e.dollar_prefix_invalid(node);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
249
|
/**
|
|
288
250
|
* Checks that the exported name is not a derived or reassigned state variable.
|
|
289
251
|
* @param {Node} node
|
|
@@ -127,44 +127,6 @@ export function is_prop_source(binding, state) {
|
|
|
127
127
|
);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
/**
|
|
131
|
-
* @param {Expression} node
|
|
132
|
-
* @param {Scope | null} scope
|
|
133
|
-
*/
|
|
134
|
-
export function should_proxy(node, scope) {
|
|
135
|
-
if (
|
|
136
|
-
!node ||
|
|
137
|
-
node.type === 'Literal' ||
|
|
138
|
-
node.type === 'TemplateLiteral' ||
|
|
139
|
-
node.type === 'ArrowFunctionExpression' ||
|
|
140
|
-
node.type === 'FunctionExpression' ||
|
|
141
|
-
node.type === 'UnaryExpression' ||
|
|
142
|
-
node.type === 'BinaryExpression' ||
|
|
143
|
-
(node.type === 'Identifier' && node.name === 'undefined')
|
|
144
|
-
) {
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (node.type === 'Identifier' && scope !== null) {
|
|
149
|
-
const binding = scope.get(node.name);
|
|
150
|
-
// Let's see if the reference is something that can be proxied
|
|
151
|
-
if (
|
|
152
|
-
binding !== null &&
|
|
153
|
-
!binding.reassigned &&
|
|
154
|
-
binding.initial !== null &&
|
|
155
|
-
binding.initial.type !== 'FunctionDeclaration' &&
|
|
156
|
-
binding.initial.type !== 'ClassDeclaration' &&
|
|
157
|
-
binding.initial.type !== 'ImportDeclaration' &&
|
|
158
|
-
binding.initial.type !== 'EachBlock' &&
|
|
159
|
-
binding.initial.type !== 'SnippetBlock'
|
|
160
|
-
) {
|
|
161
|
-
return should_proxy(binding.initial, null);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return true;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
130
|
/**
|
|
169
131
|
* An async thunk. If an `await` inside restores the reaction context via `$.save`,
|
|
170
132
|
* the body exits through `$.unsave` so the context cannot leak into foreign microtasks
|
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
is_expression_async
|
|
10
10
|
} from '../../../../utils/ast.js';
|
|
11
11
|
import { dev, locate_node } from '../../../../state.js';
|
|
12
|
-
import { build_getter
|
|
12
|
+
import { build_getter } from '../utils.js';
|
|
13
|
+
import { should_proxy, get_rune } from '../../../scope.js';
|
|
13
14
|
import { visit_assignment_expression } from '../../shared/assignments.js';
|
|
14
15
|
import { validate_mutation } from './shared/utils.js';
|
|
15
|
-
import { get_rune } from '../../../scope.js';
|
|
16
16
|
import { get_name } from '../../../nodes.js';
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
/** @import { Context } from '../types' */
|
|
3
3
|
import { dev, is_ignored } from '../../../../state.js';
|
|
4
4
|
import * as b from '#compiler/builders';
|
|
5
|
-
import { get_rune } from '../../../scope.js';
|
|
6
|
-
import { should_proxy } from '../utils.js';
|
|
5
|
+
import { get_rune, should_proxy } from '../../../scope.js';
|
|
7
6
|
import { get_inspect_args } from '../../utils.js';
|
|
8
7
|
|
|
9
8
|
/**
|
|
@@ -5,14 +5,8 @@ import { dev, is_ignored, locate_node } from '../../../../state.js';
|
|
|
5
5
|
import { extract_paths, save } from '../../../../utils/ast.js';
|
|
6
6
|
import * as b from '#compiler/builders';
|
|
7
7
|
import * as assert from '../../../../utils/assert.js';
|
|
8
|
-
import { get_rune } from '../../../scope.js';
|
|
9
|
-
import {
|
|
10
|
-
async_thunk,
|
|
11
|
-
get_prop_source,
|
|
12
|
-
is_prop_source,
|
|
13
|
-
is_state_source,
|
|
14
|
-
should_proxy
|
|
15
|
-
} from '../utils.js';
|
|
8
|
+
import { get_rune, should_proxy } from '../../../scope.js';
|
|
9
|
+
import { async_thunk, get_prop_source, is_prop_source, is_state_source } from '../utils.js';
|
|
16
10
|
import { get_value } from './shared/declarations.js';
|
|
17
11
|
|
|
18
12
|
/**
|
|
@@ -35,6 +29,7 @@ export function VariableDeclaration(node, context) {
|
|
|
35
29
|
rune === '$inspect' ||
|
|
36
30
|
rune === '$inspect.trace' ||
|
|
37
31
|
rune === '$state.snapshot' ||
|
|
32
|
+
rune === '$state.eager' ||
|
|
38
33
|
rune === '$host'
|
|
39
34
|
) {
|
|
40
35
|
declarations.push(/** @type {VariableDeclarator} */ (context.visit(declarator)));
|
|
@@ -80,6 +80,14 @@ export function build_element_attributes(node, context, transform) {
|
|
|
80
80
|
) {
|
|
81
81
|
events_to_capture.add(attribute.name);
|
|
82
82
|
}
|
|
83
|
+
} else if (
|
|
84
|
+
node.type === 'RegularElement' &&
|
|
85
|
+
node.name === 'input' &&
|
|
86
|
+
(attribute.name === 'defaultValue' || attribute.name === 'defaultChecked')
|
|
87
|
+
) {
|
|
88
|
+
attributes.push(attribute);
|
|
89
|
+
// deopt to spread at runtime, where we can handle interaction of value/defaultValue etc
|
|
90
|
+
has_spread = true;
|
|
83
91
|
// the defaultValue/defaultChecked properties don't exist as attributes
|
|
84
92
|
} else if (attribute.name !== 'defaultValue' && attribute.name !== 'defaultChecked') {
|
|
85
93
|
if (attribute.name === 'class') {
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import * as e from '../../errors.js';
|
|
10
10
|
import { walk } from 'zimmerframe';
|
|
11
11
|
import { extract_identifiers } from '../../utils/ast.js';
|
|
12
|
-
import check_graph_for_cycles from '
|
|
12
|
+
import check_graph_for_cycles from '../../utils/check_graph_for_cycles.js';
|
|
13
13
|
import is_reference from 'is-reference';
|
|
14
14
|
import { set_scope } from '../scope.js';
|
|
15
15
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** @import { Expression, PrivateIdentifier, SourceLocation } from 'estree' */
|
|
2
2
|
/** @import { AST, Binding } from '#compiler' */
|
|
3
3
|
import * as b from '#compiler/builders';
|
|
4
|
+
import * as e from '../errors.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* All nodes that can appear elsewhere than the top level, have attributes and can contain children
|
|
@@ -45,6 +46,35 @@ export function is_custom_element_node(node) {
|
|
|
45
46
|
);
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
/**
|
|
50
|
+
* @param {boolean} transparent
|
|
51
|
+
* @returns {AST.Fragment}
|
|
52
|
+
*/
|
|
53
|
+
export function create_fragment(transparent = false) {
|
|
54
|
+
return {
|
|
55
|
+
type: 'Fragment',
|
|
56
|
+
nodes: [],
|
|
57
|
+
metadata: {
|
|
58
|
+
transparent,
|
|
59
|
+
dynamic: false
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @param {AST.SvelteBody | AST.SvelteDocument | AST.SvelteOptionsRaw | AST.SvelteWindow} node
|
|
66
|
+
*/
|
|
67
|
+
export function disallow_children(node) {
|
|
68
|
+
const { nodes } = node.fragment;
|
|
69
|
+
|
|
70
|
+
if (nodes.length > 0) {
|
|
71
|
+
const first = nodes[0];
|
|
72
|
+
const last = nodes[nodes.length - 1];
|
|
73
|
+
|
|
74
|
+
e.svelte_meta_invalid_content({ start: first.start, end: last.end }, node.name);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
48
78
|
/**
|
|
49
79
|
* @param {string} name
|
|
50
80
|
* @param {SourceLocation | null} name_loc
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
} from '../utils/ast.js';
|
|
15
15
|
import { is_reserved, is_rune } from '../../utils.js';
|
|
16
16
|
import { determine_slot } from '../utils/slot.js';
|
|
17
|
-
import { validate_identifier_name } from './2-analyze/visitors/shared/utils.js';
|
|
18
17
|
|
|
19
18
|
const UNKNOWN = Symbol('unknown');
|
|
20
19
|
/** Includes `BigInt` */
|
|
@@ -1233,6 +1232,7 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) {
|
|
|
1233
1232
|
|
|
1234
1233
|
EachBlock(node, { state, visit }) {
|
|
1235
1234
|
visit(node.expression);
|
|
1235
|
+
if (node.fallback) visit(node.fallback);
|
|
1236
1236
|
|
|
1237
1237
|
// context and children are a new scope
|
|
1238
1238
|
const scope = state.scope.child();
|
|
@@ -1278,7 +1278,6 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) {
|
|
|
1278
1278
|
for (const child of node.body.nodes) {
|
|
1279
1279
|
visit(child, { scope });
|
|
1280
1280
|
}
|
|
1281
|
-
if (node.fallback) visit(node.fallback, { scope });
|
|
1282
1281
|
|
|
1283
1282
|
node.metadata = {
|
|
1284
1283
|
expression: new ExpressionMetadata(),
|
|
@@ -1469,3 +1468,79 @@ function get_global_keypath(node, scope) {
|
|
|
1469
1468
|
|
|
1470
1469
|
return n.name + joined;
|
|
1471
1470
|
}
|
|
1471
|
+
|
|
1472
|
+
/**
|
|
1473
|
+
* @param {Expression} node
|
|
1474
|
+
* @param {Scope | null} scope
|
|
1475
|
+
*/
|
|
1476
|
+
export function should_proxy(node, scope) {
|
|
1477
|
+
if (
|
|
1478
|
+
!node ||
|
|
1479
|
+
node.type === 'Literal' ||
|
|
1480
|
+
node.type === 'TemplateLiteral' ||
|
|
1481
|
+
node.type === 'ArrowFunctionExpression' ||
|
|
1482
|
+
node.type === 'FunctionExpression' ||
|
|
1483
|
+
node.type === 'UnaryExpression' ||
|
|
1484
|
+
node.type === 'BinaryExpression' ||
|
|
1485
|
+
(node.type === 'Identifier' && node.name === 'undefined')
|
|
1486
|
+
) {
|
|
1487
|
+
return false;
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
if (node.type === 'Identifier' && scope !== null) {
|
|
1491
|
+
const binding = scope.get(node.name);
|
|
1492
|
+
// Let's see if the reference is something that can be proxied
|
|
1493
|
+
if (
|
|
1494
|
+
binding !== null &&
|
|
1495
|
+
!binding.reassigned &&
|
|
1496
|
+
binding.initial !== null &&
|
|
1497
|
+
binding.initial.type !== 'FunctionDeclaration' &&
|
|
1498
|
+
binding.initial.type !== 'ClassDeclaration' &&
|
|
1499
|
+
binding.initial.type !== 'ImportDeclaration' &&
|
|
1500
|
+
binding.initial.type !== 'EachBlock' &&
|
|
1501
|
+
binding.initial.type !== 'SnippetBlock'
|
|
1502
|
+
) {
|
|
1503
|
+
return should_proxy(binding.initial, null);
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
return true;
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
/**
|
|
1511
|
+
* Checks if the name is valid, which it is when it's not starting with (or is) a dollar sign or if it's a function parameter.
|
|
1512
|
+
* The second argument is the depth of the scope, which is there for backwards compatibility reasons: In Svelte 4, you
|
|
1513
|
+
* were allowed to define `$`-prefixed variables anywhere below the top level of components. Once legacy mode is gone, this
|
|
1514
|
+
* argument can be removed / the call sites adjusted accordingly.
|
|
1515
|
+
* @param {Binding | null} binding
|
|
1516
|
+
* @param {number | undefined} [function_depth]
|
|
1517
|
+
*/
|
|
1518
|
+
export function validate_identifier_name(binding, function_depth) {
|
|
1519
|
+
if (!binding) return;
|
|
1520
|
+
|
|
1521
|
+
const declaration_kind = binding.declaration_kind;
|
|
1522
|
+
|
|
1523
|
+
if (
|
|
1524
|
+
declaration_kind !== 'synthetic' &&
|
|
1525
|
+
declaration_kind !== 'param' &&
|
|
1526
|
+
declaration_kind !== 'rest_param' &&
|
|
1527
|
+
(!function_depth || function_depth <= 1)
|
|
1528
|
+
) {
|
|
1529
|
+
const node = binding.node;
|
|
1530
|
+
|
|
1531
|
+
if (node.name === '$') {
|
|
1532
|
+
e.dollar_binding_invalid(node);
|
|
1533
|
+
} else if (
|
|
1534
|
+
node.name.startsWith('$') &&
|
|
1535
|
+
// import type { $Type } from "" - these are normally already filtered out,
|
|
1536
|
+
// but for the migration they aren't, and throwing here is preventing the migration to complete
|
|
1537
|
+
// TODO -> once migration script is gone we can remove this check
|
|
1538
|
+
!(
|
|
1539
|
+
binding.initial?.type === 'ImportDeclaration' &&
|
|
1540
|
+
/** @type {any} */ (binding.initial).importKind === 'type'
|
|
1541
|
+
)
|
|
1542
|
+
) {
|
|
1543
|
+
e.dollar_prefix_invalid(node);
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
}
|
package/src/compiler/state.js
CHANGED
|
@@ -33,10 +33,14 @@ export let component_name = '<unknown>';
|
|
|
33
33
|
export let source;
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
|
-
* The source code split into lines
|
|
37
|
-
* @type {string[]}
|
|
36
|
+
* The source code split into lines, initialized when a diagnostic needs a code frame
|
|
37
|
+
* @type {string[] | undefined}
|
|
38
38
|
*/
|
|
39
|
-
|
|
39
|
+
let source_lines;
|
|
40
|
+
|
|
41
|
+
export function get_source_lines() {
|
|
42
|
+
return (source_lines ??= source.split('\n'));
|
|
43
|
+
}
|
|
40
44
|
|
|
41
45
|
/**
|
|
42
46
|
* True if compiling with `dev: true`
|
|
@@ -52,7 +56,7 @@ export let locator;
|
|
|
52
56
|
/** @param {string} value */
|
|
53
57
|
export function set_source(value) {
|
|
54
58
|
source = value;
|
|
55
|
-
source_lines =
|
|
59
|
+
source_lines = undefined;
|
|
56
60
|
|
|
57
61
|
const l = getLocator(source, { offsetLine: 1 });
|
|
58
62
|
|
|
@@ -141,7 +145,7 @@ export function reset(state) {
|
|
|
141
145
|
runes = false;
|
|
142
146
|
component_name = UNKNOWN_FILENAME;
|
|
143
147
|
source = '';
|
|
144
|
-
source_lines =
|
|
148
|
+
source_lines = undefined;
|
|
145
149
|
filename = (state.filename ?? UNKNOWN_FILENAME).replace(/\\/g, '/');
|
|
146
150
|
warning_filter = state.warning ?? (() => true);
|
|
147
151
|
warnings = [];
|
|
@@ -286,7 +286,7 @@ function _extract_paths(paths, inserts, param, expression, update_expression, ha
|
|
|
286
286
|
const props = [];
|
|
287
287
|
|
|
288
288
|
for (const p of param.properties) {
|
|
289
|
-
if (p.type === 'Property'
|
|
289
|
+
if (p.type === 'Property') {
|
|
290
290
|
if (p.key.type === 'Identifier' && !p.computed) {
|
|
291
291
|
props.push(b.literal(p.key.name));
|
|
292
292
|
} else if (p.key.type === 'Literal') {
|
|
@@ -548,10 +548,7 @@ export function is_expression_async(expression) {
|
|
|
548
548
|
if (property.type === 'SpreadElement') {
|
|
549
549
|
return is_expression_async(property.argument);
|
|
550
550
|
} else if (property.type === 'Property') {
|
|
551
|
-
return (
|
|
552
|
-
(property.key.type !== 'PrivateIdentifier' && is_expression_async(property.key)) ||
|
|
553
|
-
is_expression_async(property.value)
|
|
554
|
-
);
|
|
551
|
+
return is_expression_async(property.key) || is_expression_async(property.value);
|
|
555
552
|
}
|
|
556
553
|
});
|
|
557
554
|
}
|
|
@@ -15,7 +15,7 @@ function tabs_to_spaces(str) {
|
|
|
15
15
|
* @param {number} column
|
|
16
16
|
*/
|
|
17
17
|
function get_code_frame(line, column) {
|
|
18
|
-
const lines = state.
|
|
18
|
+
const lines = state.get_source_lines();
|
|
19
19
|
const frame_start = Math.max(0, line - 2);
|
|
20
20
|
const frame_end = Math.min(line + 3, lines.length);
|
|
21
21
|
const digits = String(frame_end + 1).length;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/** @import { ValidatedCompileOptions } from '#compiler' */
|
|
2
|
+
|
|
2
3
|
/** @import { Processed } from '../preprocess/public.js' */
|
|
3
4
|
/** @import { SourceMap } from 'magic-string' */
|
|
4
5
|
/** @import { Source } from '../preprocess/private.js' */
|
|
5
6
|
/** @import { DecodedSourceMap, SourceMapSegment, RawSourceMap } from '@jridgewell/remapping' */
|
|
6
7
|
import remapping from '@jridgewell/remapping';
|
|
7
|
-
import { push_array } from './push_array.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @param {string} s
|
|
@@ -12,6 +12,18 @@ import { push_array } from './push_array.js';
|
|
|
12
12
|
function last_line_length(s) {
|
|
13
13
|
return s.length - s.lastIndexOf('\n') - 1;
|
|
14
14
|
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* `array.push(...items)` overflows the stack for large `items`.
|
|
18
|
+
* @template T
|
|
19
|
+
* @param {T[]} array
|
|
20
|
+
* @param {T[]} items
|
|
21
|
+
*/
|
|
22
|
+
function push_array(array, items) {
|
|
23
|
+
for (let i = 0; i < items.length; i++) {
|
|
24
|
+
array.push(items[i]);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
15
27
|
// mutate map in-place
|
|
16
28
|
|
|
17
29
|
/**
|
|
@@ -51,15 +51,6 @@ export const EFFECT_PRESERVED = 1 << 19;
|
|
|
51
51
|
export const USER_EFFECT = 1 << 20;
|
|
52
52
|
export const EFFECT_OFFSCREEN = 1 << 25;
|
|
53
53
|
|
|
54
|
-
// Flags exclusive to deriveds
|
|
55
|
-
/**
|
|
56
|
-
* Tells that we marked this derived and its reactions as visited during the "mark as (maybe) dirty"-phase.
|
|
57
|
-
* Will be lifted during execution of the derived and during checking its dirty state (both are necessary
|
|
58
|
-
* because a derived might be checked but not executed). This is a pure performance optimization flag and
|
|
59
|
-
* should not be used for any other purpose!
|
|
60
|
-
*/
|
|
61
|
-
export const WAS_MARKED = 1 << 16;
|
|
62
|
-
|
|
63
54
|
// Flags used for async
|
|
64
55
|
export const REACTION_IS_UPDATING = 1 << 21;
|
|
65
56
|
export const ASYNC = 1 << 22;
|
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
MAYBE_DIRTY,
|
|
16
16
|
RENDER_EFFECT,
|
|
17
17
|
ROOT_EFFECT,
|
|
18
|
-
WAS_MARKED,
|
|
19
18
|
MANAGED_EFFECT
|
|
20
19
|
} from '#client/constants';
|
|
21
20
|
import { snapshot } from '../../shared/clone.js';
|
|
@@ -204,7 +203,6 @@ export function log_reactions(signal) {
|
|
|
204
203
|
if ((flags & DIRTY) !== 0) names.push('DIRTY');
|
|
205
204
|
if ((flags & MAYBE_DIRTY) !== 0) names.push('MAYBE_DIRTY');
|
|
206
205
|
if ((flags & CONNECTED) !== 0) names.push('CONNECTED');
|
|
207
|
-
if ((flags & WAS_MARKED) !== 0) names.push('WAS_MARKED');
|
|
208
206
|
if ((flags & INERT) !== 0) names.push('INERT');
|
|
209
207
|
if ((flags & DESTROYED) !== 0) names.push('DESTROYED');
|
|
210
208
|
|
|
@@ -78,8 +78,11 @@ export function create_event(event_name, dom, handler, options = {}) {
|
|
|
78
78
|
event_name.startsWith('touch') ||
|
|
79
79
|
event_name === 'wheel'
|
|
80
80
|
) {
|
|
81
|
+
target_handler.__removed = false;
|
|
81
82
|
queue_micro_task(() => {
|
|
82
|
-
|
|
83
|
+
if (!target_handler.__removed) {
|
|
84
|
+
dom.addEventListener(event_name, target_handler, options);
|
|
85
|
+
}
|
|
83
86
|
});
|
|
84
87
|
} else {
|
|
85
88
|
dom.addEventListener(event_name, target_handler, options);
|
|
@@ -102,6 +105,7 @@ export function on(element, type, handler, options = {}) {
|
|
|
102
105
|
var target_handler = create_event(type, element, handler, options);
|
|
103
106
|
|
|
104
107
|
return () => {
|
|
108
|
+
target_handler.__removed = true;
|
|
105
109
|
element.removeEventListener(type, target_handler, options);
|
|
106
110
|
};
|
|
107
111
|
}
|
|
@@ -128,6 +132,7 @@ export function event(event_name, dom, handler, capture, passive) {
|
|
|
128
132
|
dom instanceof HTMLMediaElement
|
|
129
133
|
) {
|
|
130
134
|
teardown(() => {
|
|
135
|
+
target_handler.__removed = true;
|
|
131
136
|
dom.removeEventListener(event_name, target_handler, options);
|
|
132
137
|
});
|
|
133
138
|
}
|
|
@@ -429,22 +429,6 @@ export function rune_outside_svelte(rune) {
|
|
|
429
429
|
}
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
-
/**
|
|
433
|
-
* `setContext` must be called when a component first initializes, not in a subsequent effect or after an `await` expression
|
|
434
|
-
* @returns {never}
|
|
435
|
-
*/
|
|
436
|
-
export function set_context_after_init() {
|
|
437
|
-
if (DEV) {
|
|
438
|
-
const error = new Error(`set_context_after_init\n\`setContext\` must be called when a component first initializes, not in a subsequent effect or after an \`await\` expression\nhttps://svelte.dev/e/set_context_after_init`);
|
|
439
|
-
|
|
440
|
-
error.name = 'Svelte error';
|
|
441
|
-
|
|
442
|
-
throw error;
|
|
443
|
-
} else {
|
|
444
|
-
throw new Error(`https://svelte.dev/e/set_context_after_init`);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
|
|
448
432
|
/**
|
|
449
433
|
* Property descriptors defined on `$state` objects must contain `value` and always be `enumerable`, `configurable` and `writable`.
|
|
450
434
|
* @returns {never}
|
|
@@ -204,16 +204,21 @@ export function proxy(value) {
|
|
|
204
204
|
},
|
|
205
205
|
|
|
206
206
|
getOwnPropertyDescriptor(target, prop) {
|
|
207
|
+
this.has?.(target, prop);
|
|
208
|
+
|
|
207
209
|
var descriptor = Reflect.getOwnPropertyDescriptor(target, prop);
|
|
210
|
+
var s = sources.get(prop);
|
|
208
211
|
|
|
209
|
-
if (
|
|
210
|
-
var
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
212
|
+
if (s !== undefined) {
|
|
213
|
+
var value = get(s);
|
|
214
|
+
|
|
215
|
+
if (value === UNINITIALIZED) {
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
215
218
|
|
|
216
|
-
if (
|
|
219
|
+
if (descriptor && 'value' in descriptor) {
|
|
220
|
+
descriptor.value = value;
|
|
221
|
+
} else {
|
|
217
222
|
return {
|
|
218
223
|
enumerable: true,
|
|
219
224
|
configurable: true,
|