Skip to content

Commit f889aba

Browse files
committed
Merge branch 'main' into better-dev-equality-warnings
2 parents 6c328af + f488a6e commit f889aba

File tree

65 files changed

+791
-285
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+791
-285
lines changed

.changeset/bright-falcons-float.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte": patch
3+
---
4+
5+
chore: improve SSR invalid element error message

.changeset/eight-pianos-raise.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte": patch
3+
---
4+
5+
fix: add backwards-compat for old warning codes in legacy mode

.changeset/khaki-monkeys-cry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte": patch
3+
---
4+
5+
feat: add $state.is rune

.changeset/pre.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
"early-ads-tie",
9999
"early-months-whisper",
100100
"eight-hornets-punch",
101+
"eight-pianos-raise",
101102
"eight-steaks-shout",
102103
"eighty-bikes-camp",
103104
"eighty-days-cheat",

packages/svelte/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# svelte
22

3+
## 5.0.0-next.133
4+
5+
### Patch Changes
6+
7+
- fix: add backwards-compat for old warning codes in legacy mode ([#11607](https://github.com/sveltejs/svelte/pull/11607))
8+
39
## 5.0.0-next.132
410

511
### Patch Changes
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## legacy_code
2+
3+
> `%code%` is no longer valid — please use `%suggestion%` instead
4+
5+
## unknown_code
6+
7+
> `%code%` is not a recognised code
8+
9+
> `%code%` is not a recognised code (did you mean `%suggestion%`?)

packages/svelte/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "svelte",
33
"description": "Cybernetically enhanced web apps",
44
"license": "MIT",
5-
"version": "5.0.0-next.132",
5+
"version": "5.0.0-next.133",
66
"type": "module",
77
"types": "./types/index.d.ts",
88
"engines": {

packages/svelte/scripts/process-messages/index.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ function transform(name, dest) {
6161

6262
const comments = [];
6363

64-
const ast = acorn.parse(source, {
64+
let ast = acorn.parse(source, {
6565
ecmaVersion: 'latest',
6666
sourceType: 'module',
6767
onComment: (block, value, start, end) => {
@@ -80,7 +80,7 @@ function transform(name, dest) {
8080
}
8181
});
8282

83-
walk(ast, null, {
83+
ast = walk(ast, null, {
8484
_(node, { next }) {
8585
let comment;
8686

@@ -100,6 +100,18 @@ function transform(name, dest) {
100100
node.trailingComments = [comments.shift()];
101101
}
102102
}
103+
},
104+
// @ts-expect-error
105+
Identifier(node, context) {
106+
if (node.name === 'CODES') {
107+
return {
108+
type: 'ArrayExpression',
109+
elements: Object.keys(messages[name]).map((code) => ({
110+
type: 'Literal',
111+
value: code
112+
}))
113+
};
114+
}
103115
}
104116
});
105117

packages/svelte/scripts/process-messages/templates/compile-warnings.js

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,14 @@
1-
import { getLocator } from 'locate-character';
1+
import { filename, locator, warnings, ignore_stack } from './state.js';
22

33
/** @typedef {{ start?: number, end?: number }} NodeLike */
44

5-
/** @type {import('#compiler').Warning[]} */
6-
let warnings = [];
7-
8-
/** @type {string | undefined} */
9-
let filename;
10-
11-
let locator = getLocator('', { offsetLine: 1 });
12-
13-
/**
14-
* @param {{
15-
* source: string;
16-
* filename: string | undefined;
17-
* }} options
18-
* @returns {import('#compiler').Warning[]}
19-
*/
20-
export function reset_warnings(options) {
21-
filename = options.filename;
22-
locator = getLocator(options.source, { offsetLine: 1 });
23-
24-
return (warnings = []);
25-
}
26-
275
/**
286
* @param {null | NodeLike} node
297
* @param {string} code
308
* @param {string} message
319
*/
3210
function w(node, code, message) {
33-
// @ts-expect-error
34-
if (node?.ignores?.has(code)) return;
11+
if (ignore_stack.at(-1)?.has(code)) return;
3512

3613
warnings.push({
3714
code,
@@ -42,6 +19,8 @@ function w(node, code, message) {
4219
});
4320
}
4421

22+
export const codes = CODES;
23+
4524
/**
4625
* MESSAGE
4726
* @param {null | NodeLike} node

packages/svelte/src/ambient.d.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,27 @@ declare namespace $state {
6363
*/
6464
export function snapshot<T>(state: T): T;
6565

66+
/**
67+
* Compare two values, one or both of which is a reactive `$state(...)` proxy.
68+
*
69+
* Example:
70+
* ```ts
71+
* <script>
72+
* let foo = $state({});
73+
* let bar = {};
74+
*
75+
* foo.bar = bar;
76+
*
77+
* console.log(foo.bar === bar); // false — `foo.bar` is a reactive proxy
78+
* console.log($state.is(foo.bar, bar)); // true
79+
* </script>
80+
* ```
81+
*
82+
* https://svelte-5-preview.vercel.app/docs/runes#$state.is
83+
*
84+
*/
85+
export function is(a: any, b: any): boolean;
86+
6687
// prevent intellisense from being unhelpful
6788
/** @deprecated */
6889
export const apply: never;

packages/svelte/src/compiler/index.js

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { getLocator } from 'locate-character';
21
import { walk as zimmerframe_walk } from 'zimmerframe';
32
import { CompileError } from './errors.js';
43
import { convert } from './legacy.js';
@@ -8,7 +7,7 @@ import { remove_typescript_nodes } from './phases/1-parse/remove_typescript_node
87
import { analyze_component, analyze_module } from './phases/2-analyze/index.js';
98
import { transform_component, transform_module } from './phases/3-transform/index.js';
109
import { validate_component_options, validate_module_options } from './validate-options.js';
11-
import { reset_warnings } from './warnings.js';
10+
import * as state from './state.js';
1211
export { default as preprocess } from './preprocess/index.js';
1312

1413
/**
@@ -21,7 +20,8 @@ export { default as preprocess } from './preprocess/index.js';
2120
*/
2221
export function compile(source, options) {
2322
try {
24-
const warnings = reset_warnings({ source, filename: options.filename });
23+
state.reset({ source, filename: options.filename });
24+
2525
const validated = validate_component_options(options, '');
2626
let parsed = _parse(source);
2727

@@ -44,9 +44,7 @@ export function compile(source, options) {
4444
}
4545

4646
const analysis = analyze_component(parsed, source, combined_options);
47-
4847
const result = transform_component(analysis, source, combined_options);
49-
result.warnings = warnings;
5048
result.ast = to_public_ast(source, parsed, options.modernAst);
5149
return result;
5250
} catch (e) {
@@ -68,11 +66,11 @@ export function compile(source, options) {
6866
*/
6967
export function compileModule(source, options) {
7068
try {
71-
const warnings = reset_warnings({ source, filename: options.filename });
69+
state.reset({ source, filename: options.filename });
70+
7271
const validated = validate_module_options(options, '');
7372
const analysis = analyze_module(parse_acorn(source, false), validated);
7473
const result = transform_module(analysis, source, validated);
75-
result.warnings = warnings;
7674
return result;
7775
} catch (e) {
7876
if (e instanceof CompileError) {
@@ -92,10 +90,8 @@ function handle_compile_error(error, filename, source) {
9290
error.filename = filename;
9391

9492
if (error.position) {
95-
// TODO this is reused with warnings — DRY out
96-
const locator = getLocator(source, { offsetLine: 1 });
97-
const start = locator(error.position[0]);
98-
const end = locator(error.position[1]);
93+
const start = state.locator(error.position[0]);
94+
const end = state.locator(error.position[1]);
9995

10096
error.start = start;
10197
error.end = end;
@@ -142,6 +138,8 @@ function handle_compile_error(error, filename, source) {
142138
* @returns {import('#compiler').Root | import('./types/legacy-nodes.js').LegacyRoot}
143139
*/
144140
export function parse(source, options = {}) {
141+
state.reset({ source, filename: options.filename });
142+
145143
/** @type {import('#compiler').Root} */
146144
let ast;
147145
try {

packages/svelte/src/compiler/legacy.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ export function convert(source, ast) {
201201
Comment(node) {
202202
return {
203203
...node,
204-
ignores: extract_svelte_ignore(node.data)
204+
ignores: extract_svelte_ignore(node.start, node.data, false)
205205
};
206206
},
207207
ComplexSelector(node) {

packages/svelte/src/compiler/migrate/index.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import { parse } from '../phases/1-parse/index.js';
44
import { analyze_component } from '../phases/2-analyze/index.js';
55
import { validate_component_options } from '../validate-options.js';
66
import { get_rune } from '../phases/scope.js';
7-
import { reset_warnings } from '../warnings.js';
7+
import { reset } from '../state.js';
88
import { extract_identifiers } from '../utils/ast.js';
99
import { regex_is_valid_identifier } from '../phases/patterns.js';
10+
import { migrate_svelte_ignore } from '../utils/extract_svelte_ignore.js';
1011

1112
/**
1213
* Does a best-effort migration of Svelte code towards using runes, event attributes and render tags.
@@ -17,7 +18,7 @@ import { regex_is_valid_identifier } from '../phases/patterns.js';
1718
*/
1819
export function migrate(source) {
1920
try {
20-
reset_warnings({ source, filename: 'migrate.svelte' });
21+
reset({ source, filename: 'migrate.svelte' });
2122

2223
let parsed = parse(source);
2324

@@ -174,6 +175,21 @@ export function migrate(source) {
174175

175176
/** @type {import('zimmerframe').Visitors<import('../types/template.js').SvelteNode, State>} */
176177
const instance_script = {
178+
_(node, { state, next }) {
179+
// @ts-expect-error
180+
const comments = node.leadingComments;
181+
if (comments) {
182+
for (const comment of comments) {
183+
if (comment.type === 'Line') {
184+
const migrated = migrate_svelte_ignore(comment.value);
185+
if (migrated !== comment.value) {
186+
state.str.overwrite(comment.start + '//'.length, comment.end, migrated);
187+
}
188+
}
189+
}
190+
}
191+
next();
192+
},
177193
Identifier(node, { state }) {
178194
handle_identifier(node, state);
179195
},
@@ -474,6 +490,12 @@ const template = {
474490
} else {
475491
state.str.update(node.start, node.end, `{@render ${name}?.(${slot_props})}`);
476492
}
493+
},
494+
Comment(node, { state }) {
495+
const migrated = migrate_svelte_ignore(node.data);
496+
if (migrated !== node.data) {
497+
state.str.overwrite(node.start + '<!--'.length, node.end - '-->'.length, migrated);
498+
}
477499
}
478500
};
479501

packages/svelte/src/compiler/phases/1-parse/index.js

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import full_char_code_at from './utils/full_char_code_at.js';
77
import * as e from '../../errors.js';
88
import { create_fragment } from './utils/create.js';
99
import read_options from './read/options.js';
10-
import { getLocator } from 'locate-character';
10+
import { locator } from '../../state.js';
1111

1212
const regex_position_indicator = / \(\d+:\d+\)$/;
1313

@@ -42,16 +42,13 @@ export class Parser {
4242
/** @type {LastAutoClosedTag | undefined} */
4343
last_auto_closed_tag;
4444

45-
locate;
46-
4745
/** @param {string} template */
4846
constructor(template) {
4947
if (typeof template !== 'string') {
5048
throw new TypeError('Template must be a string');
5149
}
5250

5351
this.template = template.trimEnd();
54-
this.locate = getLocator(this.template, { offsetLine: 1 });
5552

5653
let match_lang;
5754

@@ -137,18 +134,6 @@ export class Parser {
137134
}
138135
}
139136

140-
/**
141-
* offset -> line/column
142-
* @param {number} start
143-
* @param {number} end
144-
*/
145-
get_location(start, end) {
146-
return {
147-
start: /** @type {import('locate-character').Location_1} */ (this.locate(start)),
148-
end: /** @type {import('locate-character').Location_1} */ (this.locate(end))
149-
};
150-
}
151-
152137
current() {
153138
return this.stack[this.stack.length - 1];
154139
}

packages/svelte/src/compiler/phases/1-parse/read/context.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
import { parse_expression_at } from '../acorn.js';
1111
import { regex_not_newline_characters } from '../../patterns.js';
1212
import * as e from '../../../errors.js';
13+
import { locator } from '../../../state.js';
1314

1415
/**
1516
* @param {import('../index.js').Parser} parser
@@ -29,7 +30,10 @@ export default function read_pattern(parser, optional_allowed = false) {
2930
type: 'Identifier',
3031
name,
3132
start,
32-
loc: parser.get_location(start, parser.index),
33+
loc: {
34+
start: /** @type {import('locate-character').Location} */ (locator(start)),
35+
end: /** @type {import('locate-character').Location} */ (locator(parser.index))
36+
},
3337
end: parser.index,
3438
typeAnnotation: annotation
3539
};

0 commit comments

Comments
 (0)