@neocompose/cli 0.76.0 → 0.76.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.76.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 80ea491: Instances share a member's declared value whenever it cannot change: the
8
+ member is `readonly` or Immutable, its declaration reads neither `this` nor a
9
+ constructor argument, and nothing in the value is writable. A readonly literal
10
+ is shared under any storage. A readonly initializer or collection is still
11
+ built per instance, since its value is fixed only at construction. An
12
+ Immutable value holding a writable member is no longer shared.
13
+
3
14
  ## 0.76.0
4
15
 
5
16
  ### Minor Changes
package/dist/neo.mjs CHANGED
@@ -5057,6 +5057,9 @@ var init_project_schema_index = __esm({
5057
5057
  for (const schemaClass2 of source.classes) {
5058
5058
  this.classesById.set(schemaClass2.id, schemaClass2);
5059
5059
  append(this.classesByName, schemaClass2.name, schemaClass2);
5060
+ if (schemaClass2.extendsClassId) {
5061
+ append(this.subclassesById, schemaClass2.extendsClassId, schemaClass2);
5062
+ }
5060
5063
  for (const [schemaKey, memberId] of Object.entries(schemaClass2.schema)) {
5061
5064
  append(this.schemaPlacementsByMemberId, memberId, {
5062
5065
  ownerClass: schemaClass2,
@@ -5101,6 +5104,8 @@ var init_project_schema_index = __esm({
5101
5104
  source;
5102
5105
  classesById = /* @__PURE__ */ new Map();
5103
5106
  classesByName = /* @__PURE__ */ new Map();
5107
+ /** Direct subclasses by the class they extend. */
5108
+ subclassesById = /* @__PURE__ */ new Map();
5104
5109
  membersById = /* @__PURE__ */ new Map();
5105
5110
  membersByName = /* @__PURE__ */ new Map();
5106
5111
  enumsById = /* @__PURE__ */ new Map();
@@ -5226,6 +5231,9 @@ function indexSchema(classes, members) {
5226
5231
  function classIndexFor(classes) {
5227
5232
  return indexClasses(classes).classesById;
5228
5233
  }
5234
+ function subclassIndexFor(classes) {
5235
+ return indexClasses(classes).subclassesById;
5236
+ }
5229
5237
  function memberIndexFor(members) {
5230
5238
  return projectSchemaIndexFor({ classes: NO_CLASSES, members }).membersById;
5231
5239
  }
@@ -5445,15 +5453,7 @@ function resolveEffectiveIsVirtual(member, members) {
5445
5453
  return modifier === 0 /* Virtual */ || modifier === 2 /* Abstract */;
5446
5454
  }
5447
5455
  function descendantClassIds(classId, allClasses) {
5448
- const childrenByClassId = /* @__PURE__ */ new Map();
5449
- for (const schemaClass2 of allClasses) {
5450
- if (!schemaClass2.extendsClassId) continue;
5451
- const children = childrenByClassId.get(schemaClass2.extendsClassId);
5452
- if (children === void 0) {
5453
- childrenByClassId.set(schemaClass2.extendsClassId, [schemaClass2]);
5454
- } else children.push(schemaClass2);
5455
- }
5456
- return descendantClassIdsInChildIndex(classId, childrenByClassId);
5456
+ return descendantClassIdsInChildIndex(classId, subclassIndexFor(allClasses));
5457
5457
  }
5458
5458
  function descendantClassIdsInChildIndex(classId, childrenByClassId) {
5459
5459
  const result = /* @__PURE__ */ new Set();
@@ -11311,103 +11311,204 @@ function buildDefaultClassMaterializationPlan(document, classId, instanceEnv) {
11311
11311
  ...document,
11312
11312
  constructors: document.constructors ?? []
11313
11313
  });
11314
- const merged = document.storedInstanceSchema?.(classId) ?? mergeInstanceSurfaceSchema(classId, document.classes, document.members);
11315
- return merged.flatMap((entry) => {
11316
- if (entry.memberId === null) return [];
11317
- const childMember = findMemberInDocument(document, entry.memberId);
11318
- if (!memberKindOwnsStoredValue(childMember.kind)) return [];
11319
- if (instanceEnv.size === 0 && isImmutableConstantMember(
11320
- document,
11321
- document.resolvedMember?.(childMember) ?? resolveMember(childMember, document.members)
11322
- ))
11323
- return [];
11324
- const member = substituteMember(
11325
- childMember,
11326
- instanceEnv,
11327
- document.members,
11328
- document.resolvedMember?.(childMember)
11329
- );
11330
- return [
11331
- {
11332
- schemaKey: entry.schemaKey,
11333
- member,
11334
- defaultSettlesConstruction: settlesConstruction(member, instanceEnv),
11335
- directScalarBody: directScalarDefaultBody(document, member)
11336
- }
11337
- ];
11338
- });
11314
+ return storedSchemaOf(document, classId).flatMap(
11315
+ (entry) => {
11316
+ if (entry.memberId === null) return [];
11317
+ const childMember = findMemberInDocument(document, entry.memberId);
11318
+ if (!memberKindOwnsStoredValue(childMember.kind)) return [];
11319
+ if (instanceEnv.size === 0 && isConstantMember(document, resolvedInDocument(document, childMember)))
11320
+ return [];
11321
+ const member = substituteMember(
11322
+ childMember,
11323
+ instanceEnv,
11324
+ document.members,
11325
+ document.resolvedMember?.(childMember)
11326
+ );
11327
+ return [
11328
+ {
11329
+ schemaKey: entry.schemaKey,
11330
+ member,
11331
+ defaultSettlesConstruction: settlesConstruction(member, instanceEnv),
11332
+ directScalarBody: directScalarDefaultBody(document, member)
11333
+ }
11334
+ ];
11335
+ }
11336
+ );
11339
11337
  }
11340
- function isImmutableConstantMember(document, resolved) {
11341
- if (resolved.storage !== 1 /* Immutable */) return false;
11338
+ function isConstantMember(document, resolved) {
11342
11339
  if (isStaticMember(resolved)) return false;
11340
+ const fixedness = fixednessOf(resolved, 0 /* Writable */);
11341
+ if (fixedness === 0 /* Writable */) return false;
11343
11342
  const declared = resolved.defaultValue;
11344
11343
  if (declared == null) return false;
11345
- return !declarationReadsInstance(
11346
- { document, visited: /* @__PURE__ */ new Set() },
11344
+ if (fixedness === 1 /* ReadOnly */ && (isMemberListBase(resolved) || isMemberDictionaryBase(resolved)))
11345
+ return false;
11346
+ return !declarationVaries(
11347
+ {
11348
+ document,
11349
+ rows: /* @__PURE__ */ new Set(),
11350
+ declarations: /* @__PURE__ */ new Set(),
11351
+ classes: /* @__PURE__ */ new Set()
11352
+ },
11347
11353
  resolved,
11348
11354
  declared,
11349
- null
11355
+ null,
11356
+ { fixedness, ownsReads: true }
11350
11357
  );
11351
11358
  }
11352
- function declarationReadsInstance(walk, member, body, rowId) {
11359
+ function fixednessOf(resolved, parent) {
11360
+ const storage = resolved.storage ?? 0 /* Inherit */;
11361
+ if (storage === 1 /* Immutable */) return 2 /* Immutable */;
11362
+ if (storage === 0 /* Inherit */ && parent === 2 /* Immutable */)
11363
+ return 2 /* Immutable */;
11364
+ return isReadOnlyMember(resolved) ? 1 /* ReadOnly */ : 0 /* Writable */;
11365
+ }
11366
+ function scopeKey(id2, scope) {
11367
+ return `${id2}:${scope.fixedness}:${scope.ownsReads}`;
11368
+ }
11369
+ function resolvedInDocument(document, member) {
11370
+ return document.resolvedMember?.(member) ?? resolveMember(member, document.members);
11371
+ }
11372
+ function declarationVaries(walk, member, body, rowId, scope) {
11353
11373
  const { document } = walk;
11374
+ const { ownsReads } = scope;
11375
+ const immutable2 = scope.fixedness === 2 /* Immutable */;
11354
11376
  if (documentHasInitValueContent(document, body)) {
11355
- const compiled = body.init.compiled;
11356
- if (compiled === void 0) return true;
11357
- const instanceParameters = /* @__PURE__ */ new Set();
11358
- for (const parameter4 of compiled.parameters) {
11359
- if (parameter4.id !== "__root__") instanceParameters.add(parameter4.id);
11360
- }
11361
- return irReadsInstance(
11362
- compiled.instructions,
11363
- instanceParameters,
11364
- /* @__PURE__ */ new Set()
11365
- );
11377
+ if (!immutable2) return true;
11378
+ if (ownsReads) {
11379
+ const compiled = body.init.compiled;
11380
+ if (compiled === void 0) return true;
11381
+ if (initializerReadsInstance(compiled)) return true;
11382
+ }
11383
+ return typeHoldsWritable(walk, member, 2 /* Immutable */);
11366
11384
  }
11367
11385
  if (!isLiteralValueContent(body)) return true;
11368
- if (irReadsInstance(body.constructorArgs, /* @__PURE__ */ new Set(), /* @__PURE__ */ new Set())) return true;
11386
+ if (!immutable2 && body.instanceConstructorId !== void 0) return true;
11387
+ if (!immutable2 && body.constructorArgs != null) return true;
11388
+ if (ownsReads && irReadsInstance(body.constructorArgs, /* @__PURE__ */ new Set(), /* @__PURE__ */ new Set()))
11389
+ return true;
11369
11390
  const value = body.value;
11370
- const ownedEntry = (entryMember) => (valueId) => typeof valueId !== "string" || rowReadsInstance(walk, entryMember, valueId);
11371
11391
  if (isMemberClassBase(member)) {
11372
11392
  if (value === null) return false;
11373
11393
  if (!isStringRecord(value)) return true;
11374
11394
  const classId = typeof body.classId === "string" ? body.classId : member.classId;
11375
- const entries = getSchemaEntryMap(document, classId);
11376
- for (const [schemaKey, valueId] of Object.entries(value)) {
11377
- const memberId = entries.get(schemaKey)?.memberId;
11378
- if (memberId == null) return true;
11379
- const child2 = findMemberInDocument(document, memberId);
11380
- if (ownedEntry(child2)(valueId)) return true;
11395
+ let owned = 0;
11396
+ for (const entry of storedSchemaOf(document, classId)) {
11397
+ if (entry.memberId === null) continue;
11398
+ const child2 = resolvedInDocument(
11399
+ document,
11400
+ findMemberInDocument(document, entry.memberId)
11401
+ );
11402
+ const childId = value[entry.schemaKey];
11403
+ if (childId !== void 0) owned++;
11404
+ else if (!memberKindOwnsStoredValue(child2.kind) || isStaticMember(child2))
11405
+ continue;
11406
+ const fixedness = fixednessOf(child2, scope.fixedness);
11407
+ if (fixedness === 0 /* Writable */) return true;
11408
+ if (childId !== void 0) {
11409
+ if (rowVaries(walk, child2, childId, { fixedness, ownsReads }))
11410
+ return true;
11411
+ continue;
11412
+ }
11413
+ const declared = child2.defaultValue;
11414
+ if (declared == null) continue;
11415
+ const childScope = { fixedness, ownsReads: false };
11416
+ const key = scopeKey(entry.memberId, childScope);
11417
+ if (walk.declarations.has(key)) continue;
11418
+ walk.declarations.add(key);
11419
+ if (declarationVaries(walk, child2, declared, null, childScope))
11420
+ return true;
11381
11421
  }
11382
- return false;
11422
+ return owned !== Object.keys(value).length;
11383
11423
  }
11384
11424
  if (isMemberListBase(member)) {
11385
- const entryMember = findMemberInDocument(document, member.entryMemberId);
11386
11425
  const entryIds = listKindOf(member) !== 1 /* Unordered */ ? value : rowId === null ? [] : document.unorderedListEntryIds?.(rowId) ?? (walk.membership ??= buildUnorderedListMembershipIndex(
11387
11426
  document.values
11388
11427
  )).get(rowId) ?? [];
11389
11428
  if (entryIds === null) return false;
11390
- return !Array.isArray(entryIds) || entryIds.some(ownedEntry(entryMember));
11429
+ if (!Array.isArray(entryIds)) return true;
11430
+ return entriesVary(walk, member.entryMemberId, entryIds, scope);
11391
11431
  }
11392
11432
  if (isMemberDictionaryBase(member)) {
11393
11433
  if (value === null) return false;
11394
11434
  if (!isStringRecord(value)) return true;
11395
- const entryMember = findMemberInDocument(document, member.entryMemberId);
11396
- return Object.values(value).some(ownedEntry(entryMember));
11435
+ return entriesVary(walk, member.entryMemberId, Object.values(value), scope);
11397
11436
  }
11398
11437
  if (member.kind === 21 /* Generic */) return true;
11399
- return irReadsInstance(value, /* @__PURE__ */ new Set(), /* @__PURE__ */ new Set());
11438
+ return ownsReads && irReadsInstance(value, /* @__PURE__ */ new Set(), /* @__PURE__ */ new Set());
11439
+ }
11440
+ function entriesVary(walk, entryMemberId, entryIds, scope) {
11441
+ if (entryIds.length === 0) return false;
11442
+ const entryMember = resolvedInDocument(
11443
+ walk.document,
11444
+ findMemberInDocument(walk.document, entryMemberId)
11445
+ );
11446
+ const fixedness = fixednessOf(entryMember, scope.fixedness);
11447
+ if (fixedness === 0 /* Writable */) return true;
11448
+ const entryScope = { fixedness, ownsReads: scope.ownsReads };
11449
+ return entryIds.some(
11450
+ (entryId) => typeof entryId !== "string" || rowVaries(walk, entryMember, entryId, entryScope)
11451
+ );
11400
11452
  }
11401
- function rowReadsInstance(walk, member, valueId) {
11402
- if (walk.visited.has(valueId)) return false;
11403
- walk.visited.add(valueId);
11453
+ function rowVaries(walk, member, valueId, scope) {
11454
+ const key = scopeKey(valueId, scope);
11455
+ if (walk.rows.has(key)) return false;
11456
+ walk.rows.add(key);
11404
11457
  const { document } = walk;
11405
11458
  const row = document.valueById?.(valueId) ?? (walk.rowById ??= new Map(
11406
11459
  document.values.map((value) => [value.id, value])
11407
11460
  )).get(valueId);
11408
11461
  if (row === void 0 || row === null) return true;
11409
- const resolved = document.resolvedMember?.(member) ?? resolveMember(member, document.members);
11410
- return declarationReadsInstance(walk, resolved, row, row.id);
11462
+ return declarationVaries(walk, member, row, row.id, scope);
11463
+ }
11464
+ function typeHoldsWritable(walk, member, fixedness) {
11465
+ if (isMemberClassBase(member)) {
11466
+ const { classes } = walk.document;
11467
+ if (!classIndexFor(classes).has(member.classId)) return true;
11468
+ if (classHoldsWritable(walk, member.classId, fixedness)) return true;
11469
+ for (const classId of descendantClassIds(member.classId, classes)) {
11470
+ if (classHoldsWritable(walk, classId, fixedness)) return true;
11471
+ }
11472
+ return false;
11473
+ }
11474
+ if (isMemberListBase(member) || isMemberDictionaryBase(member)) {
11475
+ const entryMember = resolvedInDocument(
11476
+ walk.document,
11477
+ findMemberInDocument(walk.document, member.entryMemberId)
11478
+ );
11479
+ const entryFixedness = fixednessOf(entryMember, fixedness);
11480
+ return entryFixedness === 0 /* Writable */ || typeHoldsWritable(walk, entryMember, entryFixedness);
11481
+ }
11482
+ return member.kind === 21 /* Generic */;
11483
+ }
11484
+ function classHoldsWritable(walk, classId, fixedness) {
11485
+ const key = `${classId}:${fixedness}`;
11486
+ if (walk.classes.has(key)) return false;
11487
+ walk.classes.add(key);
11488
+ const { document } = walk;
11489
+ for (const entry of storedSchemaOf(document, classId)) {
11490
+ if (entry.memberId === null) continue;
11491
+ const child2 = resolvedInDocument(
11492
+ document,
11493
+ findMemberInDocument(document, entry.memberId)
11494
+ );
11495
+ if (!memberKindOwnsStoredValue(child2.kind) || isStaticMember(child2))
11496
+ continue;
11497
+ const childFixedness = fixednessOf(child2, fixedness);
11498
+ if (childFixedness === 0 /* Writable */) return true;
11499
+ if (typeHoldsWritable(walk, child2, childFixedness)) return true;
11500
+ }
11501
+ return false;
11502
+ }
11503
+ function storedSchemaOf(document, classId) {
11504
+ return document.storedInstanceSchema?.(classId) ?? resolvedClassSchema(classId, document.classes, document.members).surface;
11505
+ }
11506
+ function initializerReadsInstance(compiled) {
11507
+ const instanceParameters = /* @__PURE__ */ new Set();
11508
+ for (const parameter4 of compiled.parameters) {
11509
+ if (parameter4.id !== "__root__") instanceParameters.add(parameter4.id);
11510
+ }
11511
+ return irReadsInstance(compiled.instructions, instanceParameters, /* @__PURE__ */ new Set());
11411
11512
  }
11412
11513
  function irReadsInstance(value, instanceParameters, visited) {
11413
11514
  if (typeof value !== "object" || value === null) return false;
@@ -51964,7 +52065,7 @@ var init_registry = __esm({
51964
52065
  "../packages/manifest/schema-contract/registry.mjs"() {
51965
52066
  "use strict";
51966
52067
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
51967
- cliVersion: "0.76.0",
52068
+ cliVersion: "0.76.1",
51968
52069
  projectFileUploadBatchSize: 32,
51969
52070
  documentRecords: {
51970
52071
  member: {
@@ -80382,7 +80483,9 @@ function readClassMember(args) {
80382
80483
  const expanded = args.expandedRecord();
80383
80484
  if (expanded !== null && Object.prototype.hasOwnProperty.call(expanded, schemaKey))
80384
80485
  return { kind: "value", value: Reflect.get(expanded, schemaKey) };
80385
- if (args.mode !== "resolved" && declaration !== void 0)
80486
+ if (args.mode === "resolved")
80487
+ return declaration !== void 0 && args.isConstant() ? { kind: "declaration", content: declaration } : { kind: "missing" };
80488
+ if (declaration !== void 0)
80386
80489
  return { kind: "declaration", content: declaration };
80387
80490
  if (args.mode === "runtime" && !isRequiredMember(member))
80388
80491
  return { kind: "null" };
@@ -81919,6 +82022,7 @@ function withEvaluationRuntime(ctx, writes) {
81919
82022
  constructionTimestamp: Date.now(),
81920
82023
  ownedValueAttachments: /* @__PURE__ */ new Map(),
81921
82024
  constructionStack: [],
82025
+ openConstructions: /* @__PURE__ */ new Map(),
81922
82026
  loopIterations: 0,
81923
82027
  budgetedConstructedRowIds: /* @__PURE__ */ new Set(),
81924
82028
  budgetedProducedEntriesByRowId: /* @__PURE__ */ new Map(),
@@ -82941,14 +83045,16 @@ function evalInstructions(instructions, scope, ctx, options) {
82941
83045
  };
82942
83046
  }
82943
83047
  const assignedReferenceValueId = targetTypeInfo.type === 7 /* Class */ || targetTypeInfo.type === 6 /* List */ || targetTypeInfo.type === 5 /* Dictionary */ ? findKnownRowIdByValueReference(value, ctx) : null;
82944
- applyOverlayAssignment(
82945
- ins.target.pointer,
82946
- targetTypeInfo,
82947
- value,
82948
- scope,
82949
- ctx,
82950
- destination
82951
- );
83048
+ if (!bindOmittedConstantSlot(destination, member, value, ctx)) {
83049
+ applyOverlayAssignment(
83050
+ ins.target.pointer,
83051
+ targetTypeInfo,
83052
+ value,
83053
+ scope,
83054
+ ctx,
83055
+ destination
83056
+ );
83057
+ }
82952
83058
  const unorderedReplacement = assignedReferenceValueId === null && member !== null && isMemberListBase(member) && listKindOf(member) === 1 /* Unordered */ && Array.isArray(value) ? unorderedReplacementProjection(
82953
83059
  ins.target.pointer,
82954
83060
  destination,
@@ -83812,6 +83918,36 @@ function applyOverlayStaticAssignment(memberId, value, ctx) {
83812
83918
  bindings.set(member.id, row.id);
83813
83919
  invalidateEvaluatorIndexes(ctx);
83814
83920
  }
83921
+ function bindOmittedConstantSlot(destination, member, value, ctx) {
83922
+ if (destination === void 0 || member === null) return false;
83923
+ const { receiver } = destination;
83924
+ if (typeof receiver !== "object" || receiver === null) return false;
83925
+ const construction = ctx.__executionState?.openConstructions.get(receiver);
83926
+ if (construction === void 0) return false;
83927
+ const key = String(destination.key);
83928
+ if (Object.prototype.hasOwnProperty.call(receiver, key)) return false;
83929
+ if (isMemberClassBase(member) || isMemberListBase(member) || isMemberDictionaryBase(member))
83930
+ return false;
83931
+ const resolved = resolveMember(member, ctx.vm.members);
83932
+ if (!isConstantMember(constructorDefaultValueDocument(ctx, member), resolved))
83933
+ return false;
83934
+ const { createdValues } = construction;
83935
+ const staged = createdValues.length;
83936
+ const row = materializeConstructorArgumentValue({
83937
+ member: resolved,
83938
+ value,
83939
+ // A constant has no instance environment.
83940
+ genericEnv: /* @__PURE__ */ new Map(),
83941
+ ctx,
83942
+ createdValues,
83943
+ createdById: /* @__PURE__ */ new Map(),
83944
+ storageKeyDeclarations: construction.storageKeyDeclarations
83945
+ });
83946
+ stageConstructedRows(createdValues.slice(staged), ctx);
83947
+ Reflect.set(receiver, key, row.id);
83948
+ invalidateEvaluatorIndexes(ctx, receiver);
83949
+ return true;
83950
+ }
83815
83951
  function touchUnknown(_ins) {
83816
83952
  void _ins;
83817
83953
  }
@@ -86198,7 +86334,7 @@ function readDeclarationDefault(member, ctx) {
86198
86334
  };
86199
86335
  }
86200
86336
  const document = constructorDefaultValueDocument(ctx, member);
86201
- const constant = shared !== void 0 && known !== false && (known !== void 0 || isImmutableConstantMember(document, member));
86337
+ const constant = shared !== void 0 && known !== false && (known !== void 0 || isConstantMember(document, member));
86202
86338
  if (shared !== void 0 && !constant) shared.set(member.id, false);
86203
86339
  const created = [];
86204
86340
  const closeFrame = pushConstructionFrame(ctx, `${member.name} declaration`);
@@ -90691,39 +90827,50 @@ function constructDeclaredClassValueWithinFrame(descriptor, record7, info, scope
90691
90827
  stageConstructedRows(createdValues, ctx);
90692
90828
  bindConstructedDelegateTargets(createdValues, ctx);
90693
90829
  if (record7 !== null) {
90694
- runDeclaredConstructorChain({
90695
- record: record7,
90696
- argumentValues,
90697
- preparedArgumentScopes,
90698
- thisValue: root.value,
90699
- ctx,
90700
- visitedConstructorIds: /* @__PURE__ */ new Set(),
90701
- applyBaseInitializerBlock: (chainRecord, chainArguments, chainThisValue) => {
90702
- const supplied2 = evaluateBaseInitializerFields({
90703
- record: chainRecord,
90704
- argumentValues: chainArguments,
90705
- thisValue: chainThisValue,
90706
- constructedClassId: classId,
90707
- instanceEnv: descriptor.instanceEnv,
90708
- ctx
90709
- });
90710
- if (supplied2.length === 0) return;
90711
- applyConstructorFields({
90712
- supplied: supplied2,
90713
- root,
90714
- rootRecord,
90715
- schemaClass: schemaClass2,
90716
- instanceEnv: descriptor.instanceEnv,
90717
- createdValues,
90718
- createdById: new Map(createdValues.map((row) => [row.id, row])),
90719
- storageKeyDeclarations,
90720
- // §1.5 base blocks are assignments, not omissions: an explicit null
90721
- // clears the slot exactly as a call-site block entry does.
90722
- nullMeansOmit: false,
90723
- ctx
90724
- });
90725
- }
90830
+ const openConstructions = ctx.__executionState?.openConstructions;
90831
+ openConstructions?.set(rootRecord, {
90832
+ createdValues,
90833
+ storageKeyDeclarations
90726
90834
  });
90835
+ try {
90836
+ runDeclaredConstructorChain({
90837
+ record: record7,
90838
+ argumentValues,
90839
+ preparedArgumentScopes,
90840
+ thisValue: root.value,
90841
+ ctx,
90842
+ visitedConstructorIds: /* @__PURE__ */ new Set(),
90843
+ applyBaseInitializerBlock: (chainRecord, chainArguments, chainThisValue) => {
90844
+ const supplied2 = evaluateBaseInitializerFields({
90845
+ record: chainRecord,
90846
+ argumentValues: chainArguments,
90847
+ thisValue: chainThisValue,
90848
+ constructedClassId: classId,
90849
+ instanceEnv: descriptor.instanceEnv,
90850
+ ctx
90851
+ });
90852
+ if (supplied2.length === 0) return;
90853
+ const staged = createdValues.length;
90854
+ applyConstructorFields({
90855
+ supplied: supplied2,
90856
+ root,
90857
+ rootRecord,
90858
+ schemaClass: schemaClass2,
90859
+ instanceEnv: descriptor.instanceEnv,
90860
+ createdValues,
90861
+ createdById: new Map(createdValues.map((row) => [row.id, row])),
90862
+ storageKeyDeclarations,
90863
+ // §1.5 base blocks are assignments, not omissions: an explicit null
90864
+ // clears the slot exactly as a call-site block entry does.
90865
+ nullMeansOmit: false,
90866
+ ctx
90867
+ });
90868
+ stageConstructedRows(createdValues.slice(staged), ctx);
90869
+ }
90870
+ });
90871
+ } finally {
90872
+ openConstructions?.delete(rootRecord);
90873
+ }
90727
90874
  }
90728
90875
  const supplied = evaluateConstructorFields(descriptor, scope, ctx);
90729
90876
  try {
@@ -122203,6 +122350,7 @@ function assertStagedVariantMemberValuesValid(projected, changes) {
122203
122350
  value: entry.value,
122204
122351
  declaration: entry.declaration,
122205
122352
  owner: entry.label,
122353
+ classes: projected.classes,
122206
122354
  classesById,
122207
122355
  variantsById,
122208
122356
  foldersById,
@@ -122275,10 +122423,7 @@ function assertVariantReferenceValid(args) {
122275
122423
  if (target.type === 7 /* Class */ && value.classId !== target.classId) {
122276
122424
  let admitted = args.admittedClassesByTarget.get(target.classId);
122277
122425
  if (admitted === void 0) {
122278
- admitted = descendantClassIds(
122279
- target.classId,
122280
- Array.from(classesById.values())
122281
- );
122426
+ admitted = descendantClassIds(target.classId, args.classes);
122282
122427
  args.admittedClassesByTarget.set(target.classId, admitted);
122283
122428
  }
122284
122429
  if (!admitted.has(value.classId)) {
@@ -191652,7 +191797,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
191652
191797
  async function main() {
191653
191798
  const args = parseArgs(process.argv.slice(2));
191654
191799
  if (args.command === "--version") {
191655
- console.log("0.76.0");
191800
+ console.log("0.76.1");
191656
191801
  return;
191657
191802
  }
191658
191803
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
@@ -5295,6 +5295,9 @@ var ProjectSchemaIndex = class {
5295
5295
  for (const schemaClass2 of source.classes) {
5296
5296
  this.classesById.set(schemaClass2.id, schemaClass2);
5297
5297
  append(this.classesByName, schemaClass2.name, schemaClass2);
5298
+ if (schemaClass2.extendsClassId) {
5299
+ append(this.subclassesById, schemaClass2.extendsClassId, schemaClass2);
5300
+ }
5298
5301
  for (const [schemaKey, memberId] of Object.entries(schemaClass2.schema)) {
5299
5302
  append(this.schemaPlacementsByMemberId, memberId, {
5300
5303
  ownerClass: schemaClass2,
@@ -5339,6 +5342,8 @@ var ProjectSchemaIndex = class {
5339
5342
  source;
5340
5343
  classesById = /* @__PURE__ */ new Map();
5341
5344
  classesByName = /* @__PURE__ */ new Map();
5345
+ /** Direct subclasses by the class they extend. */
5346
+ subclassesById = /* @__PURE__ */ new Map();
5342
5347
  membersById = /* @__PURE__ */ new Map();
5343
5348
  membersByName = /* @__PURE__ */ new Map();
5344
5349
  enumsById = /* @__PURE__ */ new Map();
@@ -5523,6 +5528,9 @@ function indexSchema(classes, members) {
5523
5528
  function classIndexFor(classes) {
5524
5529
  return indexClasses(classes).classesById;
5525
5530
  }
5531
+ function subclassIndexFor(classes) {
5532
+ return indexClasses(classes).subclassesById;
5533
+ }
5526
5534
  function memberIndexFor(members) {
5527
5535
  return projectSchemaIndexFor({ classes: NO_CLASSES, members }).membersById;
5528
5536
  }
@@ -5724,15 +5732,7 @@ function resolveMemberWithIndex(member, memberIndex) {
5724
5732
  return Object.freeze(merged);
5725
5733
  }
5726
5734
  function descendantClassIds(classId, allClasses) {
5727
- const childrenByClassId = /* @__PURE__ */ new Map();
5728
- for (const schemaClass2 of allClasses) {
5729
- if (!schemaClass2.extendsClassId) continue;
5730
- const children = childrenByClassId.get(schemaClass2.extendsClassId);
5731
- if (children === void 0) {
5732
- childrenByClassId.set(schemaClass2.extendsClassId, [schemaClass2]);
5733
- } else children.push(schemaClass2);
5734
- }
5735
- return descendantClassIdsInChildIndex(classId, childrenByClassId);
5735
+ return descendantClassIdsInChildIndex(classId, subclassIndexFor(allClasses));
5736
5736
  }
5737
5737
  function descendantClassIdsInChildIndex(classId, childrenByClassId) {
5738
5738
  const result = /* @__PURE__ */ new Set();
@@ -10667,103 +10667,204 @@ function buildDefaultClassMaterializationPlan(document2, classId, instanceEnv) {
10667
10667
  ...document2,
10668
10668
  constructors: document2.constructors ?? []
10669
10669
  });
10670
- const merged = document2.storedInstanceSchema?.(classId) ?? mergeInstanceSurfaceSchema(classId, document2.classes, document2.members);
10671
- return merged.flatMap((entry) => {
10672
- if (entry.memberId === null) return [];
10673
- const childMember = findMemberInDocument(document2, entry.memberId);
10674
- if (!memberKindOwnsStoredValue(childMember.kind)) return [];
10675
- if (instanceEnv.size === 0 && isImmutableConstantMember(
10676
- document2,
10677
- document2.resolvedMember?.(childMember) ?? resolveMember(childMember, document2.members)
10678
- ))
10679
- return [];
10680
- const member = substituteMember(
10681
- childMember,
10682
- instanceEnv,
10683
- document2.members,
10684
- document2.resolvedMember?.(childMember)
10685
- );
10686
- return [
10687
- {
10688
- schemaKey: entry.schemaKey,
10689
- member,
10690
- defaultSettlesConstruction: settlesConstruction(member, instanceEnv),
10691
- directScalarBody: directScalarDefaultBody(document2, member)
10692
- }
10693
- ];
10694
- });
10670
+ return storedSchemaOf(document2, classId).flatMap(
10671
+ (entry) => {
10672
+ if (entry.memberId === null) return [];
10673
+ const childMember = findMemberInDocument(document2, entry.memberId);
10674
+ if (!memberKindOwnsStoredValue(childMember.kind)) return [];
10675
+ if (instanceEnv.size === 0 && isConstantMember(document2, resolvedInDocument(document2, childMember)))
10676
+ return [];
10677
+ const member = substituteMember(
10678
+ childMember,
10679
+ instanceEnv,
10680
+ document2.members,
10681
+ document2.resolvedMember?.(childMember)
10682
+ );
10683
+ return [
10684
+ {
10685
+ schemaKey: entry.schemaKey,
10686
+ member,
10687
+ defaultSettlesConstruction: settlesConstruction(member, instanceEnv),
10688
+ directScalarBody: directScalarDefaultBody(document2, member)
10689
+ }
10690
+ ];
10691
+ }
10692
+ );
10695
10693
  }
10696
- function isImmutableConstantMember(document2, resolved) {
10697
- if (resolved.storage !== 1 /* Immutable */) return false;
10694
+ function isConstantMember(document2, resolved) {
10698
10695
  if (isStaticMember(resolved)) return false;
10696
+ const fixedness = fixednessOf(resolved, 0 /* Writable */);
10697
+ if (fixedness === 0 /* Writable */) return false;
10699
10698
  const declared = resolved.defaultValue;
10700
10699
  if (declared == null) return false;
10701
- return !declarationReadsInstance(
10702
- { document: document2, visited: /* @__PURE__ */ new Set() },
10700
+ if (fixedness === 1 /* ReadOnly */ && (isMemberListBase(resolved) || isMemberDictionaryBase(resolved)))
10701
+ return false;
10702
+ return !declarationVaries(
10703
+ {
10704
+ document: document2,
10705
+ rows: /* @__PURE__ */ new Set(),
10706
+ declarations: /* @__PURE__ */ new Set(),
10707
+ classes: /* @__PURE__ */ new Set()
10708
+ },
10703
10709
  resolved,
10704
10710
  declared,
10705
- null
10711
+ null,
10712
+ { fixedness, ownsReads: true }
10706
10713
  );
10707
10714
  }
10708
- function declarationReadsInstance(walk, member, body, rowId) {
10715
+ function fixednessOf(resolved, parent) {
10716
+ const storage = resolved.storage ?? 0 /* Inherit */;
10717
+ if (storage === 1 /* Immutable */) return 2 /* Immutable */;
10718
+ if (storage === 0 /* Inherit */ && parent === 2 /* Immutable */)
10719
+ return 2 /* Immutable */;
10720
+ return isReadOnlyMember(resolved) ? 1 /* ReadOnly */ : 0 /* Writable */;
10721
+ }
10722
+ function scopeKey(id, scope) {
10723
+ return `${id}:${scope.fixedness}:${scope.ownsReads}`;
10724
+ }
10725
+ function resolvedInDocument(document2, member) {
10726
+ return document2.resolvedMember?.(member) ?? resolveMember(member, document2.members);
10727
+ }
10728
+ function declarationVaries(walk, member, body, rowId, scope) {
10709
10729
  const { document: document2 } = walk;
10730
+ const { ownsReads } = scope;
10731
+ const immutable2 = scope.fixedness === 2 /* Immutable */;
10710
10732
  if (documentHasInitValueContent(document2, body)) {
10711
- const compiled = body.init.compiled;
10712
- if (compiled === void 0) return true;
10713
- const instanceParameters = /* @__PURE__ */ new Set();
10714
- for (const parameter3 of compiled.parameters) {
10715
- if (parameter3.id !== "__root__") instanceParameters.add(parameter3.id);
10716
- }
10717
- return irReadsInstance(
10718
- compiled.instructions,
10719
- instanceParameters,
10720
- /* @__PURE__ */ new Set()
10721
- );
10733
+ if (!immutable2) return true;
10734
+ if (ownsReads) {
10735
+ const compiled = body.init.compiled;
10736
+ if (compiled === void 0) return true;
10737
+ if (initializerReadsInstance(compiled)) return true;
10738
+ }
10739
+ return typeHoldsWritable(walk, member, 2 /* Immutable */);
10722
10740
  }
10723
10741
  if (!isLiteralValueContent(body)) return true;
10724
- if (irReadsInstance(body.constructorArgs, /* @__PURE__ */ new Set(), /* @__PURE__ */ new Set())) return true;
10742
+ if (!immutable2 && body.instanceConstructorId !== void 0) return true;
10743
+ if (!immutable2 && body.constructorArgs != null) return true;
10744
+ if (ownsReads && irReadsInstance(body.constructorArgs, /* @__PURE__ */ new Set(), /* @__PURE__ */ new Set()))
10745
+ return true;
10725
10746
  const value = body.value;
10726
- const ownedEntry = (entryMember) => (valueId) => typeof valueId !== "string" || rowReadsInstance(walk, entryMember, valueId);
10727
10747
  if (isMemberClassBase(member)) {
10728
10748
  if (value === null) return false;
10729
10749
  if (!isStringRecord(value)) return true;
10730
10750
  const classId = typeof body.classId === "string" ? body.classId : member.classId;
10731
- const entries = getSchemaEntryMap(document2, classId);
10732
- for (const [schemaKey, valueId] of Object.entries(value)) {
10733
- const memberId = entries.get(schemaKey)?.memberId;
10734
- if (memberId == null) return true;
10735
- const child = findMemberInDocument(document2, memberId);
10736
- if (ownedEntry(child)(valueId)) return true;
10751
+ let owned = 0;
10752
+ for (const entry of storedSchemaOf(document2, classId)) {
10753
+ if (entry.memberId === null) continue;
10754
+ const child = resolvedInDocument(
10755
+ document2,
10756
+ findMemberInDocument(document2, entry.memberId)
10757
+ );
10758
+ const childId = value[entry.schemaKey];
10759
+ if (childId !== void 0) owned++;
10760
+ else if (!memberKindOwnsStoredValue(child.kind) || isStaticMember(child))
10761
+ continue;
10762
+ const fixedness = fixednessOf(child, scope.fixedness);
10763
+ if (fixedness === 0 /* Writable */) return true;
10764
+ if (childId !== void 0) {
10765
+ if (rowVaries(walk, child, childId, { fixedness, ownsReads }))
10766
+ return true;
10767
+ continue;
10768
+ }
10769
+ const declared = child.defaultValue;
10770
+ if (declared == null) continue;
10771
+ const childScope = { fixedness, ownsReads: false };
10772
+ const key = scopeKey(entry.memberId, childScope);
10773
+ if (walk.declarations.has(key)) continue;
10774
+ walk.declarations.add(key);
10775
+ if (declarationVaries(walk, child, declared, null, childScope))
10776
+ return true;
10737
10777
  }
10738
- return false;
10778
+ return owned !== Object.keys(value).length;
10739
10779
  }
10740
10780
  if (isMemberListBase(member)) {
10741
- const entryMember = findMemberInDocument(document2, member.entryMemberId);
10742
10781
  const entryIds = listKindOf(member) !== 1 /* Unordered */ ? value : rowId === null ? [] : document2.unorderedListEntryIds?.(rowId) ?? (walk.membership ??= buildUnorderedListMembershipIndex(
10743
10782
  document2.values
10744
10783
  )).get(rowId) ?? [];
10745
10784
  if (entryIds === null) return false;
10746
- return !Array.isArray(entryIds) || entryIds.some(ownedEntry(entryMember));
10785
+ if (!Array.isArray(entryIds)) return true;
10786
+ return entriesVary(walk, member.entryMemberId, entryIds, scope);
10747
10787
  }
10748
10788
  if (isMemberDictionaryBase(member)) {
10749
10789
  if (value === null) return false;
10750
10790
  if (!isStringRecord(value)) return true;
10751
- const entryMember = findMemberInDocument(document2, member.entryMemberId);
10752
- return Object.values(value).some(ownedEntry(entryMember));
10791
+ return entriesVary(walk, member.entryMemberId, Object.values(value), scope);
10753
10792
  }
10754
10793
  if (member.kind === 21 /* Generic */) return true;
10755
- return irReadsInstance(value, /* @__PURE__ */ new Set(), /* @__PURE__ */ new Set());
10794
+ return ownsReads && irReadsInstance(value, /* @__PURE__ */ new Set(), /* @__PURE__ */ new Set());
10795
+ }
10796
+ function entriesVary(walk, entryMemberId, entryIds, scope) {
10797
+ if (entryIds.length === 0) return false;
10798
+ const entryMember = resolvedInDocument(
10799
+ walk.document,
10800
+ findMemberInDocument(walk.document, entryMemberId)
10801
+ );
10802
+ const fixedness = fixednessOf(entryMember, scope.fixedness);
10803
+ if (fixedness === 0 /* Writable */) return true;
10804
+ const entryScope = { fixedness, ownsReads: scope.ownsReads };
10805
+ return entryIds.some(
10806
+ (entryId) => typeof entryId !== "string" || rowVaries(walk, entryMember, entryId, entryScope)
10807
+ );
10756
10808
  }
10757
- function rowReadsInstance(walk, member, valueId) {
10758
- if (walk.visited.has(valueId)) return false;
10759
- walk.visited.add(valueId);
10809
+ function rowVaries(walk, member, valueId, scope) {
10810
+ const key = scopeKey(valueId, scope);
10811
+ if (walk.rows.has(key)) return false;
10812
+ walk.rows.add(key);
10760
10813
  const { document: document2 } = walk;
10761
10814
  const row = document2.valueById?.(valueId) ?? (walk.rowById ??= new Map(
10762
10815
  document2.values.map((value) => [value.id, value])
10763
10816
  )).get(valueId);
10764
10817
  if (row === void 0 || row === null) return true;
10765
- const resolved = document2.resolvedMember?.(member) ?? resolveMember(member, document2.members);
10766
- return declarationReadsInstance(walk, resolved, row, row.id);
10818
+ return declarationVaries(walk, member, row, row.id, scope);
10819
+ }
10820
+ function typeHoldsWritable(walk, member, fixedness) {
10821
+ if (isMemberClassBase(member)) {
10822
+ const { classes } = walk.document;
10823
+ if (!classIndexFor(classes).has(member.classId)) return true;
10824
+ if (classHoldsWritable(walk, member.classId, fixedness)) return true;
10825
+ for (const classId of descendantClassIds(member.classId, classes)) {
10826
+ if (classHoldsWritable(walk, classId, fixedness)) return true;
10827
+ }
10828
+ return false;
10829
+ }
10830
+ if (isMemberListBase(member) || isMemberDictionaryBase(member)) {
10831
+ const entryMember = resolvedInDocument(
10832
+ walk.document,
10833
+ findMemberInDocument(walk.document, member.entryMemberId)
10834
+ );
10835
+ const entryFixedness = fixednessOf(entryMember, fixedness);
10836
+ return entryFixedness === 0 /* Writable */ || typeHoldsWritable(walk, entryMember, entryFixedness);
10837
+ }
10838
+ return member.kind === 21 /* Generic */;
10839
+ }
10840
+ function classHoldsWritable(walk, classId, fixedness) {
10841
+ const key = `${classId}:${fixedness}`;
10842
+ if (walk.classes.has(key)) return false;
10843
+ walk.classes.add(key);
10844
+ const { document: document2 } = walk;
10845
+ for (const entry of storedSchemaOf(document2, classId)) {
10846
+ if (entry.memberId === null) continue;
10847
+ const child = resolvedInDocument(
10848
+ document2,
10849
+ findMemberInDocument(document2, entry.memberId)
10850
+ );
10851
+ if (!memberKindOwnsStoredValue(child.kind) || isStaticMember(child))
10852
+ continue;
10853
+ const childFixedness = fixednessOf(child, fixedness);
10854
+ if (childFixedness === 0 /* Writable */) return true;
10855
+ if (typeHoldsWritable(walk, child, childFixedness)) return true;
10856
+ }
10857
+ return false;
10858
+ }
10859
+ function storedSchemaOf(document2, classId) {
10860
+ return document2.storedInstanceSchema?.(classId) ?? resolvedClassSchema(classId, document2.classes, document2.members).surface;
10861
+ }
10862
+ function initializerReadsInstance(compiled) {
10863
+ const instanceParameters = /* @__PURE__ */ new Set();
10864
+ for (const parameter3 of compiled.parameters) {
10865
+ if (parameter3.id !== "__root__") instanceParameters.add(parameter3.id);
10866
+ }
10867
+ return irReadsInstance(compiled.instructions, instanceParameters, /* @__PURE__ */ new Set());
10767
10868
  }
10768
10869
  function irReadsInstance(value, instanceParameters, visited) {
10769
10870
  if (typeof value !== "object" || value === null) return false;
@@ -15468,7 +15569,9 @@ function readClassMember(args) {
15468
15569
  const expanded = args.expandedRecord();
15469
15570
  if (expanded !== null && Object.prototype.hasOwnProperty.call(expanded, schemaKey))
15470
15571
  return { kind: "value", value: Reflect.get(expanded, schemaKey) };
15471
- if (args.mode !== "resolved" && declaration !== void 0)
15572
+ if (args.mode === "resolved")
15573
+ return declaration !== void 0 && args.isConstant() ? { kind: "declaration", content: declaration } : { kind: "missing" };
15574
+ if (declaration !== void 0)
15472
15575
  return { kind: "declaration", content: declaration };
15473
15576
  if (args.mode === "runtime" && !isRequiredMember(member))
15474
15577
  return { kind: "null" };
@@ -16974,6 +17077,7 @@ function withEvaluationRuntime(ctx, writes) {
16974
17077
  constructionTimestamp: Date.now(),
16975
17078
  ownedValueAttachments: /* @__PURE__ */ new Map(),
16976
17079
  constructionStack: [],
17080
+ openConstructions: /* @__PURE__ */ new Map(),
16977
17081
  loopIterations: 0,
16978
17082
  budgetedConstructedRowIds: /* @__PURE__ */ new Set(),
16979
17083
  budgetedProducedEntriesByRowId: /* @__PURE__ */ new Map(),
@@ -18109,14 +18213,16 @@ function evalInstructions(instructions, scope, ctx, options) {
18109
18213
  };
18110
18214
  }
18111
18215
  const assignedReferenceValueId = targetTypeInfo.type === 7 /* Class */ || targetTypeInfo.type === 6 /* List */ || targetTypeInfo.type === 5 /* Dictionary */ ? findKnownRowIdByValueReference(value, ctx) : null;
18112
- applyOverlayAssignment(
18113
- ins.target.pointer,
18114
- targetTypeInfo,
18115
- value,
18116
- scope,
18117
- ctx,
18118
- destination
18119
- );
18216
+ if (!bindOmittedConstantSlot(destination, member, value, ctx)) {
18217
+ applyOverlayAssignment(
18218
+ ins.target.pointer,
18219
+ targetTypeInfo,
18220
+ value,
18221
+ scope,
18222
+ ctx,
18223
+ destination
18224
+ );
18225
+ }
18120
18226
  const unorderedReplacement = assignedReferenceValueId === null && member !== null && isMemberListBase(member) && listKindOf(member) === 1 /* Unordered */ && Array.isArray(value) ? unorderedReplacementProjection(
18121
18227
  ins.target.pointer,
18122
18228
  destination,
@@ -18971,6 +19077,36 @@ function applyOverlayStaticAssignment(memberId, value, ctx) {
18971
19077
  bindings.set(member.id, row.id);
18972
19078
  invalidateEvaluatorIndexes(ctx);
18973
19079
  }
19080
+ function bindOmittedConstantSlot(destination, member, value, ctx) {
19081
+ if (destination === void 0 || member === null) return false;
19082
+ const { receiver } = destination;
19083
+ if (typeof receiver !== "object" || receiver === null) return false;
19084
+ const construction = ctx.__executionState?.openConstructions.get(receiver);
19085
+ if (construction === void 0) return false;
19086
+ const key = String(destination.key);
19087
+ if (Object.prototype.hasOwnProperty.call(receiver, key)) return false;
19088
+ if (isMemberClassBase(member) || isMemberListBase(member) || isMemberDictionaryBase(member))
19089
+ return false;
19090
+ const resolved = resolveMember(member, ctx.vm.members);
19091
+ if (!isConstantMember(constructorDefaultValueDocument(ctx, member), resolved))
19092
+ return false;
19093
+ const { createdValues } = construction;
19094
+ const staged = createdValues.length;
19095
+ const row = materializeConstructorArgumentValue({
19096
+ member: resolved,
19097
+ value,
19098
+ // A constant has no instance environment.
19099
+ genericEnv: /* @__PURE__ */ new Map(),
19100
+ ctx,
19101
+ createdValues,
19102
+ createdById: /* @__PURE__ */ new Map(),
19103
+ storageKeyDeclarations: construction.storageKeyDeclarations
19104
+ });
19105
+ stageConstructedRows(createdValues.slice(staged), ctx);
19106
+ Reflect.set(receiver, key, row.id);
19107
+ invalidateEvaluatorIndexes(ctx, receiver);
19108
+ return true;
19109
+ }
18974
19110
  function touchUnknown(_ins) {
18975
19111
  void _ins;
18976
19112
  }
@@ -21358,7 +21494,7 @@ function readDeclarationDefault(member, ctx) {
21358
21494
  };
21359
21495
  }
21360
21496
  const document2 = constructorDefaultValueDocument(ctx, member);
21361
- const constant = shared !== void 0 && known !== false && (known !== void 0 || isImmutableConstantMember(document2, member));
21497
+ const constant = shared !== void 0 && known !== false && (known !== void 0 || isConstantMember(document2, member));
21362
21498
  if (shared !== void 0 && !constant) shared.set(member.id, false);
21363
21499
  const created = [];
21364
21500
  const closeFrame = pushConstructionFrame(ctx, `${member.name} declaration`);
@@ -25865,39 +26001,50 @@ function constructDeclaredClassValueWithinFrame(descriptor, record4, info, scope
25865
26001
  stageConstructedRows(createdValues, ctx);
25866
26002
  bindConstructedDelegateTargets(createdValues, ctx);
25867
26003
  if (record4 !== null) {
25868
- runDeclaredConstructorChain({
25869
- record: record4,
25870
- argumentValues,
25871
- preparedArgumentScopes,
25872
- thisValue: root.value,
25873
- ctx,
25874
- visitedConstructorIds: /* @__PURE__ */ new Set(),
25875
- applyBaseInitializerBlock: (chainRecord, chainArguments, chainThisValue) => {
25876
- const supplied2 = evaluateBaseInitializerFields({
25877
- record: chainRecord,
25878
- argumentValues: chainArguments,
25879
- thisValue: chainThisValue,
25880
- constructedClassId: classId,
25881
- instanceEnv: descriptor.instanceEnv,
25882
- ctx
25883
- });
25884
- if (supplied2.length === 0) return;
25885
- applyConstructorFields({
25886
- supplied: supplied2,
25887
- root,
25888
- rootRecord,
25889
- schemaClass: schemaClass2,
25890
- instanceEnv: descriptor.instanceEnv,
25891
- createdValues,
25892
- createdById: new Map(createdValues.map((row) => [row.id, row])),
25893
- storageKeyDeclarations,
25894
- // §1.5 base blocks are assignments, not omissions: an explicit null
25895
- // clears the slot exactly as a call-site block entry does.
25896
- nullMeansOmit: false,
25897
- ctx
25898
- });
25899
- }
26004
+ const openConstructions = ctx.__executionState?.openConstructions;
26005
+ openConstructions?.set(rootRecord, {
26006
+ createdValues,
26007
+ storageKeyDeclarations
25900
26008
  });
26009
+ try {
26010
+ runDeclaredConstructorChain({
26011
+ record: record4,
26012
+ argumentValues,
26013
+ preparedArgumentScopes,
26014
+ thisValue: root.value,
26015
+ ctx,
26016
+ visitedConstructorIds: /* @__PURE__ */ new Set(),
26017
+ applyBaseInitializerBlock: (chainRecord, chainArguments, chainThisValue) => {
26018
+ const supplied2 = evaluateBaseInitializerFields({
26019
+ record: chainRecord,
26020
+ argumentValues: chainArguments,
26021
+ thisValue: chainThisValue,
26022
+ constructedClassId: classId,
26023
+ instanceEnv: descriptor.instanceEnv,
26024
+ ctx
26025
+ });
26026
+ if (supplied2.length === 0) return;
26027
+ const staged = createdValues.length;
26028
+ applyConstructorFields({
26029
+ supplied: supplied2,
26030
+ root,
26031
+ rootRecord,
26032
+ schemaClass: schemaClass2,
26033
+ instanceEnv: descriptor.instanceEnv,
26034
+ createdValues,
26035
+ createdById: new Map(createdValues.map((row) => [row.id, row])),
26036
+ storageKeyDeclarations,
26037
+ // §1.5 base blocks are assignments, not omissions: an explicit null
26038
+ // clears the slot exactly as a call-site block entry does.
26039
+ nullMeansOmit: false,
26040
+ ctx
26041
+ });
26042
+ stageConstructedRows(createdValues.slice(staged), ctx);
26043
+ }
26044
+ });
26045
+ } finally {
26046
+ openConstructions?.delete(rootRecord);
26047
+ }
25901
26048
  }
25902
26049
  const supplied = evaluateConstructorFields(descriptor, scope, ctx);
25903
26050
  try {
@@ -55950,7 +56097,7 @@ var SPECIALIZED_RELATION_KINDS = /* @__PURE__ */ new Set([
55950
56097
 
55951
56098
  // ../packages/manifest/schema-contract/registry.mjs
55952
56099
  var PROJECT_SCHEMA_CONTRACT = Object.freeze({
55953
- cliVersion: "0.76.0",
56100
+ cliVersion: "0.76.1",
55954
56101
  projectFileUploadBatchSize: 32,
55955
56102
  documentRecords: {
55956
56103
  member: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neocompose/cli",
3
- "version": "0.76.0",
3
+ "version": "0.76.1",
4
4
  "description": "Neo Compose native project-source CLI with bidirectional sync.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -9,7 +9,7 @@ description: >-
9
9
  `@neocompose/cli` or `node cli/bin/neo.mjs` in the neo-compose repository.
10
10
  ---
11
11
 
12
- <!-- reviewed-through-cli: 0.76.0 -->
12
+ <!-- reviewed-through-cli: 0.76.1 -->
13
13
 
14
14
  # Neo Compose CLI
15
15
 
@@ -129,7 +129,7 @@ wrappers.
129
129
  The marker near the top of `SKILL.md` must exactly match the package version:
130
130
 
131
131
  ```html
132
- <!-- reviewed-through-cli: 0.76.0 -->
132
+ <!-- reviewed-through-cli: 0.76.1 -->
133
133
  ```
134
134
 
135
135
  The quoted version above is checked too, so this instruction cannot go stale
@@ -184,6 +184,12 @@ Readonly is shallow. A readonly collection's membership is fixed, while its
184
184
  entries' members follow their own storage and mutability. User class members
185
185
  still declare no storage.
186
186
 
187
+ A readonly member declared as a literal (no initializer or constructor call)
188
+ that reads neither `this` nor a constructor argument and holds nothing
189
+ writable is a constant. Instances share its declared value and store nothing
190
+ until a constructor or initializer block writes it. A readonly collection or
191
+ initializer is still built per instance.
192
+
187
193
  `@index(member: Field, kind: .Unique)` and
188
194
  `@column(member: Field, width: ..., visibility: ..., pin: ..., overflow: ...)`
189
195
  are repeatable List annotations. `member:` is a bare field name on the entry
@@ -459,12 +465,13 @@ construction remain subject to storage and `readonly` restrictions.
459
465
  Runtime construction never supplies an Immutable member: an initializer block,
460
466
  constructor body, base-clause argument, or generated C# factory cannot set one.
461
467
  The value is never stored with the instance. When the declaration, including
462
- every row it owns, reads neither `this` nor a constructor argument, the member
463
- is a constant and every instance shares one value. Otherwise each instance
464
- evaluates the declared initializer with its own `this` and constructor
465
- arguments, again after a reload. A method group such as `selector: SelectTorso`
466
- binds `this`. `Clone()` shares an authored or constant Immutable value and
467
- re-evaluates a per-instance one. A class with a required Immutable member and
468
+ every row it owns, reads neither `this` nor a constructor argument, and no
469
+ value of its type holds a writable member, the member is a constant and every
470
+ instance shares one value. Otherwise each instance evaluates the declared
471
+ initializer with its own `this` and constructor arguments, again after a
472
+ reload. A method group such as `selector: SelectTorso` binds `this`.
473
+ `Clone()` shares an authored Immutable value or a constant and re-evaluates a
474
+ per-instance one. A class with a required Immutable member and
468
475
  no initializer cannot be constructed at runtime; only authored values construct
469
476
  it.
470
477