Skip to content

Commit 3b1b284

Browse files
committed
address feedback
1 parent 6ea44e0 commit 3b1b284

File tree

3 files changed

+24
-5
lines changed

3 files changed

+24
-5
lines changed

packages/svelte/src/compiler/phases/2-analyze/visitors/shared/utils.js

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @import { AssignmentExpression, Expression, Identifier, Pattern, PrivateIdentifier, Super, UpdateExpression, VariableDeclarator } from 'estree' */
1+
/** @import { AssignmentExpression, Expression, Literal, Pattern, PrivateIdentifier, Super, UpdateExpression, VariableDeclarator } from 'estree' */
22
/** @import { AST, Binding } from '#compiler' */
33
/** @import { AnalysisState, Context } from '../../types' */
44
/** @import { Scope } from '../../../scope' */
@@ -176,25 +176,42 @@ export function is_safe_identifier(expression, scope) {
176176
}
177177

178178
/**
179-
* @param {Expression | Super} node
179+
* @param {Expression | Literal | Super} node
180180
* @param {Context} context
181181
* @returns {boolean}
182182
*/
183183
export function is_pure(node, context) {
184+
if (node.type === 'Literal') {
185+
return true;
186+
}
187+
if (node.type === 'CallExpression') {
188+
if (!is_pure(node.callee, context)) {
189+
return false;
190+
}
191+
for (let arg of node.arguments) {
192+
if (!is_pure(arg.type === 'SpreadElement' ? arg.argument : arg, context)) {
193+
return false;
194+
}
195+
}
196+
return true;
197+
}
184198
if (node.type !== 'Identifier' && node.type !== 'MemberExpression') {
185199
return false;
186200
}
187201

188-
if (node.type === 'MemberExpression' && node.object.type === 'Literal') {
189-
return true;
202+
/** @type {Expression | Super | null} */
203+
let left = node;
204+
while (left.type === 'MemberExpression' && !left.computed) {
205+
left = left.object;
190206
}
191207

192-
const left = object(node);
193208
if (!left) return false;
194209

195210
if (left.type === 'Identifier') {
196211
const binding = context.state.scope.get(left.name);
197212
if (binding === null) return true; // globals are assumed to be safe
213+
} else if (is_pure(left, context)) {
214+
return true;
198215
}
199216

200217
// TODO add more cases (safe Svelte imports, etc)

packages/svelte/tests/runtime-legacy/samples/inline-expressions-2/_config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ export default test({
66
<p>With text expression: 7.36</p>
77
<p>With text expression and function call: 7.36</p>
88
<p>With text expression and property access: 4</p>
9+
<h1>Hello name!</h1>
910
<p>4</p>`
1011
});

packages/svelte/tests/runtime-legacy/samples/inline-expressions-2/main.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
<p>With text expression: {7.36}</p>
33
<p>With text expression and function call: {(7.36).toLocaleString()}</p>
44
<p>With text expression and property access: {"test".length}</p>
5+
<h1>Hello {('name').toUpperCase().toLowerCase()}!</h1>
56
<p>{"test".length}</p>

0 commit comments

Comments
 (0)