@neocompose/cli 0.89.4 → 0.89.5

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.
@@ -2569,7 +2569,7 @@ var init_strict_ir = __esm({
2569
2569
  "../packages/neoscript-language/src/strict-ir.ts"() {
2570
2570
  "use strict";
2571
2571
  init_debug_info();
2572
- NEOSCRIPT_COMPILER_REVISION = 17;
2572
+ NEOSCRIPT_COMPILER_REVISION = 18;
2573
2573
  NeoScriptDialogueOp = /* @__PURE__ */ ((NeoScriptDialogueOp2) => {
2574
2574
  NeoScriptDialogueOp2["TryTrigger"] = "TryTrigger";
2575
2575
  NeoScriptDialogueOp2["CanTrigger"] = "CanTrigger";
@@ -3964,6 +3964,8 @@ function isNSWriteTarget(value) {
3964
3964
  if (!target) return false;
3965
3965
  if (!isNSPointer(target.pointer)) return false;
3966
3966
  if (!isNSTypeInfo(target.typeInfo)) return false;
3967
+ if (target.structuredLeafKind !== void 0 && !isNeoScriptVectorKind(target.structuredLeafKind))
3968
+ return false;
3967
3969
  if (target.writability === void 0) return true;
3968
3970
  return Object.values(NSWritability).includes(target.writability);
3969
3971
  }
@@ -7287,6 +7289,9 @@ function resolveMemberWithIndex(member, memberIndex) {
7287
7289
  chain.reverse();
7288
7290
  const merged = {};
7289
7291
  for (const link of chain) {
7292
+ if (link.requirement === 1 /* Required */ && link.defaultValue == null && getField(merged.defaultValue, "value") === null) {
7293
+ delete merged.defaultValue;
7294
+ }
7290
7295
  if (getField(link, "classId") !== void 0) {
7291
7296
  delete merged.interfaceId;
7292
7297
  delete merged.interfaceArguments;
@@ -15893,11 +15898,36 @@ function cloneDefaultValueForMember(args) {
15893
15898
  throw new Error(
15894
15899
  `Cannot clone default value graph: circular reference at value "${args.sourceValueId}".`
15895
15900
  );
15896
- const source = findValueInDocument(
15901
+ const member = substituteMember(
15902
+ args.member,
15903
+ args.genericEnv,
15904
+ args.document.members,
15905
+ args.document.resolvedMember?.(args.member)
15906
+ );
15907
+ const resolved = args.document.defaultValueSource?.(
15908
+ args.sourceValueId,
15909
+ member
15910
+ );
15911
+ const source = resolved?.value ?? findValueInDocument(
15897
15912
  args.document,
15898
15913
  args.sourceValueId,
15899
15914
  args.referenceLocation
15900
15915
  );
15916
+ if (resolved?.rowsById !== void 0) {
15917
+ const document = args.document;
15918
+ const rows = resolved.rowsById;
15919
+ args = {
15920
+ ...args,
15921
+ document: {
15922
+ ...document,
15923
+ valueById: (id2) => rows.get(id2) ?? document.valueById?.(id2) ?? null,
15924
+ defaultValueSource: (id2, child2) => {
15925
+ const value = rows.get(id2);
15926
+ return value === void 0 ? document.defaultValueSource?.(id2, child2) ?? null : { value };
15927
+ }
15928
+ }
15929
+ };
15930
+ }
15901
15931
  if (capture === void 0)
15902
15932
  return cloneDefaultValueForMemberCore(args, source);
15903
15933
  const start = source.changeListeners === void 0 ? void 0 : capture.begin();
@@ -19377,7 +19407,7 @@ var init_registry = __esm({
19377
19407
  "../packages/manifest/schema-contract/registry.mjs"() {
19378
19408
  "use strict";
19379
19409
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
19380
- cliVersion: "0.89.4",
19410
+ cliVersion: "0.89.5",
19381
19411
  projectFileUploadBatchSize: 32,
19382
19412
  documentRecords: {
19383
19413
  member: {
@@ -27842,6 +27872,15 @@ function isCallableMemberForCodegen(value) {
27842
27872
  }
27843
27873
  function createGenerationContext(exportData, diagnostics, docs = EMPTY_UNITY_CODEGEN_DOCS) {
27844
27874
  const classes = Object.values(exportData.classes);
27875
+ const genericDeclarations = /* @__PURE__ */ new Map();
27876
+ for (const schemaClass2 of classes) {
27877
+ for (const param of schemaClass2.genericParams ?? []) {
27878
+ genericDeclarations.set(param.id, {
27879
+ param,
27880
+ declaringClassId: schemaClass2.id
27881
+ });
27882
+ }
27883
+ }
27845
27884
  const members2 = Object.values(exportData.members);
27846
27885
  const dialogueGroups = Object.values(exportData.dialogueGroups ?? {});
27847
27886
  const dialogueGroupsByParent = /* @__PURE__ */ new Map();
@@ -27935,6 +27974,7 @@ function createGenerationContext(exportData, diagnostics, docs = EMPTY_UNITY_COD
27935
27974
  declarationSignatures: /* @__PURE__ */ new Map(),
27936
27975
  worldKinds: indexWorldSystemClassKinds(classes),
27937
27976
  resolvedMembers: /* @__PURE__ */ new Map(),
27977
+ genericDeclarations,
27938
27978
  genericScopes: /* @__PURE__ */ new Map(),
27939
27979
  genericEnvironments: /* @__PURE__ */ new Map(),
27940
27980
  functionGenericParams: indexFunctionGenericParams(
@@ -28152,12 +28192,25 @@ function inheritedGeneratedMemberContract(ctx, ownerClassId, schemaKey, memberId
28152
28192
  }
28153
28193
  return null;
28154
28194
  }
28195
+ function declaredGeneratedPropertyValueType(ctx, member, memberSaved, saved, genericEnv) {
28196
+ const declared = lookupDeclaredTypeInfo(member);
28197
+ if (declared?.type !== 21 /* Generic */ || isMultiSelectionMember(member))
28198
+ return csharpPropertyValueType(ctx, member, memberSaved, genericEnv, saved);
28199
+ const target = csharpTypeInfoValueType(ctx, declared, saved, genericEnv);
28200
+ if (target === null) return null;
28201
+ return lookupProjection(ctx, member) === "slot" /* Slot */ ? `NeoReference<${target}>${isRequiredMember(member) ? "" : "?"}` : target;
28202
+ }
28155
28203
  function emittedGeneratedMemberContract(ctx, ownerClassId, schemaKey, memberId, saved, genericEnv) {
28156
- const member = ctx.exportData.members[memberId];
28157
- if (member === void 0) return null;
28204
+ const member = resolveMemberById(ctx, memberId, `members.${memberId}`);
28205
+ if (member === null) return null;
28158
28206
  const memberSaved = memberSavedForStorage(ctx, memberId, saved, ownerClassId);
28159
- const declaredLookupType = lookupDeclaredTypeInfo(member);
28160
- const valueType = declaredLookupType !== null && declaredLookupType.type === 21 /* Generic */ ? csharpTypeInfoValueType(ctx, declaredLookupType, saved, genericEnv) : csharpPropertyValueType(ctx, member, memberSaved, genericEnv, saved);
28207
+ const valueType = declaredGeneratedPropertyValueType(
28208
+ ctx,
28209
+ member,
28210
+ memberSaved,
28211
+ saved,
28212
+ genericEnv
28213
+ );
28161
28214
  if (valueType === null) return null;
28162
28215
  const inherited = inheritedGeneratedMemberContract(
28163
28216
  ctx,
@@ -28168,11 +28221,38 @@ function emittedGeneratedMemberContract(ctx, ownerClassId, schemaKey, memberId,
28168
28221
  genericEnv
28169
28222
  );
28170
28223
  const hasSetter = emitsGeneratedSetter(member, memberSaved) && !suppressesInheritedSetter(inherited);
28224
+ const declaredValueTypeInfo = generatedValueTypeInfo(ctx, member);
28225
+ const readsReferenceValue = referenceImplementsValueContract(
28226
+ ctx,
28227
+ member,
28228
+ valueType,
28229
+ inherited
28230
+ );
28231
+ let valueTypeInfo = declaredValueTypeInfo;
28232
+ if (readsReferenceValue && inherited !== null) {
28233
+ valueTypeInfo = inherited.valueTypeInfo;
28234
+ } else if (isMemberLookupBase(member) && !isMultiSelectionMember(member) && lookupProjection(ctx, member) === "slot" /* Slot */ && declaredValueTypeInfo !== null) {
28235
+ valueTypeInfo = {
28236
+ type: 29 /* Reference */,
28237
+ required: isRequiredMember(member),
28238
+ targetTypeInfo: declaredValueTypeInfo
28239
+ };
28240
+ }
28241
+ const emittedValueType = narrowedMemberValueType(
28242
+ ctx,
28243
+ member,
28244
+ valueType,
28245
+ inherited
28246
+ );
28247
+ if (inherited?.valueTypeInfo?.type === 29 /* Reference */ && emittedValueType === inherited.valueType) {
28248
+ valueTypeInfo = inherited.valueTypeInfo;
28249
+ }
28171
28250
  return {
28172
- valueType: narrowedMemberValueType(ctx, member, valueType, inherited),
28251
+ valueType: emittedValueType,
28173
28252
  hasSetter,
28174
28253
  getOnlyContract: (inherited?.getOnlyContract ?? false) || isAbstractMember(member) === true && !hasSetter,
28175
- valueTypeInfo: generatedValueTypeInfo(ctx, member),
28254
+ valueTypeInfo,
28255
+ genericEnv,
28176
28256
  closesGenericType: (inherited?.closesGenericType ?? false) || lookupNarrowsThroughGenericParam(member) || isMemberGenericBase(member)
28177
28257
  };
28178
28258
  }
@@ -28181,7 +28261,8 @@ function suppressesInheritedSetter(contract) {
28181
28261
  }
28182
28262
  function generatedValueTypeInfo(ctx, member) {
28183
28263
  const required2 = isRequiredMember(member);
28184
- if (isMemberTupleBase(member)) return memberTypeInfoForCodegen(ctx, member);
28264
+ if (isMemberTupleBase(member) || isMemberVariantBase(member))
28265
+ return memberTypeInfoForCodegen(ctx, member);
28185
28266
  const slotType = classSlotTypeInfo(ctx, member, required2);
28186
28267
  if (slotType !== null) return slotType;
28187
28268
  const returnType = nsPropertyReturnTypeInfo(member);
@@ -28196,8 +28277,8 @@ function generatedValueTypeInfo(ctx, member) {
28196
28277
  return null;
28197
28278
  }
28198
28279
  function genericParamTypeInfo(ctx, genericParamId, required2) {
28199
- const declaration = findGenericParamDeclaration(genericParamId, ctx.classes);
28200
- if (declaration === null) {
28280
+ const declaration = ctx.genericDeclarations.get(genericParamId);
28281
+ if (declaration === void 0) {
28201
28282
  ctx.diagnostics.push({
28202
28283
  severity: "error",
28203
28284
  message: `Generic param "${genericParamId}" is not declared by any type in the export.`,
@@ -28208,7 +28289,7 @@ function genericParamTypeInfo(ctx, genericParamId, required2) {
28208
28289
  return {
28209
28290
  type: 21 /* Generic */,
28210
28291
  required: required2,
28211
- ownerClassId: declaration.declaringClass.id,
28292
+ ownerClassId: declaration.declaringClassId,
28212
28293
  genericParamId
28213
28294
  };
28214
28295
  }
@@ -28229,7 +28310,7 @@ function classSlotTypeInfo(ctx, member, required2) {
28229
28310
  "classArguments"
28230
28311
  );
28231
28312
  if (argument2 === null) return null;
28232
- const typeInfo = memberTypeInfoForCodegen(ctx, argument2);
28313
+ const typeInfo = storedMemberTypeInfoForCodegen(ctx, argument2);
28233
28314
  if (typeInfo === null) return null;
28234
28315
  typeArguments[parameterId] = typeInfo;
28235
28316
  }
@@ -28257,9 +28338,63 @@ function generatedValueClassId(ctx, member) {
28257
28338
  const typeInfo = generatedValueTypeInfo(ctx, member);
28258
28339
  return typeInfo?.type === 7 /* Class */ ? typeInfo.classId : null;
28259
28340
  }
28341
+ function referenceDepth(ctx, type2, env) {
28342
+ let depth = 0;
28343
+ let current = type2;
28344
+ let seen;
28345
+ while (current !== null) {
28346
+ if (current.type === 29 /* Reference */) {
28347
+ depth++;
28348
+ current = current.targetTypeInfo;
28349
+ continue;
28350
+ }
28351
+ if (current.type !== 21 /* Generic */) return depth;
28352
+ if (!isClassGenericParamTypeInfo(current)) return depth;
28353
+ const entry = env?.get(current.genericParamId);
28354
+ if (entry === void 0 || entry.kind === "unbound") return depth;
28355
+ seen ??= /* @__PURE__ */ new Set();
28356
+ if (seen.has(entry.memberId)) return null;
28357
+ seen.add(entry.memberId);
28358
+ const binding = resolveMemberById(ctx, entry.memberId, "genericBinding");
28359
+ if (binding === null) return null;
28360
+ if (isMemberGenericBase(binding)) {
28361
+ current = genericParamTypeInfo(ctx, binding.genericParamId, true);
28362
+ } else if (isMemberLookupBase(binding) && !isMultiSelectionMember(binding)) {
28363
+ current = slotTypeInfo(binding, ctx);
28364
+ } else {
28365
+ return depth;
28366
+ }
28367
+ }
28368
+ return null;
28369
+ }
28370
+ function referenceImplementsValueContract(ctx, member, rawValueType, contract) {
28371
+ if (contract?.getOnlyContract !== true || !isMemberLookupBase(member) || isMultiSelectionMember(member))
28372
+ return false;
28373
+ const projection = lookupProjection(ctx, member);
28374
+ if (contract.valueTypeInfo?.type === 21 /* Generic */ && (lookupDeclaredTypeInfo(member)?.type === 21 /* Generic */ || projection === "collection" /* Collection */))
28375
+ return true;
28376
+ if (projection !== "slot" /* Slot */) return false;
28377
+ const target = lookupDeclaredTypeInfo(member);
28378
+ const inherited = contract.valueTypeInfo;
28379
+ if (target?.type === 29 /* Reference */ && inherited?.type === 29 /* Reference */) {
28380
+ const targetDepth = referenceDepth(ctx, target, contract.genericEnv);
28381
+ return targetDepth !== null && targetDepth === referenceDepth(ctx, inherited, contract.genericEnv);
28382
+ }
28383
+ const wrapper = `NeoReference<${contract.valueType}>`;
28384
+ if (rawValueType === wrapper || rawValueType === `${wrapper}?`) return true;
28385
+ if (contract.valueType.endsWith("?")) {
28386
+ const requiredTarget = `NeoReference<${contract.valueType.slice(0, -1)}>`;
28387
+ return rawValueType === requiredTarget || rawValueType === `${requiredTarget}?`;
28388
+ }
28389
+ return false;
28390
+ }
28260
28391
  function narrowedMemberValueType(ctx, member, rawValueType, contract) {
28261
28392
  if (contract === null) return rawValueType;
28262
28393
  if (contract.valueType === rawValueType) return rawValueType;
28394
+ if (referenceImplementsValueContract(ctx, member, rawValueType, contract))
28395
+ return contract.valueType;
28396
+ if (contract.valueTypeInfo?.type === 29 /* Reference */ && isMemberLookupBase(member) && !isMultiSelectionMember(member))
28397
+ return contract.valueType;
28263
28398
  if (contract.closesGenericType && !isMemberGenericBase(member) && !lookupNarrowsThroughGenericParam(member)) {
28264
28399
  return contract.valueType;
28265
28400
  }
@@ -28278,6 +28413,13 @@ function narrowedMemberValueType(ctx, member, rawValueType, contract) {
28278
28413
  return rawValueType;
28279
28414
  const valueType = generatedValueTypeInfo(ctx, member);
28280
28415
  if (valueType === null) return rawValueType;
28416
+ if (isMemberVariantBase(member) && member.valueTypeInfo == null && inheritedType.type === 7 /* Class */ && valueType.type === 7 /* Class */ && inheritedType.classId === valueType.classId) {
28417
+ const declaration = ctx.exportData.classes[inheritedType.classId];
28418
+ const targetParamId = declaration?.genericParams?.[0]?.id;
28419
+ const target = targetParamId === void 0 ? void 0 : inheritedType.typeArguments?.[targetParamId];
28420
+ if (declaration?.system?.worldKind === NeoWorldSystemClassKind.Variant && target !== void 0 && isTypeInfoAssignable(member.targetTypeInfo, target, ctx))
28421
+ return contract.valueType;
28422
+ }
28281
28423
  const sourceType = valueType.type === 7 /* Class */ && inheritedType.type === 7 /* Class */ && valueType.required === false && inheritedType.required === true ? { ...valueType, required: true } : valueType;
28282
28424
  try {
28283
28425
  return isTypeInfoAssignable(sourceType, inheritedType, ctx) ? contract.valueType : rawValueType;
@@ -28380,8 +28522,13 @@ function calculateDeclarationSignature(ctx, projectionClassId, schemaKey, declar
28380
28522
  true,
28381
28523
  declaration.classDef.id
28382
28524
  );
28383
- const declaredLookupType = lookupDeclaredTypeInfo(member);
28384
- const valueType = declaredLookupType !== null && declaredLookupType.type === 21 /* Generic */ ? csharpTypeInfoValueType(ctx, declaredLookupType, true, genericEnv) : csharpPropertyValueType(ctx, member, memberSaved, genericEnv, true);
28525
+ const valueType = declaredGeneratedPropertyValueType(
28526
+ ctx,
28527
+ member,
28528
+ memberSaved,
28529
+ true,
28530
+ genericEnv
28531
+ );
28385
28532
  if (valueType === null) return null;
28386
28533
  const contract = inheritedGeneratedMemberContract(
28387
28534
  ctx,
@@ -28744,11 +28891,11 @@ function csharpGenericParamType(ctx, genericParamId, saved, env, path) {
28744
28891
  if (entry !== void 0 && entry.kind === "member") {
28745
28892
  const bindingMember = resolveMemberById(ctx, entry.memberId, path);
28746
28893
  if (bindingMember === null) return null;
28747
- return csharpValueType(ctx, bindingMember, saved, env);
28894
+ return csharpGenericArgumentMemberType(ctx, bindingMember, env, saved);
28748
28895
  }
28749
28896
  const terminalParamId = entry !== void 0 && entry.kind === "unbound" ? entry.paramId : genericParamId;
28750
- const declaration = findGenericParamDeclaration(terminalParamId, ctx.classes);
28751
- if (declaration === null) {
28897
+ const declaration = ctx.genericDeclarations.get(terminalParamId);
28898
+ if (declaration === void 0) {
28752
28899
  ctx.diagnostics.push({
28753
28900
  severity: "error",
28754
28901
  message: `Generic param "${terminalParamId}" is not declared by any type in the export.`,
@@ -28796,7 +28943,7 @@ function constructedTypeArgumentsSuffix(ctx, member, saved, env, genericBindingS
28796
28943
  }
28797
28944
  const bindingMember = resolveMemberById(ctx, arg.memberId, path);
28798
28945
  if (bindingMember === null) return null;
28799
- const argType = csharpValueType(ctx, bindingMember, true, env);
28946
+ const argType = csharpGenericArgumentMemberType(ctx, bindingMember, env);
28800
28947
  if (argType === null) {
28801
28948
  ctx.diagnostics.push({
28802
28949
  severity: "error",
@@ -28944,7 +29091,7 @@ function interfaceBridgeCodecType(ctx, typeInfo, env) {
28944
29091
  function bindingMemberValueType(ctx, memberId, env, path) {
28945
29092
  const bindingMember = resolveMemberById(ctx, memberId, path);
28946
29093
  if (bindingMember === null) return null;
28947
- return csharpValueType(ctx, bindingMember, true, env);
29094
+ return csharpGenericArgumentMemberType(ctx, bindingMember, env);
28948
29095
  }
28949
29096
  function typeInfoInterfaceArgumentsSuffix(ctx, typeInfo, genericEnv, genericBindingSaved) {
28950
29097
  const params = ctx.exportData.interfaces[typeInfo.interfaceId]?.genericParams;
@@ -28964,10 +29111,16 @@ function typeInfoInterfaceArgumentsSuffix(ctx, typeInfo, genericEnv, genericBind
28964
29111
  });
28965
29112
  return null;
28966
29113
  }
28967
- const argType = csharpTypeInfoValueType(
29114
+ const argType = sequenceParameters.has(param.id) ? csharpTypeInfoValueType(
28968
29115
  ctx,
28969
29116
  argInfo,
28970
- !sequenceParameters.has(param.id),
29117
+ false,
29118
+ genericEnv,
29119
+ genericBindingSaved
29120
+ ) : csharpGenericArgumentType(
29121
+ ctx,
29122
+ argInfo,
29123
+ true,
28971
29124
  genericEnv,
28972
29125
  genericBindingSaved
28973
29126
  );
@@ -29463,6 +29616,120 @@ function animationClipTargetType(ctx, member, env, ownerClassId) {
29463
29616
  }
29464
29617
  return constructedTarget;
29465
29618
  }
29619
+ function storedMemberTypeInfoForCodegen(ctx, member) {
29620
+ if (isMemberTupleBase(member)) return tupleMemberTypeInfo(ctx, member);
29621
+ if (isMemberLookupBase(member) || isMemberEnumBase(member))
29622
+ return slotTypeInfo(member, ctx);
29623
+ if (isMemberWithEntries(member)) {
29624
+ const entry = resolveMemberById(ctx, member.entryMemberId, "entryMemberId");
29625
+ if (entry === null) return null;
29626
+ const entryTypeInfo = storedMemberTypeInfoForCodegen(ctx, entry);
29627
+ if (entryTypeInfo === null) return null;
29628
+ return {
29629
+ type: member.kind,
29630
+ required: isRequiredMember(member),
29631
+ entryTypeInfo,
29632
+ ...isMemberDictionaryBase(member) && member.keyEnumId ? { keyEnumId: member.keyEnumId } : {}
29633
+ };
29634
+ }
29635
+ return memberTypeInfoForCodegen(ctx, member);
29636
+ }
29637
+ function csharpGenericArgumentMemberType(ctx, member, env, saved = true) {
29638
+ const type2 = storedMemberTypeInfoForCodegen(ctx, member);
29639
+ return type2 === null ? csharpValueType(ctx, member, saved, env) : csharpGenericArgumentType(ctx, type2, saved, env);
29640
+ }
29641
+ function csharpGenericArgumentType(ctx, type2, saved, env, genericBindingSaved = saved) {
29642
+ const optional2 = type2.required ? "" : "?";
29643
+ const family = saved ? "Neo" : "NeoReadOnly";
29644
+ switch (type2.type) {
29645
+ case 14 /* Vector2 */:
29646
+ case 15 /* Vector2Int */:
29647
+ case 16 /* Vector3 */:
29648
+ case 17 /* Vector3Int */:
29649
+ return `${vectorWrapperType(type2.type, saved)}${optional2}`;
29650
+ case 19 /* Color */:
29651
+ return `${family}Color${optional2}`;
29652
+ case 6 /* List */:
29653
+ case 5 /* Dictionary */:
29654
+ case 28 /* Set */:
29655
+ case 9 /* Lookup */: {
29656
+ const entry = type2.entryTypeInfo;
29657
+ const set = type2.type === 28 /* Set */ || type2.type === 9 /* Lookup */;
29658
+ let wrapper = type2.type === 6 /* List */ ? "List" : "Dictionary";
29659
+ let entryType;
29660
+ if (set && entry.type === 29 /* Reference */) {
29661
+ wrapper = "LookupSet";
29662
+ entryType = csharpGenericArgumentType(
29663
+ ctx,
29664
+ entry,
29665
+ false,
29666
+ env,
29667
+ genericBindingSaved
29668
+ );
29669
+ } else if (set && entry.type === 8 /* Enum */) {
29670
+ wrapper = "EnumSet";
29671
+ entryType = csharpTypeInfoValueType(
29672
+ ctx,
29673
+ entry,
29674
+ false,
29675
+ env,
29676
+ genericBindingSaved
29677
+ );
29678
+ } else if (set && entry.type === 18 /* DialogueLookup */) {
29679
+ return `${family}DialogueReferenceSet${optional2}`;
29680
+ } else {
29681
+ if (set) wrapper = "Set";
29682
+ const entrySaved = saved && (!set || entry.type === 7 /* Class */ || entry.type === 22 /* Interface */ || entry.type === 21 /* Generic */);
29683
+ entryType = csharpGenericArgumentType(
29684
+ ctx,
29685
+ entry,
29686
+ entrySaved,
29687
+ env,
29688
+ genericBindingSaved
29689
+ );
29690
+ }
29691
+ if (entryType === null) return null;
29692
+ if (type2.type === 5 /* Dictionary */ && type2.keyEnumId !== void 0) {
29693
+ const key = ctx.enumNames.get(type2.keyEnumId);
29694
+ if (key === void 0) return null;
29695
+ entryType = `${key}, ${entryType}`;
29696
+ }
29697
+ return `${family}${wrapper}<${entryType}>${optional2}`;
29698
+ }
29699
+ case 29 /* Reference */: {
29700
+ const collection = referencedCollectionView(
29701
+ ctx,
29702
+ type2.targetTypeInfo,
29703
+ env
29704
+ );
29705
+ if (collection !== null) return `${collection.view}${optional2}`;
29706
+ const handle = referenceHandleTypeInfo(ctx, type2);
29707
+ if (handle !== null)
29708
+ return csharpTypeInfoValueType(
29709
+ ctx,
29710
+ handle,
29711
+ false,
29712
+ env,
29713
+ genericBindingSaved
29714
+ );
29715
+ return csharpTypeInfoValueType(
29716
+ ctx,
29717
+ type2,
29718
+ false,
29719
+ env,
29720
+ genericBindingSaved
29721
+ );
29722
+ }
29723
+ default:
29724
+ return csharpTypeInfoValueType(
29725
+ ctx,
29726
+ type2,
29727
+ saved,
29728
+ env,
29729
+ genericBindingSaved
29730
+ );
29731
+ }
29732
+ }
29466
29733
  function csharpTypeInfoValueType(ctx, typeInfo, saved, genericEnv, genericBindingSaved = saved) {
29467
29734
  const optional2 = !typeInfo.required;
29468
29735
  switch (typeInfo.type) {
@@ -29648,7 +29915,7 @@ function typeInfoConstructedSuffix(ctx, typeInfo, saved, genericEnv, genericBind
29648
29915
  });
29649
29916
  return null;
29650
29917
  }
29651
- const argType = csharpTypeInfoValueType(
29918
+ const argType = csharpGenericArgumentType(
29652
29919
  ctx,
29653
29920
  argInfo,
29654
29921
  true,
@@ -30384,24 +30651,29 @@ function pointerOwnershipForStorage(storage) {
30384
30651
  return "asset";
30385
30652
  }
30386
30653
  }
30654
+ function tupleMemberTypeInfo(ctx, member) {
30655
+ const elements = [];
30656
+ for (const [index, id2] of member.elementMemberIds.entries()) {
30657
+ const descriptor = resolveMemberById(ctx, id2, "elementMemberIds");
30658
+ if (descriptor === null) return null;
30659
+ const typeInfo = storedMemberTypeInfoForCodegen(ctx, descriptor);
30660
+ if (typeInfo === null) return null;
30661
+ elements.push({
30662
+ typeInfo,
30663
+ ...descriptor.name === `Item${index + 1}` ? {} : { name: descriptor.name }
30664
+ });
30665
+ }
30666
+ return {
30667
+ type: 30 /* Tuple */,
30668
+ required: isRequiredMember(member),
30669
+ elements
30670
+ };
30671
+ }
30387
30672
  function memberTypeInfoForCodegen(ctx, member) {
30388
30673
  const required2 = isRequiredMember(member);
30389
30674
  if (isMemberGenericBase(member))
30390
30675
  return genericParamTypeInfo(ctx, member.genericParamId, required2);
30391
- if (isMemberTupleBase(member)) {
30392
- const elements = [];
30393
- for (const [index, id2] of member.elementMemberIds.entries()) {
30394
- const descriptor = resolveMemberById(ctx, id2, "elementMemberIds");
30395
- if (descriptor === null) return null;
30396
- const typeInfo = memberTypeInfoForCodegen(ctx, descriptor);
30397
- if (typeInfo === null) return null;
30398
- elements.push({
30399
- typeInfo,
30400
- ...descriptor.name === `Item${index + 1}` ? {} : { name: descriptor.name }
30401
- });
30402
- }
30403
- return { type: 30 /* Tuple */, required: required2, elements };
30404
- }
30676
+ if (isMemberTupleBase(member)) return tupleMemberTypeInfo(ctx, member);
30405
30677
  const slotType = classSlotTypeInfo(ctx, member, required2);
30406
30678
  if (slotType !== null) return slotType;
30407
30679
  if (isMemberLookupBase(member)) {
@@ -30446,9 +30718,12 @@ function memberTypeInfoForCodegen(ctx, member) {
30446
30718
  }
30447
30719
  if (isMemberNSPropertyBase(member)) return member.returnTypeInfo;
30448
30720
  if (isMemberVariantBase(member)) {
30721
+ const lookup = member.valueTypeInfo != null;
30722
+ const kind = lookup ? NeoWorldSystemClassKind.LookupVariant : NeoWorldSystemClassKind.Variant;
30723
+ const declaration = ctx.exportData.classes[requireWorldSystemClassDefinition(kind).classId];
30449
30724
  const systemClass = neoVariantSystemClass(
30450
- ctx.classes,
30451
- member.valueTypeInfo != null
30725
+ declaration === void 0 ? [] : [declaration],
30726
+ lookup
30452
30727
  );
30453
30728
  return variantMemberDeclaredTypeInfo(member, systemClass);
30454
30729
  }
@@ -36730,6 +37005,13 @@ var init_function_type_inference = __esm({
36730
37005
  this.bounds[index]?.set(`${kind}:${identity(type2)}`, { type: type2, kind });
36731
37006
  return;
36732
37007
  }
37008
+ if (pattern.kind === "tuple" && actual.kind === "tuple") {
37009
+ if (actual.elements.length !== pattern.elements.length) return;
37010
+ pattern.elements.forEach((element, index) => {
37011
+ this.add(actual.elements[index].type, element.type, kind);
37012
+ });
37013
+ return;
37014
+ }
36733
37015
  if (pattern.kind === "named" && (pattern.typeId === NEO_SEQUENCE_IDS.IEnumerable || pattern.typeId === NEO_SEQUENCE_IDS.IEnumerator)) {
36734
37016
  const sourceElement = neoScriptSequenceElementType(actual, "IEnumerable", this.project) ?? (pattern.typeId === NEO_SEQUENCE_IDS.IEnumerator ? neoScriptSequenceElementType(actual, "IEnumerator", this.project) : void 0);
36735
37017
  const expectedElement = pattern.typeArguments?.[0];
@@ -39023,6 +39305,25 @@ function addEvaluatorParentLink(indexes4, childId, parentId, key) {
39023
39305
  links.push({ parentId, key });
39024
39306
  indexes4.parentLinksByChildId.set(childId, links);
39025
39307
  }
39308
+ function indexRuntimeCollectionAppend(collection, entry, ctx) {
39309
+ const indexes4 = ctx.__indexes;
39310
+ const row = indexes4?.rowByValueReference.get(collection);
39311
+ if (indexes4 === void 0 || indexes4.invalidated || row === void 0 || ctx.__runtimeSessionValues?.get(row.id) !== row || !indexes4.indexedRowIds.has(row.id))
39312
+ return false;
39313
+ if (typeof entry === "string") {
39314
+ addEvaluatorParentLink(indexes4, entry, row.id, "");
39315
+ indexes4.ownedValueAttachmentsByValueId.delete(entry);
39316
+ indexes4.constructorOwnershipDirtyValueIds.add(entry);
39317
+ indexes4.ownershipRootIdsByRowId.clear();
39318
+ indexes4.ownershipDistancesByRowId.clear();
39319
+ indexes4.memberByRowId.clear();
39320
+ }
39321
+ forgetLocalListIndexes(ctx, collection);
39322
+ markOverlayMutated(ctx, collection);
39323
+ if (ctx.__valueOverlay instanceof LazyValueOverlay)
39324
+ indexes4.overlayRevision = ctx.__valueOverlay.revision;
39325
+ return true;
39326
+ }
39026
39327
  function evaluatorParentLinks(indexes4, childId) {
39027
39328
  const unfilteredBase = indexes4.baseParentLinksByChildId?.get(childId) ?? [];
39028
39329
  const base = indexes4.shadowedBaseRowIds.size === 0 ? unfilteredBase : unfilteredBase.filter(
@@ -39343,11 +39644,15 @@ function evaluatorDefaultValueDocument(ctx) {
39343
39644
  project: ctx.vm.project,
39344
39645
  members: ctx.vm.members,
39345
39646
  classes: ctx.vm.classes,
39647
+ constructors: ctx.vm.constructors,
39346
39648
  interfaces: ctx.vm.interfaces ?? NO_INTERFACES,
39347
39649
  enums: ctx.vm.enums,
39348
39650
  values: ctx.vm.values,
39349
39651
  memberById: ctx.vm.databaseVM?.memberById,
39350
- valueById: ctx.vm.databaseVM?.defaultValueById ?? ctx.vm.databaseVM?.valueById,
39652
+ defaultValueSource: ctx.vm.databaseVM?.defaultValueSource?.bind(
39653
+ ctx.vm.databaseVM
39654
+ ),
39655
+ valueById: ctx.vm.databaseVM?.valueById,
39351
39656
  unorderedListEntryIds: ctx.vm.databaseVM?.unorderedListEntryIds?.bind(
39352
39657
  ctx.vm.databaseVM
39353
39658
  ),
@@ -41455,6 +41760,12 @@ function evalInstructions(instructions, scope, ctx, options) {
41455
41760
  destination
41456
41761
  );
41457
41762
  }
41763
+ if (target.structuredLeafKind !== void 0 && destination !== void 0)
41764
+ validateStructuredFieldAssignment(
41765
+ target.structuredLeafKind,
41766
+ String(destination.key),
41767
+ value
41768
+ );
41458
41769
  assertStoredClosureCaptures(
41459
41770
  member,
41460
41771
  target.pointer,
@@ -41474,7 +41785,7 @@ function evalInstructions(instructions, scope, ctx, options) {
41474
41785
  const selection2 = encodeLookupInitializerSelection(
41475
41786
  lookupMember,
41476
41787
  value,
41477
- [],
41788
+ /* @__PURE__ */ new Set(),
41478
41789
  ctx,
41479
41790
  lookupTarget
41480
41791
  );
@@ -41487,7 +41798,7 @@ function evalInstructions(instructions, scope, ctx, options) {
41487
41798
  );
41488
41799
  value = selection2;
41489
41800
  }
41490
- let targetTypeInfo = target.typeInfo;
41801
+ let targetTypeInfo = runtimeConcreteTypeInfo(target.typeInfo, ctx);
41491
41802
  if (lookupMember !== null && targetTypeInfo.type !== 9 /* Lookup */ && targetTypeInfo.type !== 18 /* DialogueLookup */) {
41492
41803
  const entryTypeInfo = targetTypeInfo.type === 29 /* Reference */ ? targetTypeInfo.targetTypeInfo : targetTypeInfo;
41493
41804
  targetTypeInfo = lookupMember.collectionMemberId === void 0 ? {
@@ -42176,6 +42487,23 @@ function evalActionListenerInstruction(ins, scope, ctx, options) {
42176
42487
  ...resolvedDestinationFieldsForAssign(target, scope, ctx, destination)
42177
42488
  });
42178
42489
  }
42490
+ function validateStructuredFieldAssignment(kind, field, value) {
42491
+ const subject = kind === "Color" ? `Colour channel '${field}'` : `Vector field '${field}'`;
42492
+ if (typeof value !== "number")
42493
+ throw new NSGetterRuntimeError(`${subject} must be numeric.`);
42494
+ const numeric = value;
42495
+ if (!Number.isFinite(numeric))
42496
+ throw new NSGetterRuntimeError(`${subject} must be a finite number.`);
42497
+ if (kind === "Color" && (numeric < 0 || numeric > 1))
42498
+ throw new NSGetterRuntimeError(
42499
+ `${subject} must be within [0, 1]; found ${numeric}.`
42500
+ );
42501
+ if ((kind === "Vector2Int" || kind === "Vector3Int") && !Number.isInteger(numeric))
42502
+ throw new NSGetterRuntimeError(
42503
+ `${subject} must be an integer on an integer vector; found ${numeric}.`,
42504
+ { errorClassId: NEO_ERROR_CLASS_IDS.NeoArgumentError }
42505
+ );
42506
+ }
42179
42507
  function applyOverlayAssignment(target, targetTypeInfo, value, scope, ctx, destination) {
42180
42508
  if (target.type === "staticMember" /* staticMember */) {
42181
42509
  if (ctx.storedConstructionReplay === true) {
@@ -42193,7 +42521,6 @@ function applyOverlayAssignment(target, targetTypeInfo, value, scope, ctx, desti
42193
42521
  }
42194
42522
  const receiver = destination === void 0 ? evalPointer(target.keyOf.pointer, scope, ctx) : destination.receiver;
42195
42523
  const key = destination === void 0 ? evalPointer(target.keyOf.key, scope, ctx) : destination.key;
42196
- assertStoredReplayMutableValue(receiver, ctx, "assignment target", key);
42197
42524
  if (findKnownRowIdByValueReference(receiver, ctx) !== null)
42198
42525
  assertInterfaceValueKind(
42199
42526
  targetTypeInfo,
@@ -42202,6 +42529,13 @@ function applyOverlayAssignment(target, targetTypeInfo, value, scope, ctx, desti
42202
42529
  ctx
42203
42530
  );
42204
42531
  const referenceValueId = targetTypeInfo.type === 7 /* Class */ || targetTypeInfo.type === 22 /* Interface */ || targetTypeInfo.type === 6 /* List */ || targetTypeInfo.type === 28 /* Set */ || targetTypeInfo.type === 5 /* Dictionary */ ? findKnownRowIdByValueReference(value, ctx) : null;
42532
+ const reattachesReplaySlot = ctx.storedConstructionReplay === true && ctx.__storedConstructionReplayRootId !== void 0 && target.memberId !== void 0 && referenceValueId !== null && receiver !== null && typeof receiver === "object" && Reflect.get(receiver, String(key)) === referenceValueId && findKnownRowIdByValueReference(receiver, ctx) === ctx.__storedConstructionReplayRootId;
42533
+ assertStoredReplayMutableValue(
42534
+ receiver,
42535
+ ctx,
42536
+ "assignment target",
42537
+ reattachesReplaySlot ? void 0 : key
42538
+ );
42205
42539
  if (Array.isArray(receiver)) {
42206
42540
  const index = numberArg(key, "List assignment index");
42207
42541
  if (referenceValueId !== null) {
@@ -42246,6 +42580,14 @@ function applyOverlayAssignment(target, targetTypeInfo, value, scope, ctx, desti
42246
42580
  const object2 = objectArg(receiver, "Assignment target");
42247
42581
  const stringKey = String(key);
42248
42582
  const field = target.memberId !== void 0;
42583
+ if (field && isTypeInfoWithEntries(targetTypeInfo)) {
42584
+ const slot = collectionSlotRow(target, { receiver, key }, ctx);
42585
+ if (slot !== null && slot.id !== referenceValueId) {
42586
+ object2[stringKey] = slot.id;
42587
+ if (replaceEntryRowValue(receiver, slot.id, value, targetTypeInfo, ctx))
42588
+ return;
42589
+ }
42590
+ }
42249
42591
  if (referenceValueId !== null) {
42250
42592
  const parentId = findKnownRowIdByValueReference(receiver, ctx);
42251
42593
  if (parentId !== null) {
@@ -42312,6 +42654,9 @@ function collectionSlotRow(target, destination, ctx) {
42312
42654
  if (!isReferenceEntry(collectionReferences(receiver, ctx), entryKey))
42313
42655
  return null;
42314
42656
  slotId = Reflect.get(receiver, entryKey);
42657
+ if (typeof slotId !== "string" && target.type === "keyOf" /* keyOf */ && target.memberId !== void 0 && !Array.isArray(receiver)) {
42658
+ slotId = slotTargetId(receiver, String(key), target.memberId, ctx);
42659
+ }
42315
42660
  }
42316
42661
  if (typeof slotId !== "string") return null;
42317
42662
  return evalValueById(
@@ -42383,20 +42728,196 @@ function replaceEntryRowValue(receiver, existing, value, targetTypeInfo, ctx) {
42383
42728
  `collection entry '${existing}'`,
42384
42729
  ctx
42385
42730
  );
42386
- keepAssignedCollectionValues(value, targetTypeInfo, ctx);
42731
+ keepAssignedCollectionValues(value, targetTypeInfo, row, ctx);
42732
+ if (isTypeInfoWithEntries(targetTypeInfo))
42733
+ retainCollectionEntryReferences(row.value, ctx);
42387
42734
  replaceRowValue(row, value, receiver, ctx);
42388
42735
  updateUnorderedListProjectionAfterAssignment(row, value, ctx);
42389
42736
  return true;
42390
42737
  }
42391
- function keepAssignedCollectionValues(value, targetTypeInfo, ctx) {
42738
+ function keepAssignedCollectionValues(value, targetTypeInfo, row, ctx) {
42739
+ if (!isTypeInfoWithEntries(targetTypeInfo)) return;
42740
+ let collection;
42392
42741
  const cache = unorderedListProjectionCache(ctx);
42393
- if (Array.isArray(value) && (targetTypeInfo.type === 6 /* List */ || targetTypeInfo.type === 28 /* Set */)) {
42742
+ if (Array.isArray(value)) {
42743
+ collection = value;
42394
42744
  if (!cache.referenceEntryIndexesByArray.has(value))
42395
42745
  cache.referenceEntryIndexesByArray.set(value, /* @__PURE__ */ new Set());
42746
+ } else if (targetTypeInfo.type === 5 /* Dictionary */ && typeof value === "object" && value !== null) {
42747
+ collection = objectArg(value, "Dictionary assignment");
42748
+ if (!cache.referenceEntryKeysByRecord.has(collection))
42749
+ cache.referenceEntryKeysByRecord.set(collection, /* @__PURE__ */ new Set());
42750
+ } else {
42751
+ return;
42752
+ }
42753
+ const entryType = targetTypeInfo.entryTypeInfo;
42754
+ if (entryType.type !== 7 /* Class */ && entryType.type !== 22 /* Interface */)
42396
42755
  return;
42756
+ const member = memberForValueRow(row, ctx);
42757
+ if (member !== null && isMemberEntryCollectionBase(member) && listKindOf(member) === 1 /* Unordered */)
42758
+ return;
42759
+ preflightAssignedCollection(collection, member, row, ctx);
42760
+ forEachRawCollectionEntry(collection, ctx, ({ raw, key, valueId }) => {
42761
+ if (valueId !== null) return 0 /* Continue */;
42762
+ const rowId = findKnownRowIdByValueReference(raw, ctx);
42763
+ if (rowId !== null) {
42764
+ Reflect.set(collection, key, rowId);
42765
+ recordWrittenEntry(collection, key, true, ctx);
42766
+ }
42767
+ return 0 /* Continue */;
42768
+ });
42769
+ }
42770
+ function pendingConstructorRootsForRow(valueId, ctx) {
42771
+ const roots = /* @__PURE__ */ new Set();
42772
+ const open2 = ctx.__executionState?.openConstructions;
42773
+ if (open2 === void 0 || open2.size === 0) return roots;
42774
+ const visited = /* @__PURE__ */ new Set();
42775
+ const pending = [valueId];
42776
+ const parentEntries = /* @__PURE__ */ new Map();
42777
+ const placingMembers = /* @__PURE__ */ new Map();
42778
+ while (pending.length > 0) {
42779
+ const id2 = pending.pop();
42780
+ if (id2 === void 0 || visited.has(id2)) continue;
42781
+ visited.add(id2);
42782
+ const row = evalValueById(
42783
+ ctx,
42784
+ id2,
42785
+ ctx.__runtimeSessionValues,
42786
+ ctx.__valueOverlay
42787
+ );
42788
+ if (row === null) continue;
42789
+ if (typeof row.value === "object" && row.value !== null && open2.has(row.value))
42790
+ roots.add(id2);
42791
+ for (const owner of currentOwnedValueAttachments(
42792
+ id2,
42793
+ ctx,
42794
+ parentEntries,
42795
+ placingMembers
42796
+ )) {
42797
+ if (!owner.identity.startsWith("value:")) continue;
42798
+ const parent = evalValueById(
42799
+ ctx,
42800
+ owner.label,
42801
+ ctx.__runtimeSessionValues,
42802
+ ctx.__valueOverlay
42803
+ );
42804
+ if (parent === null) continue;
42805
+ if (parent.classId === void 0 || parent.classId === null) {
42806
+ const raw = placingMember(
42807
+ parent,
42808
+ ctx,
42809
+ void 0,
42810
+ 0,
42811
+ placingMembers,
42812
+ parentEntries
42813
+ );
42814
+ if (raw === null) continue;
42815
+ const member = raw.kind === 21 /* Generic */ ? substituteMember(raw, rowGenericEnv(parent, ctx), ctx.vm.members) : resolveMember(raw, ctx.vm.members);
42816
+ if (isMemberWithEntries(member)) {
42817
+ const rawEntry = evalMemberById(ctx.vm, member.entryMemberId);
42818
+ if (rawEntry === null) continue;
42819
+ const entry = rawEntry.kind === 21 /* Generic */ ? substituteMember(
42820
+ rawEntry,
42821
+ rowGenericEnv(parent, ctx),
42822
+ ctx.vm.members
42823
+ ) : resolveMember(rawEntry, ctx.vm.members);
42824
+ if (entry.kind === 21 /* Generic */ || isMemberLookupBase(entry))
42825
+ continue;
42826
+ }
42827
+ }
42828
+ pending.push(owner.label);
42829
+ }
42830
+ for (const link of evaluatorParentLinks(evaluatorIndexes(ctx), id2)) {
42831
+ const parent = evalValueById(
42832
+ ctx,
42833
+ link.parentId,
42834
+ ctx.__runtimeSessionValues,
42835
+ ctx.__valueOverlay
42836
+ );
42837
+ if (parent === null || !Array.isArray(parent.value)) continue;
42838
+ const member = placingMember(
42839
+ parent,
42840
+ ctx,
42841
+ void 0,
42842
+ 0,
42843
+ placingMembers,
42844
+ parentEntries
42845
+ );
42846
+ if (member === null || !isMemberTupleBase(member)) continue;
42847
+ const positions = ownershipParentEntryKeys(
42848
+ parent.value,
42849
+ id2,
42850
+ parentEntries
42851
+ );
42852
+ for (const position of positions ?? []) {
42853
+ if (typeof position !== "number") continue;
42854
+ const entryId = member.elementMemberIds[position];
42855
+ const rawEntry = entryId === void 0 ? null : evalMemberById(ctx.vm, entryId);
42856
+ if (rawEntry === null) continue;
42857
+ const entry = rawEntry.kind === 21 /* Generic */ ? substituteMember(
42858
+ rawEntry,
42859
+ rowGenericEnv(parent, ctx),
42860
+ ctx.vm.members
42861
+ ) : resolveMember(rawEntry, ctx.vm.members);
42862
+ if (entry.kind === 21 /* Generic */ || isMemberLookupBase(entry))
42863
+ continue;
42864
+ pending.push(parent.id);
42865
+ break;
42866
+ }
42867
+ }
42397
42868
  }
42398
- if (targetTypeInfo.type === 5 /* Dictionary */ && typeof value === "object" && value !== null && !cache.referenceEntryKeysByRecord.has(value)) {
42399
- cache.referenceEntryKeysByRecord.set(value, /* @__PURE__ */ new Set());
42869
+ return roots;
42870
+ }
42871
+ function preflightAssignedCollection(collection, member, row, ctx) {
42872
+ if (member === null) return;
42873
+ const env = rowGenericEnv(row, ctx);
42874
+ const resolved = substituteMember(member, env, ctx.vm.members);
42875
+ if (!isMemberWithEntries(resolved)) return;
42876
+ const rawEntry = evalMemberById(ctx.vm, resolved.entryMemberId);
42877
+ if (rawEntry === null) return;
42878
+ const entry = substituteMember(rawEntry, env, ctx.vm.members);
42879
+ if (!isClassSlotMember(entry)) return;
42880
+ const attached = /* @__PURE__ */ new Set();
42881
+ const preflight = {
42882
+ parentEntries: /* @__PURE__ */ new Map(),
42883
+ constructorRootIds: pendingConstructorRootsForRow(row.id, ctx),
42884
+ constructorArgumentTransfers: /* @__PURE__ */ new Map(),
42885
+ dependencies: /* @__PURE__ */ new Map()
42886
+ };
42887
+ forEachRawCollectionEntry(collection, ctx, ({ raw, key, valueId }) => {
42888
+ const id2 = valueId ?? findKnownRowIdByValueReference(raw, ctx);
42889
+ if (id2 === null) return 0 /* Continue */;
42890
+ if (attached.has(id2))
42891
+ throw new NSGetterRuntimeError(
42892
+ `Aggregate value '${id2}' is already owned by another entry of '${row.id}'. Call Clone() explicitly.`
42893
+ );
42894
+ attached.add(id2);
42895
+ const placement = Array.isArray(collection) ? "index" : "slot";
42896
+ assertOwnedValueAttachable(
42897
+ id2,
42898
+ { identity: `value:${row.id}:${placement}:${key}`, label: row.id },
42899
+ `${row.id}[${key}]`,
42900
+ ctx,
42901
+ false,
42902
+ "assign",
42903
+ preflight
42904
+ );
42905
+ return 0 /* Continue */;
42906
+ });
42907
+ for (const [id2, destination] of preflight.constructorArgumentTransfers)
42908
+ ctx.__executionState?.ownedValueAttachments.set(id2, destination);
42909
+ for (const [id2, destination] of preflight.dependencies)
42910
+ recordConstructorGroupDependency(id2, destination, ctx);
42911
+ }
42912
+ function retainCollectionEntryReferences(value, ctx) {
42913
+ if (collectionReferences(value, ctx) !== 0 /* RowIds */) return;
42914
+ if (Array.isArray(value)) {
42915
+ referenceEntryList(value, ctx);
42916
+ } else if (typeof value === "object" && value !== null) {
42917
+ unorderedListProjectionCache(ctx).referenceEntryKeysByRecord.set(
42918
+ value,
42919
+ new Set(Object.keys(value))
42920
+ );
42400
42921
  }
42401
42922
  }
42402
42923
  function replaceRowValue(row, value, receiver, ctx) {
@@ -42483,7 +43004,7 @@ function applyOverlayStaticAssignment(memberId, targetTypeInfo, value, ctx) {
42483
43004
  );
42484
43005
  }
42485
43006
  observeValueWrite(ctx, row);
42486
- keepAssignedCollectionValues(value, targetTypeInfo, ctx);
43007
+ keepAssignedCollectionValues(value, targetTypeInfo, row, ctx);
42487
43008
  row.value = value ?? null;
42488
43009
  row.updatedAt = Date.now();
42489
43010
  updateUnorderedListProjectionAfterAssignment(row, value, ctx);
@@ -42823,7 +43344,7 @@ function materializeSlotRow(place, targetId, ctx) {
42823
43344
  const value = member === null ? read : encodeLookupInitializerSelection(
42824
43345
  member,
42825
43346
  read,
42826
- [],
43347
+ /* @__PURE__ */ new Set(),
42827
43348
  ctx,
42828
43349
  lookupTargetTypeInfo(member, owner, ctx)
42829
43350
  );
@@ -43262,8 +43783,12 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
43262
43783
  );
43263
43784
  }
43264
43785
  const setMatch = setEntryMember !== null && Array.isArray(targetValue) && (ins.mutation === "Add" /* Add */ || ins.mutation === "Remove" /* Remove */) ? findStoredSetEntry(targetValue, args[0], setEntryMember, ctx) : null;
43265
- if (ins.mutation === "Add" /* Add */ && setMatch !== null) return;
43266
- if (ins.mutation === "Remove" /* Remove */ && setEntryMember !== null && setMatch === null) {
43786
+ if (ins.mutation === "Add" /* Add */) {
43787
+ if (setMatch !== null) return;
43788
+ if (targetValue instanceof RuntimeSet && targetValue.has(runtimeSetKey(args[0], targetValue, ctx)))
43789
+ return;
43790
+ }
43791
+ if (ins.mutation === "Remove" /* Remove */ && setEntryMember !== null && Array.isArray(targetValue) && setMatch === null) {
43267
43792
  return;
43268
43793
  }
43269
43794
  if (mutatesLocalVariable && variablePointer !== null) {
@@ -43291,6 +43816,13 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
43291
43816
  return;
43292
43817
  }
43293
43818
  validateCollectionMutation(targetValue, ins.mutation, args);
43819
+ if (!isLookupSet && entryArgumentIndex !== null && (ins.mutation === "Add" /* Add */ || ins.mutation === "Insert" /* Insert */) && findKnownRowIdByValueReference(targetValue, ctx) !== null)
43820
+ trackInsertedCollection(
43821
+ args[entryArgumentIndex],
43822
+ collectionEntryWriteType(ins.target.typeInfo, targetValue, ctx),
43823
+ targetValue,
43824
+ ctx
43825
+ );
43294
43826
  const overlayArgs = [...args];
43295
43827
  if ((ins.mutation === "Add" /* Add */ || ins.mutation === "Remove" /* Remove */) && isArrayCollection(targetValue)) {
43296
43828
  if (setMatch !== null) overlayArgs[0] = setMatch.entry;
@@ -43349,6 +43881,7 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
43349
43881
  );
43350
43882
  }
43351
43883
  const removableRowIds = isLookupSet || ins.reference === true ? null : removableEntryRowIds(targetValue, ins.mutation, overlayArgs, ctx);
43884
+ const previousSetSize = targetValue instanceof RuntimeSet ? targetValue.size : null;
43352
43885
  const removedIndex = applyLocalCollectionMutation(
43353
43886
  targetValue,
43354
43887
  ins.mutation,
@@ -43420,7 +43953,28 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
43420
43953
  cache
43421
43954
  );
43422
43955
  }
43423
- invalidateEvaluatorIndexes(ctx, targetValue);
43956
+ let indexedAppend = false;
43957
+ if (targetValue instanceof RuntimeSet) {
43958
+ if (ins.mutation === "Add" /* Add */) {
43959
+ if (targetValue.size !== previousSetSize) {
43960
+ targetValue.source.push(overlayArgs[0]);
43961
+ recordWrittenEntry(
43962
+ targetValue.source,
43963
+ targetValue.source.length - 1,
43964
+ targetValue.reference,
43965
+ ctx
43966
+ );
43967
+ indexedAppend = indexRuntimeCollectionAppend(
43968
+ targetValue.source,
43969
+ overlayArgs[0],
43970
+ ctx
43971
+ );
43972
+ }
43973
+ } else {
43974
+ exportRuntimeSetValue(targetValue, ctx);
43975
+ }
43976
+ }
43977
+ if (!indexedAppend) invalidateEvaluatorIndexes(ctx, targetValue);
43424
43978
  switch (ins.mutation) {
43425
43979
  case "Insert" /* Insert */:
43426
43980
  options.writes.push({
@@ -43566,6 +44120,90 @@ function sortCollectionInPlace(ins, value, scope, ctx, options) {
43566
44120
  ...resolvedDestinationFieldsForContainer(list, ctx)
43567
44121
  });
43568
44122
  }
44123
+ function trackInsertedCollection(value, type2, parentValue, ctx) {
44124
+ if (!isTypeInfoWithEntries(type2) && type2.type !== 9 /* Lookup */ || value === null || typeof value !== "object" || findKnownRowIdByValueReference(value, ctx) !== null)
44125
+ return;
44126
+ const parent = trackedRowForValueReference(parentValue, ctx);
44127
+ const placement = parent === null ? null : memberForValueRow(parent, ctx);
44128
+ if (parent === null || placement === null) return;
44129
+ const genericEnv = rowGenericEnv(parent, ctx);
44130
+ const parentMember = substituteMember(placement, genericEnv, ctx.vm.members);
44131
+ if (!isMemberWithEntries(parentMember)) return;
44132
+ const entry = evalMemberById(ctx.vm, parentMember.entryMemberId);
44133
+ if (entry === null) return;
44134
+ const member = substituteMember(entry, genericEnv, ctx.vm.members);
44135
+ const createdValues = [];
44136
+ const collectionAliases = /* @__PURE__ */ new Map();
44137
+ const reservations = /* @__PURE__ */ new Map();
44138
+ try {
44139
+ const row = materializeConstructorArgumentValue({
44140
+ member,
44141
+ value,
44142
+ genericEnv,
44143
+ ctx,
44144
+ createdValues,
44145
+ createdById: /* @__PURE__ */ new Map(),
44146
+ storageKeyDeclarations: /* @__PURE__ */ new Map(),
44147
+ collectionEntriesAreReferences: false,
44148
+ collectionAliases,
44149
+ attachmentReservations: reservations
44150
+ });
44151
+ row.genericBindings = computeGenericBindingsStamp(
44152
+ entry,
44153
+ genericEnv,
44154
+ ctx.vm.members
44155
+ );
44156
+ for (const [encoded, alias] of collectionAliases) {
44157
+ retainEncodedCollectionAlias(encoded, alias, ctx);
44158
+ }
44159
+ for (const created of createdValues)
44160
+ registerRuntimeSessionValue(ctx, created);
44161
+ if (ctx.__indexes !== void 0)
44162
+ indexEvaluatorRows(ctx.__indexes, createdValues);
44163
+ } catch (error) {
44164
+ for (const created of createdValues)
44165
+ ctx.__executionState?.constructorGroupDependencies.delete(created.id);
44166
+ throw error;
44167
+ } finally {
44168
+ const attachments = ctx.__executionState?.ownedValueAttachments;
44169
+ for (const [id2, previous] of reservations) {
44170
+ if (previous === void 0) attachments?.delete(id2);
44171
+ else attachments?.set(id2, previous);
44172
+ }
44173
+ }
44174
+ }
44175
+ function retainEncodedCollectionAlias(row, alias, ctx) {
44176
+ const stored = alias instanceof RuntimeSet ? alias.source : alias;
44177
+ if (Array.isArray(stored) && Array.isArray(row.value)) {
44178
+ const keys = alias instanceof RuntimeSet ? collectionEntries(alias, ctx).map(
44179
+ (item) => runtimeSetKey(item, alias, ctx)
44180
+ ) : null;
44181
+ const encoded = row.value;
44182
+ stored.length = encoded.length;
44183
+ const references = /* @__PURE__ */ new Set();
44184
+ for (let index = 0; index < encoded.length; index++) {
44185
+ stored[index] = encoded[index];
44186
+ references.add(index);
44187
+ }
44188
+ unorderedListProjectionCache(ctx).referenceEntryIndexesByArray.set(
44189
+ stored,
44190
+ references
44191
+ );
44192
+ if (alias instanceof RuntimeSet && keys !== null) {
44193
+ alias.clear();
44194
+ for (let index = 0; index < stored.length; index++)
44195
+ alias.add(keys[index], stored[index], true);
44196
+ }
44197
+ } else if (isPlainRecord(stored) && isPlainRecord(row.value)) {
44198
+ for (const [key, encoded] of Object.entries(row.value))
44199
+ setOwnField(stored, key, encoded);
44200
+ unorderedListProjectionCache(ctx).referenceEntryKeysByRecord.set(
44201
+ stored,
44202
+ new Set(Object.keys(stored))
44203
+ );
44204
+ }
44205
+ row.value = stored;
44206
+ }
43569
44207
  function storedSetEntryMember(collection, ctx) {
43570
44208
  const containerId = findKnownRowIdByValueReference(collection, ctx);
43571
44209
  if (containerId === null) return null;
@@ -44311,6 +44949,39 @@ function slotTargetId(owner, key, memberId, ctx) {
44311
44949
  if (typeof virtual === "string") return virtual;
44312
44950
  return virtualValueId(ownerId, memberId);
44313
44951
  }
44952
+ function readDispatchedGetterValue(value, member, receiver, ctx) {
44953
+ if (!(value instanceof NSSlotReference) || member === null) return value;
44954
+ const declared = nsPropertyReturnTypeInfo(cachedResolvedMember(member, ctx));
44955
+ if (declared === null) return value;
44956
+ let expected = declared;
44957
+ if (typeInfoContainsGeneric2(declared)) {
44958
+ const row = trackedRowForValueReference(receiver, ctx);
44959
+ if (row === null)
44960
+ throw new NSGetterRuntimeError(
44961
+ "Cannot resolve a generic getter contract without a tracked receiver."
44962
+ );
44963
+ expected = substituteRuntimeTypeInfo(
44964
+ declared,
44965
+ runtimeGenericEnvForValueRow(row, ctx),
44966
+ ctx
44967
+ );
44968
+ }
44969
+ let readLayers = 1;
44970
+ let actualTarget = value.target;
44971
+ while (actualTarget?.type === 29 /* Reference */) {
44972
+ readLayers += 1;
44973
+ actualTarget = actualTarget.targetTypeInfo;
44974
+ }
44975
+ let target = expected;
44976
+ while (target.type === 29 /* Reference */) {
44977
+ readLayers -= 1;
44978
+ target = target.targetTypeInfo;
44979
+ }
44980
+ while (readLayers-- > 0 && value instanceof NSSlotReference) {
44981
+ value = readThroughReference(value, ctx);
44982
+ }
44983
+ return value;
44984
+ }
44314
44985
  function readThroughReference(reference2, ctx) {
44315
44986
  if (!(reference2 instanceof NSSlotReference)) return reference2;
44316
44987
  if (reference2.place !== null) {
@@ -44562,7 +45233,13 @@ function evalPointerCore(pointer, scope, ctx, resultUsage = "value") {
44562
45233
  const schemaKey = pointer.memberId === NEO_SEQUENCE_IDS.Current ? "Current" : cachedSchemaKeyForMember(pointer.memberId, ctx);
44563
45234
  if (schemaKey !== null) {
44564
45235
  const dispatched = dispatchSchemaMember(innerThis, schemaKey, ctx);
44565
- if (dispatched.kind === "ok") return dispatched.value;
45236
+ if (dispatched.kind === "ok")
45237
+ return readDispatchedGetterValue(
45238
+ dispatched.value,
45239
+ extension,
45240
+ innerThis,
45241
+ ctx
45242
+ );
44566
45243
  }
44567
45244
  return dispatchNSGetterById(pointer.memberId, innerThis, ctx);
44568
45245
  }
@@ -47207,7 +47884,21 @@ function placingMemberBinding(row, ctx) {
47207
47884
  const syntheticMemberId = memberIdFromSyntheticDefaultValueId(row.id);
47208
47885
  return syntheticMemberId === null ? null : evalMemberById(ctx.vm, syntheticMemberId);
47209
47886
  }
47210
- function placingMember(row, ctx, ownerEdge, depth = 0) {
47887
+ function placingMember(row, ctx, ownerEdge, depth = 0, resolved, positions) {
47888
+ const known = resolved?.get(row.id);
47889
+ if (known !== void 0) return known;
47890
+ const member = resolvePlacingMember(
47891
+ row,
47892
+ ctx,
47893
+ ownerEdge,
47894
+ depth,
47895
+ resolved,
47896
+ positions
47897
+ );
47898
+ if (member !== null) resolved?.set(row.id, member);
47899
+ return member;
47900
+ }
47901
+ function resolvePlacingMember(row, ctx, ownerEdge, depth = 0, resolved, positions) {
47211
47902
  const bound = placingMemberBinding(row, ctx);
47212
47903
  if (bound !== null) return bound;
47213
47904
  const edge = ownerEdge ?? firstOwnerEdge(row, ctx);
@@ -47216,10 +47907,26 @@ function placingMember(row, ctx, ownerEdge, depth = 0) {
47216
47907
  if (depth >= MAX_AREA_DEPTH) return null;
47217
47908
  const parent = untrackedValueById(edge.parentId, ctx);
47218
47909
  if (parent === null) return null;
47219
- const parentMember = parent.classId === void 0 ? placingMember(parent, ctx, void 0, depth + 1) : null;
47910
+ const parentMember = parent.classId === void 0 ? placingMember(parent, ctx, void 0, depth + 1, resolved, positions) : null;
47220
47911
  if (parentMember !== null && isMemberTupleBase(parentMember)) {
47221
- const memberId = parentMember.elementMemberIds[Number(edge.key)];
47222
- return memberId === void 0 ? null : evalMemberById(ctx.vm, memberId);
47912
+ if (!Array.isArray(parent.value)) return null;
47913
+ const keys = ownershipParentEntryKeys(parent.value, row.id, positions);
47914
+ let selected = null;
47915
+ for (const key of keys ?? parent.value.keys()) {
47916
+ if (typeof key !== "number" || parent.value[key] !== row.id) continue;
47917
+ const memberId = parentMember.elementMemberIds[key];
47918
+ const candidate = memberId === void 0 ? null : evalMemberById(ctx.vm, memberId);
47919
+ if (candidate === null) continue;
47920
+ const contract = candidate.kind === 21 /* Generic */ ? substituteMember(
47921
+ candidate,
47922
+ rowGenericEnv(parent, ctx),
47923
+ ctx.vm.members
47924
+ ) : resolveMember(candidate, ctx.vm.members);
47925
+ if (contract.kind !== 21 /* Generic */ && !isMemberLookupBase(contract))
47926
+ return candidate;
47927
+ selected ??= candidate;
47928
+ }
47929
+ return selected;
47223
47930
  }
47224
47931
  if (parentMember !== null && isMemberWithEntries(parentMember)) {
47225
47932
  return evalMemberById(ctx.vm, parentMember.entryMemberId);
@@ -49662,7 +50369,7 @@ function validateClassConstructorDescriptor(info, ctx, requireEveryRequiredField
49662
50369
  members: ctx.vm.members,
49663
50370
  constructors: ctx.vm.constructors ?? [],
49664
50371
  values: ctx.vm.values,
49665
- valueById: ctx.vm.databaseVM?.defaultValueById ?? ctx.vm.databaseVM?.valueById,
50372
+ valueById: ctx.vm.databaseVM?.valueById,
49666
50373
  memberById: evaluatorDefaultValueDocument(ctx).memberById
49667
50374
  };
49668
50375
  const classArguments = slotArguments ?? resolveConstructionTypeArguments(typeArguments, constructionDocument);
@@ -49982,7 +50689,7 @@ function applyConstructorFields(args) {
49982
50689
  continue;
49983
50690
  }
49984
50691
  const { schemaKey, member } = validated;
49985
- const value = isMemberLookupBase(member) ? encodeLookupInitializerSelection(member, supplied, createdValues, ctx) : supplied;
50692
+ const value = isMemberLookupBase(member) ? encodeLookupInitializerSelection(member, supplied, createdById, ctx) : supplied;
49986
50693
  const trackedValueId = findKnownRowIdByValueReference(value, ctx);
49987
50694
  if (trackedValueId !== null && isClassSlotMember(member)) {
49988
50695
  const source = evalValueById(
@@ -50310,11 +51017,15 @@ function constructorDefaultValueDocument(ctx, syntheticMember2) {
50310
51017
  // the entire project for every constructor replay.
50311
51018
  values: ctx.vm.values,
50312
51019
  memberById: database?.memberById,
51020
+ defaultValueSource: database?.defaultValueSource === void 0 ? void 0 : (id2, member) => {
51021
+ ctx.valueDependencies?.add(id2);
51022
+ return database.defaultValueSource(id2, member);
51023
+ },
50313
51024
  // The declaration rows a default clones are reads of this evaluation.
50314
51025
  ...database === void 0 ? {} : {
50315
51026
  valueById: (id2) => {
50316
51027
  ctx.valueDependencies?.add(id2);
50317
- return database.defaultValueById !== void 0 ? database.defaultValueById(id2) : database.valueById(id2);
51028
+ return database.valueById(id2);
50318
51029
  }
50319
51030
  },
50320
51031
  ...entryIdsOf === void 0 ? {} : {
@@ -50994,9 +51705,12 @@ function evaluateInitializerInContext(init, member, ctx, createdValues, argument
50994
51705
  }
50995
51706
  );
50996
51707
  } catch (error) {
50997
- const ownerId = compileMemberId ?? Reflect.get(member, "id");
50998
- if (error instanceof NSGetterRuntimeError && sourceValueId === null && typeof ownerId === "string")
50999
- error.sourceOwnerId ??= ownerId;
51708
+ if (error instanceof NSGetterRuntimeError) {
51709
+ error.initializerValueId ??= sourceValueId ?? void 0;
51710
+ const ownerId = compileMemberId ?? Reflect.get(member, "id");
51711
+ if (sourceValueId === null && typeof ownerId === "string")
51712
+ error.sourceOwnerId ??= ownerId;
51713
+ }
51000
51714
  throw error;
51001
51715
  } finally {
51002
51716
  initializerCtx.__initializerGenericEnv = previousGenericEnv;
@@ -51004,7 +51718,19 @@ function evaluateInitializerInContext(init, member, ctx, createdValues, argument
51004
51718
  }
51005
51719
  const created = result.createdSessionValues ?? [];
51006
51720
  if (isMemberLookupBase(member)) {
51007
- return encodeLookupInitializerResult(member, result.value, created, ctx);
51721
+ const declaredTarget2 = lookupTargetTypeInfo(member, null, ctx);
51722
+ const target = typeInfoContainsGeneric2(declaredTarget2) ? substituteRuntimeTypeInfo(
51723
+ declaredTarget2,
51724
+ genericEnv,
51725
+ ctx
51726
+ ) : declaredTarget2;
51727
+ return encodeLookupInitializerResult(
51728
+ member,
51729
+ result.value,
51730
+ created,
51731
+ ctx,
51732
+ target
51733
+ );
51008
51734
  }
51009
51735
  let rootRow = initializerRootRow(result.value, created);
51010
51736
  for (const row of created) {
@@ -51094,12 +51820,13 @@ function ensureInitializerCompiled(args) {
51094
51820
  }
51095
51821
  return compiled;
51096
51822
  }
51097
- function encodeLookupInitializerResult(member, value, created, ctx) {
51823
+ function encodeLookupInitializerResult(member, value, created, ctx, target = lookupTargetTypeInfo(member, null, ctx)) {
51098
51824
  const selection2 = encodeLookupInitializerSelection(
51099
51825
  member,
51100
51826
  value,
51101
- created,
51102
- ctx
51827
+ new Set(created.map((row) => row.id)),
51828
+ ctx,
51829
+ target
51103
51830
  );
51104
51831
  if (created.length > 0) {
51105
51832
  for (const row of created) {
@@ -51109,11 +51836,11 @@ function encodeLookupInitializerResult(member, value, created, ctx) {
51109
51836
  }
51110
51837
  return { value: selection2, classId: null };
51111
51838
  }
51112
- function encodeLookupInitializerSelection(member, value, created, ctx, target = lookupTargetTypeInfo(member, null, ctx)) {
51839
+ function encodeLookupInitializerSelection(member, value, createdIds, ctx, target = lookupTargetTypeInfo(member, null, ctx)) {
51113
51840
  if (value === null) return null;
51114
51841
  if (value === void 0) return null;
51115
51842
  if (isMultiSelectionMember(member) !== true && isCollectionTypeInfo(target))
51116
- return [lookupInitializerSelectionId(member, value, created, ctx)];
51843
+ return [lookupInitializerSelectionId(member, value, createdIds, ctx)];
51117
51844
  if (value instanceof RuntimeSet) value = value.toArray();
51118
51845
  if (Array.isArray(value)) {
51119
51846
  if (isMultiSelectionMember(member) !== true && value.length > 1) {
@@ -51122,7 +51849,7 @@ function encodeLookupInitializerSelection(member, value, created, ctx, target =
51122
51849
  );
51123
51850
  }
51124
51851
  return value.map(
51125
- (entry) => lookupInitializerSelectionId(member, entry, created, ctx)
51852
+ (entry) => lookupInitializerSelectionId(member, entry, createdIds, ctx)
51126
51853
  );
51127
51854
  }
51128
51855
  if (isMultiSelectionMember(member) === true) {
@@ -51130,9 +51857,9 @@ function encodeLookupInitializerSelection(member, value, created, ctx, target =
51130
51857
  `Lookup member '${member.name}' is multiselect, but its initializer produced a single value instead of a selection set.`
51131
51858
  );
51132
51859
  }
51133
- return [lookupInitializerSelectionId(member, value, created, ctx)];
51860
+ return [lookupInitializerSelectionId(member, value, createdIds, ctx)];
51134
51861
  }
51135
- function lookupInitializerSelectionId(member, entry, created, ctx) {
51862
+ function lookupInitializerSelectionId(member, entry, createdIds, ctx) {
51136
51863
  if (typeof entry === "string") return entry;
51137
51864
  if (entry instanceof NSSlotReference) return entry.targetId;
51138
51865
  if (typeof entry !== "object" || entry === null) {
@@ -51144,7 +51871,7 @@ function lookupInitializerSelectionId(member, entry, created, ctx) {
51144
51871
  if (typeof cloneSourceRowId === "string") return cloneSourceRowId;
51145
51872
  const row = trackedRowForValueReference(entry, ctx);
51146
51873
  if (row !== null) {
51147
- if (created.some((candidate) => candidate.id === row.id)) {
51874
+ if (createdIds.has(row.id)) {
51148
51875
  throw new NSGetterRuntimeError(
51149
51876
  `Lookup member '${member.name}' initializer constructed a new value; a lookup selection must reference an existing collection entry.`
51150
51877
  );
@@ -51323,7 +52050,11 @@ function encodeRequiredConstructorArgument(args) {
51323
52050
  }
51324
52051
  const row2 = registerCollectionRow([]);
51325
52052
  row2.value = args.value.map(
51326
- (entry, index) => encodeEntry(entry, collectionType.entryTypeInfo, `index:${index}`)
52053
+ (entry, index) => encodeEntry(
52054
+ resolveCollectionEntry(args.value, entry, index, args.ctx),
52055
+ collectionType.entryTypeInfo,
52056
+ `index:${index}`
52057
+ )
51327
52058
  );
51328
52059
  return row2.id;
51329
52060
  }
@@ -51336,7 +52067,11 @@ function encodeRequiredConstructorArgument(args) {
51336
52067
  row.value = Object.fromEntries(
51337
52068
  Object.entries(args.value).map(([key, entry]) => [
51338
52069
  key,
51339
- encodeEntry(entry, collectionType.entryTypeInfo, `key:${key}`)
52070
+ encodeEntry(
52071
+ resolveCollectionEntry(args.value, entry, key, args.ctx),
52072
+ collectionType.entryTypeInfo,
52073
+ `key:${key}`
52074
+ )
51340
52075
  ])
51341
52076
  );
51342
52077
  return row.id;
@@ -52152,6 +52887,7 @@ function constructDeclaredClassValue(info, scope, ctx) {
52152
52887
  const descriptor = validateClassConstructorDescriptor(info, ctx, false);
52153
52888
  const schemaClass2 = descriptor.schemaClass;
52154
52889
  const record7 = resolveDeclaredConstructorRecord(info, schemaClass2, ctx);
52890
+ const replayCheckpoint = ctx.storedConstructionReplay === true && ctx.__storedConstructionReplayRowId !== void 0 && ctx.__storedConstructionReplaySlot?.classId === schemaClass2.id && ctx.__executionState?.constructionStack.length === 0 ? sessionCreationCheckpoint(ctx) : void 0;
52155
52891
  const closeFrame = pushConstructionFrame(ctx, schemaClass2.name);
52156
52892
  try {
52157
52893
  return constructDeclaredClassValueWithinFrame(
@@ -52161,6 +52897,13 @@ function constructDeclaredClassValue(info, scope, ctx) {
52161
52897
  scope,
52162
52898
  ctx
52163
52899
  );
52900
+ } catch (error) {
52901
+ if (replayCheckpoint !== void 0) {
52902
+ for (const row of createdSessionValuesSince(ctx, replayCheckpoint)) {
52903
+ deleteRuntimeSessionValue(ctx, row.id);
52904
+ }
52905
+ }
52906
+ throw error;
52164
52907
  } finally {
52165
52908
  closeFrame();
52166
52909
  }
@@ -52232,6 +52975,9 @@ function constructDeclaredClassValueWithinFrame(descriptor, record7, info, scope
52232
52975
  `Declared constructor for '${schemaClass2.name}' produced a non-record root.`
52233
52976
  );
52234
52977
  }
52978
+ if (ctx.storedConstructionReplay === true && ctx.__storedConstructionReplayRowId !== void 0 && ctx.__storedConstructionReplaySlot?.classId === classId && ctx.__executionState?.constructionStack.length === 1) {
52979
+ ctx = { ...ctx, __storedConstructionReplayRootId: root.id };
52980
+ }
52235
52981
  const rootRecord = root.value;
52236
52982
  recordConstructedFieldSchemaKeys(ctx, rootRecord, descriptor);
52237
52983
  if (record7 !== null) {
@@ -52369,7 +53115,14 @@ function constructDeclaredClassValueWithinFrame(descriptor, record7, info, scope
52369
53115
  });
52370
53116
  return root.value;
52371
53117
  }
52372
- function assertOwnedValueAttachable(valueId, destination, destinationName2, ctx, reserveUntilPublished = false, mode = "assign") {
53118
+ function ownedAttachmentIdentity(attachment, ctx) {
53119
+ const rootId = ctx.__storedConstructionReplayRootId;
53120
+ const rowId = ctx.__storedConstructionReplayRowId;
53121
+ if (rootId === void 0 || rowId === void 0) return attachment.identity;
53122
+ const prefix = `value:${rootId}:slot:`;
53123
+ return attachment.identity.startsWith(prefix) ? `value:${rowId}:slot:${attachment.identity.slice(prefix.length)}` : attachment.identity;
53124
+ }
53125
+ function assertOwnedValueAttachable(valueId, destination, destinationName2, ctx, reserveUntilPublished = false, mode = "assign", preflight) {
52373
53126
  const row = evalValueById(
52374
53127
  ctx,
52375
53128
  valueId,
@@ -52381,8 +53134,13 @@ function assertOwnedValueAttachable(valueId, destination, destinationName2, ctx,
52381
53134
  `Aggregate assignment to '${destinationName2}' references missing value '${valueId}'.`
52382
53135
  );
52383
53136
  }
52384
- for (const owner of currentOwnedValueAttachments(valueId, ctx)) {
52385
- if (mode === "assign" && owner.identity === destination.identity) continue;
53137
+ for (const owner of currentOwnedValueAttachments(
53138
+ valueId,
53139
+ ctx,
53140
+ preflight?.parentEntries
53141
+ )) {
53142
+ if (mode === "assign" && ownedAttachmentIdentity(owner, ctx) === ownedAttachmentIdentity(destination, ctx))
53143
+ continue;
52386
53144
  const error = new NSGetterRuntimeError(
52387
53145
  `Aggregate value '${valueId}' is already owned by parent value '${owner.label}' and cannot be attached to '${destinationName2}'. Call Clone() explicitly.`
52388
53146
  );
@@ -52398,9 +53156,14 @@ function assertOwnedValueAttachable(valueId, destination, destinationName2, ctx,
52398
53156
  destination.label,
52399
53157
  ctx
52400
53158
  );
52401
- if (constructorArgumentReservation && (destination.label === reserved.label || destinationConstructorGroup === reserved.label)) {
52402
- ctx.__executionState?.ownedValueAttachments.set(valueId, destination);
52403
- recordConstructorGroupDependency(valueId, destination, ctx);
53159
+ if (constructorArgumentReservation && (destination.label === reserved.label || destinationConstructorGroup === reserved.label || preflight?.constructorRootIds.has(reserved.label) === true)) {
53160
+ if (preflight === void 0) {
53161
+ ctx.__executionState?.ownedValueAttachments.set(valueId, destination);
53162
+ recordConstructorGroupDependency(valueId, destination, ctx);
53163
+ } else {
53164
+ preflight.constructorArgumentTransfers.set(valueId, destination);
53165
+ preflight.dependencies.set(valueId, destination);
53166
+ }
52404
53167
  return;
52405
53168
  }
52406
53169
  throw new NSGetterRuntimeError(
@@ -52410,7 +53173,9 @@ function assertOwnedValueAttachable(valueId, destination, destinationName2, ctx,
52410
53173
  if (reserveUntilPublished) {
52411
53174
  ctx.__executionState?.ownedValueAttachments.set(valueId, destination);
52412
53175
  }
52413
- recordConstructorGroupDependency(valueId, destination, ctx);
53176
+ if (preflight === void 0)
53177
+ recordConstructorGroupDependency(valueId, destination, ctx);
53178
+ else preflight.dependencies.set(valueId, destination);
52414
53179
  }
52415
53180
  function assertInitializerPlacement(valueId, member, ctx) {
52416
53181
  const replayRowId = ctx.__storedConstructionReplayRowId;
@@ -52430,7 +53195,25 @@ function directlyBoundMembersOf(valueId, ctx) {
52430
53195
  return NO_BOUND_MEMBERS;
52431
53196
  return ctx.vm.members.filter((member) => member.valueId === valueId);
52432
53197
  }
52433
- function currentOwnedValueAttachments(valueId, ctx) {
53198
+ function ownershipParentEntryKeys(value, valueId, cache) {
53199
+ if (cache === void 0) return void 0;
53200
+ let entries = cache.get(value);
53201
+ if (entries === void 0) {
53202
+ const indexed = /* @__PURE__ */ new Map();
53203
+ const add = (child2, key) => {
53204
+ if (typeof child2 !== "string") return;
53205
+ const keys = indexed.get(child2);
53206
+ if (keys === void 0) indexed.set(child2, [key]);
53207
+ else keys.push(key);
53208
+ };
53209
+ if (Array.isArray(value)) value.forEach(add);
53210
+ else for (const [key, child2] of Object.entries(value)) add(child2, key);
53211
+ entries = indexed;
53212
+ cache.set(value, entries);
53213
+ }
53214
+ return entries.get(valueId) ?? [];
53215
+ }
53216
+ function currentOwnedValueAttachments(valueId, ctx, parentEntries, placingMembers) {
52434
53217
  const indexes4 = evaluatorIndexes(ctx);
52435
53218
  const cached = indexes4.ownedValueAttachmentsByValueId.get(valueId);
52436
53219
  if (cached !== void 0) return [...cached];
@@ -52493,7 +53276,14 @@ function currentOwnedValueAttachments(valueId, ctx) {
52493
53276
  let member = null;
52494
53277
  let classId = parent.classId;
52495
53278
  if (classId === void 0 || classId === null) {
52496
- member = activeStaticBindingRoot(parent.id, ctx)?.member ?? memberForValueRow(parent, ctx);
53279
+ member = activeStaticBindingRoot(parent.id, ctx)?.member ?? (placingMembers === void 0 ? memberForValueRow(parent, ctx) : placingMember(
53280
+ parent,
53281
+ ctx,
53282
+ void 0,
53283
+ 0,
53284
+ placingMembers,
53285
+ parentEntries
53286
+ ));
52497
53287
  if (member !== null) {
52498
53288
  try {
52499
53289
  member = resolveMember(member, ctx.vm.members);
@@ -52510,7 +53300,14 @@ function currentOwnedValueAttachments(valueId, ctx) {
52510
53300
  classId = member !== null && isClassTypedMember(member) ? member.classId : void 0;
52511
53301
  }
52512
53302
  if (classId !== void 0 && typeof parent.value === "object" && parent.value !== null && !Array.isArray(parent.value)) {
52513
- for (const [key, childId] of Object.entries(parent.value)) {
53303
+ const keys = ownershipParentEntryKeys(
53304
+ parent.value,
53305
+ valueId,
53306
+ parentEntries
53307
+ );
53308
+ for (const rawKey of keys ?? Object.keys(parent.value)) {
53309
+ const key = String(rawKey);
53310
+ const childId = Reflect.get(parent.value, key);
52514
53311
  if (childId !== valueId) continue;
52515
53312
  add({
52516
53313
  identity: `value:${parent.id}:slot:${key}`,
@@ -52520,8 +53317,17 @@ function currentOwnedValueAttachments(valueId, ctx) {
52520
53317
  continue;
52521
53318
  }
52522
53319
  if (member !== null && isMemberEntryCollectionBase(member) && Array.isArray(parent.value)) {
52523
- for (const [index, childId] of parent.value.entries()) {
52524
- if (childId !== valueId) continue;
53320
+ const references = collectionReferences(parent.value, ctx);
53321
+ const keys = ownershipParentEntryKeys(
53322
+ parent.value,
53323
+ valueId,
53324
+ parentEntries
53325
+ );
53326
+ for (const rawKey of keys ?? parent.value.keys()) {
53327
+ const index = Number(rawKey);
53328
+ const childId = parent.value[index];
53329
+ if (childId !== valueId || !isReferenceEntry(references, index))
53330
+ continue;
52525
53331
  add({
52526
53332
  identity: `value:${parent.id}:index:${index}`,
52527
53333
  label: parent.id
@@ -52530,8 +53336,16 @@ function currentOwnedValueAttachments(valueId, ctx) {
52530
53336
  continue;
52531
53337
  }
52532
53338
  if (member !== null && isMemberDictionaryBase(member) && typeof parent.value === "object" && parent.value !== null && !Array.isArray(parent.value)) {
52533
- for (const [key, childId] of Object.entries(parent.value)) {
52534
- if (childId !== valueId) continue;
53339
+ const references = collectionReferences(parent.value, ctx);
53340
+ const keys = ownershipParentEntryKeys(
53341
+ parent.value,
53342
+ valueId,
53343
+ parentEntries
53344
+ );
53345
+ for (const rawKey of keys ?? Object.keys(parent.value)) {
53346
+ const key = String(rawKey);
53347
+ const childId = Reflect.get(parent.value, key);
53348
+ if (childId !== valueId || !isReferenceEntry(references, key)) continue;
52535
53349
  add({
52536
53350
  identity: `value:${parent.id}:slot:${key}`,
52537
53351
  label: parent.id
@@ -52858,8 +53672,12 @@ function materializeConstructorArgumentValue(args) {
52858
53672
  args.destinationName ?? args.member.name,
52859
53673
  args.ctx
52860
53674
  );
53675
+ const collectionAlias = args.value;
52861
53676
  if (args.value instanceof RuntimeSet)
52862
- args = { ...args, value: args.value.toArray() };
53677
+ args = {
53678
+ ...args,
53679
+ value: args.collectionAliases === void 0 ? args.value.toArray() : exportRuntimeSetValue(args.value, args.ctx)
53680
+ };
52863
53681
  const trackedValueId = findKnownRowIdByValueReference(args.value, args.ctx);
52864
53682
  if (args.value === null && !isRequiredMember(args.member) && isMemberWithEntries(args.member)) {
52865
53683
  return registerConstructorArgumentRow(args, null);
@@ -52895,15 +53713,18 @@ function materializeConstructorArgumentValue(args) {
52895
53713
  return row;
52896
53714
  }
52897
53715
  if (isMemberLookupBase(args.member)) {
52898
- return registerConstructorArgumentRow(
53716
+ const row = registerConstructorArgumentRow(
52899
53717
  args,
52900
53718
  encodeLookupInitializerSelection(
52901
53719
  args.member,
52902
53720
  args.value,
52903
- args.createdValues,
53721
+ args.createdById,
52904
53722
  args.ctx
52905
53723
  )
52906
53724
  );
53725
+ if (collectionAlias instanceof RuntimeSet)
53726
+ args.collectionAliases?.set(row, collectionAlias);
53727
+ return row;
52907
53728
  }
52908
53729
  if (isClassSlotMember(args.member)) {
52909
53730
  if (args.value === null || args.value === void 0) {
@@ -52946,6 +53767,14 @@ function materializeConstructorArgumentValue(args) {
52946
53767
  `Constructor Class field '${args.member.name}' has no owned destination.`
52947
53768
  );
52948
53769
  }
53770
+ if (args.attachmentReservations !== void 0 && !args.attachmentReservations.has(trackedValueId)) {
53771
+ args.attachmentReservations.set(
53772
+ trackedValueId,
53773
+ args.ctx.__executionState?.ownedValueAttachments.get(
53774
+ trackedValueId
53775
+ )
53776
+ );
53777
+ }
52949
53778
  assertOwnedValueAttachable(
52950
53779
  trackedValueId,
52951
53780
  args.owner,
@@ -53030,6 +53859,7 @@ function materializeConstructorArgumentValue(args) {
53030
53859
  }
53031
53860
  }
53032
53861
  row.value = ids;
53862
+ args.collectionAliases?.set(row, collectionAlias);
53033
53863
  return row;
53034
53864
  }
53035
53865
  if (isMemberDictionaryBase(args.member)) {
@@ -53084,6 +53914,7 @@ function materializeConstructorArgumentValue(args) {
53084
53914
  }).id;
53085
53915
  }
53086
53916
  row.value = record7;
53917
+ args.collectionAliases?.set(row, collectionAlias);
53087
53918
  return row;
53088
53919
  }
53089
53920
  return registerConstructorArgumentRow(args, args.value);
@@ -55146,7 +55977,11 @@ function materializeMemberDefaultValue(args) {
55146
55977
  valueById: (id2) => {
55147
55978
  args.readTracking?.valueIds.add(id2);
55148
55979
  const database2 = evaluatorLookups();
55149
- return database2.defaultValueById !== void 0 ? database2.defaultValueById(id2) : database2.valueById(id2);
55980
+ return database2.valueById(id2);
55981
+ },
55982
+ defaultValueSource: (id2, member) => {
55983
+ args.readTracking?.valueIds.add(id2);
55984
+ return evaluatorLookups().defaultValueSource?.(id2, member) ?? null;
55150
55985
  },
55151
55986
  unorderedListEntryIds: (containerId) => {
55152
55987
  args.readTracking?.containerIds.add(containerId);
@@ -55246,9 +56081,14 @@ var init_initializer_materialization = __esm({
55246
56081
 
55247
56082
  // ../packages/neoscript-runtime/src/declaration-default-source.ts
55248
56083
  function declarationDefaultSource(id2, stored, resolveGraph) {
55249
- if (stored !== null && !isCollapseStampedInstanceRoot(stored)) return stored;
56084
+ if (stored !== null && !isCollapseStampedInstanceRoot(stored))
56085
+ return { value: stored };
55250
56086
  const graph = resolveGraph(id2);
55251
- return defaultSourceWithListeners(graph?.rowsById.get(id2) ?? stored, graph);
56087
+ const value = defaultSourceWithListeners(
56088
+ graph?.rowsById.get(id2) ?? stored,
56089
+ graph
56090
+ );
56091
+ return value === null ? null : { value, rowsById: graph?.rowsById };
55252
56092
  }
55253
56093
  var init_declaration_default_source = __esm({
55254
56094
  "../packages/neoscript-runtime/src/declaration-default-source.ts"() {
@@ -61413,6 +62253,21 @@ function createHeadlessVirtualInstanceResolver(args) {
61413
62253
  return inherited === void 0 ? authored : { ...inherited, ...authored };
61414
62254
  };
61415
62255
  return {
62256
+ declarationDefaultGraph: (rootId, member) => {
62257
+ recorder.recordValueRead(rootId);
62258
+ const root = rawById.get(rootId);
62259
+ if (root === void 0) return null;
62260
+ return resolveStoredClassValue({
62261
+ evaluateInitializer: args.evaluateInitializer,
62262
+ materializeInitializerValue: args.materializeInitializerValue,
62263
+ materializeMemberDefaultValue: args.materializeMemberDefaultValue,
62264
+ document: resolverDocumentOnce(),
62265
+ instanceRoot: root,
62266
+ rootMember: member,
62267
+ materializedIndex: materializedIndexOnce(),
62268
+ readRecorder: recorder
62269
+ });
62270
+ },
61416
62271
  storedClassGraph: (rootId, member) => {
61417
62272
  expandRoot(rootId, member);
61418
62273
  const graph = graphByValueId.get(rootId);
@@ -61723,7 +62578,7 @@ function initializerEvaluatorLookups(document, readTracking) {
61723
62578
  },
61724
62579
  memberById: (id2) => databaseVM.memberById(id2),
61725
62580
  valueById: (id2) => databaseVM.valueById(id2),
61726
- defaultValueById: (id2) => databaseVM.defaultValueById?.(id2) ?? databaseVM.valueById(id2),
62581
+ defaultValueSource: databaseVM.defaultValueSource?.bind(databaseVM),
61727
62582
  onInitializerRead: databaseVM.onInitializerRead,
61728
62583
  localizedTextById: (id2) => databaseVM.localizedTextById?.(id2) ?? null,
61729
62584
  ...databaseVM.hasStoredValueId === void 0 ? {} : {
@@ -61794,10 +62649,10 @@ function initializerEvaluatorLookups(document, readTracking) {
61794
62649
  const lookups = {
61795
62650
  ...indexedLookups,
61796
62651
  changeListenerDefaultsForOwner: headlessVirtualResolver.changeListenerDefaultsForOwner,
61797
- defaultValueById: (id2) => declarationDefaultSource(
62652
+ defaultValueSource: (id2, member) => declarationDefaultSource(
61798
62653
  id2,
61799
62654
  indexedLookups.valueById(id2),
61800
- headlessVirtualResolver.virtualInstanceGraphForValue
62655
+ (id3) => headlessVirtualResolver.declarationDefaultGraph(id3, member)
61801
62656
  ),
61802
62657
  valueById: (id2) => indexedLookups.valueById(id2) ?? headlessVirtualResolver.valueById(id2),
61803
62658
  rowForValueReference: (value) => indexedLookups.rowForValueReference?.(value) ?? headlessVirtualResolver.rowForValueReference(value),
@@ -61852,7 +62707,8 @@ function defaultValuePlans(document) {
61852
62707
  projectFiles: document.projectFiles,
61853
62708
  textureTemplates: document.textureTemplates,
61854
62709
  memberById: lookups.memberById,
61855
- valueById: lookups.defaultValueById ?? lookups.valueById,
62710
+ valueById: lookups.valueById,
62711
+ defaultValueSource: lookups.defaultValueSource,
61856
62712
  // A host database without list membership falls back to `values`.
61857
62713
  unorderedListEntryIds: document.databaseVM?.unorderedListEntryIds === void 0 && document.databaseVM !== void 0 ? void 0 : lookups.unorderedListEntryIds
61858
62714
  });
@@ -62043,10 +62899,10 @@ function createInitializerMaterializationBatch(authoredDocument, pendingInitiali
62043
62899
  const authored = base.changeListenerDefaultsForOwner?.(id2);
62044
62900
  return inherited === void 0 ? authored : { ...inherited, ...authored };
62045
62901
  },
62046
- defaultValueById: (id2) => declarationDefaultSource(
62902
+ defaultValueSource: (id2, member) => declarationDefaultSource(
62047
62903
  id2,
62048
62904
  base.valueById(id2),
62049
- (valueId) => virtual().virtualInstanceGraphForValue(valueId)
62905
+ (id3) => virtual().declarationDefaultGraph(id3, member)
62050
62906
  ),
62051
62907
  valueById: (id2) => base.valueById(id2) ?? expandedById.get(id2) ?? virtual().valueById(id2),
62052
62908
  rowForValueReference: (value) => base.rowForValueReference(value) ?? expandedByReference.get(value) ?? virtual().rowForValueReference(value),
@@ -65867,7 +66723,7 @@ function variable(id2, type2, pointer, project) {
65867
66723
  };
65868
66724
  }
65869
66725
  function isGeneratedPositionalCall(target, expression) {
65870
- return neoScriptRequiredConstructor(target) === null && target.constructorSignature !== void 0 && expression.argumentNames === void 0 && callHasPositionalArguments(expression);
66726
+ return (target.declaredConstructors?.length ?? 0) === 0 && target.constructorSignature !== void 0 && expression.argumentNames === void 0 && callHasPositionalArguments(expression);
65871
66727
  }
65872
66728
  function closedConstructorParameters(parameters, targetType, schemaClass2, project) {
65873
66729
  return parameters.map((parameter4) => {
@@ -65911,7 +66767,7 @@ function bindConstructorArgumentNames(className, declared, argumentNames, pos) {
65911
66767
  if (positionalIndex < 0) {
65912
66768
  return argumentNames.filter((name) => name !== null);
65913
66769
  }
65914
- const sole = declared.find((candidate) => candidate.required === true);
66770
+ const sole = declared.length === 1 ? declared[0] : void 0;
65915
66771
  if (sole === void 0) {
65916
66772
  throw new CompileError(
65917
66773
  `Class '${className}' declares constructors, so argument ${positionalIndex + 1} must be passed by name \u2014 candidates: ${describeNeoScriptDeclaredConstructors(className, declared)}.`,
@@ -67479,7 +68335,7 @@ function switchValueKey(value) {
67479
68335
  const enumId = value.typeInfo.type === 8 /* Enum */ ? value.typeInfo.enumId : null;
67480
68336
  return JSON.stringify([value.typeInfo.type, enumId, value.value]);
67481
68337
  }
67482
- function resolveNeoScriptType(type2, context, project) {
68338
+ function resolveNeoScriptType(type2, context, project, referenceMode = "read") {
67483
68339
  let resolved;
67484
68340
  switch (type2.kind) {
67485
68341
  case "primitive":
@@ -67532,7 +68388,7 @@ function resolveNeoScriptType(type2, context, project) {
67532
68388
  );
67533
68389
  const ineligible = neoScriptReferenceTargetError(targetType, project);
67534
68390
  if (ineligible !== null) throw new CompileError(ineligible, type2.pos);
67535
- resolved = neoScriptReferenceType(
68391
+ resolved = referenceMode === "stored" ? { kind: "reference", target: targetType } : neoScriptReferenceType(
67536
68392
  targetType,
67537
68393
  false,
67538
68394
  (named2) => isNeoScriptValueNamedType(named2, project)
@@ -67572,7 +68428,7 @@ function resolveNeoScriptType(type2, context, project) {
67572
68428
  typeId: named.id,
67573
68429
  ...type2.typeArguments ? {
67574
68430
  typeArguments: type2.typeArguments.map(
67575
- (argument2) => resolveNeoScriptType(argument2, context, project)
68431
+ (argument2) => resolveNeoScriptType(argument2, context, project, "stored")
67576
68432
  )
67577
68433
  } : {}
67578
68434
  };
@@ -67584,7 +68440,12 @@ function resolveNeoScriptType(type2, context, project) {
67584
68440
  kind: "tuple",
67585
68441
  nullable: !type2.required,
67586
68442
  elements: type2.elements.map((element) => ({
67587
- type: resolveNeoScriptType(element.type, context, project),
68443
+ type: resolveNeoScriptType(
68444
+ element.type,
68445
+ context,
68446
+ project,
68447
+ referenceMode
68448
+ ),
67588
68449
  ...element.name ? { name: element.name } : {},
67589
68450
  ...element.nameRange && context.sourceUri ? {
67590
68451
  labelLocation: {
@@ -67597,11 +68458,21 @@ function resolveNeoScriptType(type2, context, project) {
67597
68458
  case "list":
67598
68459
  resolved = {
67599
68460
  kind: "list",
67600
- elementType: resolveNeoScriptType(type2.element, context, project)
68461
+ elementType: resolveNeoScriptType(
68462
+ type2.element,
68463
+ context,
68464
+ project,
68465
+ referenceMode
68466
+ )
67601
68467
  };
67602
68468
  break;
67603
68469
  case "set": {
67604
- const element = resolveNeoScriptType(type2.element, context, project);
68470
+ const element = resolveNeoScriptType(
68471
+ type2.element,
68472
+ context,
68473
+ project,
68474
+ referenceMode
68475
+ );
67605
68476
  resolved = {
67606
68477
  kind: "set",
67607
68478
  // P105 §2.2. Multiselect dialogue elements are bare dialogue ids.
@@ -67620,7 +68491,12 @@ function resolveNeoScriptType(type2, context, project) {
67620
68491
  resolved = {
67621
68492
  kind: "dictionary",
67622
68493
  keyType: key,
67623
- valueType: resolveNeoScriptType(type2.value, context, project)
68494
+ valueType: resolveNeoScriptType(
68495
+ type2.value,
68496
+ context,
68497
+ project,
68498
+ referenceMode
68499
+ )
67624
68500
  };
67625
68501
  break;
67626
68502
  }
@@ -67628,12 +68504,7 @@ function resolveNeoScriptType(type2, context, project) {
67628
68504
  return { ...resolved, nullable: !type2.required };
67629
68505
  }
67630
68506
  function resolveStoredReferenceTarget(type2, context, project) {
67631
- const inner = type2.kind === "named" && type2.name === "Reference" && type2.typeArguments?.length === 1 ? type2.typeArguments[0] : void 0;
67632
- if (inner === void 0) return resolveNeoScriptType(type2, context, project);
67633
- const target = resolveStoredReferenceTarget(inner, context, project);
67634
- const ineligible = neoScriptReferenceTargetError(target, project);
67635
- if (ineligible !== null) throw new CompileError(ineligible, type2.pos);
67636
- return { kind: "reference", target, nullable: !type2.required };
68507
+ return resolveNeoScriptType(type2, context, project, "stored");
67637
68508
  }
67638
68509
  function resultKind(kinds) {
67639
68510
  if (kinds.includes("targetTyped")) return "targetTyped";
@@ -67648,6 +68519,9 @@ function compilesAlike(kind, target) {
67648
68519
  );
67649
68520
  return !isPrimitive(target, "decimal");
67650
68521
  }
68522
+ function hasTupleLambda(expression) {
68523
+ return expression.kind === "lambda" || expression.kind === "tuple" && expression.elements.some((element) => hasTupleLambda(element.value));
68524
+ }
67651
68525
  function sameInputs(type2, inputs) {
67652
68526
  return type2.kind === "delegate" && type2.parameterTypes.length === inputs.length && type2.parameterTypes.every(
67653
68527
  (input, index) => sameCompilationType(input, inputs[index])
@@ -68389,6 +69263,8 @@ var init_strict_resolver = __esm({
68389
69263
  * compiling. Only one compile of each lambda argument reaches the program.
68390
69264
  */
68391
69265
  lambdaFrame;
69266
+ /** The current call's inferred callbacks, including tuple elements. */
69267
+ argumentLambdas;
68392
69268
  /** P118. Calls compiled in a lambda frame, with what their names bound to. */
68393
69269
  frameCalls = /* @__PURE__ */ new Map();
68394
69270
  frameCallsGroup;
@@ -70602,7 +71478,7 @@ var init_strict_resolver = __esm({
70602
71478
  );
70603
71479
  }
70604
71480
  const bindings = [];
70605
- const capturedTarget = statement.op !== "=" && (vectorTypeName(target.type) !== null || isBitwiseBinaryOperator(statement.op.slice(0, -1))) ? {
71481
+ const capturedTarget = statement.op !== "=" && (target.structuredLeafKind !== void 0 || vectorTypeName(target.type) !== null || isBitwiseBinaryOperator(statement.op.slice(0, -1))) ? {
70606
71482
  ...target,
70607
71483
  pointer: this.captureAssignmentTarget(target.pointer, bindings)
70608
71484
  } : target;
@@ -70684,6 +71560,7 @@ var init_strict_resolver = __esm({
70684
71560
  ...bindings.length > 0 ? { bindings } : {},
70685
71561
  target: {
70686
71562
  pointer: capturedTarget.pointer,
71563
+ ...target.structuredLeafKind === void 0 ? {} : { structuredLeafKind: target.structuredLeafKind },
70687
71564
  typeInfo: target.wireType ?? toWireType(target.type, this.project),
70688
71565
  writability
70689
71566
  },
@@ -71750,8 +72627,7 @@ var init_strict_resolver = __esm({
71750
72627
  frameCallNames(expression, scope) {
71751
72628
  if (this.lambdaFrame === void 0) return void 0;
71752
72629
  if (expression.kind !== "call") return void 0;
71753
- if (!expression.args.some((argument2) => argument2.kind === "lambda"))
71754
- return void 0;
72630
+ if (!expression.args.some(hasTupleLambda)) return void 0;
71755
72631
  if (this.overloadArgumentKind(expression, scope) !== "typed")
71756
72632
  return void 0;
71757
72633
  let names2 = this.callNames.get(expression);
@@ -71814,7 +72690,11 @@ var init_strict_resolver = __esm({
71814
72690
  resolveExpressionCore(expression, scope, expected, convertSequence = true) {
71815
72691
  if (expected?.kind === "delegate") {
71816
72692
  if (expression.kind === "lambda") {
71817
- return this.resolveDelegateLambda(expression, expected, scope);
72693
+ const lambdas = this.argumentLambdas;
72694
+ const cached = weighedLambda(lambdas?.get(expression), expected);
72695
+ if (cached !== void 0) return cached;
72696
+ const compile = () => this.resolveDelegateLambda(expression, expected, scope);
72697
+ return lambdas?.has(expression) ? this.inLambdaFrame(lambdas, expression, compile) : compile();
71818
72698
  }
71819
72699
  const methodGroup = this.resolveDelegateMethodGroup(
71820
72700
  expression,
@@ -74583,6 +75463,7 @@ var init_strict_resolver = __esm({
74583
75463
  }
74584
75464
  const primitiveMember = resolvePrimitiveMember(receiver.type, name);
74585
75465
  if (primitiveMember) {
75466
+ const structuredLeafKind = receiver.type.kind === "primitive" && isNeoScriptVectorKind(receiver.type.name) ? receiver.type.name : void 0;
74586
75467
  if (isPrimitive(receiver.type, "NeoDialogueReference")) {
74587
75468
  return {
74588
75469
  pointer: {
@@ -74604,7 +75485,8 @@ var init_strict_resolver = __esm({
74604
75485
  primitiveMember.type,
74605
75486
  nullPropagating
74606
75487
  );
74607
- if (!primitiveMember.derived) return resolved;
75488
+ if (!primitiveMember.derived)
75489
+ return structuredLeafKind === void 0 ? resolved : { ...resolved, structuredLeafKind };
74608
75490
  return {
74609
75491
  ...resolved,
74610
75492
  derivedMember: { owner: this.describe(receiver.type), name }
@@ -77717,10 +78599,13 @@ var init_strict_resolver = __esm({
77717
78599
  else if (cached && (sameCompilationType(cached.type, expected) || cached.pointer.type === "callFunction" /* CallFunction */)) {
77718
78600
  resolved = cached;
77719
78601
  } else {
77720
- const lambdas = choice?.lambdas;
77721
- const weighed = argument2.kind === "lambda" && expected.kind === "delegate" ? weighedLambda(lambdas?.get(argument2), expected) : void 0;
77722
- const compile = () => this.resolveExpression(argument2, scope, target);
77723
- resolved = weighed ?? (argument2.kind === "lambda" && lambdas ? this.inLambdaFrame(lambdas, argument2, compile) : compile());
78602
+ const previous = this.argumentLambdas;
78603
+ this.argumentLambdas = choice?.lambdas ?? inferred?.lambdas;
78604
+ try {
78605
+ resolved = this.resolveExpression(argument2, scope, target);
78606
+ } finally {
78607
+ this.argumentLambdas = previous;
78608
+ }
77724
78609
  }
77725
78610
  resolved = this.contextualReference(argument2, resolved, scope, target);
77726
78611
  resolved = this.convertSequence(resolved, target);
@@ -77781,9 +78666,7 @@ var init_strict_resolver = __esm({
77781
78666
  const callbacks = [];
77782
78667
  const probe = new Scope(scope);
77783
78668
  const resolvedArguments = /* @__PURE__ */ new Map();
77784
- argumentsList2.forEach((argument2, index) => {
77785
- const pattern = parameters[index];
77786
- if (pattern === void 0) return;
78669
+ const inferArgument = (argument2, pattern, prior) => {
77787
78670
  if (inference.unresolved(pattern).size === 0) return;
77788
78671
  if (argument2.kind === "lambda" && pattern.kind === "delegate") {
77789
78672
  argument2.params.forEach((parameter4, parameterIndex) => {
@@ -77794,8 +78677,14 @@ var init_strict_resolver = __esm({
77794
78677
  callbacks.push({ ast: argument2, type: pattern });
77795
78678
  return;
77796
78679
  }
78680
+ if (argument2.kind === "tuple" && pattern.kind === "tuple") {
78681
+ if (argument2.elements.length !== pattern.elements.length) return;
78682
+ argument2.elements.forEach((element, index) => {
78683
+ inferArgument(element.value, pattern.elements[index].type);
78684
+ });
78685
+ return;
78686
+ }
77797
78687
  if (!hasIndependentTypeEvidence(argument2)) return;
77798
- const prior = weighed?.typed[index];
77799
78688
  if (prior !== void 0) {
77800
78689
  inference.add(
77801
78690
  this.referenceInferenceType(argument2, prior, pattern),
@@ -77819,9 +78708,17 @@ var init_strict_resolver = __esm({
77819
78708
  pattern
77820
78709
  );
77821
78710
  }
78711
+ };
78712
+ argumentsList2.forEach((argument2, index) => {
78713
+ const pattern = parameters[index];
78714
+ if (pattern === void 0) return;
78715
+ if (weighed === void 0 && argument2.kind === "tuple" && pattern.kind === "tuple")
78716
+ this.typeOverloadEntries(argument2, probe);
78717
+ inferArgument(argument2, pattern, weighed?.typed[index]);
77822
78718
  });
78719
+ const lambdas = weighed?.lambdas ?? /* @__PURE__ */ new Map();
77823
78720
  const error = inference.solve(callbacks, (callback, inputs) => {
77824
- const probes = weighed?.lambdas.get(callback.ast) ?? [];
78721
+ const probes = lambdas.get(callback.ast) ?? [];
77825
78722
  let resolved = probes.find(
77826
78723
  (candidate) => sameInputs(candidate.type, inputs)
77827
78724
  );
@@ -77836,8 +78733,8 @@ var init_strict_resolver = __esm({
77836
78733
  probe,
77837
78734
  true
77838
78735
  );
77839
- resolved = weighed ? this.inLambdaFrame(weighed.lambdas, callback.ast, compile) : compile();
77840
- weighed?.lambdas.set(callback.ast, [...probes, resolved]);
78736
+ resolved = this.inLambdaFrame(lambdas, callback.ast, compile);
78737
+ lambdas.set(callback.ast, [...probes, resolved]);
77841
78738
  }
77842
78739
  if (!resolved.needsReturnContext)
77843
78740
  resolvedArguments.set(callback.ast, resolved);
@@ -77855,7 +78752,8 @@ var init_strict_resolver = __esm({
77855
78752
  }
77856
78753
  return {
77857
78754
  typeArguments: inference.arguments(),
77858
- resolved: resolvedArguments
78755
+ resolved: resolvedArguments,
78756
+ lambdas
77859
78757
  };
77860
78758
  }
77861
78759
  callableSignatureForReceiver(symbol, receiver, typeArguments, pos, inferred) {
@@ -94271,7 +95169,7 @@ function explainNeoVariantPath(index, segments, isDeclaredClass) {
94271
95169
  const className = segments[0];
94272
95170
  if (className === void 0) return null;
94273
95171
  if (segments[1] !== NEO_VARIANT_SCOPE_NAME) return null;
94274
- if (!isDeclaredClass(className)) return null;
95172
+ if (!isDeclaredClass(className)) return { kind: "unknownClass", className };
94275
95173
  if (segments.length === 3 && segments[2] === NEO_VARIANT_RESERVED_NAME) {
94276
95174
  return null;
94277
95175
  }
@@ -95692,6 +96590,7 @@ function semanticDeclarationContract(document) {
95692
96590
  ...declaration,
95693
96591
  members: declaration.members.map((member) => {
95694
96592
  if (member.kind === "field") {
96593
+ if (member.type.name === NEO_VARIANT_TYPE_NAME) return member;
95695
96594
  const initializer = member.initializer;
95696
96595
  return initializer === void 0 ? member : {
95697
96596
  ...member,
@@ -95879,6 +96778,7 @@ function createEnvironment(documents, project) {
95879
96778
  const types = /* @__PURE__ */ new Map();
95880
96779
  const globals = /* @__PURE__ */ new Map();
95881
96780
  const referenceTargets = /* @__PURE__ */ new Map();
96781
+ const variantFields = /* @__PURE__ */ new Map();
95882
96782
  for (const [name, options] of Object.entries(
95883
96783
  NEO_PROJECT_SOURCE_RECORD_CONTRACT.enums
95884
96784
  )) {
@@ -95914,6 +96814,14 @@ function createEnvironment(documents, project) {
95914
96814
  });
95915
96815
  }
95916
96816
  for (const member of declaration.members) {
96817
+ if (member.kind === "field" && member.type.name === NEO_VARIANT_TYPE_NAME) {
96818
+ let fields = variantFields.get(declaration.name);
96819
+ if (fields === void 0) {
96820
+ fields = /* @__PURE__ */ new Map();
96821
+ variantFields.set(declaration.name, fields);
96822
+ }
96823
+ fields.set(member.name, member);
96824
+ }
95917
96825
  if ((member.kind === "field" || member.kind === "property") && member.modifiers.includes("static")) {
95918
96826
  referenceTargets.set(`${declaration.name}.${member.name}`, {
95919
96827
  kind: "value",
@@ -95924,10 +96832,20 @@ function createEnvironment(documents, project) {
95924
96832
  }
95925
96833
  }
95926
96834
  }
96835
+ const projectIndex = createProjectIndex(project);
96836
+ const imageRegistryEntries = /* @__PURE__ */ new Set();
96837
+ for (const member of projectIndex.typeByName.get(
96838
+ NEOSCRIPT_IMAGE_REGISTRY_TYPE
96839
+ )?.members ?? []) {
96840
+ imageRegistryEntries.add(member.name);
96841
+ }
95927
96842
  return {
95928
96843
  documents,
95929
96844
  project,
95930
- projectIndex: createProjectIndex(project),
96845
+ projectIndex,
96846
+ imageRegistryEntries,
96847
+ variantFields,
96848
+ variantDefaults: /* @__PURE__ */ new Map(),
95931
96849
  initializerResolvers: /* @__PURE__ */ new Map(),
95932
96850
  staticMember: false,
95933
96851
  assignability: /* @__PURE__ */ new Map(),
@@ -96256,6 +97174,38 @@ function slotPosition(start, pos) {
96256
97174
  }
96257
97175
  return { line: start.line + pos.line - 1, character: pos.column - 1 };
96258
97176
  }
97177
+ function variantSourceDefault(ownerName, memberName, environment) {
97178
+ const path = /* @__PURE__ */ new Set();
97179
+ let current = environment.types.get(ownerName);
97180
+ let result = null;
97181
+ while (current !== void 0 && !path.has(current.name)) {
97182
+ const cached = environment.variantDefaults.get(current.name);
97183
+ if (cached?.has(memberName)) {
97184
+ result = cached.get(memberName) ?? null;
97185
+ break;
97186
+ }
97187
+ path.add(current.name);
97188
+ const field = environment.variantFields.get(current.name)?.get(memberName);
97189
+ const declaration = environment.construction.classes.get(current.name);
97190
+ if (field?.initializer !== void 0 && declaration !== void 0) {
97191
+ result = { uri: declaration.uri, ownerName: current.name, field };
97192
+ break;
97193
+ }
97194
+ const base = current.baseTypes.find(
97195
+ (type2) => environment.types.has(type2.name)
97196
+ );
97197
+ current = base === void 0 ? void 0 : environment.types.get(base.name);
97198
+ }
97199
+ for (const name of path) {
97200
+ let cached = environment.variantDefaults.get(name);
97201
+ if (cached === void 0) {
97202
+ cached = /* @__PURE__ */ new Map();
97203
+ environment.variantDefaults.set(name, cached);
97204
+ }
97205
+ cached.set(memberName, result);
97206
+ }
97207
+ return result;
97208
+ }
96259
97209
  function validateMember(uri, member, ownerName, documentKind, ownerScope, environment, diagnostics) {
96260
97210
  const memberType2 = semanticType(member.type);
96261
97211
  validateAnnotations(
@@ -96307,6 +97257,40 @@ function validateMember(uri, member, ownerName, documentKind, ownerScope, enviro
96307
97257
  }
96308
97258
  return;
96309
97259
  }
97260
+ if (member.initializer === void 0 && member.modifiers.includes("override") && member.type.name === NEO_VARIANT_TYPE_NAME) {
97261
+ const inherited = variantSourceDefault(ownerName, member.name, environment);
97262
+ const initializer = inherited?.field.initializer;
97263
+ if (inherited !== null && initializer !== void 0) {
97264
+ const inheritedDiagnostics = [];
97265
+ validateExpressionText(
97266
+ inherited.uri,
97267
+ initializer.text,
97268
+ { ...memberType2, nullable: true },
97269
+ scope,
97270
+ environment,
97271
+ initializer.range,
97272
+ inheritedDiagnostics,
97273
+ anchorOf(initializer)
97274
+ );
97275
+ for (const diagnostic of inheritedDiagnostics) {
97276
+ if (diagnostic.code !== "variant-default-covariance") continue;
97277
+ pushDiagnostic(
97278
+ diagnostics,
97279
+ uri,
97280
+ member.nameRange,
97281
+ "variant-inherited-default-covariance",
97282
+ `Inherited default from '${inherited.ownerName}.${member.name}' is incompatible with this override. ${diagnostic.message} Declare a compatible default on the override.`,
97283
+ "error",
97284
+ [
97285
+ {
97286
+ location: { uri: inherited.uri, range: initializer.range },
97287
+ message: `Inherited default '${initializer.text}'.`
97288
+ }
97289
+ ]
97290
+ );
97291
+ }
97292
+ }
97293
+ }
96310
97294
  if (member.initializer && !member.flowInitializer) {
96311
97295
  validateExpressionText(
96312
97296
  uri,
@@ -97292,12 +98276,25 @@ function validateExpression(expression, expected, scope, environment, uri, range
97292
98276
  environment,
97293
98277
  uri,
97294
98278
  range2,
97295
- diagnostics
98279
+ diagnostics,
98280
+ anchor
97296
98281
  );
97297
98282
  return;
97298
98283
  }
97299
98284
  if (expected && expression.kind !== "contextualEnum" && expression.kind !== "annotated" && !isReferenceCall(expression)) {
97300
98285
  const actual = inferExpressionType(expression, scope, environment);
98286
+ if (expected.name === "SpriteInfo" && (actual?.name === "NeoImage" || actual?.name === "ImageRef")) {
98287
+ let start = expression;
98288
+ while (start.kind === "member") start = start.receiver;
98289
+ pushDiagnostic(
98290
+ diagnostics,
98291
+ uri,
98292
+ anchor ? anchorSpan(anchor, start.pos, 1) : range2,
98293
+ "sprite-slice-required",
98294
+ "SpriteInfo requires a sprite slice, not an unsliced image. Select a slice with .Slice(0)."
98295
+ );
98296
+ return;
98297
+ }
97301
98298
  if (storedValue && environment.projectIndex.typeByName.get(expected.name)?.kind === "interface" && (expression.kind === "litList" || expression.kind === "litDict" || actual !== void 0 && ["List", "Set", "Dictionary"].includes(actual.name) || expression.kind === "binary" && expression.op === ".." || knownGeneratorExpression(expression, scope, environment))) {
97302
98299
  pushDiagnostic(
97303
98300
  diagnostics,
@@ -98722,6 +99719,9 @@ function inferExpressionType(expression, scope, environment) {
98722
99719
  const index = ordinal ? Number(ordinal[1]) - 1 : receiver.tupleNames?.indexOf(expression.name) ?? -1;
98723
99720
  return receiver.arguments?.[index];
98724
99721
  }
99722
+ if (receiver?.name === NEOSCRIPT_IMAGE_REGISTRY_TYPE && environment.imageRegistryEntries.has(expression.name)) {
99723
+ return { name: "NeoImage" };
99724
+ }
98725
99725
  if (receiver?.name === "Root") {
98726
99726
  const slot = PROJECT_ROOT_SOURCE_SLOTS.find(
98727
99727
  (slot2) => slot2.name === expression.name
@@ -99440,13 +100440,13 @@ function pushDiagnostic(diagnostics, uri, range2, code, message, severity = "err
99440
100440
  ...relatedInformation.length === 0 ? {} : { relatedInformation }
99441
100441
  });
99442
100442
  }
99443
- function validateVariantValuedExpression(expression, expected, environment, uri, range2, diagnostics) {
100443
+ function validateVariantValuedExpression(expression, expected, environment, uri, range2, diagnostics, anchor) {
99444
100444
  if (expression.kind === "litNull") {
99445
100445
  if (expected.nullable !== true) {
99446
100446
  pushDiagnostic(
99447
100447
  diagnostics,
99448
100448
  uri,
99449
- range2,
100449
+ anchor ? anchorSpan(anchor, expression.pos, 4) : range2,
99450
100450
  "variant-required-null",
99451
100451
  `A non-nullable ${NEO_VARIANT_TYPE_NAME} member cannot default to null. Declare it as '${NEO_VARIANT_TYPE_NAME}<...>?' for no selection, or name '<Class>.${NEO_VARIANT_SCOPE_NAME}.${NEO_VARIANT_RESERVED_NAME}' for the class with no variant applied.`
99452
100452
  );
@@ -99465,7 +100465,7 @@ function validateVariantValuedExpression(expression, expected, environment, uri,
99465
100465
  }
99466
100466
  const segments = variantPathSegments(expression);
99467
100467
  if (segments === null) return;
99468
- const resolved = resolveNeoVariantPath(environment.variantScopes, segments);
100468
+ const resolved = resolveNeoVariantPath(environment.variantScopes, segments) ?? (segments.length === 3 && segments[1] === NEO_VARIANT_SCOPE_NAME && segments[2] === NEO_VARIANT_RESERVED_NAME && environment.types.has(segments[0]) ? { kind: "base", className: segments[0] } : null);
99469
100469
  if (resolved === null) {
99470
100470
  const failure = explainNeoVariantPath(
99471
100471
  environment.variantScopes,
@@ -99473,6 +100473,18 @@ function validateVariantValuedExpression(expression, expected, environment, uri,
99473
100473
  (name) => environment.types.has(name)
99474
100474
  );
99475
100475
  if (failure === null) return;
100476
+ if (failure.kind === "unknownClass") {
100477
+ let root = expression;
100478
+ while (root.kind === "member") root = root.receiver;
100479
+ pushDiagnostic(
100480
+ diagnostics,
100481
+ uri,
100482
+ anchor ? anchorSpan(anchor, root.pos, failure.className.length) : range2,
100483
+ "unknown-variant-class",
100484
+ `Unknown class '${failure.className}' in variant path '${segments.join(".")}'.`
100485
+ );
100486
+ return;
100487
+ }
99476
100488
  pushDiagnostic(
99477
100489
  diagnostics,
99478
100490
  uri,
@@ -99503,7 +100515,7 @@ function validateVariantValuedExpression(expression, expected, environment, uri,
99503
100515
  pushDiagnostic(
99504
100516
  diagnostics,
99505
100517
  uri,
99506
- range2,
100518
+ anchor ? anchorSpan(anchor, expression.pos, 1) : range2,
99507
100519
  "variant-default-covariance",
99508
100520
  `'${segments.join(".")}' is a variant of '${owner}', which does not derive from the declared target '${target}'. A ${NEO_VARIANT_TYPE_NAME}<${target}> accepts variants of '${target}' and of its subclasses only.`
99509
100521
  );
@@ -104420,6 +105432,12 @@ function memberCompatibility(implementation, implementationSubstitution, target,
104420
105432
  environment,
104421
105433
  implementationGenericParameters
104422
105434
  ) && isClassTypedShape(targetType, environment, implementationGenericParameters);
105435
+ const permitsVariantTargetCovariance = isClassOverride && implementation.kind === "field" && target.member.kind === "field" && implementationType.name === "NeoVariant" && targetType.name === "NeoVariant" && implementationType.arguments.length === 1 && targetType.arguments.length === 1 && isTypeAssignable(
105436
+ implementationType.arguments[0],
105437
+ targetType.arguments[0],
105438
+ environment,
105439
+ implementationGenericParameters
105440
+ );
104423
105441
  const permitsDelegateReturnCovariance = isClassOverride && implementationFamily === "value" && delegateShapeAssignable(
104424
105442
  implementationType,
104425
105443
  targetType,
@@ -104428,7 +105446,7 @@ function memberCompatibility(implementation, implementationSubstitution, target,
104428
105446
  );
104429
105447
  const permitsStoredOverrideNullability = isClassOverride && implementation.kind === "field" && (target.member.kind === "field" || isAbstractPropertyContract(target.member, targetAccessors));
104430
105448
  const comparableImplementationType = permitsStoredOverrideNullability ? { ...implementationType, nullable: targetType.nullable } : implementationType;
104431
- if (!typesEqual(comparableImplementationType, targetType) && !(permitsDelegateReturnCovariance || (permitsCovariantGetter || permitsClassCovariance) && isTypeAssignable(
105449
+ if (!typesEqual(comparableImplementationType, targetType) && !(permitsDelegateReturnCovariance || permitsVariantTargetCovariance || (permitsCovariantGetter || permitsClassCovariance) && isTypeAssignable(
104432
105450
  comparableImplementationType,
104433
105451
  targetType,
104434
105452
  environment,
@@ -122362,6 +123380,7 @@ function constructsValue(expression) {
122362
123380
  if (expression.kind === "new") {
122363
123381
  return expression.args.length > 0 || (expression.initializer?.length ?? 0) > 0;
122364
123382
  }
123383
+ if (expression.kind === "tuple") return true;
122365
123384
  if (expression.kind === "litList") return expression.elements.length > 0;
122366
123385
  if (expression.kind === "litDict") return expression.entries.length > 0;
122367
123386
  return false;
@@ -126038,19 +127057,17 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
126038
127057
  }
126039
127058
  }
126040
127059
  function slotForwardsTypeParameter(context, type2, ownerClass) {
126041
- if (type2.name === "List" || type2.name === "Dictionary") {
126042
- const entry = type2.arguments.at(-1);
126043
- return entry !== void 0 && slotForwardsTypeParameter(context, entry, ownerClass);
126044
- }
126045
- if (!context.classIdsByName.has(type2.name)) return false;
126046
127060
  const parameters = context.genericParametersByClass.get(
126047
127061
  materializedId(ownerClass, "class", ownerClass.name)
126048
127062
  );
126049
- if (parameters === void 0) return false;
126050
- for (const argument2 of type2.arguments) {
126051
- if (parameters.has(argument2.name)) return true;
126052
- }
126053
- return false;
127063
+ if (parameters?.has(type2.name)) return true;
127064
+ if (type2.tupleElements !== void 0)
127065
+ return type2.tupleElements.some(
127066
+ ({ type: type3 }) => slotForwardsTypeParameter(context, type3, ownerClass)
127067
+ );
127068
+ return type2.arguments.some(
127069
+ (argument2) => slotForwardsTypeParameter(context, argument2, ownerClass)
127070
+ );
126054
127071
  }
126055
127072
  function positionRequiresEvaluation(context, expression, expected, ownerClass) {
126056
127073
  const requiresEvaluation = () => initializerRequiresEvaluation(
@@ -141298,10 +142315,10 @@ function headlessVirtualInstanceLookups(document, options = {}) {
141298
142315
  const lookups = {
141299
142316
  ...indexed,
141300
142317
  changeListenerDefaultsForOwner: virtual.changeListenerDefaultsForOwner,
141301
- defaultValueById: (id2) => declarationDefaultSource(
142318
+ defaultValueSource: (id2, member) => declarationDefaultSource(
141302
142319
  id2,
141303
142320
  indexed.valueById(id2),
141304
- virtual.virtualInstanceGraphForValue
142321
+ (id3) => virtual.declarationDefaultGraph(id3, member)
141305
142322
  ),
141306
142323
  // Raw first, then virtual: a materialized row always wins over the
141307
142324
  // expansion that would otherwise answer for it.
@@ -143677,12 +144694,8 @@ function inspectClass(options, member) {
143677
144694
  );
143678
144695
  }
143679
144696
  }
143680
- const start = options.classEntryRange?.offset ?? 0;
143681
- const end = options.classEntryRange === void 0 ? schema.length : Math.min(schema.length, start + options.classEntryRange.limit);
143682
144697
  const children3 = [];
143683
- for (let index = start; index < end; index++) {
143684
- const entry = schema[index];
143685
- if (entry === void 0) continue;
144698
+ for (const entry of schema) {
143686
144699
  const childRecord = options.index.member(entry.memberId);
143687
144700
  if (childRecord === void 0) {
143688
144701
  fail(
@@ -143716,8 +144729,7 @@ function inspectClass(options, member) {
143716
144729
  kind: "class",
143717
144730
  effectiveClassId,
143718
144731
  dependencies: [],
143719
- children: children3,
143720
- totalChildSlots: schema.length
144732
+ children: children3
143721
144733
  };
143722
144734
  }
143723
144735
  function storedRowClassId(options, member) {
@@ -161059,6 +162071,7 @@ function valueLowerSchemaIndexes(manifest) {
161059
162071
  manifest.classes.map((entry) => [entry.name, entry])
161060
162072
  ),
161061
162073
  memberOverrides: indexMemberOverrides(members2),
162074
+ variantDefaultMembers: /* @__PURE__ */ new Map(),
161062
162075
  manifestConstructors: new Map(
161063
162076
  manifest.constructors.map((constructor2) => [constructor2.id, constructor2])
161064
162077
  ),
@@ -162674,6 +163687,12 @@ function memberInitializerRequiresEvaluation(context, member, expression, source
162674
163687
  return requiresEvaluation;
162675
163688
  }
162676
163689
  function slotForwardsTypeParameter2(context, member, ownerClassId) {
163690
+ if (member.kind === "generic") {
163691
+ if (ownerClassId === void 0) return true;
163692
+ return classGenericBindings(context.classes, ownerClassId).get(
163693
+ member.genericParamId
163694
+ )?.kind !== "member";
163695
+ }
162677
163696
  if (member.kind === "tuple")
162678
163697
  return member.elementMemberIds.some((id2) => {
162679
163698
  const element = context.members.get(id2);
@@ -164986,7 +166005,7 @@ function lowerValueBody(context, member, expression, base, source, environment,
164986
166005
  case "color":
164987
166006
  return {
164988
166007
  ...next,
164989
- value: lowerStructuredLeaf(context, member, expression)
166008
+ value: lowerStructuredLeaf(context, member, expression, source)
164990
166009
  };
164991
166010
  case "enum":
164992
166011
  return { ...next, value: lowerEnum2(context, member, expression) };
@@ -165005,7 +166024,7 @@ function lowerValueBody(context, member, expression, base, source, environment,
165005
166024
  case "sprite":
165006
166025
  return {
165007
166026
  ...next,
165008
- value: lowerStructuredLeaf(context, member, expression)
166027
+ value: lowerStructuredLeaf(context, member, expression, source)
165009
166028
  };
165010
166029
  case "audio":
165011
166030
  return { ...next, value: lowerFileValue(context, member, expression) };
@@ -166701,7 +167720,7 @@ function lowerFileValue(context, member, expression) {
166701
167720
  throw new Error(`Audio member ${member.name} has an invalid file.`);
166702
167721
  return { fileId };
166703
167722
  }
166704
- function lowerStructuredLeaf(context, member, expression) {
167723
+ function lowerStructuredLeaf(context, member, expression, source) {
166705
167724
  const kind = structuredLeafKindForSlug(member.kind);
166706
167725
  if (kind === null) {
166707
167726
  throw new Error(
@@ -166721,7 +167740,7 @@ function lowerStructuredLeaf(context, member, expression) {
166721
167740
  kind,
166722
167741
  label,
166723
167742
  partial,
166724
- structuredLeafLowering(context)
167743
+ structuredLeafLowering(context, source, label)
166725
167744
  );
166726
167745
  }
166727
167746
  if (member.kind === "sprite") {
@@ -166731,12 +167750,23 @@ function lowerStructuredLeaf(context, member, expression) {
166731
167750
  kind,
166732
167751
  label,
166733
167752
  expression,
166734
- structuredLeafLowering(context)
167753
+ structuredLeafLowering(context, source, label)
166735
167754
  );
166736
167755
  }
166737
- function structuredLeafLowering(context) {
167756
+ function structuredLeafLowering(context, source, label) {
166738
167757
  return {
166739
- number: (expression) => requiredNumber2(expression),
167758
+ number: (expression) => {
167759
+ if (source.purpose !== "memberDefault") return requiredNumber2(expression);
167760
+ return requiredNumber2(expression, () => {
167761
+ const message = `${label} in "${source.label}" default has a computed component. Structured leaf components must be numeric literals.`;
167762
+ context.loweringFailures.push({
167763
+ code: "computed-structured-leaf-component",
167764
+ message,
167765
+ site: referenceSiteAt(source, leftmostPosition(expression))
167766
+ });
167767
+ throw new ReportedLoweringFailure(message);
167768
+ });
167769
+ },
166740
167770
  fileId: (expression) => fileTargetId(context, expression, "Images")
166741
167771
  };
166742
167772
  }
@@ -166745,13 +167775,14 @@ function requiredBoolean(expression) {
166745
167775
  throw new Error("Expected a bool literal.");
166746
167776
  return expression.value;
166747
167777
  }
166748
- function requiredNumber2(expression) {
167778
+ function requiredNumber2(expression, onNonLiteral) {
166749
167779
  if (expression.kind === "litInt" || expression.kind === "litFloat") {
166750
167780
  return expression.value;
166751
167781
  }
166752
167782
  if (expression.kind === "unary" && expression.op === "-") {
166753
- return -requiredNumber2(expression.operand);
167783
+ return -requiredNumber2(expression.operand, onNonLiteral);
166754
167784
  }
167785
+ if (onNonLiteral !== void 0) return onNonLiteral();
166755
167786
  throw new Error("Expected a numeric literal.");
166756
167787
  }
166757
167788
  function requiredDecimal(expression) {
@@ -167615,6 +168646,34 @@ function pendingLocalizedTextId(binding, path) {
167615
168646
  }
167616
168647
  return `__pending__:localized-text:${encodeURIComponent(binding.source.uri)}:${binding.source.range.start.line}:${binding.source.range.start.character}:${encodeURIComponent(path)}`;
167617
168648
  }
168649
+ function variantDefaultMember(context, member) {
168650
+ if (context.variantDefaultMembers.has(member.id))
168651
+ return context.variantDefaultMembers.get(member.id) ?? null;
168652
+ const path = [];
168653
+ const seen = /* @__PURE__ */ new Set();
168654
+ let current = member;
168655
+ let owner = null;
168656
+ while (current?.kind === "variant" && !seen.has(current.id)) {
168657
+ if (context.variantDefaultMembers.has(current.id)) {
168658
+ owner = context.variantDefaultMembers.get(current.id) ?? null;
168659
+ break;
168660
+ }
168661
+ seen.add(current.id);
168662
+ path.push(current);
168663
+ if (current.defaultValue !== null) {
168664
+ owner = current;
168665
+ break;
168666
+ }
168667
+ current = current.overrideOf === null ? void 0 : context.members.get(current.overrideOf);
168668
+ }
168669
+ for (let index = path.length - 1; index >= 0; index--) {
168670
+ const entry = path[index];
168671
+ if (entry.required && entry !== owner && owner?.defaultValue && "value" in owner.defaultValue && owner.defaultValue.value === null)
168672
+ owner = null;
168673
+ context.variantDefaultMembers.set(entry.id, owner);
168674
+ }
168675
+ return owner;
168676
+ }
167618
168677
  function freshChildReplaysDeclaredDefault(args) {
167619
168678
  const { context, childMember, childId, rows, localizedTexts, environment } = args;
167620
168679
  if (!isPendingId(childId)) return false;
@@ -167632,11 +168691,12 @@ function freshChildReplaysDeclaredDefault(args) {
167632
168691
  childMember,
167633
168692
  environment
167634
168693
  );
168694
+ const defaultMember = resolved.kind === "variant" ? variantDefaultMember(context, resolved) : resolved;
167635
168695
  let defaultValue = null;
167636
- if (resolved.defaultValue && "value" in resolved.defaultValue) {
167637
- defaultValue = resolved.defaultValue;
167638
- } else if (resolved.defaultValue && "serverValueId" in resolved.defaultValue) {
167639
- const storedMember = context.state[`member:${resolved.id}`]?.data;
168696
+ if (defaultMember?.defaultValue && "value" in defaultMember.defaultValue) {
168697
+ defaultValue = defaultMember.defaultValue;
168698
+ } else if (defaultMember?.defaultValue && "serverValueId" in defaultMember.defaultValue) {
168699
+ const storedMember = context.state[`member:${defaultMember.id}`]?.data;
167640
168700
  const storedDefault = isObjectRecord(storedMember) ? storedMember.defaultValue : null;
167641
168701
  if (isObjectRecord(storedDefault) && "value" in storedDefault) {
167642
168702
  defaultValue = {
@@ -206469,7 +207529,7 @@ function interfaceClassConstraintTarget(ctx, constraint, declaration, path, save
206469
207529
  ({ id: id2 }) => id2 === binding.genericParamId
206470
207530
  ) : void 0;
206471
207531
  const member = isForwardedGenericBinding(binding) ? null : resolveMemberById(ctx, binding.memberId, argPath);
206472
- const argument2 = forwarded?.name ?? (member === null ? null : csharpValueType(ctx, member, saved));
207532
+ const argument2 = forwarded?.name ?? (member === null ? null : csharpGenericArgumentMemberType(ctx, member, void 0, saved));
206473
207533
  if (argument2 === null) return null;
206474
207534
  projected.push(argument2);
206475
207535
  }
@@ -207274,6 +208334,12 @@ function generateNeoSchemaClassLines(ctx, classId, constructions) {
207274
208334
  const inheritedPropertyAdapters = generateInheritedPropertyInterfaceAdapters(
207275
208335
  ctx,
207276
208336
  classDef,
208337
+ new Map(
208338
+ mergedMemberEntries.map(({ schemaKey, memberId }) => [
208339
+ schemaKey,
208340
+ memberId
208341
+ ])
208342
+ ),
207277
208343
  memberEnv
207278
208344
  );
207279
208345
  const projectedAncestorCloneAdapters = generateProjectedAncestorCloneAdapters(
@@ -207316,7 +208382,8 @@ function generateNeoSchemaClassLines(ctx, classId, constructions) {
207316
208382
  true,
207317
208383
  extendsClassId !== void 0,
207318
208384
  className,
207319
- memberEnv
208385
+ memberEnv,
208386
+ classDef.id
207320
208387
  )
207321
208388
  );
207322
208389
  const readOnlyInterface = generateReadOnlyNeoSchemaClassInterface(
@@ -208357,7 +209424,8 @@ function generateExplicitInterfaceMember(ctx, schemaKey, memberId, interfaceName
208357
209424
  ownerClassName,
208358
209425
  null,
208359
209426
  genericEnv,
208360
- ownerClassId
209427
+ ownerClassId,
209428
+ interfaceContract
208361
209429
  );
208362
209430
  const setter = isMemberNSPropertyBase(member) && typeof member.setterCode === "string" && !suppressesInheritedSetter(interfaceContract) ? nsPropertyWriteExpression(ctx, member, schemaKey) : null;
208363
209431
  return [
@@ -208530,7 +209598,7 @@ function generateExplicitFunctionInterfaceAdapter(ctx, member, interfaceType2, r
208530
209598
  )
208531
209599
  ];
208532
209600
  }
208533
- function generateInheritedPropertyInterfaceAdapters(ctx, classDef, genericEnv) {
209601
+ function generateInheritedPropertyInterfaceAdapters(ctx, classDef, effectiveMembers, genericEnv) {
208534
209602
  let chain;
208535
209603
  try {
208536
209604
  chain = resolveInheritanceChain(classDef.id, ctx.classes);
@@ -208572,14 +209640,15 @@ function generateInheritedPropertyInterfaceAdapters(ctx, classDef, genericEnv) {
208572
209640
  true,
208573
209641
  genericEnv
208574
209642
  )?.valueType ?? null;
208575
- const interfaceValueType = emittedGeneratedMemberContract(
209643
+ const interfaceContract = emittedGeneratedMemberContract(
208576
209644
  ctx,
208577
209645
  declarationClass.id,
208578
209646
  schemaKey,
208579
209647
  memberId,
208580
209648
  false,
208581
209649
  genericEnv
208582
- )?.valueType ?? null;
209650
+ );
209651
+ const interfaceValueType = interfaceContract?.valueType ?? null;
208583
209652
  if (classType === null || interfaceValueType === null || classType === interfaceValueType) {
208584
209653
  continue;
208585
209654
  }
@@ -208590,30 +209659,56 @@ function generateInheritedPropertyInterfaceAdapters(ctx, classDef, genericEnv) {
208590
209659
  false,
208591
209660
  declarationClass.id
208592
209661
  );
208593
- const getter = isMemberWithEntries(member) ? [
208594
- ...detachedReadExpression(
208595
- ctx,
208596
- member,
208597
- schemaKey,
208598
- memberSaved,
208599
- null,
208600
- genericEnv,
208601
- declarationClass.id,
208602
- false
208603
- ),
208604
- ...collectionReadExpression(
209662
+ const referenceTarget = referenceContractTarget(interfaceContract);
209663
+ const effectiveId = effectiveMembers.get(schemaKey);
209664
+ const effectiveMember = effectiveId === void 0 ? null : resolveMemberById(ctx, effectiveId, `members.${effectiveId}`);
209665
+ let getter;
209666
+ if (effectiveMember !== null && isMemberLookupBase(effectiveMember) && !isMultiSelectionMember(effectiveMember)) {
209667
+ getter = readExpression(
208605
209668
  ctx,
208606
- member,
208607
- `node.Get<${neoMemberNodeType(member)}>("${escapeCSharpString(schemaKey)}")`,
209669
+ effectiveMember,
208608
209670
  schemaKey,
208609
- resolveMemberById(ctx, member.entryMemberId, "entryMemberId"),
209671
+ "NeoMemberLookup",
208610
209672
  memberSaved,
209673
+ classDef.name,
208611
209674
  null,
208612
209675
  genericEnv,
208613
- interfaceValueType,
208614
- false
208615
- )
208616
- ] : [`return (${interfaceValueType})(object)${source}!;`];
209676
+ classDef.id,
209677
+ interfaceContract
209678
+ );
209679
+ } else if (referenceTarget !== null) {
209680
+ const missing = interfaceValueType.endsWith("?") ? "" : ` ?? ${REQUIRED_LOOKUP_MISSING}`;
209681
+ getter = [
209682
+ `return NeoGeneratedTypesSupport.ReadReference<${referenceTarget}>(client, ${source}?.TargetId)${missing};`
209683
+ ];
209684
+ } else if (isMemberWithEntries(member)) {
209685
+ getter = [
209686
+ ...detachedReadExpression(
209687
+ ctx,
209688
+ member,
209689
+ schemaKey,
209690
+ memberSaved,
209691
+ null,
209692
+ genericEnv,
209693
+ declarationClass.id,
209694
+ false
209695
+ ),
209696
+ ...collectionReadExpression(
209697
+ ctx,
209698
+ member,
209699
+ `node.Get<${neoMemberNodeType(member)}>("${escapeCSharpString(schemaKey)}")`,
209700
+ schemaKey,
209701
+ resolveMemberById(ctx, member.entryMemberId, "entryMemberId"),
209702
+ memberSaved,
209703
+ null,
209704
+ genericEnv,
209705
+ interfaceValueType,
209706
+ false
209707
+ )
209708
+ ];
209709
+ } else {
209710
+ getter = [`return (${interfaceValueType})(object)${source}!;`];
209711
+ }
208617
209712
  const hasSetter = isMemberNSPropertyBase(member) && typeof member.setterCode === "string";
208618
209713
  const adapter = [
208619
209714
  `${interfaceValueType} ${interfaceType2}.${memberName}`,
@@ -208752,7 +209847,7 @@ function generateFunctionHandlerProperty(ctx, classDef, className, genericParams
208752
209847
  "}"
208753
209848
  ];
208754
209849
  }
208755
- function generateChangeSubscriptionMembers(ctx, entries, saved, hideBaseMembers, ownerClassName, genericEnv) {
209850
+ function generateChangeSubscriptionMembers(ctx, entries, saved, hideBaseMembers, ownerClassName, genericEnv, ownerClassId) {
208756
209851
  const fields = entries.flatMap(([schemaKey, memberId]) => {
208757
209852
  const memberName = validateSchemaMemberName(
208758
209853
  ctx,
@@ -208762,8 +209857,27 @@ function generateChangeSubscriptionMembers(ctx, entries, saved, hideBaseMembers,
208762
209857
  if (memberName === null) return [];
208763
209858
  const member = resolveMemberById(ctx, memberId, `members.${memberId}`);
208764
209859
  if (member === null) return [];
208765
- const valueType = csharpPropertyValueType(ctx, member, saved, genericEnv);
208766
- if (valueType === null) return [];
209860
+ const rawValueType = csharpPropertyValueType(
209861
+ ctx,
209862
+ member,
209863
+ saved,
209864
+ genericEnv
209865
+ );
209866
+ if (rawValueType === null) return [];
209867
+ const contract = isMemberLookupBase(member) || isMemberVariantBase(member) ? inheritedGeneratedMemberContract(
209868
+ ctx,
209869
+ ownerClassId,
209870
+ schemaKey,
209871
+ memberId,
209872
+ saved,
209873
+ genericEnv
209874
+ ) : null;
209875
+ const valueType = narrowedMemberValueType(
209876
+ ctx,
209877
+ member,
209878
+ rawValueType,
209879
+ contract
209880
+ );
208767
209881
  return [{ schemaKey, memberName, valueType, member }];
208768
209882
  });
208769
209883
  const members2 = [
@@ -210025,7 +211139,7 @@ function genericParamConstraintClauses(ctx, classDef, scope, saved, env) {
210025
211139
  continue;
210026
211140
  }
210027
211141
  const member = resolveMemberById(ctx, binding.memberId, path);
210028
- const argument2 = member === null ? null : csharpValueType(ctx, member, saved, env);
211142
+ const argument2 = member === null ? null : csharpGenericArgumentMemberType(ctx, member, env, saved);
210029
211143
  if (argument2 === null) {
210030
211144
  complete2 = false;
210031
211145
  break;
@@ -210059,7 +211173,12 @@ function baseClauseGenericArguments(ctx, classDef, extendsClassId, saved, env) {
210059
211173
  }
210060
211174
  const bindingMember = resolveMemberById(ctx, binding.memberId, path);
210061
211175
  if (bindingMember === null) return inScope.param.name;
210062
- const argType = csharpValueType(ctx, bindingMember, saved, env);
211176
+ const argType = csharpGenericArgumentMemberType(
211177
+ ctx,
211178
+ bindingMember,
211179
+ env,
211180
+ saved
211181
+ );
210063
211182
  if (argType === null) {
210064
211183
  ctx.diagnostics.push({
210065
211184
  severity: "error",
@@ -211262,7 +212381,9 @@ function generateMember(ctx, schemaKey, memberId, saved, modifier, emitBody, own
211262
212381
  ownerClassName,
211263
212382
  memberSaved && saved && !memberHasPinnedWritableStorage(ctx, memberId, ownerClassId) ? `${ownerClassName}.${memberName}` : null,
211264
212383
  genericEnv,
211265
- ownerClassId
212384
+ ownerClassId,
212385
+ inheritedContract,
212386
+ valueType
211266
212387
  );
211267
212388
  const declaredPropertySetter = isMemberNSPropertyBase(member) && typeof member.setterCode === "string" ? nsPropertyWriteExpression(ctx, member, schemaKey) : null;
211268
212389
  const propertySetter = suppressesInheritedSetter(inheritedContract) ? null : declaredPropertySetter;
@@ -212258,7 +213379,7 @@ function isAnimationClipMember(ctx, memberId) {
212258
213379
  }
212259
213380
  function factoryParameterType(ctx, member, optional2 = true, genericEnv) {
212260
213381
  if (isMemberTupleBase(member)) {
212261
- const info = memberTypeInfoForCodegen(ctx, member);
213382
+ const info = storedMemberTypeInfoForCodegen(ctx, member);
212262
213383
  return info === null ? "object?" : csharpTypeInfoValueType(
212263
213384
  ctx,
212264
213385
  { ...info, required: !optional2 },
@@ -212666,7 +213787,7 @@ function nsGetterGenericResultExpression(ctx, typeInfo, valueExpression, saved,
212666
213787
  if (constraint !== void 0 && isClassGenericConstraint(constraint)) {
212667
213788
  return `NeoGeneratedTypesSupport.ResolveNativeFunctionClassArgument<${projected2}>(client, ${valueExpression}, ${typeInfo.required ? "true" : "false"}, ${ctx.projectClassName}.NeoReadOnlyValueFactories, ${ctx.projectClassName}.NeoWritableValueFactories, "NSProperty result")!`;
212668
213789
  }
212669
- return `${valueExpression} is null || ${valueExpression} is ${projected2} ? (${projected2})${valueExpression}! : (${projected2})Convert.ChangeType(${valueExpression}, Nullable.GetUnderlyingType(typeof(${projected2})) ?? typeof(${projected2}), System.Globalization.CultureInfo.InvariantCulture)!`;
213790
+ return `NeoGeneratedTypesSupport.ReadTypeArgument<${projected2}>(client, ${valueExpression}, "${escapeCSharpString(projected2)}", ${ctx.projectClassName}.NeoReadOnlyValueFactories, ${ctx.projectClassName}.NeoWritableValueFactories)`;
212670
213791
  }
212671
213792
  const required2 = isRequiredMember(binding);
212672
213793
  if (isMemberBoolBase(binding)) {
@@ -212725,7 +213846,47 @@ function nsGetterGenericResultExpression(ctx, typeInfo, valueExpression, saved,
212725
213846
  const projected = csharpValueType(ctx, binding, saved, genericEnv) ?? "object?";
212726
213847
  return `(${projected})${valueExpression}!`;
212727
213848
  }
212728
- function readExpression(ctx, member, schemaKey, nodeType, saved, ownerClassName, writeGuardMemberName, genericEnv, ownerClassId) {
213849
+ function referenceContractTarget(contract) {
213850
+ if (contract?.valueTypeInfo?.type !== 29 /* Reference */) return null;
213851
+ const type2 = contract.valueType;
213852
+ if (!type2.startsWith("NeoReference<")) return null;
213853
+ return type2.slice("NeoReference<".length, type2.endsWith("?") ? -2 : -1);
213854
+ }
213855
+ function readExpression(ctx, member, schemaKey, nodeType, saved, ownerClassName, writeGuardMemberName, genericEnv, ownerClassId, contract = null, projectedValueType) {
213856
+ const rawValueType = contract !== null && isMemberLookupBase(member) ? csharpPropertyValueType(ctx, member, saved, genericEnv) : null;
213857
+ if (rawValueType !== null && contract !== null && referenceImplementsValueContract(ctx, member, rawValueType, contract)) {
213858
+ const key = escapeCSharpString(schemaKey);
213859
+ const missing = isRequiredMember(member) ? `${REQUIRED_LOOKUP_MISSING};` : `return default(${contract.valueType}) is null ? default! : throw new InvalidOperationException("An absent optional reference cannot supply a non-nullable value.");`;
213860
+ return [
213861
+ ...ownerClassId !== void 0 && classSupportsDetachedViews(ctx, ownerClassId) ? [
213862
+ `if (TryReadDetached("${key}", out object? detachedValue))`,
213863
+ "{",
213864
+ ...indent([
213865
+ `var reference = NeoGeneratedTypesSupport.ReadReference<${contract.valueType}>(client, detachedValue);`,
213866
+ `if (reference is null) ${missing}`,
213867
+ "return reference.Value;"
213868
+ ]),
213869
+ "}"
213870
+ ] : [],
213871
+ `var selected = node.Get<${nodeType}>("${key}").GetFirstSelected();`,
213872
+ `if (selected is null) ${missing}`,
213873
+ `return NeoGenericBindings.Referenced<${contract.valueType}, ${contract.valueType}>(client, selected);`
213874
+ ];
213875
+ }
213876
+ const referenceTarget = referenceContractTarget(contract);
213877
+ if (referenceTarget !== null && contract !== null && isMemberLookupBase(member) && !isMultiSelectionMember(member)) {
213878
+ const key = escapeCSharpString(schemaKey);
213879
+ const read = (value) => `NeoGeneratedTypesSupport.ReadReference<${referenceTarget}>(client, ${value})${contract.valueType.endsWith("?") ? "" : ` ?? ${REQUIRED_LOOKUP_MISSING}`}`;
213880
+ return [
213881
+ ...ownerClassId !== void 0 && classSupportsDetachedViews(ctx, ownerClassId) ? [
213882
+ `if (TryReadDetached("${key}", out object? detachedValue))`,
213883
+ "{",
213884
+ ...indent([`return ${read("detachedValue")};`]),
213885
+ "}"
213886
+ ] : [],
213887
+ `return ${read(`node.Get<${nodeType}>("${key}")`)};`
213888
+ ];
213889
+ }
212729
213890
  return [
212730
213891
  ...detachedReadExpression(
212731
213892
  ctx,
@@ -212745,7 +213906,8 @@ function readExpression(ctx, member, schemaKey, nodeType, saved, ownerClassName,
212745
213906
  ownerClassName,
212746
213907
  writeGuardMemberName,
212747
213908
  genericEnv,
212748
- ownerClassId
213909
+ ownerClassId,
213910
+ projectedValueType
212749
213911
  )
212750
213912
  ];
212751
213913
  }
@@ -212895,7 +214057,7 @@ function detachedValueExpression(ctx, member, value, required2, saved, genericEn
212895
214057
  }
212896
214058
  return null;
212897
214059
  }
212898
- function storedReadExpression(ctx, member, schemaKey, nodeType, saved, ownerClassName, writeGuardMemberName, genericEnv, ownerClassId) {
214060
+ function storedReadExpression(ctx, member, schemaKey, nodeType, saved, ownerClassName, writeGuardMemberName, genericEnv, ownerClassId, projectedValueType) {
212899
214061
  const getNode = `node.Get<${nodeType}>("${escapeCSharpString(schemaKey)}")`;
212900
214062
  if (isMemberTupleBase(member)) {
212901
214063
  const info = memberTypeInfoForCodegen(ctx, member);
@@ -212944,7 +214106,7 @@ function storedReadExpression(ctx, member, schemaKey, nodeType, saved, ownerClas
212944
214106
  ] : [`return NeoDecimalValues.ParseOrNull(${getNode}.value?.value);`];
212945
214107
  }
212946
214108
  if (isMemberVariantBase(member)) {
212947
- const targetType = variantTargetCSharpType(ctx, member, genericEnv) ?? UNRESOLVED_VARIANT_TARGET;
214109
+ const targetType = projectedValueType?.match(/^NeoVariant<(.+)>\??$/)?.[1] ?? variantTargetCSharpType(ctx, member, genericEnv) ?? UNRESOLVED_VARIANT_TARGET;
212948
214110
  const valueType = variantValueCSharpType(ctx, member, genericEnv);
212949
214111
  const expression = valueType === null ? `NeoGeneratedTypesSupport.ResolveVariantValue<${targetType}>(${getNode})` : `NeoGeneratedTypesSupport.ResolveLookupVariantValue<${targetType}, ${valueType}>(${getNode})`;
212950
214112
  return isRequiredMember(member) ? [
@@ -213461,9 +214623,10 @@ function lookupReferenceRead(ctx, member, node, genericEnv) {
213461
214623
  const read = `NeoGeneratedTypesSupport.ReadReference<${slotReferenceValueType(ctx, member, genericEnv)}>(client, ${node})`;
213462
214624
  return isRequiredMember(member) ? `${read} ?? ${missing}` : read;
213463
214625
  }
213464
- function lookupReferenceSetItem(ctx, member, node, genericEnv) {
214626
+ function lookupReferenceSetItem(ctx, member, node, genericEnv, selection2 = "child") {
213465
214627
  const collection = lookupCollectionView(ctx, member, genericEnv);
213466
- if (collection !== null) return `child => ${collection.read}(client, child)`;
214628
+ if (collection !== null)
214629
+ return `${selection2} => ${collection.read}(client, ${selection2})`;
213467
214630
  return `(string id) => NeoGeneratedTypesSupport.ReferenceEntry<${slotReferenceValueType(ctx, member, genericEnv)}>(client, ${node}, id)`;
213468
214631
  }
213469
214632
  function slotReferenceResult(ctx, typeInfo, valueExpression, genericEnv, genericBindingSaved = false) {
@@ -213511,7 +214674,12 @@ function lookupSelectionFactory(ctx, member, selection2, saved, writeGuardMember
213511
214674
  );
213512
214675
  if (interfaceSelection !== null) return interfaceSelection;
213513
214676
  const targetClass = lookupTargetClassProjection(ctx, member, genericEnv);
213514
- if (targetClass === null) return null;
214677
+ if (targetClass === null) {
214678
+ const target = lookupReferenceTarget(ctx, member);
214679
+ if (target?.type !== 21 /* Generic */) return null;
214680
+ const valueType = csharpTypeInfoValueType(ctx, target, true, genericEnv);
214681
+ return valueType === null ? null : `NeoGenericBindings.Resolve<${valueType}>(client, ${selection2}).Read(${selection2})`;
214682
+ }
213515
214683
  const typeName = ctx.typeNames.get(targetClass.classId) ?? "NeoNode";
213516
214684
  const savedTypeRef = `${qualifyGeneratedType(ctx, savedTypeName(typeName))}${targetClass.constructedSuffix}`;
213517
214685
  const writable = `writable${selection2[0].toUpperCase()}${selection2.slice(1)}`;
@@ -213725,6 +214893,32 @@ function childConverter(ctx, member, saved = false, branchOnReadOnly = false, ge
213725
214893
  return isMultiSelectionMember(member) ? saved ? `new ${setType}(client, (NeoMemberEnum)child, () => (NeoMemberEnumWritable)child${enumKeyCodecArguments(ctx, member.enumId)})` : `new ${setType}(client, (NeoMemberEnum)child${enumKeyCodecArguments(ctx, member.enumId)})` : isRequiredMember(member) ? `NeoGeneratedTypesSupport.ReadEnumSingle(((NeoMemberEnum)child).Selected(), ${parser}) ?? throw new InvalidOperationException("Required enum '${escapeCSharpString(member.name)}' has no selected option.")` : `NeoGeneratedTypesSupport.ReadEnumSingle(((NeoMemberEnum)child).Selected(), ${parser})`;
213726
214894
  }
213727
214895
  if (isMemberLookupBase(member)) {
214896
+ if (isMultiSelectionMember(member)) {
214897
+ const node = "((NeoMemberLookup)child)";
214898
+ const guardName = branchOnReadOnly ? member.name : null;
214899
+ const factory2 = lookupSelectionFactory(
214900
+ ctx,
214901
+ member,
214902
+ "selectedEntry",
214903
+ saved,
214904
+ guardName,
214905
+ genericEnv
214906
+ );
214907
+ let createItem;
214908
+ if (lookupProjection(ctx, member) !== "class" /* Class */) {
214909
+ createItem = lookupReferenceSetItem(
214910
+ ctx,
214911
+ member,
214912
+ node,
214913
+ genericEnv,
214914
+ "selectedEntry"
214915
+ );
214916
+ } else {
214917
+ createItem = factory2 === null ? "(string id) => new NeoLookupSelection(id)" : `selectedEntry => ${factory2}`;
214918
+ }
214919
+ const setType = csharpValueType(ctx, member, saved, genericEnv);
214920
+ return saved ? `new ${setType}(client, ${node}, () => (NeoMemberLookupWritable)child, ${createItem}${collectionGuardArguments(member, guardName)})` : `new ${setType}(client, ${node}, ${createItem})`;
214921
+ }
213728
214922
  if (lookupProjection(ctx, member) !== "class" /* Class */)
213729
214923
  return lookupReferenceRead(
213730
214924
  ctx,
@@ -238699,7 +239893,7 @@ var releaseWorkspaceLock = () => void 0;
238699
239893
  async function main() {
238700
239894
  const args = parseArgs(process.argv.slice(2));
238701
239895
  if (args.command === "--version") {
238702
- console.log("0.89.4");
239896
+ console.log("0.89.5");
238703
239897
  return;
238704
239898
  }
238705
239899
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {