ripple 0.2.182 → 0.2.184
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -2
- package/src/compiler/errors.js +3 -1
- package/src/compiler/index.d.ts +2 -1
- package/src/compiler/phases/1-parse/index.js +525 -311
- package/src/compiler/phases/1-parse/style.js +3 -1
- package/src/compiler/phases/2-analyze/css-analyze.js +116 -97
- package/src/compiler/phases/2-analyze/index.js +81 -51
- package/src/compiler/phases/2-analyze/prune.js +200 -58
- package/src/compiler/phases/2-analyze/validation.js +9 -7
- package/src/compiler/phases/3-transform/client/index.js +871 -394
- package/src/compiler/phases/3-transform/segments.js +99 -53
- package/src/compiler/phases/3-transform/server/index.js +278 -121
- package/src/compiler/scope.js +51 -104
- package/src/compiler/types/index.d.ts +834 -197
- package/src/compiler/types/parse.d.ts +1668 -0
- package/src/compiler/utils.js +62 -74
- package/src/utils/ast.js +247 -192
- package/src/utils/builders.js +309 -247
- package/src/utils/sanitize_template_string.js +2 -2
package/src/compiler/scope.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
@import {
|
|
3
|
+
Binding,
|
|
4
|
+
ScopeInterface,
|
|
5
|
+
ScopeRoot as ScopeRootInterface,
|
|
6
|
+
Context
|
|
7
|
+
} from '#compiler';
|
|
8
|
+
@import * as AST from 'estree';
|
|
9
|
+
*/
|
|
4
10
|
|
|
5
11
|
import is_reference from 'is-reference';
|
|
6
12
|
import { extract_identifiers, object, unwrap_pattern } from '../utils/ast.js';
|
|
@@ -8,79 +14,32 @@ import { walk } from 'zimmerframe';
|
|
|
8
14
|
import { is_reserved } from './utils.js';
|
|
9
15
|
import * as b from '../utils/builders.js';
|
|
10
16
|
|
|
11
|
-
export class Binding {
|
|
12
|
-
/** @type {Scope} */
|
|
13
|
-
scope;
|
|
14
|
-
|
|
15
|
-
/** @type {Identifier} */
|
|
16
|
-
node;
|
|
17
|
-
|
|
18
|
-
/** @type {BindingKind} */
|
|
19
|
-
kind;
|
|
20
|
-
|
|
21
|
-
/** @type {DeclarationKind} */
|
|
22
|
-
declaration_kind;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* What the value was initialized with
|
|
26
|
-
* @type {null | Expression | FunctionDeclaration | ClassDeclaration | ImportDeclaration}
|
|
27
|
-
*/
|
|
28
|
-
initial = null;
|
|
29
|
-
|
|
30
|
-
/** @type {Array<{ node: Identifier; path: RippleNode[] }>} */
|
|
31
|
-
references = [];
|
|
32
|
-
|
|
33
|
-
mutated = false;
|
|
34
|
-
reassigned = false;
|
|
35
|
-
is_called = false;
|
|
36
|
-
metadata = null;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* @param {Scope} scope
|
|
40
|
-
* @param {Identifier} node
|
|
41
|
-
* @param {BindingKind} kind
|
|
42
|
-
* @param {DeclarationKind} declaration_kind
|
|
43
|
-
* @param {Binding['initial']} initial
|
|
44
|
-
*/
|
|
45
|
-
constructor(scope, node, kind, declaration_kind, initial) {
|
|
46
|
-
this.scope = scope;
|
|
47
|
-
this.node = node;
|
|
48
|
-
this.initial = initial;
|
|
49
|
-
this.kind = kind;
|
|
50
|
-
this.declaration_kind = declaration_kind;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
get updated() {
|
|
54
|
-
return this.mutated || this.reassigned;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
17
|
/**
|
|
59
18
|
* Create scopes for an AST
|
|
60
|
-
* @param {Node} ast - The AST to create scopes for
|
|
61
|
-
* @param {
|
|
62
|
-
* @param {
|
|
63
|
-
* @returns {{ scope:
|
|
19
|
+
* @param {AST.Node} ast - The AST to create scopes for
|
|
20
|
+
* @param {ScopeRootInterface} root - Root scope manager
|
|
21
|
+
* @param {ScopeInterface | null} parent - Parent scope
|
|
22
|
+
* @returns {{ scope: ScopeInterface, scopes: Map<AST.Node, ScopeInterface> }} Scope information
|
|
64
23
|
*/
|
|
65
24
|
export function create_scopes(ast, root, parent) {
|
|
66
|
-
/** @typedef {{ scope:
|
|
25
|
+
/** @typedef {{ scope: ScopeInterface }} State */
|
|
67
26
|
|
|
68
|
-
/** @type {Map<
|
|
27
|
+
/** @type {Map<AST.Node, ScopeInterface>} */
|
|
69
28
|
const scopes = new Map();
|
|
70
29
|
const scope = new Scope(root, parent, false);
|
|
71
30
|
scopes.set(ast, scope);
|
|
72
31
|
|
|
73
32
|
/** @type {State} */
|
|
74
33
|
const state = { scope };
|
|
75
|
-
/** @type {Array<[
|
|
34
|
+
/** @type {Array<[ScopeInterface, { node: AST.Identifier, path: AST.Node[] }]>} */
|
|
76
35
|
const references = [];
|
|
77
|
-
/** @type {Array<[
|
|
36
|
+
/** @type {Array<[ScopeInterface, AST.Pattern | AST.MemberExpression]>} */
|
|
78
37
|
const updates = [];
|
|
79
38
|
|
|
80
39
|
/**
|
|
81
40
|
* Add parameters to scope
|
|
82
|
-
* @param {
|
|
83
|
-
* @param {Pattern[]} params - Parameter nodes
|
|
41
|
+
* @param {ScopeInterface} scope - The scope to add parameters to
|
|
42
|
+
* @param {AST.Pattern[]} params - Parameter nodes
|
|
84
43
|
*/
|
|
85
44
|
function add_params(scope, params) {
|
|
86
45
|
for (const param of params) {
|
|
@@ -92,8 +51,8 @@ export function create_scopes(ast, root, parent) {
|
|
|
92
51
|
|
|
93
52
|
/**
|
|
94
53
|
* Create a block scope
|
|
95
|
-
* @param {
|
|
96
|
-
* @param {
|
|
54
|
+
* @param {AST.Node} node - AST node
|
|
55
|
+
* @param {Context<AST.Node, State>} context - Visitor context
|
|
97
56
|
*/
|
|
98
57
|
const create_block_scope = (node, { state, next }) => {
|
|
99
58
|
const scope = state.scope.child(true);
|
|
@@ -108,13 +67,13 @@ export function create_scopes(ast, root, parent) {
|
|
|
108
67
|
next({ scope });
|
|
109
68
|
};
|
|
110
69
|
|
|
111
|
-
walk(
|
|
70
|
+
walk(ast, state, {
|
|
112
71
|
// references
|
|
113
72
|
Identifier(node, { path, state }) {
|
|
114
73
|
const parent = path.at(-1);
|
|
115
74
|
if (
|
|
116
75
|
parent &&
|
|
117
|
-
is_reference(node, /** @type {Node} */ (parent)) &&
|
|
76
|
+
is_reference(node, /** @type {AST.Node} */ (parent)) &&
|
|
118
77
|
// TSTypeAnnotation, TSInterfaceDeclaration etc - these are normally already filtered out,
|
|
119
78
|
// but for the migration they aren't, so we need to filter them out here
|
|
120
79
|
// TODO -> once migration script is gone we can remove this check
|
|
@@ -130,7 +89,10 @@ export function create_scopes(ast, root, parent) {
|
|
|
130
89
|
},
|
|
131
90
|
|
|
132
91
|
UpdateExpression(node, { state, next }) {
|
|
133
|
-
updates.push([
|
|
92
|
+
updates.push([
|
|
93
|
+
state.scope,
|
|
94
|
+
/** @type {AST.Identifier | AST.MemberExpression} */ (node.argument),
|
|
95
|
+
]);
|
|
134
96
|
next();
|
|
135
97
|
},
|
|
136
98
|
|
|
@@ -140,12 +102,6 @@ export function create_scopes(ast, root, parent) {
|
|
|
140
102
|
}
|
|
141
103
|
},
|
|
142
104
|
|
|
143
|
-
/**
|
|
144
|
-
* @param {Component} node
|
|
145
|
-
* @param {Object} context
|
|
146
|
-
* @param {any} context.state
|
|
147
|
-
* @param {Function} context.next
|
|
148
|
-
*/
|
|
149
105
|
Component(node, { state, next }) {
|
|
150
106
|
const scope = state.scope.child();
|
|
151
107
|
scopes.set(node, scope);
|
|
@@ -159,12 +115,6 @@ export function create_scopes(ast, root, parent) {
|
|
|
159
115
|
next({ scope });
|
|
160
116
|
},
|
|
161
117
|
|
|
162
|
-
/**
|
|
163
|
-
* @param {Element} node
|
|
164
|
-
* @param {Object} context
|
|
165
|
-
* @param {any} context.state
|
|
166
|
-
* @param {Function} context.next
|
|
167
|
-
*/
|
|
168
118
|
Element(node, { state, next }) {
|
|
169
119
|
const scope = state.scope.child();
|
|
170
120
|
scopes.set(node, scope);
|
|
@@ -290,13 +240,14 @@ export function create_scopes(ast, root, parent) {
|
|
|
290
240
|
};
|
|
291
241
|
}
|
|
292
242
|
|
|
243
|
+
/** @implements {ScopeInterface} */
|
|
293
244
|
export class Scope {
|
|
294
|
-
/** @type {
|
|
245
|
+
/** @type {ScopeRootInterface} */
|
|
295
246
|
root;
|
|
296
247
|
|
|
297
248
|
/**
|
|
298
249
|
* The immediate parent scope
|
|
299
|
-
* @type {
|
|
250
|
+
* @type {ScopeInterface['parent']}
|
|
300
251
|
*/
|
|
301
252
|
parent;
|
|
302
253
|
|
|
@@ -309,45 +260,46 @@ export class Scope {
|
|
|
309
260
|
/**
|
|
310
261
|
* A map of every identifier declared by this scope, and all the
|
|
311
262
|
* identifiers that reference it
|
|
312
|
-
* @type {
|
|
263
|
+
* @type {ScopeInterface['declarations']}
|
|
313
264
|
*/
|
|
314
265
|
declarations = new Map();
|
|
315
266
|
|
|
316
267
|
/**
|
|
317
268
|
* A map of declarators to the bindings they declare
|
|
318
|
-
* @type {
|
|
269
|
+
* @type {ScopeInterface['declarators']}
|
|
319
270
|
*/
|
|
320
271
|
declarators = new Map();
|
|
321
272
|
|
|
322
273
|
/**
|
|
323
274
|
* A set of all the names referenced with this scope
|
|
324
275
|
* — useful for generating unique names
|
|
325
|
-
* @type {
|
|
276
|
+
* @type {ScopeInterface['references']}
|
|
326
277
|
*/
|
|
327
278
|
references = new Map();
|
|
328
279
|
|
|
329
280
|
/**
|
|
330
281
|
* The scope depth allows us to determine if a state variable is referenced in its own scope,
|
|
331
282
|
* which is usually an error. Block statements do not increase this value
|
|
283
|
+
* @type {ScopeInterface['function_depth']}
|
|
332
284
|
*/
|
|
333
285
|
function_depth = 0;
|
|
334
286
|
|
|
335
287
|
/**
|
|
336
288
|
* If tracing of reactive dependencies is enabled for this scope
|
|
337
|
-
* @type {
|
|
289
|
+
* @type {ScopeInterface['tracing']}
|
|
338
290
|
*/
|
|
339
291
|
tracing = null;
|
|
340
292
|
|
|
341
293
|
/**
|
|
342
294
|
* Is this scope a top-level server block scope
|
|
343
|
-
* @type {
|
|
295
|
+
* @type {ScopeInterface['server_block']}
|
|
344
296
|
*/
|
|
345
297
|
server_block = false;
|
|
346
298
|
|
|
347
299
|
/**
|
|
348
300
|
*
|
|
349
|
-
* @param {
|
|
350
|
-
* @param {
|
|
301
|
+
* @param {ScopeRootInterface} root
|
|
302
|
+
* @param {ScopeInterface | null} parent
|
|
351
303
|
* @param {boolean} porous
|
|
352
304
|
*/
|
|
353
305
|
constructor(root, parent, porous) {
|
|
@@ -358,11 +310,7 @@ export class Scope {
|
|
|
358
310
|
}
|
|
359
311
|
|
|
360
312
|
/**
|
|
361
|
-
* @
|
|
362
|
-
* @param {Binding['kind']} kind
|
|
363
|
-
* @param {DeclarationKind} declaration_kind
|
|
364
|
-
* @param {null | Expression | FunctionDeclaration | ClassDeclaration | ImportDeclaration} initial
|
|
365
|
-
* @returns {Binding}
|
|
313
|
+
* @type {ScopeInterface['declare']}
|
|
366
314
|
*/
|
|
367
315
|
declare(node, kind, declaration_kind, initial = null) {
|
|
368
316
|
if (this.parent) {
|
|
@@ -403,17 +351,19 @@ export class Scope {
|
|
|
403
351
|
return binding;
|
|
404
352
|
}
|
|
405
353
|
|
|
354
|
+
/**
|
|
355
|
+
* @type {ScopeInterface['child']}
|
|
356
|
+
*/
|
|
406
357
|
child(porous = false) {
|
|
407
358
|
return new Scope(this.root, this, porous);
|
|
408
359
|
}
|
|
409
360
|
|
|
410
361
|
/**
|
|
411
|
-
* @
|
|
412
|
-
* @returns {string}
|
|
362
|
+
* @type {ScopeInterface['generate']}
|
|
413
363
|
*/
|
|
414
364
|
generate(preferred_name) {
|
|
415
365
|
if (this.#porous) {
|
|
416
|
-
return /** @type {
|
|
366
|
+
return /** @type {ScopeInterface} */ (this.parent).generate(preferred_name);
|
|
417
367
|
}
|
|
418
368
|
|
|
419
369
|
preferred_name = preferred_name.replace(/[^a-zA-Z0-9_$]/g, '_').replace(/^[0-9]/, '_');
|
|
@@ -435,16 +385,14 @@ export class Scope {
|
|
|
435
385
|
}
|
|
436
386
|
|
|
437
387
|
/**
|
|
438
|
-
* @
|
|
439
|
-
* @returns {Binding | null}
|
|
388
|
+
* @type {ScopeInterface['get']}
|
|
440
389
|
*/
|
|
441
390
|
get(name) {
|
|
442
391
|
return this.declarations.get(name) ?? this.parent?.get(name) ?? null;
|
|
443
392
|
}
|
|
444
393
|
|
|
445
394
|
/**
|
|
446
|
-
* @
|
|
447
|
-
* @returns {Binding[]}
|
|
395
|
+
* @type {ScopeInterface['get_bindings']}
|
|
448
396
|
*/
|
|
449
397
|
get_bindings(node) {
|
|
450
398
|
const bindings = this.declarators.get(node);
|
|
@@ -455,16 +403,14 @@ export class Scope {
|
|
|
455
403
|
}
|
|
456
404
|
|
|
457
405
|
/**
|
|
458
|
-
* @
|
|
459
|
-
* @returns {Scope | null}
|
|
406
|
+
* @type {ScopeInterface['owner']}
|
|
460
407
|
*/
|
|
461
408
|
owner(name) {
|
|
462
409
|
return this.declarations.has(name) ? this : this.parent && this.parent.owner(name);
|
|
463
410
|
}
|
|
464
411
|
|
|
465
412
|
/**
|
|
466
|
-
* @
|
|
467
|
-
* @param {RippleNode[]} path
|
|
413
|
+
* @type {ScopeInterface['reference']}
|
|
468
414
|
*/
|
|
469
415
|
reference(node, path) {
|
|
470
416
|
path = [...path]; // ensure that mutations to path afterwards don't affect this reference
|
|
@@ -487,12 +433,13 @@ export class Scope {
|
|
|
487
433
|
}
|
|
488
434
|
}
|
|
489
435
|
|
|
436
|
+
/** @implements {ScopeRootInterface} */
|
|
490
437
|
export class ScopeRoot {
|
|
491
|
-
/** @type {
|
|
438
|
+
/** @type {ScopeRootInterface['conflicts']} */
|
|
492
439
|
conflicts = new Set();
|
|
493
440
|
|
|
494
441
|
/**
|
|
495
|
-
* @
|
|
442
|
+
* @type {ScopeRootInterface['unique']}
|
|
496
443
|
*/
|
|
497
444
|
unique(preferred_name) {
|
|
498
445
|
preferred_name = preferred_name.replace(/[^a-zA-Z0-9_$]/g, '_');
|