@scriptc/compiler 0.0.32 → 0.0.34

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.
Files changed (120) hide show
  1. package/dist/backend/cc-cache.test.js +430 -1
  2. package/dist/backend/cc-cache.test.js.map +1 -1
  3. package/dist/backend/cc.d.ts +25 -0
  4. package/dist/backend/cc.js +818 -88
  5. package/dist/backend/cc.js.map +1 -1
  6. package/dist/backend/emission/emit-exprs.js +79 -3
  7. package/dist/backend/emission/emit-exprs.js.map +1 -1
  8. package/dist/backend/emission/emit-shapes.js +37 -4
  9. package/dist/backend/emission/emit-shapes.js.map +1 -1
  10. package/dist/backend/emission/emitter.d.ts +23 -7
  11. package/dist/backend/emission/emitter.js +171 -27
  12. package/dist/backend/emission/emitter.js.map +1 -1
  13. package/dist/backend/emission/may-throw.js +7 -4
  14. package/dist/backend/emission/may-throw.js.map +1 -1
  15. package/dist/backend/ffi-callbacks.d.ts +38 -1
  16. package/dist/backend/ffi-callbacks.js +76 -3
  17. package/dist/backend/ffi-callbacks.js.map +1 -1
  18. package/dist/backend/library-identity.d.ts +22 -0
  19. package/dist/backend/library-identity.js +103 -0
  20. package/dist/backend/library-identity.js.map +1 -0
  21. package/dist/backend/llvm/emitter.d.ts +3 -0
  22. package/dist/backend/llvm/emitter.js +278 -17
  23. package/dist/backend/llvm/emitter.js.map +1 -1
  24. package/dist/backend/llvm/shapes.d.ts +1 -0
  25. package/dist/backend/llvm/shapes.js +25 -1
  26. package/dist/backend/llvm/shapes.js.map +1 -1
  27. package/dist/backend/mangle.d.ts +1 -0
  28. package/dist/backend/mangle.js +3 -0
  29. package/dist/backend/mangle.js.map +1 -1
  30. package/dist/backend/object-localize.d.ts +5 -5
  31. package/dist/backend/object-localize.js +19 -16
  32. package/dist/backend/object-localize.js.map +1 -1
  33. package/dist/backend/object-localize.test.js +37 -13
  34. package/dist/backend/object-localize.test.js.map +1 -1
  35. package/dist/diagnostics/diagnostic.js +2 -0
  36. package/dist/diagnostics/diagnostic.js.map +1 -1
  37. package/dist/ffi/profile.d.ts +17 -5
  38. package/dist/ffi/profile.js +169 -22
  39. package/dist/ffi/profile.js.map +1 -1
  40. package/dist/frontend/input-tracker.d.ts +82 -0
  41. package/dist/frontend/input-tracker.js +380 -0
  42. package/dist/frontend/input-tracker.js.map +1 -0
  43. package/dist/frontend/input-tracker.test.d.ts +1 -0
  44. package/dist/frontend/input-tracker.test.js +137 -0
  45. package/dist/frontend/input-tracker.test.js.map +1 -0
  46. package/dist/frontend/lowering/lower-builtins.js +2 -8
  47. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  48. package/dist/frontend/lowering/lower-calls.d.ts +1 -0
  49. package/dist/frontend/lowering/lower-calls.js +244 -163
  50. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  51. package/dist/frontend/lowering/lower-classes.js +3 -0
  52. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  53. package/dist/frontend/lowering/lower-containers.js +113 -28
  54. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  55. package/dist/frontend/lowering/lower-exprs.js +67 -1
  56. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  57. package/dist/frontend/lowering/lower-inspect.js +45 -26
  58. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  59. package/dist/frontend/lowering/lower-modules.js +1 -1
  60. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  61. package/dist/frontend/lowering/lower-stmts.js +48 -3
  62. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  63. package/dist/frontend/lowering/lowerer.d.ts +79 -29
  64. package/dist/frontend/lowering/lowerer.js +429 -87
  65. package/dist/frontend/lowering/lowerer.js.map +1 -1
  66. package/dist/frontend/npm-static-rewrite.js +25 -26
  67. package/dist/frontend/npm-static-rewrite.js.map +1 -1
  68. package/dist/frontend/npm-static.js +29 -30
  69. package/dist/frontend/npm-static.js.map +1 -1
  70. package/dist/frontend/npm-static.test.d.ts +1 -0
  71. package/dist/frontend/npm-static.test.js +15 -0
  72. package/dist/frontend/npm-static.test.js.map +1 -0
  73. package/dist/frontend/npm.js +5 -17
  74. package/dist/frontend/npm.js.map +1 -1
  75. package/dist/frontend/program.js +2 -6
  76. package/dist/frontend/program.js.map +1 -1
  77. package/dist/frontend/resolve.js +8 -29
  78. package/dist/frontend/resolve.js.map +1 -1
  79. package/dist/frontend/ts7/checker.d.ts +2 -0
  80. package/dist/frontend/ts7/checker.js +20 -3
  81. package/dist/frontend/ts7/checker.js.map +1 -1
  82. package/dist/frontend/ts7/program.js +17 -18
  83. package/dist/frontend/ts7/program.js.map +1 -1
  84. package/dist/frontend/types.d.ts +41 -0
  85. package/dist/frontend/types.js +147 -8
  86. package/dist/frontend/types.js.map +1 -1
  87. package/dist/index.d.ts +1 -1
  88. package/dist/index.js +275 -41
  89. package/dist/index.js.map +1 -1
  90. package/dist/ir/nodes.d.ts +42 -12
  91. package/dist/ir/nodes.js +7 -1
  92. package/dist/ir/nodes.js.map +1 -1
  93. package/dist/ir/serialize.d.ts +1 -1
  94. package/dist/ir/serialize.js +1 -1
  95. package/dist/ir/validate.js +104 -1
  96. package/dist/ir/validate.js.map +1 -1
  97. package/dist/library/early-cache.d.ts +65 -0
  98. package/dist/library/early-cache.js +380 -0
  99. package/dist/library/early-cache.js.map +1 -0
  100. package/dist/library/early-cache.test.d.ts +1 -0
  101. package/dist/library/early-cache.test.js +528 -0
  102. package/dist/library/early-cache.test.js.map +1 -0
  103. package/dist/library/int-infer.js +14 -0
  104. package/dist/library/int-infer.js.map +1 -1
  105. package/dist/library/int-infer.test.js +21 -4
  106. package/dist/library/int-infer.test.js.map +1 -1
  107. package/dist/library/profile.d.ts +3 -0
  108. package/dist/library/profile.js +9 -1
  109. package/dist/library/profile.js.map +1 -1
  110. package/dist/library/semantic-source.d.ts +13 -0
  111. package/dist/library/semantic-source.js +257 -0
  112. package/dist/library/semantic-source.js.map +1 -0
  113. package/dist/library/semantic-source.test.d.ts +1 -0
  114. package/dist/library/semantic-source.test.js +113 -0
  115. package/dist/library/semantic-source.test.js.map +1 -0
  116. package/dist/library/sidecar.d.ts +6 -0
  117. package/dist/library/sidecar.js +11 -0
  118. package/dist/library/sidecar.js.map +1 -1
  119. package/package.json +2 -2
  120. package/surface-manifest.json +1 -1
@@ -55,6 +55,20 @@ const PARSE_ARGS_DYN_TYPES = new Set([
55
55
  export function isParseArgsDynTypeName(name) {
56
56
  return PARSE_ARGS_DYN_TYPES.has(name);
57
57
  }
58
+ function priorityRank(priority) {
59
+ return "rank" in priority ? priority.rank : priority;
60
+ }
61
+ function comparePriority(left, right) {
62
+ const a = priorityRank(left);
63
+ const b = priorityRank(right);
64
+ const length = Math.max(a.length, b.length);
65
+ for (let i = 0; i < length; i++) {
66
+ const d = (a[i] ?? 0) - (b[i] ?? 0);
67
+ if (d !== 0)
68
+ return d;
69
+ }
70
+ return 0;
71
+ }
58
72
  /** The frontend's record-shape interner. Records are monomorphic structural
59
73
  * shapes: fields sorted by name form the canonical identity, and two types
60
74
  * with the same canonical field list share one shapeId (and later one C
@@ -63,6 +77,19 @@ export function isParseArgsDynTypeName(name) {
63
77
  export class ShapeRegistry {
64
78
  byKey = new Map();
65
79
  byId = new Map();
80
+ /** Historical emit-order rank of the declaration-order metadata each
81
+ * shape kept. Collection runs at rank 0; retained reachability bodies
82
+ * install their old emit positions while they lower. This lets a body
83
+ * reached after an init replace metadata the worklist encountered first
84
+ * when the old emitter would have lowered that body first. */
85
+ declaredOrderPriority = new Map();
86
+ declaredOrderCandidates = new Map();
87
+ /** Derived shapes whose order is inherited from another shape. The
88
+ * source can settle after the derived shape was interned (notably
89
+ * Partial<T> inside a retained generic body), so refresh the adopted
90
+ * writer after all priority candidates have closed. */
91
+ derivedDeclaredOrderFinalizers = [];
92
+ currentDeclaredOrderPriority = [0, 0];
66
93
  /** All interned shapes in first-seen (`r0`, `r1`, ...) order. */
67
94
  shapes = [];
68
95
  /** ts.Types currently being mapped — a BACK-REFERENCE to one of these is
@@ -94,6 +121,77 @@ export class ShapeRegistry {
94
121
  (indexValue ? `idx<${typeKey(indexValue)}>!` : "") +
95
122
  JSON.stringify(fields.map((f) => [f.name, typeKey(f.type)])));
96
123
  }
124
+ /** Runs one lowering unit under its historical emit-order rank. Shape
125
+ * ids remain demand-assigned; only first-seen declaration-order metadata
126
+ * uses this rank, because Object.keys/JSON/inspect observe it. */
127
+ withDeclaredOrderPriority(priority, fn) {
128
+ const previous = this.currentDeclaredOrderPriority;
129
+ this.currentDeclaredOrderPriority = priority;
130
+ try {
131
+ return fn();
132
+ }
133
+ finally {
134
+ this.currentDeclaredOrderPriority = previous;
135
+ }
136
+ }
137
+ adoptDeclaredOrder(shape, declaredOrder) {
138
+ if (declaredOrder === undefined)
139
+ return;
140
+ const candidates = this.declaredOrderCandidates.get(shape.id);
141
+ const candidate = { order: declaredOrder, priority: this.currentDeclaredOrderPriority };
142
+ if (candidates)
143
+ candidates.push(candidate);
144
+ else
145
+ this.declaredOrderCandidates.set(shape.id, [candidate]);
146
+ const previous = this.declaredOrderPriority.get(shape.id);
147
+ if (previous !== undefined && comparePriority(previous, this.currentDeclaredOrderPriority) <= 0) {
148
+ return;
149
+ }
150
+ shape.declaredOrder = declaredOrder;
151
+ this.declaredOrderPriority.set(shape.id, this.currentDeclaredOrderPriority);
152
+ }
153
+ /** Mutable generic-instance ranks settle only after reachability closes.
154
+ * Re-choose each shape's first historical writer from the retained
155
+ * candidates before derived metadata and helper bodies finalize. */
156
+ settleDeclaredOrderPriorities() {
157
+ for (const [shapeId, candidates] of this.declaredOrderCandidates) {
158
+ let best = candidates[0];
159
+ if (!best)
160
+ continue;
161
+ for (const candidate of candidates.slice(1)) {
162
+ if (comparePriority(candidate.priority, best.priority) < 0)
163
+ best = candidate;
164
+ }
165
+ const shape = this.byId.get(shapeId);
166
+ if (!shape)
167
+ continue;
168
+ shape.declaredOrder = best.order;
169
+ this.declaredOrderPriority.set(shapeId, best.priority);
170
+ }
171
+ for (const finalize of this.derivedDeclaredOrderFinalizers)
172
+ finalize();
173
+ }
174
+ /** Tracks a derived shape that inherits its key order unchanged from a
175
+ * source shape. Identity-gating preserves first-writer-wins when an
176
+ * equivalent derived shape was already adopted from another source. */
177
+ inheritDeclaredOrder(shapeId, originalOrder, sourceShapeId) {
178
+ this.derivedDeclaredOrderFinalizers.push(this.declaredOrderFinalizer(shapeId, originalOrder, () => this.get(sourceShapeId)?.declaredOrder));
179
+ }
180
+ /** Captures the current historical rank for a derived shape whose order
181
+ * must be recomputed after retained reachability settles its source. */
182
+ declaredOrderFinalizer(shapeId, originalOrder, order) {
183
+ return () => {
184
+ const shape = this.byId.get(shapeId);
185
+ // Only the writer whose array the shape actually adopted may revise
186
+ // it. Another structurally-equal type at the same historical rank
187
+ // still obeys first-writer-wins.
188
+ if (shape?.declaredOrder !== originalOrder)
189
+ return;
190
+ const next = order();
191
+ if (next !== undefined)
192
+ shape.declaredOrder = next;
193
+ };
194
+ }
97
195
  /** The shape id a back-reference to an in-progress type resolves to:
98
196
  * reuses the type's persistent recursive id or mints a PLACEHOLDER
99
197
  * entry (empty fields) the outer frame finalizes. */
@@ -134,8 +232,7 @@ export class ShapeRegistry {
134
232
  shape.fields = fields;
135
233
  if (indexValue)
136
234
  shape.indexValue = indexValue;
137
- if (declaredOrder)
138
- shape.declaredOrder = declaredOrder;
235
+ this.adoptDeclaredOrder(shape, declaredOrder);
139
236
  this.pendingRec.delete(id);
140
237
  const key = this.keyOf(fields, false, indexValue);
141
238
  if (!this.byKey.has(key))
@@ -169,6 +266,15 @@ export class ShapeRegistry {
169
266
  this.byKey.set(key, id);
170
267
  this.byId.set(id, shape);
171
268
  this.shapes.push(shape);
269
+ if (declaredOrder !== undefined) {
270
+ this.declaredOrderCandidates.set(id, [
271
+ { order: declaredOrder, priority: this.currentDeclaredOrderPriority },
272
+ ]);
273
+ this.declaredOrderPriority.set(id, this.currentDeclaredOrderPriority);
274
+ }
275
+ }
276
+ else {
277
+ this.adoptDeclaredOrder(this.byId.get(id), declaredOrder);
172
278
  }
173
279
  return id;
174
280
  }
@@ -565,9 +671,11 @@ function genChannels(yieldTs, retTs, nextTs, ctx) {
565
671
  * fallback for it. */
566
672
  const MAP_TYPE_MAX_DEPTH = 64;
567
673
  let mapTypeDepth = 0;
568
- /** Bumped whenever mapType resolves a type through CONTEXT-SENSITIVE hooks
569
- * (a generic body's type parameter, a mixin instantiation) — mappings that
570
- * make the same ts.Type answer differently across instantiation contexts.
674
+ /** Bumped whenever mapType resolves a type through CONTEXT-SENSITIVE or
675
+ * collection-sensitive hooks (a generic body's type parameter, a mixin
676
+ * instantiation, a generic class instance) — mappings that can make the same
677
+ * ts.Type answer differently across instantiation contexts or collection
678
+ * phases.
571
679
  * The recursive-shape machinery keys shape identity by checker type, which
572
680
  * is sound only for context-FREE mappings: a recursive frame that observes
573
681
  * a bump between entry and exit stays fenced (recursive generic-open types
@@ -576,9 +684,27 @@ let contextResolutions = 0;
576
684
  export function mapType(type, ctx) {
577
685
  if (mapTypeDepth >= MAP_TYPE_MAX_DEPTH)
578
686
  return null;
687
+ const topLevel = mapTypeDepth === 0;
688
+ const typeId = type.id;
689
+ const memoizable = typeId !== undefined && (ctx.canMemoizeType?.() ?? true);
690
+ const memoKey = memoizable ? `${ctx.dynamic ? 1 : 0}:${typeId}` : null;
691
+ if (memoKey !== null) {
692
+ const memo = ctx.typeMemo?.get(memoKey);
693
+ if (memo !== undefined)
694
+ return memo;
695
+ }
696
+ const sensitivityAtEntry = contextResolutions;
579
697
  mapTypeDepth++;
580
698
  try {
581
- return mapTypeInner(type, ctx);
699
+ const mapped = mapTypeInner(type, ctx);
700
+ if (mapped !== null &&
701
+ memoKey !== null &&
702
+ topLevel &&
703
+ contextResolutions === sensitivityAtEntry &&
704
+ (ctx.canMemoizeType?.() ?? true)) {
705
+ ctx.typeMemo?.set(memoKey, mapped);
706
+ }
707
+ return mapped;
582
708
  }
583
709
  finally {
584
710
  mapTypeDepth--;
@@ -1054,7 +1180,15 @@ function mapTypeInner(type, ctx) {
1054
1180
  // INSTANTIATION's class (`Box%0`), registered on demand — the Lowerer
1055
1181
  // hook owns the instance table (monomorphization by flow).
1056
1182
  if (classDecl.typeParameters) {
1057
- return ctx.genericClassInstance ? ctx.genericClassInstance(classDecl, widened) : null;
1183
+ const instance = ctx.genericClassInstance
1184
+ ? ctx.genericClassInstance(classDecl, widened)
1185
+ : null;
1186
+ // Before the generic declaration's collection turn, the hook can only
1187
+ // return its family shell; after collection the same checker type names
1188
+ // a concrete registered instance. Never memoize either phase's answer.
1189
+ if (instance !== null)
1190
+ contextResolutions++;
1191
+ return instance;
1058
1192
  }
1059
1193
  return { kind: "object", className: classNamer(classDecl) };
1060
1194
  }
@@ -2541,7 +2675,12 @@ function mapGenericUtilityAlias(widened, ctx) {
2541
2675
  }
2542
2676
  // Fields inherit the source shape's canonical (name-sorted) order — and
2543
2677
  // its declaration order (mapped types preserve property order in TS).
2544
- return { kind: "record", shapeId: shapes.intern(fields, false, undefined, shape.declaredOrder) };
2678
+ const originalOrder = shape.declaredOrder;
2679
+ const shapeId = shapes.intern(fields, false, undefined, originalOrder);
2680
+ if (originalOrder !== undefined) {
2681
+ shapes.inheritDeclaredOrder(shapeId, originalOrder, bound.shapeId);
2682
+ }
2683
+ return { kind: "record", shapeId };
2545
2684
  }
2546
2685
  /** The UNIT-ONLY slot type: the interned `null | undefined` union, the one
2547
2686
  * representation the IR already has for values that are nothing but units.