ripple 0.2.180 → 0.2.183

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.
@@ -1,6 +1,5 @@
1
- /** @import { ClassDeclaration, Expression, FunctionDeclaration, FunctionExpression, Identifier, ImportDeclaration, MemberExpression, LogicalOperator, Node, Pattern, UnaryOperator, VariableDeclarator, Super } from 'estree' */
2
- /** @import { DeclarationKind, BindingKind, Component, Element } from '#compiler' */
3
- /** @import { RippleNode } from '#compiler' */
1
+ /** @import { Binding, ScopeInterface, ScopeRoot as ScopeRootInterface } from '#compiler' */
2
+ /** @import * as AST from 'estree' */
4
3
 
5
4
  import is_reference from 'is-reference';
6
5
  import { extract_identifiers, object, unwrap_pattern } from '../utils/ast.js';
@@ -8,79 +7,32 @@ import { walk } from 'zimmerframe';
8
7
  import { is_reserved } from './utils.js';
9
8
  import * as b from '../utils/builders.js';
10
9
 
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
10
  /**
59
11
  * Create scopes for an AST
60
- * @param {Node} ast - The AST to create scopes for
61
- * @param {ScopeRoot} root - Root scope manager
62
- * @param {Scope | null} parent - Parent scope
63
- * @returns {{ scope: Scope, scopes: Map<RippleNode, Scope> }} Scope information
12
+ * @param {AST.Node} ast - The AST to create scopes for
13
+ * @param {ScopeRootInterface} root - Root scope manager
14
+ * @param {ScopeInterface | null} parent - Parent scope
15
+ * @returns {{ scope: ScopeInterface, scopes: Map<AST.Node, ScopeInterface> }} Scope information
64
16
  */
65
17
  export function create_scopes(ast, root, parent) {
66
- /** @typedef {{ scope: Scope }} State */
18
+ /** @typedef {{ scope: ScopeInterface }} State */
67
19
 
68
- /** @type {Map<RippleNode, Scope>} */
20
+ /** @type {Map<AST.Node, ScopeInterface>} */
69
21
  const scopes = new Map();
70
22
  const scope = new Scope(root, parent, false);
71
23
  scopes.set(ast, scope);
72
24
 
73
25
  /** @type {State} */
74
26
  const state = { scope };
75
- /** @type {Array<[Scope, { node: Identifier, path: RippleNode[] }]>} */
27
+ /** @type {Array<[ScopeInterface, { node: AST.Identifier, path: AST.Node[] }]>} */
76
28
  const references = [];
77
- /** @type {Array<[Scope, Pattern | MemberExpression]>} */
29
+ /** @type {Array<[ScopeInterface, AST.Pattern | AST.MemberExpression]>} */
78
30
  const updates = [];
79
31
 
80
32
  /**
81
33
  * Add parameters to scope
82
- * @param {Scope} scope - The scope to add parameters to
83
- * @param {Pattern[]} params - Parameter nodes
34
+ * @param {ScopeInterface} scope - The scope to add parameters to
35
+ * @param {AST.Pattern[]} params - Parameter nodes
84
36
  */
85
37
  function add_params(scope, params) {
86
38
  for (const param of params) {
@@ -92,7 +44,7 @@ export function create_scopes(ast, root, parent) {
92
44
 
93
45
  /**
94
46
  * Create a block scope
95
- * @param {any} node - AST node
47
+ * @param {AST.Node} node - AST node
96
48
  * @param {{ state: any, next: Function }} context - Visitor context
97
49
  */
98
50
  const create_block_scope = (node, { state, next }) => {
@@ -108,13 +60,13 @@ export function create_scopes(ast, root, parent) {
108
60
  next({ scope });
109
61
  };
110
62
 
111
- walk(/** @type {RippleNode} */ (ast), state, {
63
+ walk(/** @type {AST.Node} */ (ast), state, {
112
64
  // references
113
65
  Identifier(node, { path, state }) {
114
66
  const parent = path.at(-1);
115
67
  if (
116
68
  parent &&
117
- is_reference(node, /** @type {Node} */ (parent)) &&
69
+ is_reference(node, /** @type {AST.Node} */ (parent)) &&
118
70
  // TSTypeAnnotation, TSInterfaceDeclaration etc - these are normally already filtered out,
119
71
  // but for the migration they aren't, so we need to filter them out here
120
72
  // TODO -> once migration script is gone we can remove this check
@@ -130,7 +82,10 @@ export function create_scopes(ast, root, parent) {
130
82
  },
131
83
 
132
84
  UpdateExpression(node, { state, next }) {
133
- updates.push([state.scope, /** @type {Identifier | MemberExpression} */ (node.argument)]);
85
+ updates.push([
86
+ state.scope,
87
+ /** @type {AST.Identifier | AST.MemberExpression} */ (node.argument),
88
+ ]);
134
89
  next();
135
90
  },
136
91
 
@@ -141,7 +96,7 @@ export function create_scopes(ast, root, parent) {
141
96
  },
142
97
 
143
98
  /**
144
- * @param {Component} node
99
+ * @param {AST.Component} node
145
100
  * @param {Object} context
146
101
  * @param {any} context.state
147
102
  * @param {Function} context.next
@@ -160,7 +115,7 @@ export function create_scopes(ast, root, parent) {
160
115
  },
161
116
 
162
117
  /**
163
- * @param {Element} node
118
+ * @param {AST.Element} node
164
119
  * @param {Object} context
165
120
  * @param {any} context.state
166
121
  * @param {Function} context.next
@@ -290,13 +245,14 @@ export function create_scopes(ast, root, parent) {
290
245
  };
291
246
  }
292
247
 
248
+ /** @implements {ScopeInterface} */
293
249
  export class Scope {
294
- /** @type {ScopeRoot} */
250
+ /** @type {ScopeRootInterface} */
295
251
  root;
296
252
 
297
253
  /**
298
254
  * The immediate parent scope
299
- * @type {Scope | null}
255
+ * @type {ScopeInterface['parent']}
300
256
  */
301
257
  parent;
302
258
 
@@ -309,45 +265,46 @@ export class Scope {
309
265
  /**
310
266
  * A map of every identifier declared by this scope, and all the
311
267
  * identifiers that reference it
312
- * @type {Map<string, Binding>}
268
+ * @type {ScopeInterface['declarations']}
313
269
  */
314
270
  declarations = new Map();
315
271
 
316
272
  /**
317
273
  * A map of declarators to the bindings they declare
318
- * @type {Map<VariableDeclarator, Binding[]>}
274
+ * @type {ScopeInterface['declarators']}
319
275
  */
320
276
  declarators = new Map();
321
277
 
322
278
  /**
323
279
  * A set of all the names referenced with this scope
324
280
  * — useful for generating unique names
325
- * @type {Map<string, { node: Identifier; path: RippleNode[] }[]>}
281
+ * @type {ScopeInterface['references']}
326
282
  */
327
283
  references = new Map();
328
284
 
329
285
  /**
330
286
  * The scope depth allows us to determine if a state variable is referenced in its own scope,
331
287
  * which is usually an error. Block statements do not increase this value
288
+ * @type {ScopeInterface['function_depth']}
332
289
  */
333
290
  function_depth = 0;
334
291
 
335
292
  /**
336
293
  * If tracing of reactive dependencies is enabled for this scope
337
- * @type {null | Expression}
294
+ * @type {ScopeInterface['tracing']}
338
295
  */
339
296
  tracing = null;
340
297
 
341
298
  /**
342
299
  * Is this scope a top-level server block scope
343
- * @type {boolean}
300
+ * @type {ScopeInterface['server_block']}
344
301
  */
345
302
  server_block = false;
346
303
 
347
304
  /**
348
305
  *
349
- * @param {ScopeRoot} root
350
- * @param {Scope | null} parent
306
+ * @param {ScopeRootInterface} root
307
+ * @param {ScopeInterface | null} parent
351
308
  * @param {boolean} porous
352
309
  */
353
310
  constructor(root, parent, porous) {
@@ -358,11 +315,7 @@ export class Scope {
358
315
  }
359
316
 
360
317
  /**
361
- * @param {Identifier} node
362
- * @param {Binding['kind']} kind
363
- * @param {DeclarationKind} declaration_kind
364
- * @param {null | Expression | FunctionDeclaration | ClassDeclaration | ImportDeclaration} initial
365
- * @returns {Binding}
318
+ * @type {ScopeInterface['declare']}
366
319
  */
367
320
  declare(node, kind, declaration_kind, initial = null) {
368
321
  if (this.parent) {
@@ -403,17 +356,19 @@ export class Scope {
403
356
  return binding;
404
357
  }
405
358
 
359
+ /**
360
+ * @type {ScopeInterface['child']}
361
+ */
406
362
  child(porous = false) {
407
363
  return new Scope(this.root, this, porous);
408
364
  }
409
365
 
410
366
  /**
411
- * @param {string} preferred_name
412
- * @returns {string}
367
+ * @type {ScopeInterface['generate']}
413
368
  */
414
369
  generate(preferred_name) {
415
370
  if (this.#porous) {
416
- return /** @type {Scope} */ (this.parent).generate(preferred_name);
371
+ return /** @type {ScopeInterface} */ (this.parent).generate(preferred_name);
417
372
  }
418
373
 
419
374
  preferred_name = preferred_name.replace(/[^a-zA-Z0-9_$]/g, '_').replace(/^[0-9]/, '_');
@@ -435,16 +390,14 @@ export class Scope {
435
390
  }
436
391
 
437
392
  /**
438
- * @param {string} name
439
- * @returns {Binding | null}
393
+ * @type {ScopeInterface['get']}
440
394
  */
441
395
  get(name) {
442
396
  return this.declarations.get(name) ?? this.parent?.get(name) ?? null;
443
397
  }
444
398
 
445
399
  /**
446
- * @param {VariableDeclarator} node
447
- * @returns {Binding[]}
400
+ * @type {ScopeInterface['get_bindings']}
448
401
  */
449
402
  get_bindings(node) {
450
403
  const bindings = this.declarators.get(node);
@@ -455,16 +408,14 @@ export class Scope {
455
408
  }
456
409
 
457
410
  /**
458
- * @param {string} name
459
- * @returns {Scope | null}
411
+ * @type {ScopeInterface['owner']}
460
412
  */
461
413
  owner(name) {
462
414
  return this.declarations.has(name) ? this : this.parent && this.parent.owner(name);
463
415
  }
464
416
 
465
417
  /**
466
- * @param {Identifier} node
467
- * @param {RippleNode[]} path
418
+ * @type {ScopeInterface['reference']}
468
419
  */
469
420
  reference(node, path) {
470
421
  path = [...path]; // ensure that mutations to path afterwards don't affect this reference
@@ -487,12 +438,13 @@ export class Scope {
487
438
  }
488
439
  }
489
440
 
441
+ /** @implements {ScopeRootInterface} */
490
442
  export class ScopeRoot {
491
- /** @type {Set<string>} */
443
+ /** @type {ScopeRootInterface['conflicts']} */
492
444
  conflicts = new Set();
493
445
 
494
446
  /**
495
- * @param {string} preferred_name
447
+ * @type {ScopeRootInterface['unique']}
496
448
  */
497
449
  unique(preferred_name) {
498
450
  preferred_name = preferred_name.replace(/[^a-zA-Z0-9_$]/g, '_');