@neocompose/cli 0.16.0 → 0.16.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.
Files changed (3) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/neo.mjs +374 -54
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.16.1] - 2026-07-30
4
+
5
+ ### Fixed
6
+
7
+ - Lower member defaults that read their declaring class's constructor
8
+ parameters, including nested class and collection entries, while preserving
9
+ authored row identities and source-positioned diagnostics.
10
+ - Seed structural rows for newly authored class-valued members, including root
11
+ scope members, so a new object graph can be created in the same push that
12
+ declares it.
13
+ - Resolve shared collection entry types in the overriding class's concrete
14
+ generic environment. A `List<NeoAnimationSegmentFrame<SpriteInfo>>` override
15
+ now agrees with its inherited `List<NeoAnimationSegmentFrame<T>>` declaration
16
+ and generates the corresponding concrete C# property signature.
17
+
3
18
  ## [0.16.0] - 2026-07-30
4
19
 
5
20
  ### Added
package/dist/neo.mjs CHANGED
@@ -30222,14 +30222,18 @@ function declaresParameterlessConstructor(index, className) {
30222
30222
  if (declared === void 0) return false;
30223
30223
  return declared.some((entry) => entry.parameters.length === 0);
30224
30224
  }
30225
- function initializerRequiresEvaluation(index, expression, targetClassName) {
30225
+ function initializerRequiresEvaluation(index, expression, targetClassName, runtimeIdentifiers = /* @__PURE__ */ new Set()) {
30226
30226
  if (expression.kind === "annotated") {
30227
30227
  return initializerRequiresEvaluation(
30228
30228
  index,
30229
30229
  expression.expression,
30230
- targetClassName
30230
+ targetClassName,
30231
+ runtimeIdentifiers
30231
30232
  );
30232
30233
  }
30234
+ if (expressionReadsRuntimeIdentifier(expression, runtimeIdentifiers)) {
30235
+ return true;
30236
+ }
30233
30237
  if (expression.kind === "call") return !isLiteralCall(expression);
30234
30238
  if (expression.kind !== "new") return false;
30235
30239
  const className = expression.className ?? targetClassName;
@@ -30239,6 +30243,73 @@ function initializerRequiresEvaluation(index, expression, targetClassName) {
30239
30243
  }
30240
30244
  return declaresParameterlessConstructor(index, className);
30241
30245
  }
30246
+ function declaredConstructorParameterNames(index, className) {
30247
+ if (className === null) return /* @__PURE__ */ new Set();
30248
+ return new Set(
30249
+ (index.byClassName.get(className) ?? []).flatMap(
30250
+ (constructor2) => constructor2.parameters.map((parameter3) => parameter3.name)
30251
+ )
30252
+ );
30253
+ }
30254
+ function expressionReadsRuntimeIdentifier(expression, runtimeIdentifiers) {
30255
+ if (runtimeIdentifiers.size === 0) return false;
30256
+ switch (expression.kind) {
30257
+ case "ident":
30258
+ return runtimeIdentifiers.has(expression.name);
30259
+ case "annotated":
30260
+ return expressionReadsRuntimeIdentifier(
30261
+ expression.expression,
30262
+ runtimeIdentifiers
30263
+ );
30264
+ case "new":
30265
+ return expression.args.some(
30266
+ (argument2) => expressionReadsRuntimeIdentifier(argument2, runtimeIdentifiers)
30267
+ );
30268
+ case "call":
30269
+ return expressionReadsRuntimeIdentifier(
30270
+ expression.callee,
30271
+ runtimeIdentifiers
30272
+ ) || expression.args.some(
30273
+ (argument2) => expressionReadsRuntimeIdentifier(argument2, runtimeIdentifiers)
30274
+ );
30275
+ case "member":
30276
+ return expressionReadsRuntimeIdentifier(
30277
+ expression.receiver,
30278
+ runtimeIdentifiers
30279
+ );
30280
+ case "index":
30281
+ return expressionReadsRuntimeIdentifier(
30282
+ expression.receiver,
30283
+ runtimeIdentifiers
30284
+ ) || expressionReadsRuntimeIdentifier(expression.index, runtimeIdentifiers);
30285
+ case "binary":
30286
+ case "coalesce":
30287
+ return expressionReadsRuntimeIdentifier(expression.left, runtimeIdentifiers) || expressionReadsRuntimeIdentifier(expression.right, runtimeIdentifiers);
30288
+ case "unary":
30289
+ case "force":
30290
+ case "is":
30291
+ return expressionReadsRuntimeIdentifier(
30292
+ expression.operand,
30293
+ runtimeIdentifiers
30294
+ );
30295
+ case "litInterp":
30296
+ return expression.parts.some(
30297
+ (part) => part.kind === "expr" && expressionReadsRuntimeIdentifier(part.expr, runtimeIdentifiers)
30298
+ );
30299
+ case "lambda":
30300
+ return false;
30301
+ case "litList":
30302
+ case "litDict":
30303
+ case "litNull":
30304
+ case "litBool":
30305
+ case "litInt":
30306
+ case "litFloat":
30307
+ case "litString":
30308
+ case "litTripleString":
30309
+ case "contextualEnum":
30310
+ return false;
30311
+ }
30312
+ }
30242
30313
  function isLiteralCall(expression) {
30243
30314
  if (expression.callee.kind === "ident" && expression.callee.name === "Reference") {
30244
30315
  return true;
@@ -38124,13 +38195,21 @@ function lowerClass(context, declaration) {
38124
38195
  const placements = context.placements.get(memberId) ?? [];
38125
38196
  placements.push(placement);
38126
38197
  context.placements.set(memberId, placements);
38127
- const lowered = lowerMember(
38128
- context,
38129
- declaration,
38130
- memberDeclaration,
38131
- memberId,
38132
- { kind: "classMember", ...placement }
38133
- );
38198
+ let lowered;
38199
+ try {
38200
+ lowered = lowerMember(context, declaration, memberDeclaration, memberId, {
38201
+ kind: "classMember",
38202
+ ...placement
38203
+ });
38204
+ } catch (error) {
38205
+ if (error instanceof SchemaSourceError) throw error;
38206
+ throw new SchemaSourceError(
38207
+ error instanceof Error ? error.message : String(error),
38208
+ memberDeclaration.source.uri,
38209
+ memberDeclaration.source.range.start.line + 1,
38210
+ memberDeclaration.source.range.start.character + 1
38211
+ );
38212
+ }
38134
38213
  const existing = context.loweredMembers.get(memberId);
38135
38214
  if (existing && !sameSharedMember(existing, lowered)) {
38136
38215
  throw new Error(
@@ -38551,10 +38630,20 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
38551
38630
  multiselect: true
38552
38631
  };
38553
38632
  }
38554
- const entryId = collectionEntryMemberId(
38555
- declaringCollectionMemberId(context, id2, common.overrideOf)
38633
+ const declaringMemberId = declaringCollectionMemberId(
38634
+ context,
38635
+ id2,
38636
+ common.overrideOf
38637
+ );
38638
+ const entryId = collectionEntryMemberId(declaringMemberId);
38639
+ lowerCollectionEntry(
38640
+ context,
38641
+ ownerClass,
38642
+ entryType,
38643
+ entryId,
38644
+ id2,
38645
+ declaringMemberId
38556
38646
  );
38557
- lowerCollectionEntry(context, ownerClass, entryType, entryId, id2);
38558
38647
  return {
38559
38648
  ...common,
38560
38649
  kind: "list",
@@ -38570,10 +38659,20 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
38570
38659
  }
38571
38660
  const keyType = requiredTypeArgument(fieldType, 0);
38572
38661
  const entryType = requiredTypeArgument(fieldType, 1);
38573
- const entryId = collectionEntryMemberId(
38574
- declaringCollectionMemberId(context, id2, common.overrideOf)
38662
+ const declaringMemberId = declaringCollectionMemberId(
38663
+ context,
38664
+ id2,
38665
+ common.overrideOf
38666
+ );
38667
+ const entryId = collectionEntryMemberId(declaringMemberId);
38668
+ lowerCollectionEntry(
38669
+ context,
38670
+ ownerClass,
38671
+ entryType,
38672
+ entryId,
38673
+ id2,
38674
+ declaringMemberId
38575
38675
  );
38576
- lowerCollectionEntry(context, ownerClass, entryType, entryId, id2);
38577
38676
  return {
38578
38677
  ...common,
38579
38678
  kind: "dictionary",
@@ -38723,12 +38822,24 @@ function overrideParentMemberId(context, memberId) {
38723
38822
  const overrides = member.modifiers.includes("override") || member.modifiers.includes("sealed");
38724
38823
  return overrides ? inheritedMemberId(context, ownerClass, member.name) : null;
38725
38824
  }
38726
- function lowerCollectionEntry(context, ownerClass, entryType, entryId, parentMemberId) {
38825
+ function lowerCollectionEntry(context, ownerClass, entryType, entryId, parentMemberId, declaringMemberId) {
38826
+ const declared = declaredCollectionEntryType(context, declaringMemberId);
38827
+ const expected = declared === null ? null : resolveManifestTypeInDescendant(
38828
+ context,
38829
+ declared.type,
38830
+ declared.ownerClass,
38831
+ ownerClass
38832
+ );
38833
+ if (expected !== null && !sameManifestType(expected, entryType)) {
38834
+ throw new Error(
38835
+ `Collection member ${ownerClass.name}.${parentMemberId} declares entry type ${formatManifestType(entryType)}, but the member it overrides declares ${formatManifestType(expected)}. An override cannot change a collection's element type.`
38836
+ );
38837
+ }
38727
38838
  const already = context.entryTypesByEntryId.get(entryId);
38728
38839
  if (already !== void 0) {
38729
- if (JSON.stringify(already) !== JSON.stringify(entryType)) {
38840
+ if (expected === null && !sameManifestType(already, entryType)) {
38730
38841
  throw new Error(
38731
- `Collection member ${ownerClass.name}.${parentMemberId} declares entry type ${entryType.name}, but the member it overrides declares ${already.name}. An override cannot change a collection's element type.`
38842
+ `Collection member ${ownerClass.name}.${parentMemberId} declares entry type ${formatManifestType(entryType)}, but the member it overrides declares ${formatManifestType(already)}. An override cannot change a collection's element type.`
38732
38843
  );
38733
38844
  }
38734
38845
  return;
@@ -38772,6 +38883,82 @@ function lowerCollectionEntry(context, ownerClass, entryType, entryId, parentMem
38772
38883
  lowerFieldMember(context, ownerClass, declaration, entryId, common, base)
38773
38884
  );
38774
38885
  }
38886
+ function declaredCollectionEntryType(context, declaringMemberId) {
38887
+ const placement = context.sourceMembersById.get(declaringMemberId);
38888
+ if (placement === void 0) return null;
38889
+ const collectionType = placement.member.type;
38890
+ const argumentIndex = collectionType.name === "Dictionary" ? 1 : 0;
38891
+ const type = collectionType.arguments[argumentIndex];
38892
+ return type === void 0 ? null : { type, ownerClass: placement.ownerClass };
38893
+ }
38894
+ function resolveManifestTypeInDescendant(context, type, declaringOwner, descendantOwner) {
38895
+ const declaringOwnerId = materializedId(
38896
+ declaringOwner,
38897
+ "class",
38898
+ declaringOwner.name
38899
+ );
38900
+ let current = descendantOwner;
38901
+ let environment = new Map(
38902
+ current.genericParameters.map((parameter3) => [
38903
+ parameter3.name,
38904
+ manifestNamedType(parameter3.name)
38905
+ ])
38906
+ );
38907
+ const visited = /* @__PURE__ */ new Set();
38908
+ while (true) {
38909
+ const currentId = materializedId(current, "class", current.name);
38910
+ if (currentId === declaringOwnerId) {
38911
+ return substituteManifestType2(type, environment);
38912
+ }
38913
+ if (visited.has(currentId)) return null;
38914
+ visited.add(currentId);
38915
+ const baseType = current.baseTypes[0];
38916
+ if (baseType === void 0) return null;
38917
+ const baseId = context.classIdsByName.get(baseType.name);
38918
+ if (baseId === void 0) return null;
38919
+ const baseClass = context.sourceClasses.get(baseId);
38920
+ if (baseClass === void 0) return null;
38921
+ if (baseType.arguments.length !== baseClass.genericParameters.length) {
38922
+ return null;
38923
+ }
38924
+ environment = new Map(
38925
+ baseClass.genericParameters.map((parameter3, index) => [
38926
+ parameter3.name,
38927
+ substituteManifestType2(baseType.arguments[index], environment)
38928
+ ])
38929
+ );
38930
+ current = baseClass;
38931
+ }
38932
+ }
38933
+ function substituteManifestType2(type, environment) {
38934
+ if (type.arguments.length === 0) {
38935
+ const binding = environment.get(type.name);
38936
+ if (binding !== void 0) {
38937
+ return {
38938
+ ...binding,
38939
+ nullable: type.nullable || binding.nullable
38940
+ };
38941
+ }
38942
+ }
38943
+ return {
38944
+ ...type,
38945
+ arguments: type.arguments.map(
38946
+ (argument2) => substituteManifestType2(argument2, environment)
38947
+ )
38948
+ };
38949
+ }
38950
+ function sameManifestType(left, right) {
38951
+ return left.name === right.name && left.nullable === right.nullable && left.arguments.length === right.arguments.length && left.arguments.every(
38952
+ (argument2, index) => sameManifestType(argument2, right.arguments[index])
38953
+ );
38954
+ }
38955
+ function manifestNamedType(name) {
38956
+ return { name, nullable: false, arguments: [] };
38957
+ }
38958
+ function formatManifestType(type) {
38959
+ const argumentsText = type.arguments.length === 0 ? "" : `<${type.arguments.map(formatManifestType).join(", ")}>`;
38960
+ return `${type.name}${argumentsText}${type.nullable ? "?" : ""}`;
38961
+ }
38775
38962
  function lowerInterface(context, declaration) {
38776
38963
  const id2 = materializedId(declaration, "interface", declaration.name);
38777
38964
  const base = context.baseInterfaces.get(id2);
@@ -38962,7 +39149,11 @@ function lowerDefault(context, initializer, type, ownerClass, base, memberId, st
38962
39149
  if (initializerRequiresEvaluation(
38963
39150
  context.declaredConstructors,
38964
39151
  expression,
38965
- type.name
39152
+ type.name,
39153
+ declaredConstructorParameterNames(
39154
+ context.declaredConstructors,
39155
+ ownerClass.name
39156
+ )
38966
39157
  )) {
38967
39158
  return { init: { code: normalizeInitializerSource(initializer) } };
38968
39159
  }
@@ -39021,6 +39212,17 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
39021
39212
  declaredExpected,
39022
39213
  genericEnvironment
39023
39214
  );
39215
+ if (initializerRequiresEvaluation(
39216
+ context.declaredConstructors,
39217
+ expression,
39218
+ expected.name,
39219
+ declaredConstructorParameterNames(
39220
+ context.declaredConstructors,
39221
+ ownerClass.name
39222
+ )
39223
+ )) {
39224
+ return null;
39225
+ }
39024
39226
  if (expression.kind === "annotated") {
39025
39227
  return lowerExpressionValue(
39026
39228
  context,
@@ -39755,6 +39957,7 @@ var init_lower_members = __esm({
39755
39957
  init_generic_argument_member_id();
39756
39958
  init_structured_leaf_source();
39757
39959
  init_member_kind_type_names();
39960
+ init_source_diagnostics();
39758
39961
  UNSET_LIST_COLUMN_WIDTH = -1;
39759
39962
  EMPTY_GENERIC_TYPE_ENVIRONMENT = /* @__PURE__ */ new Map();
39760
39963
  primitiveMemberKinds = /* @__PURE__ */ new Set([
@@ -46244,14 +46447,15 @@ function indexInitializerAuthoredRowIds(analysis, declaredConstructors2, classes
46244
46447
  declaration.initializer,
46245
46448
  declaration.type,
46246
46449
  declaredConstructors2,
46247
- classesByName
46450
+ classesByName,
46451
+ sourceClass.name
46248
46452
  );
46249
46453
  for (const source of sources) indexAuthoredRowIds(index, source, label);
46250
46454
  }
46251
46455
  }
46252
46456
  return index;
46253
46457
  }
46254
- function initializerSourcesRequiringEvaluation(initializer, declaredType, declaredConstructors2, classesByName) {
46458
+ function initializerSourcesRequiringEvaluation(initializer, declaredType, declaredConstructors2, classesByName, ownerClassName) {
46255
46459
  let expression;
46256
46460
  try {
46257
46461
  expression = parseExpression(initializer);
@@ -46262,7 +46466,8 @@ function initializerSourcesRequiringEvaluation(initializer, declaredType, declar
46262
46466
  if (initializerRequiresEvaluation(
46263
46467
  declaredConstructors2,
46264
46468
  expression,
46265
- targetClassName
46469
+ targetClassName,
46470
+ declaredConstructorParameterNames(declaredConstructors2, ownerClassName)
46266
46471
  )) {
46267
46472
  return [normalizeInitializerSource(initializer)];
46268
46473
  }
@@ -46270,7 +46475,12 @@ function initializerSourcesRequiringEvaluation(initializer, declaredType, declar
46270
46475
  const entryClassName = declaredEntryClassName(declaredType, classesByName);
46271
46476
  if (body.kind === "litList") {
46272
46477
  return topLevelEntrySlices(initializer, "[", "]").filter(
46273
- (entry) => entrySliceRequiresEvaluation(entry, declaredConstructors2, entryClassName)
46478
+ (entry) => entrySliceRequiresEvaluation(
46479
+ entry,
46480
+ declaredConstructors2,
46481
+ entryClassName,
46482
+ ownerClassName
46483
+ )
46274
46484
  );
46275
46485
  }
46276
46486
  if (body.kind === "litDict") {
@@ -46278,7 +46488,8 @@ function initializerSourcesRequiringEvaluation(initializer, declaredType, declar
46278
46488
  (entry) => entrySliceRequiresEvaluation(
46279
46489
  entry,
46280
46490
  declaredConstructors2,
46281
- entryClassName
46491
+ entryClassName,
46492
+ ownerClassName
46282
46493
  )
46283
46494
  );
46284
46495
  }
@@ -46292,12 +46503,13 @@ function declaredEntryClassName(declaredType, classesByName) {
46292
46503
  if (entryType === void 0) return null;
46293
46504
  return declaredClassName(entryType, classesByName);
46294
46505
  }
46295
- function entrySliceRequiresEvaluation(entry, declaredConstructors2, entryClassName) {
46506
+ function entrySliceRequiresEvaluation(entry, declaredConstructors2, entryClassName, ownerClassName) {
46296
46507
  try {
46297
46508
  return initializerRequiresEvaluation(
46298
46509
  declaredConstructors2,
46299
46510
  parseExpression(entry),
46300
- entryClassName
46511
+ entryClassName,
46512
+ declaredConstructorParameterNames(declaredConstructors2, ownerClassName)
46301
46513
  );
46302
46514
  } catch {
46303
46515
  return false;
@@ -46384,7 +46596,8 @@ function lowerMemberDefaultSourcesV4(state, analysis, manifest, options = {}) {
46384
46596
  const requiresEvaluation = initializerRequiresEvaluation(
46385
46597
  context.declaredConstructors,
46386
46598
  annotatedValue(expression).expression,
46387
- memberClassName(context, member)
46599
+ memberClassName(context, member),
46600
+ bindingRuntimeIdentifiers(context, binding)
46388
46601
  );
46389
46602
  const baseData3 = stateData(context, "member", memberId);
46390
46603
  const backed = baseData3 === null || requiresEvaluation ? null : rowBackedDefaultBody(baseData3, (id2) => pulledValueIds.has(id2));
@@ -46395,7 +46608,9 @@ function lowerMemberDefaultSourcesV4(state, analysis, manifest, options = {}) {
46395
46608
  );
46396
46609
  continue;
46397
46610
  }
46398
- if (!defaultRequiresOwnedRows(context, member, expression)) continue;
46611
+ if (!defaultRequiresOwnedRows(context, member, expression, binding)) {
46612
+ continue;
46613
+ }
46399
46614
  const rootValueId = pendingValueId(binding, `${label}.default`);
46400
46615
  const seed = lowerStaticSeed(
46401
46616
  context,
@@ -46783,12 +46998,13 @@ function declaredCollectionMemberIds(context, collectionMemberId) {
46783
46998
  }
46784
46999
  return ids;
46785
47000
  }
46786
- function defaultRequiresOwnedRows(context, member, sourceExpression) {
47001
+ function defaultRequiresOwnedRows(context, member, sourceExpression, source) {
46787
47002
  const expression = annotatedValue(sourceExpression).expression;
46788
47003
  if (initializerRequiresEvaluation(
46789
47004
  context.declaredConstructors,
46790
47005
  expression,
46791
- memberClassName(context, member)
47006
+ memberClassName(context, member),
47007
+ bindingRuntimeIdentifiers(context, source)
46792
47008
  )) {
46793
47009
  return false;
46794
47010
  }
@@ -46847,12 +47063,33 @@ function memberClassName(context, member) {
46847
47063
  if (member.kind !== "class") return null;
46848
47064
  return context.classes.get(member.classId)?.name ?? null;
46849
47065
  }
47066
+ function bindingRuntimeIdentifiers(context, source) {
47067
+ const ownerClassName = source.ownerClassId === void 0 ? null : context.classes.get(source.ownerClassId)?.name ?? null;
47068
+ return declaredConstructorParameterNames(
47069
+ context.declaredConstructors,
47070
+ ownerClassName
47071
+ );
47072
+ }
47073
+ function bindingGenericEnvironment(context, source) {
47074
+ if (source.ownerClassId === void 0) return /* @__PURE__ */ new Map();
47075
+ return classGenericEnvironment(context, source.ownerClassId);
47076
+ }
47077
+ function classGenericEnvironment(context, classId) {
47078
+ const bindings = classGenericBindings(context.classes, classId);
47079
+ const environment = /* @__PURE__ */ new Map();
47080
+ for (const genericParamId of bindings.keys()) {
47081
+ const memberId = terminalGenericBindingMemberId(genericParamId, bindings);
47082
+ if (memberId !== void 0) environment.set(genericParamId, memberId);
47083
+ }
47084
+ return environment;
47085
+ }
46850
47086
  function lowerRowBackedDefault(context, member, backed, baseData3, binding) {
46851
47087
  const baseDefault = isObjectRecord2(baseData3.defaultValue) ? baseData3.defaultValue : {};
46852
47088
  const storedClassId = stringOrNull(baseDefault.classId);
46853
47089
  const expression = annotatedValue(
46854
47090
  parseCachedInitializer(context.parsedInitializers, binding.initializer)
46855
47091
  ).expression;
47092
+ const bindingEnvironment = bindingGenericEnvironment(context, binding);
46856
47093
  if (member.kind === "class" && backed.kind === "class") {
46857
47094
  if (expression.kind !== "new") {
46858
47095
  throw new Error(`Default value ${binding.label} requires new(...).`);
@@ -46870,7 +47107,7 @@ function lowerRowBackedDefault(context, member, backed, baseData3, binding) {
46870
47107
  context,
46871
47108
  classId,
46872
47109
  member,
46873
- void 0
47110
+ bindingEnvironment
46874
47111
  );
46875
47112
  const environment = inferAnimationChildOverrideLowerEnvironment(
46876
47113
  context,
@@ -46956,7 +47193,7 @@ function lowerRowBackedDefault(context, member, backed, baseData3, binding) {
46956
47193
  element,
46957
47194
  itemId,
46958
47195
  binding,
46959
- void 0,
47196
+ bindingEnvironment,
46960
47197
  entrySlices[index]
46961
47198
  );
46962
47199
  });
@@ -46990,7 +47227,7 @@ function lowerRowBackedDefault(context, member, backed, baseData3, binding) {
46990
47227
  entry.value,
46991
47228
  entryId,
46992
47229
  binding,
46993
- void 0,
47230
+ bindingEnvironment,
46994
47231
  dictionaryValueSlice(entrySlices[entryIndex])
46995
47232
  );
46996
47233
  entryIndex += 1;
@@ -47033,7 +47270,15 @@ function lowerStoredBinding(context, binding, memberValueIds, seeds) {
47033
47270
  (pending) => pending.id
47034
47271
  )
47035
47272
  );
47036
- lowerValueRow(context, member, expression, valueId, binding);
47273
+ lowerValueRow(
47274
+ context,
47275
+ member,
47276
+ expression,
47277
+ valueId,
47278
+ binding,
47279
+ bindingGenericEnvironment(context, binding),
47280
+ binding.initializer
47281
+ );
47037
47282
  const pendingRows = [...context.pendingValues.values()].filter(
47038
47283
  (row) => !existingPendingValueIds.has(row.id)
47039
47284
  );
@@ -47133,7 +47378,7 @@ function lowerStaticSeed(context, member, sourceExpression, source, valueId) {
47133
47378
  rows,
47134
47379
  localizedTexts,
47135
47380
  void 0,
47136
- void 0,
47381
+ bindingGenericEnvironment(context, source),
47137
47382
  void 0,
47138
47383
  source.initializer
47139
47384
  );
@@ -47164,7 +47409,8 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
47164
47409
  if (initializerRequiresEvaluation(
47165
47410
  context.declaredConstructors,
47166
47411
  expression,
47167
- memberClassName(context, resolvedMember)
47412
+ memberClassName(context, resolvedMember),
47413
+ bindingRuntimeIdentifiers(context, source)
47168
47414
  )) {
47169
47415
  const code = initializerExpressionSlice(authoredSlice);
47170
47416
  if (code === void 0) {
@@ -47543,7 +47789,8 @@ function lowerValueRow(context, member, sourceExpression, expectedValueId, sourc
47543
47789
  if (initializerRequiresEvaluation(
47544
47790
  context.declaredConstructors,
47545
47791
  expression,
47546
- memberClassName(context, resolvedMember)
47792
+ memberClassName(context, resolvedMember),
47793
+ bindingRuntimeIdentifiers(context, source)
47547
47794
  )) {
47548
47795
  const code = initializerExpressionSlice(authoredSlice);
47549
47796
  if (code === void 0) {
@@ -47570,12 +47817,13 @@ function lowerValueRow(context, member, sourceExpression, expectedValueId, sourc
47570
47817
  expression,
47571
47818
  base,
47572
47819
  source,
47573
- environment
47820
+ environment,
47821
+ authoredSlice
47574
47822
  );
47575
47823
  addReconstructed(context, "value", expectedValueId, value, source.source);
47576
47824
  return expectedValueId;
47577
47825
  }
47578
- function lowerValueBody(context, member, expression, base, source, environment) {
47826
+ function lowerValueBody(context, member, expression, base, source, environment, authoredSlice) {
47579
47827
  const next = valueFileFields(base);
47580
47828
  if (expression.kind === "litNull") return { ...next, value: null };
47581
47829
  switch (member.kind) {
@@ -47635,7 +47883,8 @@ function lowerValueBody(context, member, expression, base, source, environment)
47635
47883
  expression,
47636
47884
  base,
47637
47885
  source,
47638
- environment
47886
+ environment,
47887
+ authoredSlice
47639
47888
  );
47640
47889
  case "list":
47641
47890
  return lowerListValue(
@@ -47661,7 +47910,7 @@ function lowerValueBody(context, member, expression, base, source, environment)
47661
47910
  );
47662
47911
  }
47663
47912
  }
47664
- function lowerClassValue(context, member, expression, base, source, outerEnvironment) {
47913
+ function lowerClassValue(context, member, expression, base, source, outerEnvironment, authoredSlice) {
47665
47914
  if (expression.kind !== "new")
47666
47915
  throw new Error("Class values require new(...).");
47667
47916
  const currentClassId = stringOrNull(base.classId) ?? member.classId;
@@ -47699,6 +47948,7 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
47699
47948
  );
47700
47949
  const baseBody = isObjectRecord2(base.value) ? base.value : {};
47701
47950
  const body = { ...baseBody };
47951
+ const assignmentSlices = objectInitializerSlices(authoredSlice);
47702
47952
  lowerConstructorProjections(
47703
47953
  context,
47704
47954
  schemaClass2,
@@ -47720,9 +47970,26 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
47720
47970
  }
47721
47971
  const childId = baseBody[assignment.name];
47722
47972
  if (typeof childId !== "string") {
47723
- throw new Error(
47724
- `Class value ${String(base.id)}.${assignment.name} has no existing structural row. New structural rows are not implemented by this slice.`
47973
+ const symbolId2 = sourceValueSymbol(context, assignment.value);
47974
+ if (symbolId2 !== null) {
47975
+ throw new Error(
47976
+ `Class value ${String(base.id)}.${assignment.name} cannot place existing value ${symbolId2} into a new structural slot. Create the nested value inline so the atomic construction transaction can own it.`
47977
+ );
47978
+ }
47979
+ body[assignment.name] = lowerSeedChild(
47980
+ context,
47981
+ recursivePartialMember(member, childMember),
47982
+ assignment.value,
47983
+ source,
47984
+ `${String(base.id)}.${assignment.name}`,
47985
+ /* @__PURE__ */ new Map(),
47986
+ /* @__PURE__ */ new Map(),
47987
+ void 0,
47988
+ environment,
47989
+ void 0,
47990
+ assignmentSlices.get(assignment.name)
47725
47991
  );
47992
+ continue;
47726
47993
  }
47727
47994
  const symbolId = sourceValueSymbol(context, assignment.value);
47728
47995
  if (symbolId !== null) {
@@ -47740,7 +48007,8 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
47740
48007
  assignment.value,
47741
48008
  childId,
47742
48009
  source,
47743
- environment
48010
+ environment,
48011
+ assignmentSlices.get(assignment.name)
47744
48012
  );
47745
48013
  }
47746
48014
  return {
@@ -49587,7 +49855,7 @@ function lowerInstanceGenericEnvironment(context, classId, member, outerEnvironm
49587
49855
  });
49588
49856
  }
49589
49857
  }
49590
- const environment = /* @__PURE__ */ new Map();
49858
+ const environment = new Map(classGenericEnvironment(context, classId));
49591
49859
  for (const genericParamId of bindings.keys()) {
49592
49860
  const memberId = terminalGenericBindingMemberId(genericParamId, bindings);
49593
49861
  if (memberId !== void 0) environment.set(genericParamId, memberId);
@@ -54187,7 +54455,7 @@ function computeWorkspaceStatus(workspace, options = {}) {
54187
54455
  );
54188
54456
  } catch (error) {
54189
54457
  parseErrors.push(
54190
- new SchemaSourceError(
54458
+ error instanceof SchemaSourceError ? error : new SchemaSourceError(
54191
54459
  error instanceof Error ? error.message : String(error),
54192
54460
  "<project>",
54193
54461
  1,
@@ -54256,9 +54524,15 @@ function computeWorkspaceStatus(workspace, options = {}) {
54256
54524
  { registry: valueLowerRegistry }
54257
54525
  );
54258
54526
  staticValueSeeds = new Map([...staticValueSeeds, ...rootValues.seeds]);
54527
+ const rootPathResolutionState = overlayProspectiveSourceRecords(
54528
+ workspace.state.records,
54529
+ documents,
54530
+ [...staticValues.records, ...memberDefaults.records, ...rootValues.records],
54531
+ staticMemberValueIds
54532
+ );
54259
54533
  const resolvedCollectionPaths = resolveRootPathCollectionValuesV4({
54260
54534
  manifest,
54261
- state: workspace.state.records,
54535
+ state: rootPathResolutionState,
54262
54536
  registry: valueLowerRegistry,
54263
54537
  siteForMember: (memberId) => {
54264
54538
  const span2 = sourceByKey.get(recordStateKey("member", memberId))?.span;
@@ -54587,7 +54861,28 @@ function prospectiveAnimationDocumentV4(records2) {
54587
54861
  }
54588
54862
  }
54589
54863
  if (project === void 0) return null;
54590
- return { project, classes, members, values };
54864
+ const classIdByName = new Map(classes.map((value) => [value.name, value.id]));
54865
+ const validationValues = values.map((value) => {
54866
+ if (typeof value.classId === "string") return value;
54867
+ const authoredInit = Reflect.get(value, "init");
54868
+ const init = isObjectRecord2(authoredInit) ? authoredInit : null;
54869
+ if (typeof init?.code !== "string") return value;
54870
+ let expression;
54871
+ try {
54872
+ expression = parseExpression(init.code);
54873
+ while (expression.kind === "annotated") {
54874
+ expression = expression.expression;
54875
+ }
54876
+ } catch {
54877
+ return value;
54878
+ }
54879
+ if (expression.kind !== "new" || expression.className === null)
54880
+ return value;
54881
+ const classId = classIdByName.get(expression.className);
54882
+ if (classId === void 0) return value;
54883
+ return { ...value, classId };
54884
+ });
54885
+ return { project, classes, members, values: validationValues };
54591
54886
  }
54592
54887
  function declaresAnimationWorldKind(system) {
54593
54888
  if (!isObjectRecord2(system)) return false;
@@ -61525,13 +61820,24 @@ function createdSessionValuesSince(session, existingIds) {
61525
61820
  function evaluateNSGetter(getter, ctx) {
61526
61821
  return evaluateNSGetterWithEffects(getter, ctx).value;
61527
61822
  }
61528
- function evaluateNSGetterWithEffects(getter, ctx) {
61823
+ function evaluateNSGetterWithEffects(getter, ctx, argumentValues = []) {
61529
61824
  const ownsInvocationState = ctx.__executionState === void 0;
61530
61825
  const requestedWrites = [];
61531
61826
  const runtimeCtx = withEvaluationRuntime(ctx, requestedWrites);
61532
61827
  const writes = runtimeCtx.__executionState?.writes ?? requestedWrites;
61533
61828
  const existingIds = new Set(runtimeCtx.__runtimeSessionValues.keys());
61534
61829
  const scope = createTopLevelScope(runtimeCtx);
61830
+ const parameters = getter.parameters.slice(2);
61831
+ if (parameters.length !== argumentValues.length) {
61832
+ throw new NSGetterRuntimeError(
61833
+ `NeoScript getter expected ${parameters.length} argument(s), got ${argumentValues.length}.`
61834
+ );
61835
+ }
61836
+ for (let index = 0; index < argumentValues.length; index += 1) {
61837
+ const parameter3 = parameters[index];
61838
+ if (parameter3 === void 0) continue;
61839
+ scope.set(parameter3.id, argumentValues[index]);
61840
+ }
61535
61841
  try {
61536
61842
  const result = evalInstructions(
61537
61843
  getter.instructions,
@@ -64931,10 +65237,16 @@ function runDeclaredConstructorChain(args) {
64931
65237
  true
64932
65238
  );
64933
65239
  }
64934
- function constructionInitEvaluator(ctx, createdValues) {
64935
- return (member, init) => evaluateInitializerInContext(init, member, ctx, createdValues);
65240
+ function constructionInitEvaluator(ctx, createdValues, argumentValues = []) {
65241
+ return (member, init) => evaluateInitializerInContext(
65242
+ init,
65243
+ member,
65244
+ ctx,
65245
+ createdValues,
65246
+ argumentValues
65247
+ );
64936
65248
  }
64937
- function evaluateInitializerInContext(init, member, ctx, createdValues) {
65249
+ function evaluateInitializerInContext(init, member, ctx, createdValues, argumentValues = []) {
64938
65250
  const compiled = init.compiled;
64939
65251
  if (compiled === void 0) {
64940
65252
  throw new NSGetterRuntimeError(
@@ -64944,7 +65256,11 @@ function evaluateInitializerInContext(init, member, ctx, createdValues) {
64944
65256
  const closeFrame = pushConstructionFrame(ctx, `${member.name} initializer`);
64945
65257
  let result;
64946
65258
  try {
64947
- result = evaluateNSGetterWithEffects(compiled, { ...ctx, thisValue: null });
65259
+ result = evaluateNSGetterWithEffects(
65260
+ compiled,
65261
+ { ...ctx, thisValue: null },
65262
+ argumentValues
65263
+ );
64948
65264
  } finally {
64949
65265
  closeFrame();
64950
65266
  }
@@ -65004,7 +65320,11 @@ function constructDeclaredClassValueWithinFrame(descriptor, record3, info, scope
65004
65320
  topLevelClassId: classId,
65005
65321
  createdValues,
65006
65322
  storageKeyDeclarations,
65007
- initEvaluator: constructionInitEvaluator(ctx, createdValues),
65323
+ initEvaluator: constructionInitEvaluator(
65324
+ ctx,
65325
+ createdValues,
65326
+ argumentValues
65327
+ ),
65008
65328
  constructorRoot: {
65009
65329
  providedSchemaKeys: new Set(
65010
65330
  descriptor.fields.map((validated) => validated.field.schemaKey)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neocompose/cli",
3
- "version": "0.16.0",
3
+ "version": "0.16.1",
4
4
  "description": "Neo Compose native project-source CLI with bidirectional sync.",
5
5
  "license": "MIT",
6
6
  "type": "module",