mirror of
https://github.com/sveltejs/svelte.git
synced 2024-11-24 08:17:29 +01:00
fix: ensure inline object literals are correctly serialised (#14325)
* fix: ensure inline object literals are correctly serialised * Apply suggestions from code review * address feedback * address feedback --------- Co-authored-by: Rich Harris <rich.harris@vercel.com>
This commit is contained in:
parent
95ab85fad7
commit
3a69b4c415
5
.changeset/wicked-readers-knock.md
Normal file
5
.changeset/wicked-readers-knock.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: treat property accesses of literals as pure
|
@ -1,4 +1,4 @@
|
||||
/** @import { AssignmentExpression, Expression, Identifier, Pattern, PrivateIdentifier, Super, UpdateExpression, VariableDeclarator } from 'estree' */
|
||||
/** @import { AssignmentExpression, Expression, Literal, Pattern, PrivateIdentifier, Super, UpdateExpression, VariableDeclarator } from 'estree' */
|
||||
/** @import { AST, Binding } from '#compiler' */
|
||||
/** @import { AnalysisState, Context } from '../../types' */
|
||||
/** @import { Scope } from '../../../scope' */
|
||||
@ -176,21 +176,42 @@ export function is_safe_identifier(expression, scope) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Expression | Super} node
|
||||
* @param {Expression | Literal | Super} node
|
||||
* @param {Context} context
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function is_pure(node, context) {
|
||||
if (node.type === 'Literal') {
|
||||
return true;
|
||||
}
|
||||
if (node.type === 'CallExpression') {
|
||||
if (!is_pure(node.callee, context)) {
|
||||
return false;
|
||||
}
|
||||
for (let arg of node.arguments) {
|
||||
if (!is_pure(arg.type === 'SpreadElement' ? arg.argument : arg, context)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (node.type !== 'Identifier' && node.type !== 'MemberExpression') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const left = object(node);
|
||||
/** @type {Expression | Super | null} */
|
||||
let left = node;
|
||||
while (left.type === 'MemberExpression') {
|
||||
left = left.object;
|
||||
}
|
||||
|
||||
if (!left) return false;
|
||||
|
||||
if (left.type === 'Identifier') {
|
||||
const binding = context.state.scope.get(left.name);
|
||||
if (binding === null) return true; // globals are assumed to be safe
|
||||
} else if (is_pure(left, context)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO add more cases (safe Svelte imports, etc)
|
||||
|
@ -0,0 +1,11 @@
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
html: `
|
||||
<p>Without text expression: 7.36</p>
|
||||
<p>With text expression: 7.36</p>
|
||||
<p>With text expression and function call: 7.36</p>
|
||||
<p>With text expression and property access: 4</p>
|
||||
<h1>Hello name!</h1>
|
||||
<p>4</p>`
|
||||
});
|
@ -0,0 +1,6 @@
|
||||
<p>Without text expression: 7.36</p>
|
||||
<p>With text expression: {7.36}</p>
|
||||
<p>With text expression and function call: {(7.36).toLocaleString()}</p>
|
||||
<p>With text expression and property access: {"test".length}</p>
|
||||
<h1>Hello {('name').toUpperCase().toLowerCase()}!</h1>
|
||||
<p>{"test".length}</p>
|
Loading…
Reference in New Issue
Block a user