Skip to content

Commit 90563e9

Browse files
feat: add partial evaluation (#15494)
* feat: add partial evaluation * fix * tweak * more * more * evaluate stuff in template * update test * SSR * unused * changeset * remove TODO * Apply suggestions from code review Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com> * allow unknown operators * use blocks and block-scoping in switch statement --------- Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
1 parent a051f96 commit 90563e9

File tree

9 files changed

+357
-33
lines changed

9 files changed

+357
-33
lines changed

.changeset/selfish-onions-begin.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': minor
3+
---
4+
5+
feat: partially evaluate certain expressions

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -685,14 +685,13 @@ function build_element_special_value_attribute(element, node_id, attribute, cont
685685
: value
686686
);
687687

688+
const evaluated = context.state.scope.evaluate(value);
689+
const assignment = b.assignment('=', b.member(node_id, '__value'), value);
690+
688691
const inner_assignment = b.assignment(
689692
'=',
690693
b.member(node_id, 'value'),
691-
b.conditional(
692-
b.binary('==', b.null, b.assignment('=', b.member(node_id, '__value'), value)),
693-
b.literal(''), // render null/undefined values as empty string to support placeholder options
694-
value
695-
)
694+
evaluated.is_defined ? assignment : b.logical('??', assignment, b.literal(''))
696695
);
697696

698697
const update = b.stmt(

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -89,21 +89,21 @@ export function build_template_chunk(
8989
}
9090
}
9191

92-
const is_defined =
93-
value.type === 'BinaryExpression' ||
94-
(value.type === 'UnaryExpression' && value.operator !== 'void') ||
95-
(value.type === 'LogicalExpression' && value.right.type === 'Literal') ||
96-
(value.type === 'Identifier' && value.name === state.analysis.props_id?.name);
97-
98-
if (!is_defined) {
99-
// add `?? ''` where necessary (TODO optimise more cases)
100-
value = b.logical('??', value, b.literal(''));
101-
}
92+
const evaluated = state.scope.evaluate(value);
10293

103-
expressions.push(value);
94+
if (evaluated.is_known) {
95+
quasi.value.cooked += evaluated.value + '';
96+
} else {
97+
if (!evaluated.is_defined) {
98+
// add `?? ''` where necessary
99+
value = b.logical('??', value, b.literal(''));
100+
}
104101

105-
quasi = b.quasi('', i + 1 === values.length);
106-
quasis.push(quasi);
102+
expressions.push(value);
103+
104+
quasi = b.quasi('', i + 1 === values.length);
105+
quasis.push(quasi);
106+
}
107107
}
108108
}
109109

packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,17 @@ export function process_children(nodes, { visit, state }) {
4444
if (node.type === 'Text' || node.type === 'Comment') {
4545
quasi.value.cooked +=
4646
node.type === 'Comment' ? `<!--${node.data}-->` : escape_html(node.data);
47-
} else if (node.type === 'ExpressionTag' && node.expression.type === 'Literal') {
48-
if (node.expression.value != null) {
49-
quasi.value.cooked += escape_html(node.expression.value + '');
50-
}
5147
} else {
52-
expressions.push(b.call('$.escape', /** @type {Expression} */ (visit(node.expression))));
48+
const evaluated = state.scope.evaluate(node.expression);
49+
50+
if (evaluated.is_known) {
51+
quasi.value.cooked += escape_html((evaluated.value ?? '') + '');
52+
} else {
53+
expressions.push(b.call('$.escape', /** @type {Expression} */ (visit(node.expression))));
5354

54-
quasi = b.quasi('', i + 1 === sequence.length);
55-
quasis.push(quasi);
55+
quasi = b.quasi('', i + 1 === sequence.length);
56+
quasis.push(quasi);
57+
}
5658
}
5759
}
5860

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy