svelte 5.42.1 → 5.42.2
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 +1 -1
- package/src/compiler/phases/1-parse/state/element.js +8 -9
- package/src/compiler/phases/1-parse/state/tag.js +9 -9
- package/src/compiler/phases/2-analyze/index.js +6 -6
- package/src/compiler/phases/2-analyze/visitors/CallExpression.js +2 -2
- package/src/compiler/phases/2-analyze/visitors/RenderTag.js +2 -2
- package/src/compiler/phases/2-analyze/visitors/shared/utils.js +4 -1
- package/src/compiler/phases/3-transform/client/visitors/CallExpression.js +11 -0
- package/src/compiler/phases/3-transform/client/visitors/ExpressionStatement.js +0 -10
- package/src/compiler/phases/3-transform/client/visitors/RegularElement.js +27 -19
- package/src/compiler/phases/3-transform/client/visitors/RenderTag.js +1 -1
- package/src/compiler/phases/3-transform/client/visitors/SlotElement.js +1 -1
- package/src/compiler/phases/3-transform/client/visitors/shared/component.js +3 -3
- package/src/compiler/phases/3-transform/client/visitors/shared/element.js +7 -10
- package/src/compiler/phases/3-transform/client/visitors/shared/events.js +2 -1
- package/src/compiler/phases/3-transform/client/visitors/shared/utils.js +15 -6
- package/src/compiler/phases/3-transform/server/transform-server.js +12 -12
- package/src/compiler/phases/3-transform/server/visitors/shared/element.js +4 -8
- package/src/compiler/phases/3-transform/server/visitors/shared/utils.js +3 -2
- package/src/compiler/phases/nodes.js +27 -14
- package/src/compiler/phases/scope.js +2 -2
- package/src/version.js +1 -1
- package/types/index.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -9,11 +9,10 @@ import { decode_character_references } from '../utils/html.js';
|
|
|
9
9
|
import * as e from '../../../errors.js';
|
|
10
10
|
import * as w from '../../../warnings.js';
|
|
11
11
|
import { create_fragment } from '../utils/create.js';
|
|
12
|
-
import { create_attribute,
|
|
12
|
+
import { create_attribute, ExpressionMetadata, is_element_node } from '../../nodes.js';
|
|
13
13
|
import { get_attribute_expression, is_expression_attribute } from '../../../utils/ast.js';
|
|
14
14
|
import { closing_tag_omitted } from '../../../../html-tree-validation.js';
|
|
15
15
|
import { list } from '../../../utils/string.js';
|
|
16
|
-
import { regex_whitespace } from '../../patterns.js';
|
|
17
16
|
|
|
18
17
|
const regex_invalid_unquoted_attribute_value = /^(\/>|[\s"'=<>`])/;
|
|
19
18
|
const regex_closing_textarea_tag = /^<\/textarea(\s[^>]*)?>/i;
|
|
@@ -297,7 +296,7 @@ export default function element(parser) {
|
|
|
297
296
|
element.tag = get_attribute_expression(definition);
|
|
298
297
|
}
|
|
299
298
|
|
|
300
|
-
element.metadata.expression =
|
|
299
|
+
element.metadata.expression = new ExpressionMetadata();
|
|
301
300
|
}
|
|
302
301
|
|
|
303
302
|
if (is_top_level_script_or_style) {
|
|
@@ -508,7 +507,7 @@ function read_attribute(parser) {
|
|
|
508
507
|
end: parser.index,
|
|
509
508
|
expression,
|
|
510
509
|
metadata: {
|
|
511
|
-
expression:
|
|
510
|
+
expression: new ExpressionMetadata()
|
|
512
511
|
}
|
|
513
512
|
};
|
|
514
513
|
|
|
@@ -528,7 +527,7 @@ function read_attribute(parser) {
|
|
|
528
527
|
end: parser.index,
|
|
529
528
|
expression,
|
|
530
529
|
metadata: {
|
|
531
|
-
expression:
|
|
530
|
+
expression: new ExpressionMetadata()
|
|
532
531
|
}
|
|
533
532
|
};
|
|
534
533
|
|
|
@@ -568,7 +567,7 @@ function read_attribute(parser) {
|
|
|
568
567
|
name
|
|
569
568
|
},
|
|
570
569
|
metadata: {
|
|
571
|
-
expression:
|
|
570
|
+
expression: new ExpressionMetadata()
|
|
572
571
|
}
|
|
573
572
|
};
|
|
574
573
|
|
|
@@ -628,7 +627,7 @@ function read_attribute(parser) {
|
|
|
628
627
|
modifiers: /** @type {Array<'important'>} */ (modifiers),
|
|
629
628
|
value,
|
|
630
629
|
metadata: {
|
|
631
|
-
expression:
|
|
630
|
+
expression: new ExpressionMetadata()
|
|
632
631
|
}
|
|
633
632
|
};
|
|
634
633
|
}
|
|
@@ -658,7 +657,7 @@ function read_attribute(parser) {
|
|
|
658
657
|
name: directive_name,
|
|
659
658
|
expression,
|
|
660
659
|
metadata: {
|
|
661
|
-
expression:
|
|
660
|
+
expression: new ExpressionMetadata()
|
|
662
661
|
}
|
|
663
662
|
};
|
|
664
663
|
|
|
@@ -824,7 +823,7 @@ function read_sequence(parser, done, location) {
|
|
|
824
823
|
end: parser.index,
|
|
825
824
|
expression,
|
|
826
825
|
metadata: {
|
|
827
|
-
expression:
|
|
826
|
+
expression: new ExpressionMetadata()
|
|
828
827
|
}
|
|
829
828
|
};
|
|
830
829
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/** @import { Parser } from '../index.js' */
|
|
4
4
|
import { walk } from 'zimmerframe';
|
|
5
5
|
import * as e from '../../../errors.js';
|
|
6
|
-
import {
|
|
6
|
+
import { ExpressionMetadata } from '../../nodes.js';
|
|
7
7
|
import { parse_expression_at } from '../acorn.js';
|
|
8
8
|
import read_pattern from '../read/context.js';
|
|
9
9
|
import read_expression, { get_loose_identifier } from '../read/expression.js';
|
|
@@ -42,7 +42,7 @@ export default function tag(parser) {
|
|
|
42
42
|
end: parser.index,
|
|
43
43
|
expression,
|
|
44
44
|
metadata: {
|
|
45
|
-
expression:
|
|
45
|
+
expression: new ExpressionMetadata()
|
|
46
46
|
}
|
|
47
47
|
});
|
|
48
48
|
}
|
|
@@ -65,7 +65,7 @@ function open(parser) {
|
|
|
65
65
|
consequent: create_fragment(),
|
|
66
66
|
alternate: null,
|
|
67
67
|
metadata: {
|
|
68
|
-
expression:
|
|
68
|
+
expression: new ExpressionMetadata()
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
71
|
|
|
@@ -249,7 +249,7 @@ function open(parser) {
|
|
|
249
249
|
then: null,
|
|
250
250
|
catch: null,
|
|
251
251
|
metadata: {
|
|
252
|
-
expression:
|
|
252
|
+
expression: new ExpressionMetadata()
|
|
253
253
|
}
|
|
254
254
|
});
|
|
255
255
|
|
|
@@ -334,7 +334,7 @@ function open(parser) {
|
|
|
334
334
|
expression,
|
|
335
335
|
fragment: create_fragment(),
|
|
336
336
|
metadata: {
|
|
337
|
-
expression:
|
|
337
|
+
expression: new ExpressionMetadata()
|
|
338
338
|
}
|
|
339
339
|
});
|
|
340
340
|
|
|
@@ -477,7 +477,7 @@ function next(parser) {
|
|
|
477
477
|
consequent: create_fragment(),
|
|
478
478
|
alternate: null,
|
|
479
479
|
metadata: {
|
|
480
|
-
expression:
|
|
480
|
+
expression: new ExpressionMetadata()
|
|
481
481
|
}
|
|
482
482
|
});
|
|
483
483
|
|
|
@@ -643,7 +643,7 @@ function special(parser) {
|
|
|
643
643
|
end: parser.index,
|
|
644
644
|
expression,
|
|
645
645
|
metadata: {
|
|
646
|
-
expression:
|
|
646
|
+
expression: new ExpressionMetadata()
|
|
647
647
|
}
|
|
648
648
|
});
|
|
649
649
|
|
|
@@ -721,7 +721,7 @@ function special(parser) {
|
|
|
721
721
|
end: parser.index - 1
|
|
722
722
|
},
|
|
723
723
|
metadata: {
|
|
724
|
-
expression:
|
|
724
|
+
expression: new ExpressionMetadata()
|
|
725
725
|
}
|
|
726
726
|
});
|
|
727
727
|
}
|
|
@@ -748,7 +748,7 @@ function special(parser) {
|
|
|
748
748
|
end: parser.index,
|
|
749
749
|
expression: /** @type {AST.RenderTag['expression']} */ (expression),
|
|
750
750
|
metadata: {
|
|
751
|
-
expression:
|
|
751
|
+
expression: new ExpressionMetadata(),
|
|
752
752
|
dynamic: false,
|
|
753
753
|
arguments: [],
|
|
754
754
|
path: [],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @import
|
|
1
|
+
/** @import * as ESTree from 'estree' */
|
|
2
2
|
/** @import { Binding, AST, ValidatedCompileOptions, ValidatedModuleCompileOptions } from '#compiler' */
|
|
3
3
|
/** @import { AnalysisState, Visitors } from './types' */
|
|
4
4
|
/** @import { Analysis, ComponentAnalysis, Js, ReactiveStatement, Template } from '../types' */
|
|
@@ -206,7 +206,7 @@ const visitors = {
|
|
|
206
206
|
* @returns {Js}
|
|
207
207
|
*/
|
|
208
208
|
function js(script, root, allow_reactive_declarations, parent) {
|
|
209
|
-
/** @type {Program} */
|
|
209
|
+
/** @type {ESTree.Program} */
|
|
210
210
|
const ast = script?.content ?? {
|
|
211
211
|
type: 'Program',
|
|
212
212
|
sourceType: 'module',
|
|
@@ -289,7 +289,7 @@ export function analyze_module(source, options) {
|
|
|
289
289
|
});
|
|
290
290
|
|
|
291
291
|
walk(
|
|
292
|
-
/** @type {Node} */ (ast),
|
|
292
|
+
/** @type {ESTree.Node} */ (ast),
|
|
293
293
|
{
|
|
294
294
|
scope,
|
|
295
295
|
scopes,
|
|
@@ -347,7 +347,7 @@ export function analyze_component(root, source, options) {
|
|
|
347
347
|
|
|
348
348
|
const store_name = name.slice(1);
|
|
349
349
|
const declaration = instance.scope.get(store_name);
|
|
350
|
-
const init = /** @type {Node | undefined} */ (declaration?.initial);
|
|
350
|
+
const init = /** @type {ESTree.Node | undefined} */ (declaration?.initial);
|
|
351
351
|
|
|
352
352
|
// If we're not in legacy mode through the compiler option, assume the user
|
|
353
353
|
// is referencing a rune and not a global store.
|
|
@@ -407,7 +407,7 @@ export function analyze_component(root, source, options) {
|
|
|
407
407
|
/** @type {number} */ (node.start) > /** @type {number} */ (module.ast.start) &&
|
|
408
408
|
/** @type {number} */ (node.end) < /** @type {number} */ (module.ast.end) &&
|
|
409
409
|
// const state = $state(0) is valid
|
|
410
|
-
get_rune(/** @type {Node} */ (path.at(-1)), module.scope) === null
|
|
410
|
+
get_rune(/** @type {ESTree.Node} */ (path.at(-1)), module.scope) === null
|
|
411
411
|
) {
|
|
412
412
|
e.store_invalid_subscription(node);
|
|
413
413
|
}
|
|
@@ -636,7 +636,7 @@ export function analyze_component(root, source, options) {
|
|
|
636
636
|
// @ts-expect-error
|
|
637
637
|
_: set_scope,
|
|
638
638
|
Identifier(node, context) {
|
|
639
|
-
const parent = /** @type {Expression} */ (context.path.at(-1));
|
|
639
|
+
const parent = /** @type {ESTree.Expression} */ (context.path.at(-1));
|
|
640
640
|
|
|
641
641
|
if (is_reference(node, parent)) {
|
|
642
642
|
const binding = context.state.scope.get(node.name);
|
|
@@ -7,7 +7,7 @@ import { get_parent } from '../../../utils/ast.js';
|
|
|
7
7
|
import { is_pure, is_safe_identifier } from './shared/utils.js';
|
|
8
8
|
import { dev, locate_node, source } from '../../../state.js';
|
|
9
9
|
import * as b from '#compiler/builders';
|
|
10
|
-
import {
|
|
10
|
+
import { ExpressionMetadata } from '../../nodes.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* @param {CallExpression} node
|
|
@@ -243,7 +243,7 @@ export function CallExpression(node, context) {
|
|
|
243
243
|
|
|
244
244
|
// `$inspect(foo)` or `$derived(foo) should not trigger the `static-state-reference` warning
|
|
245
245
|
if (rune === '$derived') {
|
|
246
|
-
const expression =
|
|
246
|
+
const expression = new ExpressionMetadata();
|
|
247
247
|
|
|
248
248
|
context.next({
|
|
249
249
|
...context.state,
|
|
@@ -5,7 +5,7 @@ import * as e from '../../../errors.js';
|
|
|
5
5
|
import { validate_opening_tag } from './shared/utils.js';
|
|
6
6
|
import { mark_subtree_dynamic } from './shared/fragment.js';
|
|
7
7
|
import { is_resolved_snippet } from './shared/snippets.js';
|
|
8
|
-
import {
|
|
8
|
+
import { ExpressionMetadata } from '../../nodes.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @param {AST.RenderTag} node
|
|
@@ -57,7 +57,7 @@ export function RenderTag(node, context) {
|
|
|
57
57
|
context.visit(callee, { ...context.state, expression: node.metadata.expression });
|
|
58
58
|
|
|
59
59
|
for (const arg of expression.arguments) {
|
|
60
|
-
const metadata =
|
|
60
|
+
const metadata = new ExpressionMetadata();
|
|
61
61
|
node.metadata.arguments.push(metadata);
|
|
62
62
|
|
|
63
63
|
context.visit(arg, {
|
|
@@ -22,7 +22,10 @@ export function validate_assignment(node, argument, context) {
|
|
|
22
22
|
const binding = context.state.scope.get(argument.name);
|
|
23
23
|
|
|
24
24
|
if (context.state.analysis.runes) {
|
|
25
|
-
if (
|
|
25
|
+
if (
|
|
26
|
+
context.state.analysis.props_id != null &&
|
|
27
|
+
binding?.node === context.state.analysis.props_id
|
|
28
|
+
) {
|
|
26
29
|
e.constant_assignment(node, '$props.id()');
|
|
27
30
|
}
|
|
28
31
|
|
|
@@ -62,6 +62,17 @@ export function CallExpression(node, context) {
|
|
|
62
62
|
is_ignored(node, 'state_snapshot_uncloneable') && b.true
|
|
63
63
|
);
|
|
64
64
|
|
|
65
|
+
case '$effect':
|
|
66
|
+
case '$effect.pre': {
|
|
67
|
+
const callee = rune === '$effect' ? '$.user_effect' : '$.user_pre_effect';
|
|
68
|
+
const func = /** @type {Expression} */ (context.visit(node.arguments[0]));
|
|
69
|
+
|
|
70
|
+
const expr = b.call(callee, /** @type {Expression} */ (func));
|
|
71
|
+
expr.callee.loc = node.callee.loc; // ensure correct mapping
|
|
72
|
+
|
|
73
|
+
return expr;
|
|
74
|
+
}
|
|
75
|
+
|
|
65
76
|
case '$effect.root':
|
|
66
77
|
return b.call(
|
|
67
78
|
'$.effect_root',
|
|
@@ -11,16 +11,6 @@ export function ExpressionStatement(node, context) {
|
|
|
11
11
|
if (node.expression.type === 'CallExpression') {
|
|
12
12
|
const rune = get_rune(node.expression, context.state.scope);
|
|
13
13
|
|
|
14
|
-
if (rune === '$effect' || rune === '$effect.pre') {
|
|
15
|
-
const callee = rune === '$effect' ? '$.user_effect' : '$.user_pre_effect';
|
|
16
|
-
const func = /** @type {Expression} */ (context.visit(node.expression.arguments[0]));
|
|
17
|
-
|
|
18
|
-
const expr = b.call(callee, /** @type {Expression} */ (func));
|
|
19
|
-
expr.callee.loc = node.expression.callee.loc; // ensure correct mapping
|
|
20
|
-
|
|
21
|
-
return b.stmt(expr);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
14
|
if (rune === '$inspect.trace') {
|
|
25
15
|
return b.empty;
|
|
26
16
|
}
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import { is_ignored } from '../../../../state.js';
|
|
12
12
|
import { is_event_attribute, is_text_attribute } from '../../../../utils/ast.js';
|
|
13
13
|
import * as b from '#compiler/builders';
|
|
14
|
-
import { create_attribute, is_custom_element_node } from '../../../nodes.js';
|
|
14
|
+
import { create_attribute, ExpressionMetadata, is_custom_element_node } from '../../../nodes.js';
|
|
15
15
|
import { clean_nodes, determine_namespace_for_children } from '../../utils.js';
|
|
16
16
|
import { build_getter } from '../utils.js';
|
|
17
17
|
import {
|
|
@@ -267,10 +267,7 @@ export function RegularElement(node, context) {
|
|
|
267
267
|
const { value, has_state } = build_attribute_value(
|
|
268
268
|
attribute.value,
|
|
269
269
|
context,
|
|
270
|
-
(value, metadata) =>
|
|
271
|
-
metadata.has_call || metadata.has_await
|
|
272
|
-
? context.state.memoizer.add(value, metadata.has_await)
|
|
273
|
-
: value
|
|
270
|
+
(value, metadata) => context.state.memoizer.add(value, metadata)
|
|
274
271
|
);
|
|
275
272
|
|
|
276
273
|
const update = build_element_attribute_update(node, node_id, name, value, attributes);
|
|
@@ -487,11 +484,25 @@ function setup_select_synchronization(value_binding, context) {
|
|
|
487
484
|
);
|
|
488
485
|
}
|
|
489
486
|
|
|
487
|
+
/**
|
|
488
|
+
* @param {ExpressionMetadata} target
|
|
489
|
+
* @param {ExpressionMetadata} source
|
|
490
|
+
*/
|
|
491
|
+
function merge_metadata(target, source) {
|
|
492
|
+
target.has_assignment ||= source.has_assignment;
|
|
493
|
+
target.has_await ||= source.has_await;
|
|
494
|
+
target.has_call ||= source.has_call;
|
|
495
|
+
target.has_member_expression ||= source.has_member_expression;
|
|
496
|
+
target.has_state ||= source.has_state;
|
|
497
|
+
|
|
498
|
+
for (const r of source.references) target.references.add(r);
|
|
499
|
+
for (const b of source.dependencies) target.dependencies.add(b);
|
|
500
|
+
}
|
|
501
|
+
|
|
490
502
|
/**
|
|
491
503
|
* @param {AST.ClassDirective[]} class_directives
|
|
492
504
|
* @param {ComponentContext} context
|
|
493
505
|
* @param {Memoizer} memoizer
|
|
494
|
-
* @return {ObjectExpression | Identifier}
|
|
495
506
|
*/
|
|
496
507
|
export function build_class_directives_object(
|
|
497
508
|
class_directives,
|
|
@@ -499,26 +510,25 @@ export function build_class_directives_object(
|
|
|
499
510
|
memoizer = context.state.memoizer
|
|
500
511
|
) {
|
|
501
512
|
let properties = [];
|
|
502
|
-
|
|
503
|
-
|
|
513
|
+
|
|
514
|
+
const metadata = new ExpressionMetadata();
|
|
504
515
|
|
|
505
516
|
for (const d of class_directives) {
|
|
517
|
+
merge_metadata(metadata, d.metadata.expression);
|
|
518
|
+
|
|
506
519
|
const expression = /** @type Expression */ (context.visit(d.expression));
|
|
507
520
|
properties.push(b.init(d.name, expression));
|
|
508
|
-
has_call_or_state ||= d.metadata.expression.has_call || d.metadata.expression.has_state;
|
|
509
|
-
has_await ||= d.metadata.expression.has_await;
|
|
510
521
|
}
|
|
511
522
|
|
|
512
523
|
const directives = b.object(properties);
|
|
513
524
|
|
|
514
|
-
return
|
|
525
|
+
return memoizer.add(directives, metadata);
|
|
515
526
|
}
|
|
516
527
|
|
|
517
528
|
/**
|
|
518
529
|
* @param {AST.StyleDirective[]} style_directives
|
|
519
530
|
* @param {ComponentContext} context
|
|
520
531
|
* @param {Memoizer} memoizer
|
|
521
|
-
* @return {ObjectExpression | ArrayExpression | Identifier}}
|
|
522
532
|
*/
|
|
523
533
|
export function build_style_directives_object(
|
|
524
534
|
style_directives,
|
|
@@ -528,10 +538,11 @@ export function build_style_directives_object(
|
|
|
528
538
|
const normal = b.object([]);
|
|
529
539
|
const important = b.object([]);
|
|
530
540
|
|
|
531
|
-
|
|
532
|
-
let has_await = false;
|
|
541
|
+
const metadata = new ExpressionMetadata();
|
|
533
542
|
|
|
534
543
|
for (const d of style_directives) {
|
|
544
|
+
merge_metadata(metadata, d.metadata.expression);
|
|
545
|
+
|
|
535
546
|
const expression =
|
|
536
547
|
d.value === true
|
|
537
548
|
? build_getter(b.id(d.name), context.state)
|
|
@@ -539,14 +550,11 @@ export function build_style_directives_object(
|
|
|
539
550
|
|
|
540
551
|
const object = d.modifiers.includes('important') ? important : normal;
|
|
541
552
|
object.properties.push(b.init(d.name, expression));
|
|
542
|
-
|
|
543
|
-
has_call_or_state ||= d.metadata.expression.has_call || d.metadata.expression.has_state;
|
|
544
|
-
has_await ||= d.metadata.expression.has_await;
|
|
545
553
|
}
|
|
546
554
|
|
|
547
555
|
const directives = important.properties.length ? b.array([normal, important]) : normal;
|
|
548
556
|
|
|
549
|
-
return
|
|
557
|
+
return memoizer.add(directives, metadata);
|
|
550
558
|
}
|
|
551
559
|
|
|
552
560
|
/**
|
|
@@ -675,7 +683,7 @@ function build_element_special_value_attribute(
|
|
|
675
683
|
element === 'select' && attribute.value !== true && !is_text_attribute(attribute);
|
|
676
684
|
|
|
677
685
|
const { value, has_state } = build_attribute_value(attribute.value, context, (value, metadata) =>
|
|
678
|
-
|
|
686
|
+
state.memoizer.add(value, metadata)
|
|
679
687
|
);
|
|
680
688
|
|
|
681
689
|
const evaluated = context.state.scope.evaluate(value);
|
|
@@ -26,7 +26,7 @@ export function RenderTag(node, context) {
|
|
|
26
26
|
let expression = build_expression(context, arg, metadata);
|
|
27
27
|
|
|
28
28
|
if (metadata.has_await || metadata.has_call) {
|
|
29
|
-
expression = b.call('$.get', memoizer.add(expression, metadata
|
|
29
|
+
expression = b.call('$.get', memoizer.add(expression, metadata));
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
args.push(b.thunk(expression));
|
|
@@ -134,7 +134,7 @@ export function build_component(node, component_name, context) {
|
|
|
134
134
|
props_and_spreads.push(
|
|
135
135
|
b.thunk(
|
|
136
136
|
attribute.metadata.expression.has_await || attribute.metadata.expression.has_call
|
|
137
|
-
? b.call('$.get', memoizer.add(expression, attribute.metadata.expression
|
|
137
|
+
? b.call('$.get', memoizer.add(expression, attribute.metadata.expression))
|
|
138
138
|
: expression
|
|
139
139
|
)
|
|
140
140
|
);
|
|
@@ -149,7 +149,7 @@ export function build_component(node, component_name, context) {
|
|
|
149
149
|
build_attribute_value(attribute.value, context, (value, metadata) => {
|
|
150
150
|
// TODO put the derived in the local block
|
|
151
151
|
return metadata.has_call || metadata.has_await
|
|
152
|
-
? b.call('$.get', memoizer.add(value, metadata
|
|
152
|
+
? b.call('$.get', memoizer.add(value, metadata))
|
|
153
153
|
: value;
|
|
154
154
|
}).value
|
|
155
155
|
)
|
|
@@ -185,7 +185,7 @@ export function build_component(node, component_name, context) {
|
|
|
185
185
|
});
|
|
186
186
|
|
|
187
187
|
return should_wrap_in_derived
|
|
188
|
-
? b.call('$.get', memoizer.add(value, metadata
|
|
188
|
+
? b.call('$.get', memoizer.add(value, metadata, true))
|
|
189
189
|
: value;
|
|
190
190
|
}
|
|
191
191
|
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @import { Expression, Identifier, ObjectExpression } from 'estree' */
|
|
2
|
-
/** @import { AST
|
|
2
|
+
/** @import { AST } from '#compiler' */
|
|
3
3
|
/** @import { ComponentContext } from '../../types' */
|
|
4
4
|
import { escape_html } from '../../../../../../escaping.js';
|
|
5
5
|
import { normalize_attribute } from '../../../../../../utils.js';
|
|
@@ -8,6 +8,7 @@ import { is_event_attribute } from '../../../../../utils/ast.js';
|
|
|
8
8
|
import * as b from '#compiler/builders';
|
|
9
9
|
import { build_class_directives_object, build_style_directives_object } from '../RegularElement.js';
|
|
10
10
|
import { build_expression, build_template_chunk, Memoizer } from './utils.js';
|
|
11
|
+
import { ExpressionMetadata } from '../../../../nodes.js';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* @param {Array<AST.Attribute | AST.SpreadAttribute>} attributes
|
|
@@ -35,7 +36,7 @@ export function build_attribute_effect(
|
|
|
35
36
|
for (const attribute of attributes) {
|
|
36
37
|
if (attribute.type === 'Attribute') {
|
|
37
38
|
const { value } = build_attribute_value(attribute.value, context, (value, metadata) =>
|
|
38
|
-
|
|
39
|
+
memoizer.add(value, metadata)
|
|
39
40
|
);
|
|
40
41
|
|
|
41
42
|
if (
|
|
@@ -52,9 +53,7 @@ export function build_attribute_effect(
|
|
|
52
53
|
} else {
|
|
53
54
|
let value = /** @type {Expression} */ (context.visit(attribute));
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
value = memoizer.add(value, attribute.metadata.expression.has_await);
|
|
57
|
-
}
|
|
56
|
+
value = memoizer.add(value, attribute.metadata.expression);
|
|
58
57
|
|
|
59
58
|
values.push(b.spread(value));
|
|
60
59
|
}
|
|
@@ -155,9 +154,7 @@ export function build_set_class(element, node_id, attribute, class_directives, c
|
|
|
155
154
|
value = b.call('$.clsx', value);
|
|
156
155
|
}
|
|
157
156
|
|
|
158
|
-
return
|
|
159
|
-
? context.state.memoizer.add(value, metadata.has_await)
|
|
160
|
-
: value;
|
|
157
|
+
return context.state.memoizer.add(value, metadata);
|
|
161
158
|
});
|
|
162
159
|
|
|
163
160
|
/** @type {Identifier | undefined} */
|
|
@@ -166,7 +163,7 @@ export function build_set_class(element, node_id, attribute, class_directives, c
|
|
|
166
163
|
/** @type {ObjectExpression | Identifier | undefined} */
|
|
167
164
|
let prev;
|
|
168
165
|
|
|
169
|
-
/** @type {
|
|
166
|
+
/** @type {Expression | undefined} */
|
|
170
167
|
let next;
|
|
171
168
|
|
|
172
169
|
if (class_directives.length) {
|
|
@@ -227,7 +224,7 @@ export function build_set_class(element, node_id, attribute, class_directives, c
|
|
|
227
224
|
*/
|
|
228
225
|
export function build_set_style(node_id, attribute, style_directives, context) {
|
|
229
226
|
let { value, has_state } = build_attribute_value(attribute.value, context, (value, metadata) =>
|
|
230
|
-
|
|
227
|
+
context.state.memoizer.add(value, metadata)
|
|
231
228
|
);
|
|
232
229
|
|
|
233
230
|
/** @type {Identifier | undefined} */
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/** @import { Expression } from 'estree' */
|
|
2
|
-
/** @import { AST
|
|
2
|
+
/** @import { AST } from '#compiler' */
|
|
3
3
|
/** @import { ComponentContext } from '../../types' */
|
|
4
4
|
import { is_capture_event, is_passive_event } from '../../../../../../utils.js';
|
|
5
5
|
import { dev, locator } from '../../../../../state.js';
|
|
6
6
|
import * as b from '#compiler/builders';
|
|
7
|
+
import { ExpressionMetadata } from '../../../../nodes.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* @param {AST.Attribute} node
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @import { AssignmentExpression, Expression, Identifier, MemberExpression, SequenceExpression, Literal, Super, UpdateExpression, ExpressionStatement } from 'estree' */
|
|
2
|
-
/** @import { AST
|
|
2
|
+
/** @import { AST } from '#compiler' */
|
|
3
3
|
/** @import { ComponentClientTransformState, ComponentContext, Context } from '../../types' */
|
|
4
4
|
import { walk } from 'zimmerframe';
|
|
5
5
|
import { object } from '../../../../../utils/ast.js';
|
|
@@ -9,6 +9,7 @@ import { regex_is_valid_identifier } from '../../../../patterns.js';
|
|
|
9
9
|
import is_reference from 'is-reference';
|
|
10
10
|
import { dev, is_ignored, locator, component_name } from '../../../../../state.js';
|
|
11
11
|
import { build_getter } from '../../utils.js';
|
|
12
|
+
import { ExpressionMetadata } from '../../../../nodes.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* A utility for extracting complex expressions (such as call expressions)
|
|
@@ -23,12 +24,21 @@ export class Memoizer {
|
|
|
23
24
|
|
|
24
25
|
/**
|
|
25
26
|
* @param {Expression} expression
|
|
26
|
-
* @param {
|
|
27
|
+
* @param {ExpressionMetadata} metadata
|
|
28
|
+
* @param {boolean} memoize_if_state
|
|
27
29
|
*/
|
|
28
|
-
add(expression,
|
|
30
|
+
add(expression, metadata, memoize_if_state = false) {
|
|
31
|
+
const should_memoize =
|
|
32
|
+
metadata.has_call || metadata.has_await || (memoize_if_state && metadata.has_state);
|
|
33
|
+
|
|
34
|
+
if (!should_memoize) {
|
|
35
|
+
// no memoization required
|
|
36
|
+
return expression;
|
|
37
|
+
}
|
|
38
|
+
|
|
29
39
|
const id = b.id('#'); // filled in later
|
|
30
40
|
|
|
31
|
-
(has_await ? this.#async : this.#sync).push({ id, expression });
|
|
41
|
+
(metadata.has_await ? this.#async : this.#sync).push({ id, expression });
|
|
32
42
|
|
|
33
43
|
return id;
|
|
34
44
|
}
|
|
@@ -72,8 +82,7 @@ export function build_template_chunk(
|
|
|
72
82
|
values,
|
|
73
83
|
context,
|
|
74
84
|
state = context.state,
|
|
75
|
-
memoize = (value, metadata) =>
|
|
76
|
-
metadata.has_call || metadata.has_await ? state.memoizer.add(value, metadata.has_await) : value
|
|
85
|
+
memoize = (value, metadata) => state.memoizer.add(value, metadata)
|
|
77
86
|
) {
|
|
78
87
|
/** @type {Expression[]} */
|
|
79
88
|
const expressions = [];
|