mirror of
https://github.com/sveltejs/svelte.git
synced 2024-11-24 16:29:46 +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 { AST, Binding } from '#compiler' */
|
||||||
/** @import { AnalysisState, Context } from '../../types' */
|
/** @import { AnalysisState, Context } from '../../types' */
|
||||||
/** @import { Scope } from '../../../scope' */
|
/** @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
|
* @param {Context} context
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export function is_pure(node, context) {
|
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') {
|
if (node.type !== 'Identifier' && node.type !== 'MemberExpression') {
|
||||||
return false;
|
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) return false;
|
||||||
|
|
||||||
if (left.type === 'Identifier') {
|
if (left.type === 'Identifier') {
|
||||||
const binding = context.state.scope.get(left.name);
|
const binding = context.state.scope.get(left.name);
|
||||||
if (binding === null) return true; // globals are assumed to be safe
|
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)
|
// 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