Skip to content

Commit 486d10c

Browse files
committed
WIP
1 parent a0f86c5 commit 486d10c

File tree

16 files changed

+312
-116
lines changed

16 files changed

+312
-116
lines changed

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

Lines changed: 50 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import fs from 'node:fs';
44
import * as acorn from 'acorn';
55
import { walk } from 'zimmerframe';
66
import * as esrap from 'esrap';
7+
import ts from 'esrap/languages/ts';
78

89
const DIR = '../../documentation/docs/98-reference/.generated';
910

@@ -98,55 +99,18 @@ function run() {
9899
.replace(/\r\n/g, '\n');
99100

100101
/**
101-
* @type {Array<{
102-
* type: string;
103-
* value: string;
104-
* start: number;
105-
* end: number
106-
* }>}
102+
* @type {any[]}
107103
*/
108104
const comments = [];
109105

110106
let ast = acorn.parse(source, {
111107
ecmaVersion: 'latest',
112108
sourceType: 'module',
113-
onComment: (block, value, start, end) => {
114-
if (block && /\n/.test(value)) {
115-
let a = start;
116-
while (a > 0 && source[a - 1] !== '\n') a -= 1;
117-
118-
let b = a;
119-
while (/[ \t]/.test(source[b])) b += 1;
120-
121-
const indentation = source.slice(a, b);
122-
value = value.replace(new RegExp(`^${indentation}`, 'gm'), '');
123-
}
124-
125-
comments.push({ type: block ? 'Block' : 'Line', value, start, end });
126-
}
109+
locations: true,
110+
onComment: comments
127111
});
128112

129113
ast = walk(ast, null, {
130-
_(node, { next }) {
131-
let comment;
132-
133-
while (comments[0] && comments[0].start < node.start) {
134-
comment = comments.shift();
135-
// @ts-expect-error
136-
(node.leadingComments ||= []).push(comment);
137-
}
138-
139-
next();
140-
141-
if (comments[0]) {
142-
const slice = source.slice(node.end, comments[0].start);
143-
144-
if (/^[,) \t]*$/.test(slice)) {
145-
// @ts-expect-error
146-
node.trailingComments = [comments.shift()];
147-
}
148-
}
149-
},
150114
// @ts-expect-error
151115
Identifier(node, context) {
152116
if (node.name === 'CODES') {
@@ -161,11 +125,6 @@ function run() {
161125
}
162126
});
163127

164-
if (comments.length > 0) {
165-
// @ts-expect-error
166-
(ast.trailingComments ||= []).push(...comments);
167-
}
168-
169128
const category = messages[name];
170129

171130
// find the `export function CODE` node
@@ -184,6 +143,16 @@ function run() {
184143
const template_node = ast.body[index];
185144
ast.body.splice(index, 1);
186145

146+
const jsdoc = comments.findLast((comment) => comment.start < template_node.start);
147+
148+
const printed = esrap.print(
149+
ast,
150+
// @ts-expect-error
151+
ts({
152+
comments: comments.filter((comment) => comment !== jsdoc)
153+
})
154+
);
155+
187156
for (const code in category) {
188157
const { messages } = category[code];
189158
/** @type {string[]} */
@@ -273,41 +242,6 @@ function run() {
273242
}
274243

275244
const clone = walk(/** @type {import('estree').Node} */ (template_node), null, {
276-
// @ts-expect-error Block is a block comment, which is not recognised
277-
Block(node, context) {
278-
if (!node.value.includes('PARAMETER')) return;
279-
280-
const value = /** @type {string} */ (node.value)
281-
.split('\n')
282-
.map((line) => {
283-
if (line === ' * MESSAGE') {
284-
return messages[messages.length - 1]
285-
.split('\n')
286-
.map((line) => ` * ${line}`)
287-
.join('\n');
288-
}
289-
290-
if (line.includes('PARAMETER')) {
291-
return vars
292-
.map((name, i) => {
293-
const optional = i >= group[0].vars.length;
294-
295-
return optional
296-
? ` * @param {string | undefined | null} [${name}]`
297-
: ` * @param {string} ${name}`;
298-
})
299-
.join('\n');
300-
}
301-
302-
return line;
303-
})
304-
.filter((x) => x !== '')
305-
.join('\n');
306-
307-
if (value !== node.value) {
308-
return { ...node, value };
309-
}
310-
},
311245
FunctionDeclaration(node, context) {
312246
if (node.id.name !== 'CODE') return;
313247

@@ -394,16 +328,49 @@ function run() {
394328
}
395329
});
396330

331+
const jsdoc_clone = {
332+
...jsdoc,
333+
value: /** @type {string} */ (jsdoc.value)
334+
.split('\n')
335+
.map((line) => {
336+
if (line === ' * MESSAGE') {
337+
return messages[messages.length - 1]
338+
.split('\n')
339+
.map((line) => ` * ${line}`)
340+
.join('\n');
341+
}
342+
343+
if (line.includes('PARAMETER')) {
344+
return vars
345+
.map((name, i) => {
346+
const optional = i >= group[0].vars.length;
347+
348+
return optional
349+
? ` * @param {string | undefined | null} [${name}]`
350+
: ` * @param {string} ${name}`;
351+
})
352+
.join('\n');
353+
}
354+
355+
return line;
356+
})
357+
.filter((x) => x !== '')
358+
.join('\n')
359+
};
360+
361+
// @ts-expect-error
362+
const block = esrap.print({ ...ast, body: [clone] }, ts({ comments: [jsdoc_clone] })).code;
363+
364+
printed.code += `\n\n${block}`;
365+
397366
// @ts-expect-error
398367
ast.body.push(clone);
399368
}
400369

401-
const module = esrap.print(ast);
402-
403370
fs.writeFileSync(
404371
dest,
405372
`/* This file is generated by scripts/process-messages/index.js. Do not edit! */\n\n` +
406-
module.code,
373+
printed.code,
407374
'utf-8'
408375
);
409376
}

packages/svelte/src/compiler/errors.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,25 @@ import { CompileDiagnostic } from './utils/compile_diagnostic.js';
44

55
/** @typedef {{ start?: number, end?: number }} NodeLike */
66
class InternalCompileError extends Error {
7-
message = ''; // ensure this property is enumerable
7+
message = '';
8+
9+
// ensure this property is enumerable
810
#diagnostic;
911

1012
/**
11-
* @param {string} code
12-
* @param {string} message
13-
* @param {[number, number] | undefined} position
14-
*/
13+
* @param {string} code
14+
* @param {string} message
15+
* @param {[number, number] | undefined} position
16+
*/
1517
constructor(code, message, position) {
1618
super(message);
1719
this.stack = ''; // avoid unnecessary noise; don't set it as a class property or it becomes enumerable
20+
1821
// We want to extend from Error so that various bundler plugins properly handle it.
1922
// But we also want to share the same object shape with that of warnings, therefore
2023
// we create an instance of the shared class an copy over its properties.
2124
this.#diagnostic = new CompileDiagnostic(code, message, position);
25+
2226
Object.assign(this, this.#diagnostic);
2327
this.name = 'CompileError';
2428
}
@@ -816,7 +820,9 @@ export function bind_invalid_expression(node) {
816820
* @returns {never}
817821
*/
818822
export function bind_invalid_name(node, name, explanation) {
819-
e(node, 'bind_invalid_name', `${explanation ? `\`bind:${name}\` is not a valid binding. ${explanation}` : `\`bind:${name}\` is not a valid binding`}\nhttps://svelte.dev/e/bind_invalid_name`);
823+
e(node, 'bind_invalid_name', `${explanation
824+
? `\`bind:${name}\` is not a valid binding. ${explanation}`
825+
: `\`bind:${name}\` is not a valid binding`}\nhttps://svelte.dev/e/bind_invalid_name`);
820826
}
821827

822828
/**

packages/svelte/src/compiler/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { transform_component, transform_module } from './phases/3-transform/inde
1111
import { validate_component_options, validate_module_options } from './validate-options.js';
1212
import * as state from './state.js';
1313
export { default as preprocess } from './preprocess/index.js';
14+
export { print } from './print/index.js';
1415

1516
/**
1617
* `compile` converts your `.svelte` source code into a JavaScript module that exports a component

packages/svelte/src/compiler/legacy.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ export function convert(source, ast) {
451451
SpreadAttribute(node) {
452452
return { ...node, type: 'Spread' };
453453
},
454+
// @ts-ignore
454455
StyleSheet(node, context) {
455456
return {
456457
...node,

packages/svelte/src/compiler/phases/3-transform/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/** @import { ValidatedCompileOptions, CompileResult, ValidatedModuleCompileOptions } from '#compiler' */
22
/** @import { ComponentAnalysis, Analysis } from '../types' */
33
import { print } from 'esrap';
4+
import ts from 'esrap/languages/ts';
45
import { VERSION } from '../../../version.js';
56
import { server_component, server_module } from './server/transform-server.js';
67
import { client_component, client_module } from './client/transform-client.js';
@@ -34,7 +35,8 @@ export function transform_component(analysis, source, options) {
3435

3536
const js_source_name = get_source_name(options.filename, options.outputFilename, 'input.svelte');
3637

37-
const js = print(program, {
38+
// @ts-ignore TODO
39+
const js = print(program, ts(), {
3840
// include source content; makes it easier/more robust looking up the source map code
3941
// (else esrap does return null for source and sourceMapContent which may trip up tooling)
4042
sourceMapContent: source,
@@ -94,7 +96,8 @@ export function transform_module(analysis, source, options) {
9496
}
9597

9698
return {
97-
js: print(program, {
99+
// @ts-expect-error
100+
js: print(program, ts(), {
98101
// include source content; makes it easier/more robust looking up the source map code
99102
// (else esrap does return null for source and sourceMapContent which may trip up tooling)
100103
sourceMapContent: source,

0 commit comments

Comments
 (0)