@neocompose/cli 0.89.4 → 0.89.6

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.6",
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"() {
@@ -56302,6 +57142,7 @@ function rowGenericEnvironment(document, row, contextualRootMember) {
56302
57142
  for (const [paramId, binding] of envFromStamp(row.genericBindings)) {
56303
57143
  env.set(paramId, binding);
56304
57144
  }
57145
+ closeForwardedGenericParams(env);
56305
57146
  return env;
56306
57147
  }
56307
57148
  function tryResolveTypeInfo(document, rawTypeInfo, env) {
@@ -61413,6 +62254,21 @@ function createHeadlessVirtualInstanceResolver(args) {
61413
62254
  return inherited === void 0 ? authored : { ...inherited, ...authored };
61414
62255
  };
61415
62256
  return {
62257
+ declarationDefaultGraph: (rootId, member) => {
62258
+ recorder.recordValueRead(rootId);
62259
+ const root = rawById.get(rootId);
62260
+ if (root === void 0) return null;
62261
+ return resolveStoredClassValue({
62262
+ evaluateInitializer: args.evaluateInitializer,
62263
+ materializeInitializerValue: args.materializeInitializerValue,
62264
+ materializeMemberDefaultValue: args.materializeMemberDefaultValue,
62265
+ document: resolverDocumentOnce(),
62266
+ instanceRoot: root,
62267
+ rootMember: member,
62268
+ materializedIndex: materializedIndexOnce(),
62269
+ readRecorder: recorder
62270
+ });
62271
+ },
61416
62272
  storedClassGraph: (rootId, member) => {
61417
62273
  expandRoot(rootId, member);
61418
62274
  const graph = graphByValueId.get(rootId);
@@ -61723,7 +62579,7 @@ function initializerEvaluatorLookups(document, readTracking) {
61723
62579
  },
61724
62580
  memberById: (id2) => databaseVM.memberById(id2),
61725
62581
  valueById: (id2) => databaseVM.valueById(id2),
61726
- defaultValueById: (id2) => databaseVM.defaultValueById?.(id2) ?? databaseVM.valueById(id2),
62582
+ defaultValueSource: databaseVM.defaultValueSource?.bind(databaseVM),
61727
62583
  onInitializerRead: databaseVM.onInitializerRead,
61728
62584
  localizedTextById: (id2) => databaseVM.localizedTextById?.(id2) ?? null,
61729
62585
  ...databaseVM.hasStoredValueId === void 0 ? {} : {
@@ -61794,10 +62650,10 @@ function initializerEvaluatorLookups(document, readTracking) {
61794
62650
  const lookups = {
61795
62651
  ...indexedLookups,
61796
62652
  changeListenerDefaultsForOwner: headlessVirtualResolver.changeListenerDefaultsForOwner,
61797
- defaultValueById: (id2) => declarationDefaultSource(
62653
+ defaultValueSource: (id2, member) => declarationDefaultSource(
61798
62654
  id2,
61799
62655
  indexedLookups.valueById(id2),
61800
- headlessVirtualResolver.virtualInstanceGraphForValue
62656
+ (id3) => headlessVirtualResolver.declarationDefaultGraph(id3, member)
61801
62657
  ),
61802
62658
  valueById: (id2) => indexedLookups.valueById(id2) ?? headlessVirtualResolver.valueById(id2),
61803
62659
  rowForValueReference: (value) => indexedLookups.rowForValueReference?.(value) ?? headlessVirtualResolver.rowForValueReference(value),
@@ -61852,7 +62708,8 @@ function defaultValuePlans(document) {
61852
62708
  projectFiles: document.projectFiles,
61853
62709
  textureTemplates: document.textureTemplates,
61854
62710
  memberById: lookups.memberById,
61855
- valueById: lookups.defaultValueById ?? lookups.valueById,
62711
+ valueById: lookups.valueById,
62712
+ defaultValueSource: lookups.defaultValueSource,
61856
62713
  // A host database without list membership falls back to `values`.
61857
62714
  unorderedListEntryIds: document.databaseVM?.unorderedListEntryIds === void 0 && document.databaseVM !== void 0 ? void 0 : lookups.unorderedListEntryIds
61858
62715
  });
@@ -62043,10 +62900,10 @@ function createInitializerMaterializationBatch(authoredDocument, pendingInitiali
62043
62900
  const authored = base.changeListenerDefaultsForOwner?.(id2);
62044
62901
  return inherited === void 0 ? authored : { ...inherited, ...authored };
62045
62902
  },
62046
- defaultValueById: (id2) => declarationDefaultSource(
62903
+ defaultValueSource: (id2, member) => declarationDefaultSource(
62047
62904
  id2,
62048
62905
  base.valueById(id2),
62049
- (valueId) => virtual().virtualInstanceGraphForValue(valueId)
62906
+ (id3) => virtual().declarationDefaultGraph(id3, member)
62050
62907
  ),
62051
62908
  valueById: (id2) => base.valueById(id2) ?? expandedById.get(id2) ?? virtual().valueById(id2),
62052
62909
  rowForValueReference: (value) => base.rowForValueReference(value) ?? expandedByReference.get(value) ?? virtual().rowForValueReference(value),
@@ -65867,7 +66724,7 @@ function variable(id2, type2, pointer, project) {
65867
66724
  };
65868
66725
  }
65869
66726
  function isGeneratedPositionalCall(target, expression) {
65870
- return neoScriptRequiredConstructor(target) === null && target.constructorSignature !== void 0 && expression.argumentNames === void 0 && callHasPositionalArguments(expression);
66727
+ return (target.declaredConstructors?.length ?? 0) === 0 && target.constructorSignature !== void 0 && expression.argumentNames === void 0 && callHasPositionalArguments(expression);
65871
66728
  }
65872
66729
  function closedConstructorParameters(parameters, targetType, schemaClass2, project) {
65873
66730
  return parameters.map((parameter4) => {
@@ -65911,7 +66768,7 @@ function bindConstructorArgumentNames(className, declared, argumentNames, pos) {
65911
66768
  if (positionalIndex < 0) {
65912
66769
  return argumentNames.filter((name) => name !== null);
65913
66770
  }
65914
- const sole = declared.find((candidate) => candidate.required === true);
66771
+ const sole = declared.length === 1 ? declared[0] : void 0;
65915
66772
  if (sole === void 0) {
65916
66773
  throw new CompileError(
65917
66774
  `Class '${className}' declares constructors, so argument ${positionalIndex + 1} must be passed by name \u2014 candidates: ${describeNeoScriptDeclaredConstructors(className, declared)}.`,
@@ -67479,7 +68336,7 @@ function switchValueKey(value) {
67479
68336
  const enumId = value.typeInfo.type === 8 /* Enum */ ? value.typeInfo.enumId : null;
67480
68337
  return JSON.stringify([value.typeInfo.type, enumId, value.value]);
67481
68338
  }
67482
- function resolveNeoScriptType(type2, context, project) {
68339
+ function resolveNeoScriptType(type2, context, project, referenceMode = "read") {
67483
68340
  let resolved;
67484
68341
  switch (type2.kind) {
67485
68342
  case "primitive":
@@ -67532,7 +68389,7 @@ function resolveNeoScriptType(type2, context, project) {
67532
68389
  );
67533
68390
  const ineligible = neoScriptReferenceTargetError(targetType, project);
67534
68391
  if (ineligible !== null) throw new CompileError(ineligible, type2.pos);
67535
- resolved = neoScriptReferenceType(
68392
+ resolved = referenceMode === "stored" ? { kind: "reference", target: targetType } : neoScriptReferenceType(
67536
68393
  targetType,
67537
68394
  false,
67538
68395
  (named2) => isNeoScriptValueNamedType(named2, project)
@@ -67572,7 +68429,7 @@ function resolveNeoScriptType(type2, context, project) {
67572
68429
  typeId: named.id,
67573
68430
  ...type2.typeArguments ? {
67574
68431
  typeArguments: type2.typeArguments.map(
67575
- (argument2) => resolveNeoScriptType(argument2, context, project)
68432
+ (argument2) => resolveNeoScriptType(argument2, context, project, "stored")
67576
68433
  )
67577
68434
  } : {}
67578
68435
  };
@@ -67584,7 +68441,12 @@ function resolveNeoScriptType(type2, context, project) {
67584
68441
  kind: "tuple",
67585
68442
  nullable: !type2.required,
67586
68443
  elements: type2.elements.map((element) => ({
67587
- type: resolveNeoScriptType(element.type, context, project),
68444
+ type: resolveNeoScriptType(
68445
+ element.type,
68446
+ context,
68447
+ project,
68448
+ referenceMode
68449
+ ),
67588
68450
  ...element.name ? { name: element.name } : {},
67589
68451
  ...element.nameRange && context.sourceUri ? {
67590
68452
  labelLocation: {
@@ -67597,11 +68459,21 @@ function resolveNeoScriptType(type2, context, project) {
67597
68459
  case "list":
67598
68460
  resolved = {
67599
68461
  kind: "list",
67600
- elementType: resolveNeoScriptType(type2.element, context, project)
68462
+ elementType: resolveNeoScriptType(
68463
+ type2.element,
68464
+ context,
68465
+ project,
68466
+ referenceMode
68467
+ )
67601
68468
  };
67602
68469
  break;
67603
68470
  case "set": {
67604
- const element = resolveNeoScriptType(type2.element, context, project);
68471
+ const element = resolveNeoScriptType(
68472
+ type2.element,
68473
+ context,
68474
+ project,
68475
+ referenceMode
68476
+ );
67605
68477
  resolved = {
67606
68478
  kind: "set",
67607
68479
  // P105 §2.2. Multiselect dialogue elements are bare dialogue ids.
@@ -67620,7 +68492,12 @@ function resolveNeoScriptType(type2, context, project) {
67620
68492
  resolved = {
67621
68493
  kind: "dictionary",
67622
68494
  keyType: key,
67623
- valueType: resolveNeoScriptType(type2.value, context, project)
68495
+ valueType: resolveNeoScriptType(
68496
+ type2.value,
68497
+ context,
68498
+ project,
68499
+ referenceMode
68500
+ )
67624
68501
  };
67625
68502
  break;
67626
68503
  }
@@ -67628,12 +68505,7 @@ function resolveNeoScriptType(type2, context, project) {
67628
68505
  return { ...resolved, nullable: !type2.required };
67629
68506
  }
67630
68507
  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 };
68508
+ return resolveNeoScriptType(type2, context, project, "stored");
67637
68509
  }
67638
68510
  function resultKind(kinds) {
67639
68511
  if (kinds.includes("targetTyped")) return "targetTyped";
@@ -67648,6 +68520,9 @@ function compilesAlike(kind, target) {
67648
68520
  );
67649
68521
  return !isPrimitive(target, "decimal");
67650
68522
  }
68523
+ function hasTupleLambda(expression) {
68524
+ return expression.kind === "lambda" || expression.kind === "tuple" && expression.elements.some((element) => hasTupleLambda(element.value));
68525
+ }
67651
68526
  function sameInputs(type2, inputs) {
67652
68527
  return type2.kind === "delegate" && type2.parameterTypes.length === inputs.length && type2.parameterTypes.every(
67653
68528
  (input, index) => sameCompilationType(input, inputs[index])
@@ -68389,6 +69264,8 @@ var init_strict_resolver = __esm({
68389
69264
  * compiling. Only one compile of each lambda argument reaches the program.
68390
69265
  */
68391
69266
  lambdaFrame;
69267
+ /** The current call's inferred callbacks, including tuple elements. */
69268
+ argumentLambdas;
68392
69269
  /** P118. Calls compiled in a lambda frame, with what their names bound to. */
68393
69270
  frameCalls = /* @__PURE__ */ new Map();
68394
69271
  frameCallsGroup;
@@ -70602,7 +71479,7 @@ var init_strict_resolver = __esm({
70602
71479
  );
70603
71480
  }
70604
71481
  const bindings = [];
70605
- const capturedTarget = statement.op !== "=" && (vectorTypeName(target.type) !== null || isBitwiseBinaryOperator(statement.op.slice(0, -1))) ? {
71482
+ const capturedTarget = statement.op !== "=" && (target.structuredLeafKind !== void 0 || vectorTypeName(target.type) !== null || isBitwiseBinaryOperator(statement.op.slice(0, -1))) ? {
70606
71483
  ...target,
70607
71484
  pointer: this.captureAssignmentTarget(target.pointer, bindings)
70608
71485
  } : target;
@@ -70684,6 +71561,7 @@ var init_strict_resolver = __esm({
70684
71561
  ...bindings.length > 0 ? { bindings } : {},
70685
71562
  target: {
70686
71563
  pointer: capturedTarget.pointer,
71564
+ ...target.structuredLeafKind === void 0 ? {} : { structuredLeafKind: target.structuredLeafKind },
70687
71565
  typeInfo: target.wireType ?? toWireType(target.type, this.project),
70688
71566
  writability
70689
71567
  },
@@ -71750,8 +72628,7 @@ var init_strict_resolver = __esm({
71750
72628
  frameCallNames(expression, scope) {
71751
72629
  if (this.lambdaFrame === void 0) return void 0;
71752
72630
  if (expression.kind !== "call") return void 0;
71753
- if (!expression.args.some((argument2) => argument2.kind === "lambda"))
71754
- return void 0;
72631
+ if (!expression.args.some(hasTupleLambda)) return void 0;
71755
72632
  if (this.overloadArgumentKind(expression, scope) !== "typed")
71756
72633
  return void 0;
71757
72634
  let names2 = this.callNames.get(expression);
@@ -71814,7 +72691,11 @@ var init_strict_resolver = __esm({
71814
72691
  resolveExpressionCore(expression, scope, expected, convertSequence = true) {
71815
72692
  if (expected?.kind === "delegate") {
71816
72693
  if (expression.kind === "lambda") {
71817
- return this.resolveDelegateLambda(expression, expected, scope);
72694
+ const lambdas = this.argumentLambdas;
72695
+ const cached = weighedLambda(lambdas?.get(expression), expected);
72696
+ if (cached !== void 0) return cached;
72697
+ const compile = () => this.resolveDelegateLambda(expression, expected, scope);
72698
+ return lambdas?.has(expression) ? this.inLambdaFrame(lambdas, expression, compile) : compile();
71818
72699
  }
71819
72700
  const methodGroup = this.resolveDelegateMethodGroup(
71820
72701
  expression,
@@ -74583,6 +75464,7 @@ var init_strict_resolver = __esm({
74583
75464
  }
74584
75465
  const primitiveMember = resolvePrimitiveMember(receiver.type, name);
74585
75466
  if (primitiveMember) {
75467
+ const structuredLeafKind = receiver.type.kind === "primitive" && isNeoScriptVectorKind(receiver.type.name) ? receiver.type.name : void 0;
74586
75468
  if (isPrimitive(receiver.type, "NeoDialogueReference")) {
74587
75469
  return {
74588
75470
  pointer: {
@@ -74604,7 +75486,8 @@ var init_strict_resolver = __esm({
74604
75486
  primitiveMember.type,
74605
75487
  nullPropagating
74606
75488
  );
74607
- if (!primitiveMember.derived) return resolved;
75489
+ if (!primitiveMember.derived)
75490
+ return structuredLeafKind === void 0 ? resolved : { ...resolved, structuredLeafKind };
74608
75491
  return {
74609
75492
  ...resolved,
74610
75493
  derivedMember: { owner: this.describe(receiver.type), name }
@@ -77717,10 +78600,13 @@ var init_strict_resolver = __esm({
77717
78600
  else if (cached && (sameCompilationType(cached.type, expected) || cached.pointer.type === "callFunction" /* CallFunction */)) {
77718
78601
  resolved = cached;
77719
78602
  } 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());
78603
+ const previous = this.argumentLambdas;
78604
+ this.argumentLambdas = choice?.lambdas ?? inferred?.lambdas;
78605
+ try {
78606
+ resolved = this.resolveExpression(argument2, scope, target);
78607
+ } finally {
78608
+ this.argumentLambdas = previous;
78609
+ }
77724
78610
  }
77725
78611
  resolved = this.contextualReference(argument2, resolved, scope, target);
77726
78612
  resolved = this.convertSequence(resolved, target);
@@ -77781,9 +78667,7 @@ var init_strict_resolver = __esm({
77781
78667
  const callbacks = [];
77782
78668
  const probe = new Scope(scope);
77783
78669
  const resolvedArguments = /* @__PURE__ */ new Map();
77784
- argumentsList2.forEach((argument2, index) => {
77785
- const pattern = parameters[index];
77786
- if (pattern === void 0) return;
78670
+ const inferArgument = (argument2, pattern, prior) => {
77787
78671
  if (inference.unresolved(pattern).size === 0) return;
77788
78672
  if (argument2.kind === "lambda" && pattern.kind === "delegate") {
77789
78673
  argument2.params.forEach((parameter4, parameterIndex) => {
@@ -77794,8 +78678,14 @@ var init_strict_resolver = __esm({
77794
78678
  callbacks.push({ ast: argument2, type: pattern });
77795
78679
  return;
77796
78680
  }
78681
+ if (argument2.kind === "tuple" && pattern.kind === "tuple") {
78682
+ if (argument2.elements.length !== pattern.elements.length) return;
78683
+ argument2.elements.forEach((element, index) => {
78684
+ inferArgument(element.value, pattern.elements[index].type);
78685
+ });
78686
+ return;
78687
+ }
77797
78688
  if (!hasIndependentTypeEvidence(argument2)) return;
77798
- const prior = weighed?.typed[index];
77799
78689
  if (prior !== void 0) {
77800
78690
  inference.add(
77801
78691
  this.referenceInferenceType(argument2, prior, pattern),
@@ -77819,9 +78709,17 @@ var init_strict_resolver = __esm({
77819
78709
  pattern
77820
78710
  );
77821
78711
  }
78712
+ };
78713
+ argumentsList2.forEach((argument2, index) => {
78714
+ const pattern = parameters[index];
78715
+ if (pattern === void 0) return;
78716
+ if (weighed === void 0 && argument2.kind === "tuple" && pattern.kind === "tuple")
78717
+ this.typeOverloadEntries(argument2, probe);
78718
+ inferArgument(argument2, pattern, weighed?.typed[index]);
77822
78719
  });
78720
+ const lambdas = weighed?.lambdas ?? /* @__PURE__ */ new Map();
77823
78721
  const error = inference.solve(callbacks, (callback, inputs) => {
77824
- const probes = weighed?.lambdas.get(callback.ast) ?? [];
78722
+ const probes = lambdas.get(callback.ast) ?? [];
77825
78723
  let resolved = probes.find(
77826
78724
  (candidate) => sameInputs(candidate.type, inputs)
77827
78725
  );
@@ -77836,8 +78734,8 @@ var init_strict_resolver = __esm({
77836
78734
  probe,
77837
78735
  true
77838
78736
  );
77839
- resolved = weighed ? this.inLambdaFrame(weighed.lambdas, callback.ast, compile) : compile();
77840
- weighed?.lambdas.set(callback.ast, [...probes, resolved]);
78737
+ resolved = this.inLambdaFrame(lambdas, callback.ast, compile);
78738
+ lambdas.set(callback.ast, [...probes, resolved]);
77841
78739
  }
77842
78740
  if (!resolved.needsReturnContext)
77843
78741
  resolvedArguments.set(callback.ast, resolved);
@@ -77855,7 +78753,8 @@ var init_strict_resolver = __esm({
77855
78753
  }
77856
78754
  return {
77857
78755
  typeArguments: inference.arguments(),
77858
- resolved: resolvedArguments
78756
+ resolved: resolvedArguments,
78757
+ lambdas
77859
78758
  };
77860
78759
  }
77861
78760
  callableSignatureForReceiver(symbol, receiver, typeArguments, pos, inferred) {
@@ -94271,7 +95170,7 @@ function explainNeoVariantPath(index, segments, isDeclaredClass) {
94271
95170
  const className = segments[0];
94272
95171
  if (className === void 0) return null;
94273
95172
  if (segments[1] !== NEO_VARIANT_SCOPE_NAME) return null;
94274
- if (!isDeclaredClass(className)) return null;
95173
+ if (!isDeclaredClass(className)) return { kind: "unknownClass", className };
94275
95174
  if (segments.length === 3 && segments[2] === NEO_VARIANT_RESERVED_NAME) {
94276
95175
  return null;
94277
95176
  }
@@ -95692,6 +96591,7 @@ function semanticDeclarationContract(document) {
95692
96591
  ...declaration,
95693
96592
  members: declaration.members.map((member) => {
95694
96593
  if (member.kind === "field") {
96594
+ if (member.type.name === NEO_VARIANT_TYPE_NAME) return member;
95695
96595
  const initializer = member.initializer;
95696
96596
  return initializer === void 0 ? member : {
95697
96597
  ...member,
@@ -95879,6 +96779,7 @@ function createEnvironment(documents, project) {
95879
96779
  const types = /* @__PURE__ */ new Map();
95880
96780
  const globals = /* @__PURE__ */ new Map();
95881
96781
  const referenceTargets = /* @__PURE__ */ new Map();
96782
+ const variantFields = /* @__PURE__ */ new Map();
95882
96783
  for (const [name, options] of Object.entries(
95883
96784
  NEO_PROJECT_SOURCE_RECORD_CONTRACT.enums
95884
96785
  )) {
@@ -95914,6 +96815,14 @@ function createEnvironment(documents, project) {
95914
96815
  });
95915
96816
  }
95916
96817
  for (const member of declaration.members) {
96818
+ if (member.kind === "field" && member.type.name === NEO_VARIANT_TYPE_NAME) {
96819
+ let fields = variantFields.get(declaration.name);
96820
+ if (fields === void 0) {
96821
+ fields = /* @__PURE__ */ new Map();
96822
+ variantFields.set(declaration.name, fields);
96823
+ }
96824
+ fields.set(member.name, member);
96825
+ }
95917
96826
  if ((member.kind === "field" || member.kind === "property") && member.modifiers.includes("static")) {
95918
96827
  referenceTargets.set(`${declaration.name}.${member.name}`, {
95919
96828
  kind: "value",
@@ -95924,10 +96833,20 @@ function createEnvironment(documents, project) {
95924
96833
  }
95925
96834
  }
95926
96835
  }
96836
+ const projectIndex = createProjectIndex(project);
96837
+ const imageRegistryEntries = /* @__PURE__ */ new Set();
96838
+ for (const member of projectIndex.typeByName.get(
96839
+ NEOSCRIPT_IMAGE_REGISTRY_TYPE
96840
+ )?.members ?? []) {
96841
+ imageRegistryEntries.add(member.name);
96842
+ }
95927
96843
  return {
95928
96844
  documents,
95929
96845
  project,
95930
- projectIndex: createProjectIndex(project),
96846
+ projectIndex,
96847
+ imageRegistryEntries,
96848
+ variantFields,
96849
+ variantDefaults: /* @__PURE__ */ new Map(),
95931
96850
  initializerResolvers: /* @__PURE__ */ new Map(),
95932
96851
  staticMember: false,
95933
96852
  assignability: /* @__PURE__ */ new Map(),
@@ -96256,6 +97175,38 @@ function slotPosition(start, pos) {
96256
97175
  }
96257
97176
  return { line: start.line + pos.line - 1, character: pos.column - 1 };
96258
97177
  }
97178
+ function variantSourceDefault(ownerName, memberName, environment) {
97179
+ const path = /* @__PURE__ */ new Set();
97180
+ let current = environment.types.get(ownerName);
97181
+ let result = null;
97182
+ while (current !== void 0 && !path.has(current.name)) {
97183
+ const cached = environment.variantDefaults.get(current.name);
97184
+ if (cached?.has(memberName)) {
97185
+ result = cached.get(memberName) ?? null;
97186
+ break;
97187
+ }
97188
+ path.add(current.name);
97189
+ const field = environment.variantFields.get(current.name)?.get(memberName);
97190
+ const declaration = environment.construction.classes.get(current.name);
97191
+ if (field?.initializer !== void 0 && declaration !== void 0) {
97192
+ result = { uri: declaration.uri, ownerName: current.name, field };
97193
+ break;
97194
+ }
97195
+ const base = current.baseTypes.find(
97196
+ (type2) => environment.types.has(type2.name)
97197
+ );
97198
+ current = base === void 0 ? void 0 : environment.types.get(base.name);
97199
+ }
97200
+ for (const name of path) {
97201
+ let cached = environment.variantDefaults.get(name);
97202
+ if (cached === void 0) {
97203
+ cached = /* @__PURE__ */ new Map();
97204
+ environment.variantDefaults.set(name, cached);
97205
+ }
97206
+ cached.set(memberName, result);
97207
+ }
97208
+ return result;
97209
+ }
96259
97210
  function validateMember(uri, member, ownerName, documentKind, ownerScope, environment, diagnostics) {
96260
97211
  const memberType2 = semanticType(member.type);
96261
97212
  validateAnnotations(
@@ -96307,6 +97258,40 @@ function validateMember(uri, member, ownerName, documentKind, ownerScope, enviro
96307
97258
  }
96308
97259
  return;
96309
97260
  }
97261
+ if (member.initializer === void 0 && member.modifiers.includes("override") && member.type.name === NEO_VARIANT_TYPE_NAME) {
97262
+ const inherited = variantSourceDefault(ownerName, member.name, environment);
97263
+ const initializer = inherited?.field.initializer;
97264
+ if (inherited !== null && initializer !== void 0) {
97265
+ const inheritedDiagnostics = [];
97266
+ validateExpressionText(
97267
+ inherited.uri,
97268
+ initializer.text,
97269
+ { ...memberType2, nullable: true },
97270
+ scope,
97271
+ environment,
97272
+ initializer.range,
97273
+ inheritedDiagnostics,
97274
+ anchorOf(initializer)
97275
+ );
97276
+ for (const diagnostic of inheritedDiagnostics) {
97277
+ if (diagnostic.code !== "variant-default-covariance") continue;
97278
+ pushDiagnostic(
97279
+ diagnostics,
97280
+ uri,
97281
+ member.nameRange,
97282
+ "variant-inherited-default-covariance",
97283
+ `Inherited default from '${inherited.ownerName}.${member.name}' is incompatible with this override. ${diagnostic.message} Declare a compatible default on the override.`,
97284
+ "error",
97285
+ [
97286
+ {
97287
+ location: { uri: inherited.uri, range: initializer.range },
97288
+ message: `Inherited default '${initializer.text}'.`
97289
+ }
97290
+ ]
97291
+ );
97292
+ }
97293
+ }
97294
+ }
96310
97295
  if (member.initializer && !member.flowInitializer) {
96311
97296
  validateExpressionText(
96312
97297
  uri,
@@ -97292,12 +98277,25 @@ function validateExpression(expression, expected, scope, environment, uri, range
97292
98277
  environment,
97293
98278
  uri,
97294
98279
  range2,
97295
- diagnostics
98280
+ diagnostics,
98281
+ anchor
97296
98282
  );
97297
98283
  return;
97298
98284
  }
97299
98285
  if (expected && expression.kind !== "contextualEnum" && expression.kind !== "annotated" && !isReferenceCall(expression)) {
97300
98286
  const actual = inferExpressionType(expression, scope, environment);
98287
+ if (expected.name === "SpriteInfo" && (actual?.name === "NeoImage" || actual?.name === "ImageRef")) {
98288
+ let start = expression;
98289
+ while (start.kind === "member") start = start.receiver;
98290
+ pushDiagnostic(
98291
+ diagnostics,
98292
+ uri,
98293
+ anchor ? anchorSpan(anchor, start.pos, 1) : range2,
98294
+ "sprite-slice-required",
98295
+ "SpriteInfo requires a sprite slice, not an unsliced image. Select a slice with .Slice(0)."
98296
+ );
98297
+ return;
98298
+ }
97301
98299
  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
98300
  pushDiagnostic(
97303
98301
  diagnostics,
@@ -98722,6 +99720,9 @@ function inferExpressionType(expression, scope, environment) {
98722
99720
  const index = ordinal ? Number(ordinal[1]) - 1 : receiver.tupleNames?.indexOf(expression.name) ?? -1;
98723
99721
  return receiver.arguments?.[index];
98724
99722
  }
99723
+ if (receiver?.name === NEOSCRIPT_IMAGE_REGISTRY_TYPE && environment.imageRegistryEntries.has(expression.name)) {
99724
+ return { name: "NeoImage" };
99725
+ }
98725
99726
  if (receiver?.name === "Root") {
98726
99727
  const slot = PROJECT_ROOT_SOURCE_SLOTS.find(
98727
99728
  (slot2) => slot2.name === expression.name
@@ -99440,13 +100441,13 @@ function pushDiagnostic(diagnostics, uri, range2, code, message, severity = "err
99440
100441
  ...relatedInformation.length === 0 ? {} : { relatedInformation }
99441
100442
  });
99442
100443
  }
99443
- function validateVariantValuedExpression(expression, expected, environment, uri, range2, diagnostics) {
100444
+ function validateVariantValuedExpression(expression, expected, environment, uri, range2, diagnostics, anchor) {
99444
100445
  if (expression.kind === "litNull") {
99445
100446
  if (expected.nullable !== true) {
99446
100447
  pushDiagnostic(
99447
100448
  diagnostics,
99448
100449
  uri,
99449
- range2,
100450
+ anchor ? anchorSpan(anchor, expression.pos, 4) : range2,
99450
100451
  "variant-required-null",
99451
100452
  `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
100453
  );
@@ -99465,7 +100466,7 @@ function validateVariantValuedExpression(expression, expected, environment, uri,
99465
100466
  }
99466
100467
  const segments = variantPathSegments(expression);
99467
100468
  if (segments === null) return;
99468
- const resolved = resolveNeoVariantPath(environment.variantScopes, segments);
100469
+ 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
100470
  if (resolved === null) {
99470
100471
  const failure = explainNeoVariantPath(
99471
100472
  environment.variantScopes,
@@ -99473,6 +100474,18 @@ function validateVariantValuedExpression(expression, expected, environment, uri,
99473
100474
  (name) => environment.types.has(name)
99474
100475
  );
99475
100476
  if (failure === null) return;
100477
+ if (failure.kind === "unknownClass") {
100478
+ let root = expression;
100479
+ while (root.kind === "member") root = root.receiver;
100480
+ pushDiagnostic(
100481
+ diagnostics,
100482
+ uri,
100483
+ anchor ? anchorSpan(anchor, root.pos, failure.className.length) : range2,
100484
+ "unknown-variant-class",
100485
+ `Unknown class '${failure.className}' in variant path '${segments.join(".")}'.`
100486
+ );
100487
+ return;
100488
+ }
99476
100489
  pushDiagnostic(
99477
100490
  diagnostics,
99478
100491
  uri,
@@ -99503,7 +100516,7 @@ function validateVariantValuedExpression(expression, expected, environment, uri,
99503
100516
  pushDiagnostic(
99504
100517
  diagnostics,
99505
100518
  uri,
99506
- range2,
100519
+ anchor ? anchorSpan(anchor, expression.pos, 1) : range2,
99507
100520
  "variant-default-covariance",
99508
100521
  `'${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
100522
  );
@@ -104420,6 +105433,12 @@ function memberCompatibility(implementation, implementationSubstitution, target,
104420
105433
  environment,
104421
105434
  implementationGenericParameters
104422
105435
  ) && isClassTypedShape(targetType, environment, implementationGenericParameters);
105436
+ 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(
105437
+ implementationType.arguments[0],
105438
+ targetType.arguments[0],
105439
+ environment,
105440
+ implementationGenericParameters
105441
+ );
104423
105442
  const permitsDelegateReturnCovariance = isClassOverride && implementationFamily === "value" && delegateShapeAssignable(
104424
105443
  implementationType,
104425
105444
  targetType,
@@ -104428,7 +105447,7 @@ function memberCompatibility(implementation, implementationSubstitution, target,
104428
105447
  );
104429
105448
  const permitsStoredOverrideNullability = isClassOverride && implementation.kind === "field" && (target.member.kind === "field" || isAbstractPropertyContract(target.member, targetAccessors));
104430
105449
  const comparableImplementationType = permitsStoredOverrideNullability ? { ...implementationType, nullable: targetType.nullable } : implementationType;
104431
- if (!typesEqual(comparableImplementationType, targetType) && !(permitsDelegateReturnCovariance || (permitsCovariantGetter || permitsClassCovariance) && isTypeAssignable(
105450
+ if (!typesEqual(comparableImplementationType, targetType) && !(permitsDelegateReturnCovariance || permitsVariantTargetCovariance || (permitsCovariantGetter || permitsClassCovariance) && isTypeAssignable(
104432
105451
  comparableImplementationType,
104433
105452
  targetType,
104434
105453
  environment,
@@ -122362,6 +123381,7 @@ function constructsValue(expression) {
122362
123381
  if (expression.kind === "new") {
122363
123382
  return expression.args.length > 0 || (expression.initializer?.length ?? 0) > 0;
122364
123383
  }
123384
+ if (expression.kind === "tuple") return true;
122365
123385
  if (expression.kind === "litList") return expression.elements.length > 0;
122366
123386
  if (expression.kind === "litDict") return expression.entries.length > 0;
122367
123387
  return false;
@@ -126038,19 +127058,17 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
126038
127058
  }
126039
127059
  }
126040
127060
  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
127061
  const parameters = context.genericParametersByClass.get(
126047
127062
  materializedId(ownerClass, "class", ownerClass.name)
126048
127063
  );
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;
127064
+ if (parameters?.has(type2.name)) return true;
127065
+ if (type2.tupleElements !== void 0)
127066
+ return type2.tupleElements.some(
127067
+ ({ type: type3 }) => slotForwardsTypeParameter(context, type3, ownerClass)
127068
+ );
127069
+ return type2.arguments.some(
127070
+ (argument2) => slotForwardsTypeParameter(context, argument2, ownerClass)
127071
+ );
126054
127072
  }
126055
127073
  function positionRequiresEvaluation(context, expression, expected, ownerClass) {
126056
127074
  const requiresEvaluation = () => initializerRequiresEvaluation(
@@ -141298,10 +142316,10 @@ function headlessVirtualInstanceLookups(document, options = {}) {
141298
142316
  const lookups = {
141299
142317
  ...indexed,
141300
142318
  changeListenerDefaultsForOwner: virtual.changeListenerDefaultsForOwner,
141301
- defaultValueById: (id2) => declarationDefaultSource(
142319
+ defaultValueSource: (id2, member) => declarationDefaultSource(
141302
142320
  id2,
141303
142321
  indexed.valueById(id2),
141304
- virtual.virtualInstanceGraphForValue
142322
+ (id3) => virtual.declarationDefaultGraph(id3, member)
141305
142323
  ),
141306
142324
  // Raw first, then virtual: a materialized row always wins over the
141307
142325
  // expansion that would otherwise answer for it.
@@ -143677,12 +144695,8 @@ function inspectClass(options, member) {
143677
144695
  );
143678
144696
  }
143679
144697
  }
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
144698
  const children3 = [];
143683
- for (let index = start; index < end; index++) {
143684
- const entry = schema[index];
143685
- if (entry === void 0) continue;
144699
+ for (const entry of schema) {
143686
144700
  const childRecord = options.index.member(entry.memberId);
143687
144701
  if (childRecord === void 0) {
143688
144702
  fail(
@@ -143716,8 +144730,7 @@ function inspectClass(options, member) {
143716
144730
  kind: "class",
143717
144731
  effectiveClassId,
143718
144732
  dependencies: [],
143719
- children: children3,
143720
- totalChildSlots: schema.length
144733
+ children: children3
143721
144734
  };
143722
144735
  }
143723
144736
  function storedRowClassId(options, member) {
@@ -161059,6 +162072,7 @@ function valueLowerSchemaIndexes(manifest) {
161059
162072
  manifest.classes.map((entry) => [entry.name, entry])
161060
162073
  ),
161061
162074
  memberOverrides: indexMemberOverrides(members2),
162075
+ variantDefaultMembers: /* @__PURE__ */ new Map(),
161062
162076
  manifestConstructors: new Map(
161063
162077
  manifest.constructors.map((constructor2) => [constructor2.id, constructor2])
161064
162078
  ),
@@ -162674,6 +163688,12 @@ function memberInitializerRequiresEvaluation(context, member, expression, source
162674
163688
  return requiresEvaluation;
162675
163689
  }
162676
163690
  function slotForwardsTypeParameter2(context, member, ownerClassId) {
163691
+ if (member.kind === "generic") {
163692
+ if (ownerClassId === void 0) return true;
163693
+ return classGenericBindings(context.classes, ownerClassId).get(
163694
+ member.genericParamId
163695
+ )?.kind !== "member";
163696
+ }
162677
163697
  if (member.kind === "tuple")
162678
163698
  return member.elementMemberIds.some((id2) => {
162679
163699
  const element = context.members.get(id2);
@@ -164986,7 +166006,7 @@ function lowerValueBody(context, member, expression, base, source, environment,
164986
166006
  case "color":
164987
166007
  return {
164988
166008
  ...next,
164989
- value: lowerStructuredLeaf(context, member, expression)
166009
+ value: lowerStructuredLeaf(context, member, expression, source)
164990
166010
  };
164991
166011
  case "enum":
164992
166012
  return { ...next, value: lowerEnum2(context, member, expression) };
@@ -165005,7 +166025,7 @@ function lowerValueBody(context, member, expression, base, source, environment,
165005
166025
  case "sprite":
165006
166026
  return {
165007
166027
  ...next,
165008
- value: lowerStructuredLeaf(context, member, expression)
166028
+ value: lowerStructuredLeaf(context, member, expression, source)
165009
166029
  };
165010
166030
  case "audio":
165011
166031
  return { ...next, value: lowerFileValue(context, member, expression) };
@@ -166701,7 +167721,7 @@ function lowerFileValue(context, member, expression) {
166701
167721
  throw new Error(`Audio member ${member.name} has an invalid file.`);
166702
167722
  return { fileId };
166703
167723
  }
166704
- function lowerStructuredLeaf(context, member, expression) {
167724
+ function lowerStructuredLeaf(context, member, expression, source) {
166705
167725
  const kind = structuredLeafKindForSlug(member.kind);
166706
167726
  if (kind === null) {
166707
167727
  throw new Error(
@@ -166721,7 +167741,7 @@ function lowerStructuredLeaf(context, member, expression) {
166721
167741
  kind,
166722
167742
  label,
166723
167743
  partial,
166724
- structuredLeafLowering(context)
167744
+ structuredLeafLowering(context, source, label)
166725
167745
  );
166726
167746
  }
166727
167747
  if (member.kind === "sprite") {
@@ -166731,12 +167751,23 @@ function lowerStructuredLeaf(context, member, expression) {
166731
167751
  kind,
166732
167752
  label,
166733
167753
  expression,
166734
- structuredLeafLowering(context)
167754
+ structuredLeafLowering(context, source, label)
166735
167755
  );
166736
167756
  }
166737
- function structuredLeafLowering(context) {
167757
+ function structuredLeafLowering(context, source, label) {
166738
167758
  return {
166739
- number: (expression) => requiredNumber2(expression),
167759
+ number: (expression) => {
167760
+ if (source.purpose !== "memberDefault") return requiredNumber2(expression);
167761
+ return requiredNumber2(expression, () => {
167762
+ const message = `${label} in "${source.label}" default has a computed component. Structured leaf components must be numeric literals.`;
167763
+ context.loweringFailures.push({
167764
+ code: "computed-structured-leaf-component",
167765
+ message,
167766
+ site: referenceSiteAt(source, leftmostPosition(expression))
167767
+ });
167768
+ throw new ReportedLoweringFailure(message);
167769
+ });
167770
+ },
166740
167771
  fileId: (expression) => fileTargetId(context, expression, "Images")
166741
167772
  };
166742
167773
  }
@@ -166745,13 +167776,14 @@ function requiredBoolean(expression) {
166745
167776
  throw new Error("Expected a bool literal.");
166746
167777
  return expression.value;
166747
167778
  }
166748
- function requiredNumber2(expression) {
167779
+ function requiredNumber2(expression, onNonLiteral) {
166749
167780
  if (expression.kind === "litInt" || expression.kind === "litFloat") {
166750
167781
  return expression.value;
166751
167782
  }
166752
167783
  if (expression.kind === "unary" && expression.op === "-") {
166753
- return -requiredNumber2(expression.operand);
167784
+ return -requiredNumber2(expression.operand, onNonLiteral);
166754
167785
  }
167786
+ if (onNonLiteral !== void 0) return onNonLiteral();
166755
167787
  throw new Error("Expected a numeric literal.");
166756
167788
  }
166757
167789
  function requiredDecimal(expression) {
@@ -167615,6 +168647,34 @@ function pendingLocalizedTextId(binding, path) {
167615
168647
  }
167616
168648
  return `__pending__:localized-text:${encodeURIComponent(binding.source.uri)}:${binding.source.range.start.line}:${binding.source.range.start.character}:${encodeURIComponent(path)}`;
167617
168649
  }
168650
+ function variantDefaultMember(context, member) {
168651
+ if (context.variantDefaultMembers.has(member.id))
168652
+ return context.variantDefaultMembers.get(member.id) ?? null;
168653
+ const path = [];
168654
+ const seen = /* @__PURE__ */ new Set();
168655
+ let current = member;
168656
+ let owner = null;
168657
+ while (current?.kind === "variant" && !seen.has(current.id)) {
168658
+ if (context.variantDefaultMembers.has(current.id)) {
168659
+ owner = context.variantDefaultMembers.get(current.id) ?? null;
168660
+ break;
168661
+ }
168662
+ seen.add(current.id);
168663
+ path.push(current);
168664
+ if (current.defaultValue !== null) {
168665
+ owner = current;
168666
+ break;
168667
+ }
168668
+ current = current.overrideOf === null ? void 0 : context.members.get(current.overrideOf);
168669
+ }
168670
+ for (let index = path.length - 1; index >= 0; index--) {
168671
+ const entry = path[index];
168672
+ if (entry.required && entry !== owner && owner?.defaultValue && "value" in owner.defaultValue && owner.defaultValue.value === null)
168673
+ owner = null;
168674
+ context.variantDefaultMembers.set(entry.id, owner);
168675
+ }
168676
+ return owner;
168677
+ }
167618
168678
  function freshChildReplaysDeclaredDefault(args) {
167619
168679
  const { context, childMember, childId, rows, localizedTexts, environment } = args;
167620
168680
  if (!isPendingId(childId)) return false;
@@ -167632,11 +168692,12 @@ function freshChildReplaysDeclaredDefault(args) {
167632
168692
  childMember,
167633
168693
  environment
167634
168694
  );
168695
+ const defaultMember = resolved.kind === "variant" ? variantDefaultMember(context, resolved) : resolved;
167635
168696
  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;
168697
+ if (defaultMember?.defaultValue && "value" in defaultMember.defaultValue) {
168698
+ defaultValue = defaultMember.defaultValue;
168699
+ } else if (defaultMember?.defaultValue && "serverValueId" in defaultMember.defaultValue) {
168700
+ const storedMember = context.state[`member:${defaultMember.id}`]?.data;
167640
168701
  const storedDefault = isObjectRecord(storedMember) ? storedMember.defaultValue : null;
167641
168702
  if (isObjectRecord(storedDefault) && "value" in storedDefault) {
167642
168703
  defaultValue = {
@@ -206469,7 +207530,7 @@ function interfaceClassConstraintTarget(ctx, constraint, declaration, path, save
206469
207530
  ({ id: id2 }) => id2 === binding.genericParamId
206470
207531
  ) : void 0;
206471
207532
  const member = isForwardedGenericBinding(binding) ? null : resolveMemberById(ctx, binding.memberId, argPath);
206472
- const argument2 = forwarded?.name ?? (member === null ? null : csharpValueType(ctx, member, saved));
207533
+ const argument2 = forwarded?.name ?? (member === null ? null : csharpGenericArgumentMemberType(ctx, member, void 0, saved));
206473
207534
  if (argument2 === null) return null;
206474
207535
  projected.push(argument2);
206475
207536
  }
@@ -207274,6 +208335,12 @@ function generateNeoSchemaClassLines(ctx, classId, constructions) {
207274
208335
  const inheritedPropertyAdapters = generateInheritedPropertyInterfaceAdapters(
207275
208336
  ctx,
207276
208337
  classDef,
208338
+ new Map(
208339
+ mergedMemberEntries.map(({ schemaKey, memberId }) => [
208340
+ schemaKey,
208341
+ memberId
208342
+ ])
208343
+ ),
207277
208344
  memberEnv
207278
208345
  );
207279
208346
  const projectedAncestorCloneAdapters = generateProjectedAncestorCloneAdapters(
@@ -207316,7 +208383,8 @@ function generateNeoSchemaClassLines(ctx, classId, constructions) {
207316
208383
  true,
207317
208384
  extendsClassId !== void 0,
207318
208385
  className,
207319
- memberEnv
208386
+ memberEnv,
208387
+ classDef.id
207320
208388
  )
207321
208389
  );
207322
208390
  const readOnlyInterface = generateReadOnlyNeoSchemaClassInterface(
@@ -208357,7 +209425,8 @@ function generateExplicitInterfaceMember(ctx, schemaKey, memberId, interfaceName
208357
209425
  ownerClassName,
208358
209426
  null,
208359
209427
  genericEnv,
208360
- ownerClassId
209428
+ ownerClassId,
209429
+ interfaceContract
208361
209430
  );
208362
209431
  const setter = isMemberNSPropertyBase(member) && typeof member.setterCode === "string" && !suppressesInheritedSetter(interfaceContract) ? nsPropertyWriteExpression(ctx, member, schemaKey) : null;
208363
209432
  return [
@@ -208530,7 +209599,7 @@ function generateExplicitFunctionInterfaceAdapter(ctx, member, interfaceType2, r
208530
209599
  )
208531
209600
  ];
208532
209601
  }
208533
- function generateInheritedPropertyInterfaceAdapters(ctx, classDef, genericEnv) {
209602
+ function generateInheritedPropertyInterfaceAdapters(ctx, classDef, effectiveMembers, genericEnv) {
208534
209603
  let chain;
208535
209604
  try {
208536
209605
  chain = resolveInheritanceChain(classDef.id, ctx.classes);
@@ -208572,14 +209641,15 @@ function generateInheritedPropertyInterfaceAdapters(ctx, classDef, genericEnv) {
208572
209641
  true,
208573
209642
  genericEnv
208574
209643
  )?.valueType ?? null;
208575
- const interfaceValueType = emittedGeneratedMemberContract(
209644
+ const interfaceContract = emittedGeneratedMemberContract(
208576
209645
  ctx,
208577
209646
  declarationClass.id,
208578
209647
  schemaKey,
208579
209648
  memberId,
208580
209649
  false,
208581
209650
  genericEnv
208582
- )?.valueType ?? null;
209651
+ );
209652
+ const interfaceValueType = interfaceContract?.valueType ?? null;
208583
209653
  if (classType === null || interfaceValueType === null || classType === interfaceValueType) {
208584
209654
  continue;
208585
209655
  }
@@ -208590,30 +209660,56 @@ function generateInheritedPropertyInterfaceAdapters(ctx, classDef, genericEnv) {
208590
209660
  false,
208591
209661
  declarationClass.id
208592
209662
  );
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(
209663
+ const referenceTarget = referenceContractTarget(interfaceContract);
209664
+ const effectiveId = effectiveMembers.get(schemaKey);
209665
+ const effectiveMember = effectiveId === void 0 ? null : resolveMemberById(ctx, effectiveId, `members.${effectiveId}`);
209666
+ let getter;
209667
+ if (effectiveMember !== null && isMemberLookupBase(effectiveMember) && !isMultiSelectionMember(effectiveMember)) {
209668
+ getter = readExpression(
208605
209669
  ctx,
208606
- member,
208607
- `node.Get<${neoMemberNodeType(member)}>("${escapeCSharpString(schemaKey)}")`,
209670
+ effectiveMember,
208608
209671
  schemaKey,
208609
- resolveMemberById(ctx, member.entryMemberId, "entryMemberId"),
209672
+ "NeoMemberLookup",
208610
209673
  memberSaved,
209674
+ classDef.name,
208611
209675
  null,
208612
209676
  genericEnv,
208613
- interfaceValueType,
208614
- false
208615
- )
208616
- ] : [`return (${interfaceValueType})(object)${source}!;`];
209677
+ classDef.id,
209678
+ interfaceContract
209679
+ );
209680
+ } else if (referenceTarget !== null) {
209681
+ const missing = interfaceValueType.endsWith("?") ? "" : ` ?? ${REQUIRED_LOOKUP_MISSING}`;
209682
+ getter = [
209683
+ `return NeoGeneratedTypesSupport.ReadReference<${referenceTarget}>(client, ${source}?.TargetId)${missing};`
209684
+ ];
209685
+ } else if (isMemberWithEntries(member)) {
209686
+ getter = [
209687
+ ...detachedReadExpression(
209688
+ ctx,
209689
+ member,
209690
+ schemaKey,
209691
+ memberSaved,
209692
+ null,
209693
+ genericEnv,
209694
+ declarationClass.id,
209695
+ false
209696
+ ),
209697
+ ...collectionReadExpression(
209698
+ ctx,
209699
+ member,
209700
+ `node.Get<${neoMemberNodeType(member)}>("${escapeCSharpString(schemaKey)}")`,
209701
+ schemaKey,
209702
+ resolveMemberById(ctx, member.entryMemberId, "entryMemberId"),
209703
+ memberSaved,
209704
+ null,
209705
+ genericEnv,
209706
+ interfaceValueType,
209707
+ false
209708
+ )
209709
+ ];
209710
+ } else {
209711
+ getter = [`return (${interfaceValueType})(object)${source}!;`];
209712
+ }
208617
209713
  const hasSetter = isMemberNSPropertyBase(member) && typeof member.setterCode === "string";
208618
209714
  const adapter = [
208619
209715
  `${interfaceValueType} ${interfaceType2}.${memberName}`,
@@ -208752,7 +209848,7 @@ function generateFunctionHandlerProperty(ctx, classDef, className, genericParams
208752
209848
  "}"
208753
209849
  ];
208754
209850
  }
208755
- function generateChangeSubscriptionMembers(ctx, entries, saved, hideBaseMembers, ownerClassName, genericEnv) {
209851
+ function generateChangeSubscriptionMembers(ctx, entries, saved, hideBaseMembers, ownerClassName, genericEnv, ownerClassId) {
208756
209852
  const fields = entries.flatMap(([schemaKey, memberId]) => {
208757
209853
  const memberName = validateSchemaMemberName(
208758
209854
  ctx,
@@ -208762,8 +209858,27 @@ function generateChangeSubscriptionMembers(ctx, entries, saved, hideBaseMembers,
208762
209858
  if (memberName === null) return [];
208763
209859
  const member = resolveMemberById(ctx, memberId, `members.${memberId}`);
208764
209860
  if (member === null) return [];
208765
- const valueType = csharpPropertyValueType(ctx, member, saved, genericEnv);
208766
- if (valueType === null) return [];
209861
+ const rawValueType = csharpPropertyValueType(
209862
+ ctx,
209863
+ member,
209864
+ saved,
209865
+ genericEnv
209866
+ );
209867
+ if (rawValueType === null) return [];
209868
+ const contract = isMemberLookupBase(member) || isMemberVariantBase(member) ? inheritedGeneratedMemberContract(
209869
+ ctx,
209870
+ ownerClassId,
209871
+ schemaKey,
209872
+ memberId,
209873
+ saved,
209874
+ genericEnv
209875
+ ) : null;
209876
+ const valueType = narrowedMemberValueType(
209877
+ ctx,
209878
+ member,
209879
+ rawValueType,
209880
+ contract
209881
+ );
208767
209882
  return [{ schemaKey, memberName, valueType, member }];
208768
209883
  });
208769
209884
  const members2 = [
@@ -210025,7 +211140,7 @@ function genericParamConstraintClauses(ctx, classDef, scope, saved, env) {
210025
211140
  continue;
210026
211141
  }
210027
211142
  const member = resolveMemberById(ctx, binding.memberId, path);
210028
- const argument2 = member === null ? null : csharpValueType(ctx, member, saved, env);
211143
+ const argument2 = member === null ? null : csharpGenericArgumentMemberType(ctx, member, env, saved);
210029
211144
  if (argument2 === null) {
210030
211145
  complete2 = false;
210031
211146
  break;
@@ -210059,7 +211174,12 @@ function baseClauseGenericArguments(ctx, classDef, extendsClassId, saved, env) {
210059
211174
  }
210060
211175
  const bindingMember = resolveMemberById(ctx, binding.memberId, path);
210061
211176
  if (bindingMember === null) return inScope.param.name;
210062
- const argType = csharpValueType(ctx, bindingMember, saved, env);
211177
+ const argType = csharpGenericArgumentMemberType(
211178
+ ctx,
211179
+ bindingMember,
211180
+ env,
211181
+ saved
211182
+ );
210063
211183
  if (argType === null) {
210064
211184
  ctx.diagnostics.push({
210065
211185
  severity: "error",
@@ -211262,7 +212382,9 @@ function generateMember(ctx, schemaKey, memberId, saved, modifier, emitBody, own
211262
212382
  ownerClassName,
211263
212383
  memberSaved && saved && !memberHasPinnedWritableStorage(ctx, memberId, ownerClassId) ? `${ownerClassName}.${memberName}` : null,
211264
212384
  genericEnv,
211265
- ownerClassId
212385
+ ownerClassId,
212386
+ inheritedContract,
212387
+ valueType
211266
212388
  );
211267
212389
  const declaredPropertySetter = isMemberNSPropertyBase(member) && typeof member.setterCode === "string" ? nsPropertyWriteExpression(ctx, member, schemaKey) : null;
211268
212390
  const propertySetter = suppressesInheritedSetter(inheritedContract) ? null : declaredPropertySetter;
@@ -212258,7 +213380,7 @@ function isAnimationClipMember(ctx, memberId) {
212258
213380
  }
212259
213381
  function factoryParameterType(ctx, member, optional2 = true, genericEnv) {
212260
213382
  if (isMemberTupleBase(member)) {
212261
- const info = memberTypeInfoForCodegen(ctx, member);
213383
+ const info = storedMemberTypeInfoForCodegen(ctx, member);
212262
213384
  return info === null ? "object?" : csharpTypeInfoValueType(
212263
213385
  ctx,
212264
213386
  { ...info, required: !optional2 },
@@ -212666,7 +213788,7 @@ function nsGetterGenericResultExpression(ctx, typeInfo, valueExpression, saved,
212666
213788
  if (constraint !== void 0 && isClassGenericConstraint(constraint)) {
212667
213789
  return `NeoGeneratedTypesSupport.ResolveNativeFunctionClassArgument<${projected2}>(client, ${valueExpression}, ${typeInfo.required ? "true" : "false"}, ${ctx.projectClassName}.NeoReadOnlyValueFactories, ${ctx.projectClassName}.NeoWritableValueFactories, "NSProperty result")!`;
212668
213790
  }
212669
- return `${valueExpression} is null || ${valueExpression} is ${projected2} ? (${projected2})${valueExpression}! : (${projected2})Convert.ChangeType(${valueExpression}, Nullable.GetUnderlyingType(typeof(${projected2})) ?? typeof(${projected2}), System.Globalization.CultureInfo.InvariantCulture)!`;
213791
+ return `NeoGeneratedTypesSupport.ReadTypeArgument<${projected2}>(client, ${valueExpression}, "${escapeCSharpString(projected2)}", ${ctx.projectClassName}.NeoReadOnlyValueFactories, ${ctx.projectClassName}.NeoWritableValueFactories)`;
212670
213792
  }
212671
213793
  const required2 = isRequiredMember(binding);
212672
213794
  if (isMemberBoolBase(binding)) {
@@ -212725,7 +213847,47 @@ function nsGetterGenericResultExpression(ctx, typeInfo, valueExpression, saved,
212725
213847
  const projected = csharpValueType(ctx, binding, saved, genericEnv) ?? "object?";
212726
213848
  return `(${projected})${valueExpression}!`;
212727
213849
  }
212728
- function readExpression(ctx, member, schemaKey, nodeType, saved, ownerClassName, writeGuardMemberName, genericEnv, ownerClassId) {
213850
+ function referenceContractTarget(contract) {
213851
+ if (contract?.valueTypeInfo?.type !== 29 /* Reference */) return null;
213852
+ const type2 = contract.valueType;
213853
+ if (!type2.startsWith("NeoReference<")) return null;
213854
+ return type2.slice("NeoReference<".length, type2.endsWith("?") ? -2 : -1);
213855
+ }
213856
+ function readExpression(ctx, member, schemaKey, nodeType, saved, ownerClassName, writeGuardMemberName, genericEnv, ownerClassId, contract = null, projectedValueType) {
213857
+ const rawValueType = contract !== null && isMemberLookupBase(member) ? csharpPropertyValueType(ctx, member, saved, genericEnv) : null;
213858
+ if (rawValueType !== null && contract !== null && referenceImplementsValueContract(ctx, member, rawValueType, contract)) {
213859
+ const key = escapeCSharpString(schemaKey);
213860
+ 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.");`;
213861
+ return [
213862
+ ...ownerClassId !== void 0 && classSupportsDetachedViews(ctx, ownerClassId) ? [
213863
+ `if (TryReadDetached("${key}", out object? detachedValue))`,
213864
+ "{",
213865
+ ...indent([
213866
+ `var reference = NeoGeneratedTypesSupport.ReadReference<${contract.valueType}>(client, detachedValue);`,
213867
+ `if (reference is null) ${missing}`,
213868
+ "return reference.Value;"
213869
+ ]),
213870
+ "}"
213871
+ ] : [],
213872
+ `var selected = node.Get<${nodeType}>("${key}").GetFirstSelected();`,
213873
+ `if (selected is null) ${missing}`,
213874
+ `return NeoGenericBindings.Referenced<${contract.valueType}, ${contract.valueType}>(client, selected);`
213875
+ ];
213876
+ }
213877
+ const referenceTarget = referenceContractTarget(contract);
213878
+ if (referenceTarget !== null && contract !== null && isMemberLookupBase(member) && !isMultiSelectionMember(member)) {
213879
+ const key = escapeCSharpString(schemaKey);
213880
+ const read = (value) => `NeoGeneratedTypesSupport.ReadReference<${referenceTarget}>(client, ${value})${contract.valueType.endsWith("?") ? "" : ` ?? ${REQUIRED_LOOKUP_MISSING}`}`;
213881
+ return [
213882
+ ...ownerClassId !== void 0 && classSupportsDetachedViews(ctx, ownerClassId) ? [
213883
+ `if (TryReadDetached("${key}", out object? detachedValue))`,
213884
+ "{",
213885
+ ...indent([`return ${read("detachedValue")};`]),
213886
+ "}"
213887
+ ] : [],
213888
+ `return ${read(`node.Get<${nodeType}>("${key}")`)};`
213889
+ ];
213890
+ }
212729
213891
  return [
212730
213892
  ...detachedReadExpression(
212731
213893
  ctx,
@@ -212745,7 +213907,8 @@ function readExpression(ctx, member, schemaKey, nodeType, saved, ownerClassName,
212745
213907
  ownerClassName,
212746
213908
  writeGuardMemberName,
212747
213909
  genericEnv,
212748
- ownerClassId
213910
+ ownerClassId,
213911
+ projectedValueType
212749
213912
  )
212750
213913
  ];
212751
213914
  }
@@ -212895,7 +214058,7 @@ function detachedValueExpression(ctx, member, value, required2, saved, genericEn
212895
214058
  }
212896
214059
  return null;
212897
214060
  }
212898
- function storedReadExpression(ctx, member, schemaKey, nodeType, saved, ownerClassName, writeGuardMemberName, genericEnv, ownerClassId) {
214061
+ function storedReadExpression(ctx, member, schemaKey, nodeType, saved, ownerClassName, writeGuardMemberName, genericEnv, ownerClassId, projectedValueType) {
212899
214062
  const getNode = `node.Get<${nodeType}>("${escapeCSharpString(schemaKey)}")`;
212900
214063
  if (isMemberTupleBase(member)) {
212901
214064
  const info = memberTypeInfoForCodegen(ctx, member);
@@ -212944,7 +214107,7 @@ function storedReadExpression(ctx, member, schemaKey, nodeType, saved, ownerClas
212944
214107
  ] : [`return NeoDecimalValues.ParseOrNull(${getNode}.value?.value);`];
212945
214108
  }
212946
214109
  if (isMemberVariantBase(member)) {
212947
- const targetType = variantTargetCSharpType(ctx, member, genericEnv) ?? UNRESOLVED_VARIANT_TARGET;
214110
+ const targetType = projectedValueType?.match(/^NeoVariant<(.+)>\??$/)?.[1] ?? variantTargetCSharpType(ctx, member, genericEnv) ?? UNRESOLVED_VARIANT_TARGET;
212948
214111
  const valueType = variantValueCSharpType(ctx, member, genericEnv);
212949
214112
  const expression = valueType === null ? `NeoGeneratedTypesSupport.ResolveVariantValue<${targetType}>(${getNode})` : `NeoGeneratedTypesSupport.ResolveLookupVariantValue<${targetType}, ${valueType}>(${getNode})`;
212950
214113
  return isRequiredMember(member) ? [
@@ -213461,9 +214624,10 @@ function lookupReferenceRead(ctx, member, node, genericEnv) {
213461
214624
  const read = `NeoGeneratedTypesSupport.ReadReference<${slotReferenceValueType(ctx, member, genericEnv)}>(client, ${node})`;
213462
214625
  return isRequiredMember(member) ? `${read} ?? ${missing}` : read;
213463
214626
  }
213464
- function lookupReferenceSetItem(ctx, member, node, genericEnv) {
214627
+ function lookupReferenceSetItem(ctx, member, node, genericEnv, selection2 = "child") {
213465
214628
  const collection = lookupCollectionView(ctx, member, genericEnv);
213466
- if (collection !== null) return `child => ${collection.read}(client, child)`;
214629
+ if (collection !== null)
214630
+ return `${selection2} => ${collection.read}(client, ${selection2})`;
213467
214631
  return `(string id) => NeoGeneratedTypesSupport.ReferenceEntry<${slotReferenceValueType(ctx, member, genericEnv)}>(client, ${node}, id)`;
213468
214632
  }
213469
214633
  function slotReferenceResult(ctx, typeInfo, valueExpression, genericEnv, genericBindingSaved = false) {
@@ -213511,7 +214675,12 @@ function lookupSelectionFactory(ctx, member, selection2, saved, writeGuardMember
213511
214675
  );
213512
214676
  if (interfaceSelection !== null) return interfaceSelection;
213513
214677
  const targetClass = lookupTargetClassProjection(ctx, member, genericEnv);
213514
- if (targetClass === null) return null;
214678
+ if (targetClass === null) {
214679
+ const target = lookupReferenceTarget(ctx, member);
214680
+ if (target?.type !== 21 /* Generic */) return null;
214681
+ const valueType = csharpTypeInfoValueType(ctx, target, true, genericEnv);
214682
+ return valueType === null ? null : `NeoGenericBindings.Resolve<${valueType}>(client, ${selection2}).Read(${selection2})`;
214683
+ }
213515
214684
  const typeName = ctx.typeNames.get(targetClass.classId) ?? "NeoNode";
213516
214685
  const savedTypeRef = `${qualifyGeneratedType(ctx, savedTypeName(typeName))}${targetClass.constructedSuffix}`;
213517
214686
  const writable = `writable${selection2[0].toUpperCase()}${selection2.slice(1)}`;
@@ -213725,6 +214894,32 @@ function childConverter(ctx, member, saved = false, branchOnReadOnly = false, ge
213725
214894
  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
214895
  }
213727
214896
  if (isMemberLookupBase(member)) {
214897
+ if (isMultiSelectionMember(member)) {
214898
+ const node = "((NeoMemberLookup)child)";
214899
+ const guardName = branchOnReadOnly ? member.name : null;
214900
+ const factory2 = lookupSelectionFactory(
214901
+ ctx,
214902
+ member,
214903
+ "selectedEntry",
214904
+ saved,
214905
+ guardName,
214906
+ genericEnv
214907
+ );
214908
+ let createItem;
214909
+ if (lookupProjection(ctx, member) !== "class" /* Class */) {
214910
+ createItem = lookupReferenceSetItem(
214911
+ ctx,
214912
+ member,
214913
+ node,
214914
+ genericEnv,
214915
+ "selectedEntry"
214916
+ );
214917
+ } else {
214918
+ createItem = factory2 === null ? "(string id) => new NeoLookupSelection(id)" : `selectedEntry => ${factory2}`;
214919
+ }
214920
+ const setType = csharpValueType(ctx, member, saved, genericEnv);
214921
+ return saved ? `new ${setType}(client, ${node}, () => (NeoMemberLookupWritable)child, ${createItem}${collectionGuardArguments(member, guardName)})` : `new ${setType}(client, ${node}, ${createItem})`;
214922
+ }
213728
214923
  if (lookupProjection(ctx, member) !== "class" /* Class */)
213729
214924
  return lookupReferenceRead(
213730
214925
  ctx,
@@ -238699,7 +239894,7 @@ var releaseWorkspaceLock = () => void 0;
238699
239894
  async function main() {
238700
239895
  const args = parseArgs(process.argv.slice(2));
238701
239896
  if (args.command === "--version") {
238702
- console.log("0.89.4");
239897
+ console.log("0.89.6");
238703
239898
  return;
238704
239899
  }
238705
239900
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {