@neocompose/cli 0.79.1 → 0.81.0

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.
@@ -1013,11 +1013,11 @@ var NeoWorldSystemClassKind = {
1013
1013
  ObjectCollider: "objectCollider",
1014
1014
  SortingGroup: "sortingGroup",
1015
1015
  LayerGroupBase: "layerGroupBase",
1016
- SpriteObject: "spriteObject",
1017
1016
  PlacementTile: "placementTile",
1018
1017
  TileLayerLink: "tileLayerLink",
1019
1018
  ObjectLayerLink: "objectLayerLink",
1020
1019
  Object: "object",
1020
+ SpriteObject: "spriteObject",
1021
1021
  SmartTile: "smartTile",
1022
1022
  SmartTileRule: "smartTileRule",
1023
1023
  SmartTileNeighbor: "smartTileNeighbor",
@@ -2966,9 +2966,21 @@ function isNSTypeInfoInterface(value) {
2966
2966
  if (typeof v.interfaceId !== "string") return false;
2967
2967
  return v.interfaceId.length > 0;
2968
2968
  }
2969
+ function isClassGenericParamTypeInfo(value) {
2970
+ return "ownerClassId" in value;
2971
+ }
2969
2972
  function isNSTypeInfoGenericParam(value) {
2970
2973
  if (!isNSTypeInfoBase(value)) return false;
2971
2974
  if (value.type !== 21 /* Generic */) return false;
2975
+ if ("ownerMemberId" in value) {
2976
+ if ("ownerClassId" in value) return false;
2977
+ if ("genericParamId" in value) return false;
2978
+ const v2 = value;
2979
+ if (typeof v2.ownerMemberId !== "string") return false;
2980
+ if (typeof v2.index !== "number") return false;
2981
+ return Number.isInteger(v2.index) && v2.index >= 0;
2982
+ }
2983
+ if ("index" in value) return false;
2972
2984
  const v = value;
2973
2985
  if (typeof v.ownerClassId !== "string") return false;
2974
2986
  if (v.ownerClassId.length === 0) return false;
@@ -3116,6 +3128,86 @@ function hasValidParameterDefault(value) {
3116
3128
  return false;
3117
3129
  }
3118
3130
  }
3131
+ function isFunctionGenericParams(value, isValidName) {
3132
+ if (!Array.isArray(value) || value.length === 0) return false;
3133
+ const names = /* @__PURE__ */ new Set();
3134
+ let defaulted = false;
3135
+ for (const entry of value) {
3136
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
3137
+ return false;
3138
+ const v = entry;
3139
+ for (const key of Object.keys(v)) {
3140
+ if (key !== "name" && key !== "constraint" && key !== "defaultType")
3141
+ return false;
3142
+ }
3143
+ if (!isValidName(v.name)) return false;
3144
+ const name = v.name;
3145
+ if (names.has(name)) return false;
3146
+ names.add(name);
3147
+ if (v.constraint !== void 0) {
3148
+ const constraint = v.constraint;
3149
+ if (!isNSTypeInfoClass(constraint) && !isNSTypeInfoEnum(constraint))
3150
+ return false;
3151
+ if (constraint.required !== true) return false;
3152
+ if (typeInfoContainsFunctionGeneric(constraint, /* @__PURE__ */ new Set()))
3153
+ return false;
3154
+ }
3155
+ if (v.defaultType === void 0) {
3156
+ if (defaulted) return false;
3157
+ continue;
3158
+ }
3159
+ defaulted = true;
3160
+ if (!isNSTypeInfo(v.defaultType)) return false;
3161
+ if (v.defaultType.required !== true) return false;
3162
+ if (v.defaultType.type === NS_TYPE_UNKNOWN) return false;
3163
+ if (typeInfoContainsGeneric(v.defaultType, /* @__PURE__ */ new Set())) return false;
3164
+ }
3165
+ return true;
3166
+ }
3167
+ function typeInfoContainsFunctionGeneric(value, ancestors) {
3168
+ return typeInfoSome(
3169
+ value,
3170
+ (type) => type.type === 21 /* Generic */ && "ownerMemberId" in type,
3171
+ ancestors
3172
+ );
3173
+ }
3174
+ function typeInfoContainsGeneric(value, ancestors) {
3175
+ return typeInfoSome(
3176
+ value,
3177
+ (type) => type.type === 21 /* Generic */,
3178
+ ancestors
3179
+ );
3180
+ }
3181
+ function typeInfoSome(value, predicate, ancestors) {
3182
+ if (predicate(value)) return true;
3183
+ if (ancestors.has(value)) return true;
3184
+ ancestors.add(value);
3185
+ try {
3186
+ switch (value.type) {
3187
+ case 6 /* List */:
3188
+ case 28 /* Set */:
3189
+ case 5 /* Dictionary */:
3190
+ case 9 /* Lookup */:
3191
+ return typeInfoSome(value.entryTypeInfo, predicate, ancestors);
3192
+ case 25 /* NSDelegate */:
3193
+ return value.returnTypeInfo.type !== NS_TYPE_VOID && typeInfoSome(value.returnTypeInfo, predicate, ancestors) || value.argumentTypes.some(
3194
+ (argument2) => typeInfoSome(argument2, predicate, ancestors)
3195
+ );
3196
+ case 26 /* NSAction */:
3197
+ return value.argumentTypes.some(
3198
+ (argument2) => typeInfoSome(argument2, predicate, ancestors)
3199
+ );
3200
+ case 7 /* Class */:
3201
+ return Object.values(value.typeArguments ?? {}).some(
3202
+ (argument2) => typeInfoSome(argument2, predicate, ancestors)
3203
+ );
3204
+ default:
3205
+ return false;
3206
+ }
3207
+ } finally {
3208
+ ancestors.delete(value);
3209
+ }
3210
+ }
3119
3211
  function typeInfoContainsUnknown(value, ancestors) {
3120
3212
  if (value.type === NS_TYPE_UNKNOWN) return true;
3121
3213
  if (ancestors.has(value)) return true;
@@ -3336,7 +3428,9 @@ function isNSPointerCallFunction(value) {
3336
3428
  if (v.missingMemberFallback === "valueEquality" && (!hasMemberKey || v.receiver?.kind !== "instance" || v.args.length !== 1)) {
3337
3429
  return false;
3338
3430
  }
3339
- return true;
3431
+ if (v.typeArguments === void 0) return true;
3432
+ if (!Array.isArray(v.typeArguments)) return false;
3433
+ return v.typeArguments.every(isNSTypeInfo);
3340
3434
  }
3341
3435
  function isNSPointerObjectInitializer(value) {
3342
3436
  if (typeof value !== "object" || value === null) return false;
@@ -4135,6 +4229,9 @@ function typeInfosInvariantlyEqual(left, right) {
4135
4229
  return left.interfaceId === right.interfaceId;
4136
4230
  }
4137
4231
  if (left.type === 21 /* Generic */ && right.type === 21 /* Generic */) {
4232
+ if ("index" in left || "index" in right) {
4233
+ return "index" in left && "index" in right && left.index === right.index;
4234
+ }
4138
4235
  return left.ownerClassId === right.ownerClassId && left.genericParamId === right.genericParamId;
4139
4236
  }
4140
4237
  if (left.type === 8 /* Enum */ && right.type === 8 /* Enum */) {
@@ -4767,6 +4864,7 @@ function isMemberFunctionBase(value) {
4767
4864
  if (!Array.isArray(v.argumentTypes)) return false;
4768
4865
  if (v.dispatch !== void 0 && v.dispatch !== 0 /* Synchronous */ && v.dispatch !== 1 /* Asynchronous */)
4769
4866
  return false;
4867
+ if (!hasValidFunctionGenericParams(v)) return false;
4770
4868
  const names = /* @__PURE__ */ new Set();
4771
4869
  const argumentTypes = [];
4772
4870
  for (const arg of v.argumentTypes) {
@@ -4782,6 +4880,13 @@ function isMemberFunctionBase(value) {
4782
4880
  v.dispatch === 1 /* Asynchronous */
4783
4881
  );
4784
4882
  }
4883
+ function hasValidFunctionGenericParams(value) {
4884
+ if (value.genericParams === void 0) return true;
4885
+ return isFunctionGenericParams(
4886
+ value.genericParams,
4887
+ isValidSchemaBindingIdentifier
4888
+ );
4889
+ }
4785
4890
  function hasValidParameterDefaults(argumentTypes, deferred) {
4786
4891
  if (deferred && hasAnyParameterDefault(argumentTypes)) return false;
4787
4892
  return validateParameterDefaults(argumentTypes).length === 0;
@@ -4835,6 +4940,7 @@ function isMemberNSFunctionBase(value) {
4835
4940
  if (v.action !== void 0 && v.action !== null) return false;
4836
4941
  if (v.bodyMode !== void 0 && v.bodyMode !== 0 /* Code */ && v.bodyMode !== 1 /* UI */)
4837
4942
  return false;
4943
+ if (!hasValidFunctionGenericParams(v)) return false;
4838
4944
  const names = /* @__PURE__ */ new Set();
4839
4945
  const argumentTypes = [];
4840
4946
  for (const argument2 of v.argumentTypes) {
@@ -5108,6 +5214,13 @@ function hasValidEffectField(v) {
5108
5214
  if (!isFunctionEffectKind(v.effect)) return false;
5109
5215
  return v.kind === 13 /* Function */ || v.kind === 23 /* NSFunction */;
5110
5216
  }
5217
+ function hasValidOverrideGenericParams(v) {
5218
+ if (v.genericParams === void 0) return true;
5219
+ if (v.kind !== 13 /* Function */ && v.kind !== 23 /* NSFunction */) {
5220
+ return false;
5221
+ }
5222
+ return hasValidFunctionGenericParams(v);
5223
+ }
5111
5224
  function hasValidDistributionField(v) {
5112
5225
  if (v.distribution === void 0) return true;
5113
5226
  if (!isNeoSubtreeDistributionKind(v.distribution)) return false;
@@ -5246,6 +5359,7 @@ function isMemberOverrideBase(value) {
5246
5359
  if (!hasValidStorageField(v, false)) return false;
5247
5360
  if (!hasValidDistributionField(v)) return false;
5248
5361
  if (!hasValidEffectField(v)) return false;
5362
+ if (!hasValidOverrideGenericParams(v)) return false;
5249
5363
  if (v.defaultValue !== void 0 && v.defaultValue !== null && !isMemberValueBase(v.defaultValue)) {
5250
5364
  return false;
5251
5365
  }
@@ -7229,64 +7343,6 @@ var WORLD_SYSTEM_CLASS_DEFINITIONS = [
7229
7343
  modifier: 1 /* Abstract */,
7230
7344
  worldKind: "layerGroupBase"
7231
7345
  },
7232
- {
7233
- classId: "system_d48b66ab-4d59-47e7-a25a-591fe97062de",
7234
- name: "NeoSpriteObject",
7235
- extendsWorldKind: "objectBase",
7236
- schemaFields: [
7237
- {
7238
- memberId: "system_441cb790-a45f-4488-a5a9-6f375af6c369",
7239
- memberKind: "string",
7240
- defaultValue: "",
7241
- format: 1 /* Plain */,
7242
- distribution: 1 /* Packed */,
7243
- requirement: 1 /* Required */,
7244
- schemaKey: "Name"
7245
- },
7246
- {
7247
- memberId: "system_e9288ba9-f5a2-4485-8443-6afb155b31e0",
7248
- memberKind: "sprite",
7249
- defaultValue: { fileId: "", sliceIndex: 0 },
7250
- requirement: 1 /* Required */,
7251
- schemaKey: "Sprite"
7252
- },
7253
- {
7254
- memberId: "system_9fcab37a-9743-4e35-8eee-80cb560f1433",
7255
- memberKind: "bool",
7256
- defaultValue: false,
7257
- docsText: "Mirrors the sprite horizontally about its own centre. Maps to SpriteRenderer.flipX.",
7258
- requirement: 1 /* Required */,
7259
- schemaKey: "FlipX"
7260
- },
7261
- {
7262
- memberId: "system_ddd09f08-1656-4404-b36b-5570a4c01fcf",
7263
- memberKind: "bool",
7264
- defaultValue: false,
7265
- docsText: "Mirrors the sprite vertically about its own centre. Maps to SpriteRenderer.flipY.",
7266
- requirement: 1 /* Required */,
7267
- schemaKey: "FlipY"
7268
- },
7269
- {
7270
- memberId: "system_f2a8c86d-ace5-421b-9475-0f3f6f97b2a6",
7271
- memberKind: "enum",
7272
- defaultValue: ["system_9d607a4f-60c3-4347-94fc-f24b538bf468"],
7273
- docsText: "How this sprite reacts to sprite masks. Maps to SpriteRenderer.maskInteraction. The web canvas has no real sprite mask, so anything other than None previews as a distinguishable treatment rather than as the mask itself \u2014 only Unity renders the real thing.",
7274
- enumId: "system_4e6c4d6f-1d0b-402a-ad3a-be92242dceec",
7275
- requirement: 1 /* Required */,
7276
- schemaKey: "MaskInteraction"
7277
- },
7278
- {
7279
- memberId: "system_6f32f1f2-83ea-42fc-8647-34ed0946b7f1",
7280
- memberKind: "int",
7281
- defaultValue: null,
7282
- docsText: "Added to the object layer's sorting order; it does not replace it. The result competes with every renderer in the sorting layer, or in the enclosing sorting group, and among equal orders the renderer lower on screen draws in front. Leave unset to use the layer's order.",
7283
- minValue: -32768,
7284
- maxValue: 32767,
7285
- schemaKey: "SortingOrder"
7286
- }
7287
- ],
7288
- worldKind: "spriteObject"
7289
- },
7290
7346
  {
7291
7347
  classId: "system_ccc3330c-2db5-44dc-9c8e-5ebfe430dec9",
7292
7348
  name: "NeoPlacementTile",
@@ -7365,6 +7421,7 @@ var WORLD_SYSTEM_CLASS_DEFINITIONS = [
7365
7421
  memberId: "system_5a9ca1f5-a21b-4d4e-8c55-00341af594b4",
7366
7422
  memberKind: "list",
7367
7423
  defaultValue: [],
7424
+ docsText: "The cells this object occupies, as offsets from its placement cell. An empty list occupies nothing: the object blocks no placement and answers no cell query, but a placed object still has a Cell.",
7368
7425
  entryMemberId: "system_96c7650a-1805-5b27-ae99-d1e49d3cb207",
7369
7426
  requirement: 1 /* Required */,
7370
7427
  schemaKey: "PlacementTiles"
@@ -7399,14 +7456,15 @@ var WORLD_SYSTEM_CLASS_DEFINITIONS = [
7399
7456
  {
7400
7457
  memberId: "system_f5ca386c-990c-54a1-8473-2d49d2cd887d",
7401
7458
  memberKind: "function",
7402
- docsText: "Objects at the cells around this placement, shifted by offset, in pattern order. Use GetObjects<T>(pattern, offset) to filter by class. A repeated footprint can appear more than once.",
7459
+ docsText: "Objects of type T at the cells around this placement, shifted by offset, in pattern order. A repeated footprint can appear more than once.",
7403
7460
  returnTypeInfo: {
7404
7461
  type: 6,
7405
7462
  required: true,
7406
7463
  entryTypeInfo: {
7407
- type: 7,
7464
+ type: 21,
7408
7465
  required: true,
7409
- classId: "system_f671535d-0eb6-4139-9caf-5c5276febd31"
7466
+ ownerMemberId: "system_f5ca386c-990c-54a1-8473-2d49d2cd887d",
7467
+ index: 0
7410
7468
  }
7411
7469
  },
7412
7470
  argumentTypes: [
@@ -7423,17 +7481,33 @@ var WORLD_SYSTEM_CLASS_DEFINITIONS = [
7423
7481
  defaultValue: { value: null }
7424
7482
  }
7425
7483
  ],
7484
+ genericParams: [
7485
+ {
7486
+ name: "T",
7487
+ constraint: {
7488
+ type: 7,
7489
+ required: true,
7490
+ classId: "system_f671535d-0eb6-4139-9caf-5c5276febd31"
7491
+ },
7492
+ defaultType: {
7493
+ type: 7,
7494
+ required: true,
7495
+ classId: "system_f671535d-0eb6-4139-9caf-5c5276febd31"
7496
+ }
7497
+ }
7498
+ ],
7426
7499
  dispatch: 0 /* Synchronous */,
7427
7500
  schemaKey: "GetObjects"
7428
7501
  },
7429
7502
  {
7430
7503
  memberId: "system_593e6208-e2ca-505e-9933-04b17102b6d2",
7431
7504
  memberKind: "function",
7432
- docsText: "The first tile found in pattern order around this placement, shifted by offset, or null. Each cell uses the grid layer precedence.",
7505
+ docsText: "The first tile of type T found in pattern order around this placement, shifted by offset, or null. Each cell uses the grid layer precedence.",
7433
7506
  returnTypeInfo: {
7434
- type: 7,
7507
+ type: 21,
7435
7508
  required: false,
7436
- classId: "system_d7fa161b-b269-4bf1-9ec9-3aebec67e6e0"
7509
+ ownerMemberId: "system_593e6208-e2ca-505e-9933-04b17102b6d2",
7510
+ index: 0
7437
7511
  },
7438
7512
  argumentTypes: [
7439
7513
  {
@@ -7449,20 +7523,36 @@ var WORLD_SYSTEM_CLASS_DEFINITIONS = [
7449
7523
  defaultValue: { value: null }
7450
7524
  }
7451
7525
  ],
7526
+ genericParams: [
7527
+ {
7528
+ name: "T",
7529
+ constraint: {
7530
+ type: 7,
7531
+ required: true,
7532
+ classId: "system_d7fa161b-b269-4bf1-9ec9-3aebec67e6e0"
7533
+ },
7534
+ defaultType: {
7535
+ type: 7,
7536
+ required: true,
7537
+ classId: "system_d7fa161b-b269-4bf1-9ec9-3aebec67e6e0"
7538
+ }
7539
+ }
7540
+ ],
7452
7541
  dispatch: 0 /* Synchronous */,
7453
7542
  schemaKey: "GetTile"
7454
7543
  },
7455
7544
  {
7456
7545
  memberId: "system_5a41d36a-bcd9-4867-9e46-d743f6e09582",
7457
7546
  memberKind: "function",
7458
- docsText: "The tiles at the cells around this placement, shifted by offset, in pattern order. Each cell uses the grid layer precedence and empty cells are skipped.",
7547
+ docsText: "The tiles of type T at the cells around this placement, shifted by offset, in pattern order. Each cell uses the grid layer precedence and empty cells are skipped.",
7459
7548
  returnTypeInfo: {
7460
7549
  type: 6,
7461
7550
  required: true,
7462
7551
  entryTypeInfo: {
7463
- type: 7,
7552
+ type: 21,
7464
7553
  required: true,
7465
- classId: "system_d7fa161b-b269-4bf1-9ec9-3aebec67e6e0"
7554
+ ownerMemberId: "system_5a41d36a-bcd9-4867-9e46-d743f6e09582",
7555
+ index: 0
7466
7556
  }
7467
7557
  },
7468
7558
  argumentTypes: [
@@ -7479,6 +7569,21 @@ var WORLD_SYSTEM_CLASS_DEFINITIONS = [
7479
7569
  defaultValue: { value: null }
7480
7570
  }
7481
7571
  ],
7572
+ genericParams: [
7573
+ {
7574
+ name: "T",
7575
+ constraint: {
7576
+ type: 7,
7577
+ required: true,
7578
+ classId: "system_d7fa161b-b269-4bf1-9ec9-3aebec67e6e0"
7579
+ },
7580
+ defaultType: {
7581
+ type: 7,
7582
+ required: true,
7583
+ classId: "system_d7fa161b-b269-4bf1-9ec9-3aebec67e6e0"
7584
+ }
7585
+ }
7586
+ ],
7482
7587
  dispatch: 0 /* Synchronous */,
7483
7588
  schemaKey: "GetTiles"
7484
7589
  }
@@ -7501,6 +7606,64 @@ var WORLD_SYSTEM_CLASS_DEFINITIONS = [
7501
7606
  ],
7502
7607
  worldKind: "object"
7503
7608
  },
7609
+ {
7610
+ classId: "system_d48b66ab-4d59-47e7-a25a-591fe97062de",
7611
+ name: "NeoSpriteObject",
7612
+ extendsWorldKind: "object",
7613
+ schemaFields: [
7614
+ {
7615
+ memberId: "system_441cb790-a45f-4488-a5a9-6f375af6c369",
7616
+ memberKind: "string",
7617
+ defaultValue: "",
7618
+ format: 1 /* Plain */,
7619
+ distribution: 1 /* Packed */,
7620
+ requirement: 1 /* Required */,
7621
+ schemaKey: "Name"
7622
+ },
7623
+ {
7624
+ memberId: "system_e9288ba9-f5a2-4485-8443-6afb155b31e0",
7625
+ memberKind: "sprite",
7626
+ defaultValue: { fileId: "", sliceIndex: 0 },
7627
+ requirement: 1 /* Required */,
7628
+ schemaKey: "Sprite"
7629
+ },
7630
+ {
7631
+ memberId: "system_9fcab37a-9743-4e35-8eee-80cb560f1433",
7632
+ memberKind: "bool",
7633
+ defaultValue: false,
7634
+ docsText: "Mirrors the sprite horizontally about its own centre. Maps to SpriteRenderer.flipX.",
7635
+ requirement: 1 /* Required */,
7636
+ schemaKey: "FlipX"
7637
+ },
7638
+ {
7639
+ memberId: "system_ddd09f08-1656-4404-b36b-5570a4c01fcf",
7640
+ memberKind: "bool",
7641
+ defaultValue: false,
7642
+ docsText: "Mirrors the sprite vertically about its own centre. Maps to SpriteRenderer.flipY.",
7643
+ requirement: 1 /* Required */,
7644
+ schemaKey: "FlipY"
7645
+ },
7646
+ {
7647
+ memberId: "system_f2a8c86d-ace5-421b-9475-0f3f6f97b2a6",
7648
+ memberKind: "enum",
7649
+ defaultValue: ["system_9d607a4f-60c3-4347-94fc-f24b538bf468"],
7650
+ docsText: "How this sprite reacts to sprite masks. Maps to SpriteRenderer.maskInteraction. The web canvas has no real sprite mask, so anything other than None previews as a distinguishable treatment rather than as the mask itself \u2014 only Unity renders the real thing.",
7651
+ enumId: "system_4e6c4d6f-1d0b-402a-ad3a-be92242dceec",
7652
+ requirement: 1 /* Required */,
7653
+ schemaKey: "MaskInteraction"
7654
+ },
7655
+ {
7656
+ memberId: "system_6f32f1f2-83ea-42fc-8647-34ed0946b7f1",
7657
+ memberKind: "int",
7658
+ defaultValue: null,
7659
+ docsText: "Added to the object layer's sorting order; it does not replace it. The result competes with every renderer in the sorting layer, or in the enclosing sorting group, and among equal orders the renderer lower on screen draws in front. Leave unset to use the layer's order.",
7660
+ minValue: -32768,
7661
+ maxValue: 32767,
7662
+ schemaKey: "SortingOrder"
7663
+ }
7664
+ ],
7665
+ worldKind: "spriteObject"
7666
+ },
7504
7667
  {
7505
7668
  classId: "system_9f34deed-2616-43c9-b614-d812da89ee51",
7506
7669
  name: "NeoSmartTile",
@@ -9111,7 +9274,8 @@ function callableBindingMember(memberId, slotName, members) {
9111
9274
  return binding;
9112
9275
  }
9113
9276
  function mapGenericTypeInfo(typeInfo, close) {
9114
- if (typeInfo.type === 21 /* Generic */) return close(typeInfo);
9277
+ if (typeInfo.type === 21 /* Generic */)
9278
+ return isClassGenericParamTypeInfo(typeInfo) ? close(typeInfo) : typeInfo;
9115
9279
  if (typeInfo.type === 6 /* List */ || typeInfo.type === 28 /* Set */ || typeInfo.type === 5 /* Dictionary */ || typeInfo.type === 9 /* Lookup */) {
9116
9280
  return {
9117
9281
  ...typeInfo,
@@ -11796,11 +11960,7 @@ function completeDefaultClassRecord(args) {
11796
11960
  if (!shouldMaterializeChildDefaultForRoot(
11797
11961
  args.constructorRoot,
11798
11962
  resolvedChildMember,
11799
- defaultSettlesConstruction2,
11800
- documentHasInitValueContent(
11801
- args.document,
11802
- resolvedChildMember.defaultValue
11803
- )
11963
+ defaultSettlesConstruction2
11804
11964
  )) {
11805
11965
  continue;
11806
11966
  }
@@ -12228,11 +12388,6 @@ function shouldMaterializeChildDefault(member) {
12228
12388
  }
12229
12389
  return member.defaultValue !== void 0;
12230
12390
  }
12231
- function shouldMaterializeConstructorChildDefault(member, isInitializer = isInitValueContent(member.defaultValue)) {
12232
- if (isInitializer) return true;
12233
- if (!isRequiredMember(member)) return false;
12234
- return shouldMaterializeChildDefault(member);
12235
- }
12236
12391
  function skipProvidedConstructorSchemaKey(constructorRoot, schemaKey, member, defaultSettlesConstruction2, isInitializer = isInitValueContent(member.defaultValue)) {
12237
12392
  if (constructorRoot === void 0) return false;
12238
12393
  if (!constructorRoot.providedSchemaKeys.has(schemaKey)) return false;
@@ -12241,16 +12396,11 @@ function skipProvidedConstructorSchemaKey(constructorRoot, schemaKey, member, de
12241
12396
  }
12242
12397
  return !isInitializer && !defaultSettlesConstruction2;
12243
12398
  }
12244
- function shouldMaterializeChildDefaultForRoot(constructorRoot, member, defaultSettlesConstruction2, isInitializer = isInitValueContent(member.defaultValue)) {
12245
- if (constructorRoot === void 0)
12246
- return shouldMaterializeChildDefault(member);
12247
- if (constructorRoot.omitMissingRequired === true && !defaultSettlesConstruction2) {
12399
+ function shouldMaterializeChildDefaultForRoot(constructorRoot, member, defaultSettlesConstruction2) {
12400
+ if (constructorRoot?.omitMissingRequired === true && !defaultSettlesConstruction2) {
12248
12401
  return false;
12249
12402
  }
12250
- if (constructorRoot.runsMemberInitializers === true) {
12251
- return shouldMaterializeChildDefault(member);
12252
- }
12253
- return shouldMaterializeConstructorChildDefault(member, isInitializer);
12403
+ return shouldMaterializeChildDefault(member);
12254
12404
  }
12255
12405
  function primitiveFallbackValue(document2, member) {
12256
12406
  if (isMemberBoolBase(member)) return { value: false };
@@ -12507,6 +12657,14 @@ function validateAudioMemberValue(document2, member, body) {
12507
12657
  }
12508
12658
  }
12509
12659
 
12660
+ // ../packages/models/src/members/list-index-values.ts
12661
+ function normalizeListIndexKey(value, kind) {
12662
+ if (kind === "enum") {
12663
+ return Array.isArray(value) && typeof value[0] === "string" ? value[0] : null;
12664
+ }
12665
+ return typeof value === "string" ? value : null;
12666
+ }
12667
+
12510
12668
  // ../packages/models/src/members/list-indexes.ts
12511
12669
  function validateListIndexDefinitions(ctx, listMember) {
12512
12670
  const errors = [];
@@ -13030,6 +13188,109 @@ function classImplementsInterface(classId, interfaceId, classes, interfaces) {
13030
13188
  );
13031
13189
  }
13032
13190
 
13191
+ // ../packages/models/src/neoscript/function-type-arguments.ts
13192
+ function functionGenericParamsOf(member) {
13193
+ const kind = getField(member, "kind");
13194
+ if (kind !== 13 /* Function */ && kind !== 23 /* NSFunction */) {
13195
+ return void 0;
13196
+ }
13197
+ const params = getField(member, "genericParams");
13198
+ return isFunctionGenericParams(params, isValidSchemaBindingIdentifier) ? params : void 0;
13199
+ }
13200
+ function firstFunctionGenericReference(typeInfo, matches) {
13201
+ switch (typeInfo.type) {
13202
+ case 21 /* Generic */:
13203
+ if (isClassGenericParamTypeInfo(typeInfo)) return null;
13204
+ return matches(typeInfo) ? typeInfo : null;
13205
+ case 6 /* List */:
13206
+ case 28 /* Set */:
13207
+ case 5 /* Dictionary */:
13208
+ case 9 /* Lookup */:
13209
+ return firstFunctionGenericReference(typeInfo.entryTypeInfo, matches);
13210
+ case 25 /* NSDelegate */:
13211
+ return firstInList(
13212
+ [typeInfo.returnTypeInfo, ...typeInfo.argumentTypes],
13213
+ matches
13214
+ );
13215
+ case 26 /* NSAction */:
13216
+ return firstInList(typeInfo.argumentTypes, matches);
13217
+ case 7 /* Class */:
13218
+ return firstInList(Object.values(typeInfo.typeArguments ?? {}), matches);
13219
+ default:
13220
+ return null;
13221
+ }
13222
+ }
13223
+ function firstInList(list, matches) {
13224
+ for (const entry of list) {
13225
+ const found = firstFunctionGenericReference(entry, matches);
13226
+ if (found !== null) return found;
13227
+ }
13228
+ return null;
13229
+ }
13230
+ function typeInfoHasFunctionGeneric(typeInfo) {
13231
+ return firstFunctionGenericReference(typeInfo, () => true) !== null;
13232
+ }
13233
+ function bindFunctionTypeArguments(typeInfo, table) {
13234
+ switch (typeInfo.type) {
13235
+ case 21 /* Generic */: {
13236
+ if (isClassGenericParamTypeInfo(typeInfo)) return typeInfo;
13237
+ const bound = table[typeInfo.index];
13238
+ if (bound === void 0) return typeInfo;
13239
+ return { ...bound, required: bound.required && typeInfo.required };
13240
+ }
13241
+ case 6 /* List */:
13242
+ case 28 /* Set */:
13243
+ case 5 /* Dictionary */:
13244
+ case 9 /* Lookup */: {
13245
+ const entry = bindFunctionTypeArguments(typeInfo.entryTypeInfo, table);
13246
+ return entry === typeInfo.entryTypeInfo ? typeInfo : { ...typeInfo, entryTypeInfo: entry };
13247
+ }
13248
+ case 25 /* NSDelegate */: {
13249
+ const returnTypeInfo = bindFunctionTypeArguments(
13250
+ typeInfo.returnTypeInfo,
13251
+ table
13252
+ );
13253
+ const argumentTypes = bindTypeInfoList(typeInfo.argumentTypes, table);
13254
+ return returnTypeInfo === typeInfo.returnTypeInfo && argumentTypes === typeInfo.argumentTypes ? typeInfo : { ...typeInfo, returnTypeInfo, argumentTypes };
13255
+ }
13256
+ case 26 /* NSAction */: {
13257
+ const argumentTypes = bindTypeInfoList(typeInfo.argumentTypes, table);
13258
+ return argumentTypes === typeInfo.argumentTypes ? typeInfo : { ...typeInfo, argumentTypes };
13259
+ }
13260
+ case 7 /* Class */: {
13261
+ if (!typeInfo.typeArguments) return typeInfo;
13262
+ let typeArguments;
13263
+ for (const [key, argument2] of Object.entries(typeInfo.typeArguments)) {
13264
+ const bound = bindFunctionTypeArguments(argument2, table);
13265
+ if (bound === argument2) continue;
13266
+ typeArguments ??= { ...typeInfo.typeArguments };
13267
+ typeArguments[key] = bound;
13268
+ }
13269
+ return typeArguments === void 0 ? typeInfo : { ...typeInfo, typeArguments };
13270
+ }
13271
+ default:
13272
+ return typeInfo;
13273
+ }
13274
+ }
13275
+ function bindArgumentTypeArguments(argument2, table) {
13276
+ const bound = bindFunctionTypeArguments(argument2, table);
13277
+ if (bound === argument2) return argument2;
13278
+ if (argument2.defaultValue === void 0) {
13279
+ return { ...bound, name: argument2.name };
13280
+ }
13281
+ return { ...bound, name: argument2.name, defaultValue: { value: null } };
13282
+ }
13283
+ function bindTypeInfoList(list, table) {
13284
+ let bound;
13285
+ for (let index = 0; index < list.length; index++) {
13286
+ const entry = bindFunctionTypeArguments(list[index], table);
13287
+ if (entry === list[index]) continue;
13288
+ bound ??= [...list];
13289
+ bound[index] = entry;
13290
+ }
13291
+ return bound ?? list;
13292
+ }
13293
+
13033
13294
  // ../packages/manifest/src/value-comparison.ts
13034
13295
  function isObjectRecord(value) {
13035
13296
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -13326,6 +13587,9 @@ import { createHash as createHash2, randomUUID } from "node:crypto";
13326
13587
  import { isDeepStrictEqual } from "node:util";
13327
13588
 
13328
13589
  // ../packages/neoscript-language/src/project.ts
13590
+ function functionTypeParameterId(memberId, index) {
13591
+ return `${memberId}#${index}`;
13592
+ }
13329
13593
  function neoScriptMemberLookupType(type) {
13330
13594
  if (type.kind !== "typeParameter") return type;
13331
13595
  const visited = /* @__PURE__ */ new Set();
@@ -14102,6 +14366,61 @@ var UncompiledInitializerRuntimeError = class extends NSGetterRuntimeError {
14102
14366
  valueId;
14103
14367
  };
14104
14368
 
14369
+ // ../packages/neoscript-runtime/src/neoscript/runtime-set.ts
14370
+ var RuntimeSet = class {
14371
+ constructor(source, reference, enumEntries) {
14372
+ this.source = source;
14373
+ this.reference = reference;
14374
+ this.enumEntries = enumEntries;
14375
+ }
14376
+ source;
14377
+ reference;
14378
+ enumEntries;
14379
+ entries = /* @__PURE__ */ new Map();
14380
+ validations = /* @__PURE__ */ new Map();
14381
+ snapshot;
14382
+ get size() {
14383
+ return this.entries.size;
14384
+ }
14385
+ has(key) {
14386
+ return this.entries.has(key);
14387
+ }
14388
+ add(key, raw, reference) {
14389
+ if (this.entries.has(key)) return;
14390
+ this.entries.set(key, { raw, reference });
14391
+ for (const check2 of this.validations.values())
14392
+ if (!check2.test(raw)) check2.invalid.add(key);
14393
+ this.snapshot = void 0;
14394
+ }
14395
+ remove(key) {
14396
+ if (this.entries.delete(key)) {
14397
+ this.snapshot = void 0;
14398
+ for (const check2 of this.validations.values()) check2.invalid.delete(key);
14399
+ }
14400
+ }
14401
+ clear() {
14402
+ this.entries.clear();
14403
+ for (const check2 of this.validations.values()) check2.invalid.clear();
14404
+ this.snapshot = void 0;
14405
+ }
14406
+ matches(type, test) {
14407
+ let check2 = this.validations.get(type);
14408
+ if (check2 === void 0) {
14409
+ check2 = { test, invalid: /* @__PURE__ */ new Set() };
14410
+ for (const [key, entry] of this.entries)
14411
+ if (!test(entry.raw)) check2.invalid.add(key);
14412
+ this.validations.set(type, check2);
14413
+ }
14414
+ return check2.invalid.size === 0;
14415
+ }
14416
+ membership() {
14417
+ return this.snapshot ??= [...this.entries.values()];
14418
+ }
14419
+ toArray() {
14420
+ return this.membership().map((entry) => entry.raw);
14421
+ }
14422
+ };
14423
+
14105
14424
  // ../packages/neoscript-runtime/src/listener-write-index.ts
14106
14425
  var indexes = /* @__PURE__ */ new WeakMap();
14107
14426
  var empty = /* @__PURE__ */ new Map();
@@ -14756,6 +15075,10 @@ var NEO_CELL_PATTERN_PURE_NATIVE_MEMBER_IDS = /* @__PURE__ */ new Set([
14756
15075
  ]);
14757
15076
  var NEO_OBJECT_CLASS_ID = "system_f671535d-0eb6-4139-9caf-5c5276febd31";
14758
15077
 
15078
+ // ../packages/neoscript-language/src/tile-conversion.ts
15079
+ var NEO_TILE_CONVERT_MEMBER_ID = "system_54ecc5a7-874d-54ed-92f4-38100a4b7465";
15080
+ var NEO_TILE_CLASS_ID = "system_d7fa161b-b269-4bf1-9ec9-3aebec67e6e0";
15081
+
14759
15082
  // ../packages/neoscript-runtime/src/neoscript/cell-pattern.ts
14760
15083
  function integer(value, name) {
14761
15084
  if (typeof value !== "number" || !Number.isInteger(value)) {
@@ -15671,8 +15994,11 @@ var WorldGridQueryIndex = class {
15671
15994
  );
15672
15995
  return matches[0];
15673
15996
  }
15674
- /** `shift` moves the whole pattern; null queries around the placement cell. */
15675
- objects(placement, offsets, reads, shift = null) {
15997
+ /**
15998
+ * `shift` moves the whole pattern; null queries around the placement cell.
15999
+ * `accepts` (P110 §6) keeps only objects of a class; every cell is still read.
16000
+ */
16001
+ objects(placement, offsets, reads, shift = null, accepts) {
15676
16002
  reads?.add({ kind: "placement", valueId: placement.valueId });
15677
16003
  const origin = shiftedOrigin(placement, shift);
15678
16004
  const result = [];
@@ -15680,24 +16006,34 @@ var WorldGridQueryIndex = class {
15680
16006
  const cell = translated2(origin, offset);
15681
16007
  reads?.add({ kind: "objects", gridId: placement.gridId, cell });
15682
16008
  for (const item of this.objectsAt(placement.gridId, cell)) {
15683
- result.push(item.valueId);
16009
+ if (accepts === void 0 || accepts(item.classId)) {
16010
+ result.push(item.valueId);
16011
+ }
15684
16012
  }
15685
16013
  }
15686
16014
  return result;
15687
16015
  }
15688
- tile(placement, offsets, reads, shift = null) {
16016
+ /** The first cell's winner that `accepts` keeps, in pattern order. */
16017
+ tile(placement, offsets, reads, shift = null, accepts) {
15689
16018
  reads?.add({ kind: "placement", valueId: placement.valueId });
15690
16019
  const origin = shiftedOrigin(placement, shift);
15691
16020
  let result = null;
15692
16021
  for (const offset of offsets) {
15693
16022
  const cell = translated2(origin, offset);
15694
16023
  reads?.add({ kind: "tile", gridId: placement.gridId, cell });
15695
- result ??= this.tileAt(placement.gridId, cell);
16024
+ if (result !== null) continue;
16025
+ const tile = this.tileAt(placement.gridId, cell);
16026
+ if (tile !== null && (accepts === void 0 || accepts(tile.classId))) {
16027
+ result = tile;
16028
+ }
15696
16029
  }
15697
16030
  return result;
15698
16031
  }
15699
- /** One tile per occupied pattern cell, in pattern order. */
15700
- tiles(placement, offsets, reads, shift = null) {
16032
+ /**
16033
+ * One tile per occupied pattern cell, in pattern order. `accepts` filters
16034
+ * each cell's winner; it never looks under a winner.
16035
+ */
16036
+ tiles(placement, offsets, reads, shift = null, accepts) {
15701
16037
  reads?.add({ kind: "placement", valueId: placement.valueId });
15702
16038
  const origin = shiftedOrigin(placement, shift);
15703
16039
  const result = [];
@@ -15705,7 +16041,9 @@ var WorldGridQueryIndex = class {
15705
16041
  const cell = translated2(origin, offset);
15706
16042
  reads?.add({ kind: "tile", gridId: placement.gridId, cell });
15707
16043
  const tile = this.tileAt(placement.gridId, cell);
15708
- if (tile !== null) result.push(tile.placementValueId);
16044
+ if (tile !== null && (accepts === void 0 || accepts(tile.classId))) {
16045
+ result.push(tile.placementValueId);
16046
+ }
15709
16047
  }
15710
16048
  return result;
15711
16049
  }
@@ -15898,7 +16236,11 @@ function buildIndex(source) {
15898
16236
  }
15899
16237
  const placement = {
15900
16238
  valueId,
15901
- isNeoObject: kinds.get(row.classId) === NeoWorldSystemClassKind.Object,
16239
+ isNeoObject: classInheritsWorldKind(
16240
+ row.classId,
16241
+ NeoWorldSystemClassKind.Object,
16242
+ relations.classesById
16243
+ ),
15902
16244
  classId: row.classId,
15903
16245
  gridId: root.id,
15904
16246
  layerId,
@@ -16584,6 +16926,9 @@ var NeoScriptScope = class {
16584
16926
  // ../packages/neoscript-runtime/src/neoscript/evaluateNSGetter.ts
16585
16927
  var DELEGATE_LEXICAL_THIS = /* @__PURE__ */ Symbol("neoDelegateLexicalThis");
16586
16928
  var DELEGATE_LEXICAL_ROOT = /* @__PURE__ */ Symbol("neoDelegateLexicalRoot");
16929
+ var DELEGATE_LEXICAL_TYPE_ARGUMENTS = /* @__PURE__ */ Symbol(
16930
+ "neoDelegateLexicalTypeArguments"
16931
+ );
16587
16932
  var NonCatchableNSGetterRuntimeError = class extends NSGetterRuntimeError {
16588
16933
  };
16589
16934
  var NativeFunctionDelegateUnavailableError = class extends NonCatchableNSGetterRuntimeError {
@@ -17309,6 +17654,7 @@ function forgetLocalListIndexes(ctx, list) {
17309
17654
  ctx.__indexes?.declaredListByArray.delete(list);
17310
17655
  }
17311
17656
  function trackedRowForValueReference(value, ctx) {
17657
+ if (value instanceof RuntimeSet) value = value.source;
17312
17658
  if (typeof value !== "object" || value === null) return null;
17313
17659
  const indexes3 = evaluatorIndexes(ctx);
17314
17660
  const indexed = indexes3.rowByValueReference.get(value) ?? indexes3.baseRowByValueReference?.get(value) ?? ctx.vm.databaseVM?.rowForValueReference?.(value) ?? null;
@@ -17708,6 +18054,10 @@ function evaluateNSGetterWithEffects(getter, ctx, argumentValues = [], options =
17708
18054
  if (getter.typeInfo.type === 20 /* Decimal */ && typeof result.value === "number") {
17709
18055
  result.value = coerceDecimalOperand(result.value, "return");
17710
18056
  }
18057
+ if (ownsInvocationState) {
18058
+ flushRuntimeSets(runtimeCtx);
18059
+ result.value = exportRuntimeSetValue(result.value, runtimeCtx);
18060
+ }
17711
18061
  const initializerResult = options.initializerResult;
17712
18062
  if (initializerResult !== void 0 && result.value !== null && isMemberWithEntries(initializerResult.member) && findKnownRowIdByValueReference(result.value, runtimeCtx) === null) {
17713
18063
  const createdValues = createdSessionValuesSince(runtimeCtx, creationCheckpoint);
@@ -17824,6 +18174,10 @@ function evaluateNSFunction(action, ctx, args) {
17824
18174
  runtimeArgs,
17825
18175
  action.typeInfo.type === 0 /* Null */
17826
18176
  );
18177
+ if (ownsInvocationState) {
18178
+ flushRuntimeSets(runtimeCtx);
18179
+ value = exportRuntimeSetValue(value, runtimeCtx);
18180
+ }
17827
18181
  exported = prepareSessionValueExport(
17828
18182
  runtimeCtx,
17829
18183
  creationCheckpoint,
@@ -17860,10 +18214,18 @@ function evaluateNSFunction(action, ctx, args) {
17860
18214
  }
17861
18215
  function evaluateNSDelegate(value, ctx, args = []) {
17862
18216
  const runtimeCtx = withEvaluationRuntime(ctx, []);
17863
- return preserveReadOnlyReturnIdentity(
17864
- invokeDelegateValue(value, args, runtimeCtx),
17865
- runtimeCtx
17866
- );
18217
+ try {
18218
+ const result = preserveReadOnlyReturnIdentity(
18219
+ invokeDelegateValue(value, args, runtimeCtx),
18220
+ runtimeCtx
18221
+ );
18222
+ if (ctx.__executionState !== void 0) return result;
18223
+ flushRuntimeSets(runtimeCtx);
18224
+ return exportRuntimeSetValue(result, runtimeCtx);
18225
+ } finally {
18226
+ if (ctx.__executionState === void 0)
18227
+ runtimeCtx.__dirtyRuntimeSets?.clear();
18228
+ }
17867
18229
  }
17868
18230
  function bindNeoScriptDelegateToContext(value, ctx) {
17869
18231
  if (!isNSDelegateClosureValue(value)) return value;
@@ -17891,6 +18253,8 @@ function withEvaluationRuntime(ctx, writes) {
17891
18253
  if (ctx.__runtimeSessionValues !== void 0 && ctx.__executionState !== void 0 && ctx.__valueOverlay !== void 0) {
17892
18254
  ctx.__unorderedListProjections ??= createUnorderedListProjectionCache();
17893
18255
  ctx.__setEntryIndexes ??= /* @__PURE__ */ new WeakMap();
18256
+ ctx.__runtimeSets ??= /* @__PURE__ */ new WeakMap();
18257
+ ctx.__dirtyRuntimeSets ??= /* @__PURE__ */ new Set();
17894
18258
  ctx.__runtimeClassOverrides ??= /* @__PURE__ */ new Map();
17895
18259
  ctx.__getterSubscriptions ??= getterSubscriptionsFor(ctx);
17896
18260
  return ctx;
@@ -17925,6 +18289,8 @@ function withEvaluationRuntime(ctx, writes) {
17925
18289
  __valueOverlay: overlay,
17926
18290
  __unorderedListProjections: ctx.__unorderedListProjections ?? createUnorderedListProjectionCache(),
17927
18291
  __setEntryIndexes: ctx.__setEntryIndexes ?? /* @__PURE__ */ new WeakMap(),
18292
+ __runtimeSets: ctx.__runtimeSets ?? /* @__PURE__ */ new WeakMap(),
18293
+ __dirtyRuntimeSets: ctx.__dirtyRuntimeSets ?? /* @__PURE__ */ new Set(),
17928
18294
  __runtimeReferenceRemap: referenceRemap,
17929
18295
  __executionState: ctx.__executionState ?? {
17930
18296
  writes,
@@ -18023,6 +18389,7 @@ function cleanupRowDatabase(ctx, session, groupByRowId) {
18023
18389
  }
18024
18390
  function finalizeConstructorAllocations(ctx, returnValue, ownsInvocationState, returnTypeInfo, retainListenerReceivers = true) {
18025
18391
  if (!ownsInvocationState) return;
18392
+ ctx.__dirtyRuntimeSets?.clear();
18026
18393
  const state = ctx.__executionState;
18027
18394
  const session = ctx.__runtimeSessionValues;
18028
18395
  if (state === void 0 || session === void 0) return;
@@ -18555,7 +18922,7 @@ function executeCompiledFunction(action, ctx, args, allowFallthroughReturn, runt
18555
18922
  for (let index = 0; index < filledArgs.length; index += 1) {
18556
18923
  const parameter3 = action.parameters[index + 2];
18557
18924
  const runtimeTypeInfo = runtimeArgumentTypes[index];
18558
- const value2 = filledArgs[index];
18925
+ const value2 = asDeclaredRuntimeSet(filledArgs[index], runtimeTypeInfo, ctx);
18559
18926
  if (!runtimeValueMatchesType(value2, runtimeTypeInfo, ctx)) {
18560
18927
  throw new NSGetterRuntimeError(
18561
18928
  `NSFunction argument ${index + 1} does not match its declared runtime type.`
@@ -18933,6 +19300,7 @@ function evalInstructions(instructions, scope, ctx, options) {
18933
19300
  if (ins.variable.typeInfo.type === 20 /* Decimal */ && typeof value === "number") {
18934
19301
  value = coerceDecimalOperand(value, "variable initialization");
18935
19302
  }
19303
+ value = asDeclaredRuntimeSet(value, ins.variable.typeInfo, ctx);
18936
19304
  scope.setLocal(ins.variable.id, value);
18937
19305
  break;
18938
19306
  }
@@ -20134,7 +20502,7 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
20134
20502
  }
20135
20503
  writableStaticBindingMap(member, ctx);
20136
20504
  }
20137
- const targetValue = evalPointer(ins.target.pointer, scope, ctx);
20505
+ let targetValue = evalPointer(ins.target.pointer, scope, ctx);
20138
20506
  const variablePointer = ins.target.pointer.type === "variable" /* variable */ ? ins.target.pointer : null;
20139
20507
  const unorderedContainerValueId = unorderedListProjectionContainerId(
20140
20508
  targetValue,
@@ -20157,6 +20525,14 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
20157
20525
  const args = ins.args.map((arg) => evalPointer(arg, scope, ctx));
20158
20526
  const setEntryMember = mutatesLocalVariable ? null : storedSetEntryMember(targetValue, ctx);
20159
20527
  const isLookupSet = setEntryMember === null && ins.target.typeInfo.type === 9 /* Lookup */;
20528
+ if (isLookupSet && Array.isArray(targetValue)) {
20529
+ targetValue = runtimeSet(
20530
+ targetValue,
20531
+ ins.reference === true,
20532
+ ins.target.typeInfo.type === 9 /* Lookup */ && (ins.target.typeInfo.entryTypeInfo.type === 8 /* Enum */ || ins.target.typeInfo.entryTypeInfo.type === 18 /* DialogueLookup */),
20533
+ ctx
20534
+ );
20535
+ }
20160
20536
  const setMatch = setEntryMember !== null && Array.isArray(targetValue) && (ins.mutation === "Add" /* Add */ || ins.mutation === "Remove" /* Remove */) ? findStoredSetEntry(targetValue, args[0], setEntryMember, ctx) : null;
20161
20537
  if (ins.mutation === "Add" /* Add */ && setMatch !== null) return;
20162
20538
  if (ins.mutation === "Remove" /* Remove */ && setEntryMember !== null && setMatch === null) {
@@ -20187,7 +20563,7 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
20187
20563
  }
20188
20564
  validateCollectionMutation(targetValue, ins.mutation, args);
20189
20565
  const overlayArgs = [...args];
20190
- if ((ins.mutation === "Add" /* Add */ || ins.mutation === "Remove" /* Remove */) && Array.isArray(targetValue)) {
20566
+ if ((ins.mutation === "Add" /* Add */ || ins.mutation === "Remove" /* Remove */) && isArrayCollection(targetValue)) {
20191
20567
  if (setMatch !== null) overlayArgs[0] = setMatch.entry;
20192
20568
  else if (isLookupSet)
20193
20569
  overlayArgs[0] = lookupSetSelectionValue(
@@ -20199,10 +20575,10 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
20199
20575
  overlayArgs[0] = findKnownRowIdByValueReference(args[0], ctx) ?? args[0];
20200
20576
  } else if (ins.mutation === "Insert" /* Insert */) {
20201
20577
  overlayArgs[1] = findKnownRowIdByValueReference(args[1], ctx) ?? args[1];
20202
- } else if (ins.mutation === "Add" /* Add */ && !Array.isArray(targetValue)) {
20578
+ } else if (ins.mutation === "Add" /* Add */ && !isArrayCollection(targetValue)) {
20203
20579
  overlayArgs[1] = findKnownRowIdByValueReference(args[1], ctx) ?? args[1];
20204
20580
  }
20205
- if (ins.mutation === "Add" /* Add */ && Array.isArray(targetValue) && unorderedContainerValueId !== null && !isLookupSet && findKnownRowIdByValueReference(args[0], ctx) === null) {
20581
+ if (ins.mutation === "Add" /* Add */ && isArrayCollection(targetValue) && unorderedContainerValueId !== null && !isLookupSet && findKnownRowIdByValueReference(args[0], ctx) === null) {
20206
20582
  overlayArgs[0] = createUnorderedScalarProjectionEntry(
20207
20583
  unorderedContainerValueId,
20208
20584
  args[0],
@@ -20211,7 +20587,7 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
20211
20587
  }
20212
20588
  const unorderedEntriesBeforeMutation = unorderedContainerValueId === null || !Array.isArray(targetValue) || ins.mutation === "Add" /* Add */ ? null : [...targetValue];
20213
20589
  if ((ins.mutation === "Add" /* Add */ || ins.mutation === "Insert" /* Insert */) && !isLookupSet) {
20214
- const attachedValue = Array.isArray(targetValue) && ins.mutation !== "Insert" /* Insert */ ? args[0] : args[1];
20590
+ const attachedValue = isArrayCollection(targetValue) && ins.mutation !== "Insert" /* Insert */ ? args[0] : args[1];
20215
20591
  const attachedValueId = findKnownRowIdByValueReference(attachedValue, ctx);
20216
20592
  const parentId = findKnownRowIdByValueReference(targetValue, ctx);
20217
20593
  if (attachedValueId !== null && parentId !== null) {
@@ -20220,8 +20596,8 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
20220
20596
  unorderedContainerValueId ?? void 0
20221
20597
  );
20222
20598
  let slot = `slot:${String(args[0])}`;
20223
- if (Array.isArray(targetValue)) {
20224
- const insertionIndex = ins.mutation === "Insert" /* Insert */ ? args[0] : targetValue.length;
20599
+ if (isArrayCollection(targetValue)) {
20600
+ const insertionIndex = ins.mutation === "Insert" /* Insert */ ? args[0] : collectionLength(targetValue);
20225
20601
  slot = `index:${insertionIndex}`;
20226
20602
  }
20227
20603
  assertOwnedValueAttachable(
@@ -20240,7 +20616,7 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
20240
20616
  overlayArgs,
20241
20617
  ctx,
20242
20618
  isLookupSet,
20243
- ins.reference !== true && ins.mutation === "Remove" /* Remove */ && Array.isArray(targetValue) && unorderedContainerValueId !== null && !isLookupSet && findKnownRowIdByValueReference(args[0], ctx) === null,
20619
+ ins.reference !== true && ins.mutation === "Remove" /* Remove */ && isArrayCollection(targetValue) && setEntryMember === null && !isLookupSet && findKnownRowIdByValueReference(args[0], ctx) === null,
20244
20620
  ins.reference === true
20245
20621
  );
20246
20622
  updateCollectionReferenceProvenance(
@@ -20278,7 +20654,7 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
20278
20654
  });
20279
20655
  return;
20280
20656
  case "Add" /* Add */:
20281
- if (Array.isArray(targetValue)) {
20657
+ if (isArrayCollection(targetValue)) {
20282
20658
  options.writes.push({
20283
20659
  kind: "add",
20284
20660
  target: ins.target,
@@ -20300,7 +20676,7 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
20300
20676
  });
20301
20677
  return;
20302
20678
  case "Remove" /* Remove */:
20303
- if (Array.isArray(targetValue)) {
20679
+ if (isArrayCollection(targetValue)) {
20304
20680
  options.writes.push({
20305
20681
  kind: "remove",
20306
20682
  target: ins.target,
@@ -20366,6 +20742,101 @@ function storedSetEntryMember(collection, ctx) {
20366
20742
  ctx.vm.members
20367
20743
  );
20368
20744
  }
20745
+ function flushRuntimeSets(ctx) {
20746
+ for (const set of ctx.__dirtyRuntimeSets ?? [])
20747
+ exportRuntimeSetValue(set, ctx);
20748
+ ctx.__dirtyRuntimeSets?.clear();
20749
+ for (const write of ctx.__executionState?.writes ?? []) {
20750
+ if ("value" in write) write.value = exportRuntimeSetValue(write.value, ctx);
20751
+ }
20752
+ }
20753
+ function exportRuntimeSetValue(value, ctx, seen = /* @__PURE__ */ new Map()) {
20754
+ if (typeof value !== "object" || value === null) return value;
20755
+ if (seen.has(value)) return seen.get(value);
20756
+ if (value instanceof RuntimeSet) {
20757
+ seen.set(value, value.source);
20758
+ const entries = value.membership();
20759
+ value.source.length = entries.length;
20760
+ const references = /* @__PURE__ */ new Set();
20761
+ for (let index = 0; index < entries.length; index++) {
20762
+ value.source[index] = exportRuntimeSetValue(
20763
+ entries[index].raw,
20764
+ ctx,
20765
+ seen
20766
+ );
20767
+ if (entries[index].reference) references.add(index);
20768
+ }
20769
+ unorderedListProjectionCache(ctx).referenceEntryIndexesByArray.set(
20770
+ value.source,
20771
+ references
20772
+ );
20773
+ ctx.__dirtyRuntimeSets?.delete(value);
20774
+ return value.source;
20775
+ }
20776
+ if (Array.isArray(value)) {
20777
+ const copy = [];
20778
+ seen.set(value, copy);
20779
+ let changed = false;
20780
+ for (const entry of value) {
20781
+ const exported = exportRuntimeSetValue(entry, ctx, seen);
20782
+ copy.push(exported);
20783
+ changed ||= exported !== entry;
20784
+ }
20785
+ const result = changed ? copy : value;
20786
+ seen.set(value, result);
20787
+ return result;
20788
+ }
20789
+ if (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null) {
20790
+ const copy = {};
20791
+ seen.set(value, copy);
20792
+ let changed = false;
20793
+ for (const [key, entry] of Object.entries(value)) {
20794
+ const exported = exportRuntimeSetValue(entry, ctx, seen);
20795
+ setOwnField(copy, key, exported);
20796
+ changed ||= exported !== entry;
20797
+ }
20798
+ const result = changed ? copy : value;
20799
+ seen.set(value, result);
20800
+ return result;
20801
+ }
20802
+ return value;
20803
+ }
20804
+ function isArrayCollection(value) {
20805
+ return Array.isArray(value) || value instanceof RuntimeSet;
20806
+ }
20807
+ function asDeclaredRuntimeSet(value, type, ctx) {
20808
+ if (type.type !== 9 /* Lookup */ || !Array.isArray(value) || storedSetEntryMember(value, ctx) !== null)
20809
+ return value;
20810
+ const entry = type.entryTypeInfo.type;
20811
+ return runtimeSet(
20812
+ value,
20813
+ entry === 7 /* Class */ || entry === 22 /* Interface */ || entry === 6 /* List */ || entry === 5 /* Dictionary */ || entry === 9 /* Lookup */,
20814
+ entry === 8 /* Enum */ || entry === 18 /* DialogueLookup */,
20815
+ ctx
20816
+ );
20817
+ }
20818
+ function runtimeSetKey(value, set, ctx) {
20819
+ if (set.enumEntries && Array.isArray(value) && value.length === 1)
20820
+ value = value[0];
20821
+ return toSetEntryKey(value, null, set.reference, ctx);
20822
+ }
20823
+ function runtimeSet(array2, reference, enumEntries, ctx) {
20824
+ const sets = ctx.__runtimeSets ??= /* @__PURE__ */ new WeakMap();
20825
+ ctx.__dirtyRuntimeSets ??= /* @__PURE__ */ new Set();
20826
+ const existing = sets.get(array2);
20827
+ if (existing !== void 0) return existing;
20828
+ const set = new RuntimeSet(array2, reference, enumEntries);
20829
+ for (let index = 0; index < array2.length; index++) {
20830
+ const raw = array2[index];
20831
+ const resolves = collectionEntryUsesReferenceResolution(array2, index, ctx);
20832
+ const value = resolves ? resolveValueIfId(raw, ctx) : raw;
20833
+ const key = runtimeSetKey(value, set, ctx);
20834
+ set.add(key, enumEntries ? key : raw, !enumEntries && resolves);
20835
+ }
20836
+ sets.set(array2, set);
20837
+ (ctx.__dirtyRuntimeSets ??= /* @__PURE__ */ new Set()).add(set);
20838
+ return set;
20839
+ }
20369
20840
  function storedSetEntryMatch(raw, entryMember, ctx) {
20370
20841
  const byIdentity = entryMember.kind === 7 /* Class */;
20371
20842
  const row = byIdentity || typeof raw !== "string" ? null : evalValueById(ctx, raw, ctx.__runtimeSessionValues, ctx.__valueOverlay);
@@ -20407,7 +20878,29 @@ function findStoredSetEntry(set, value, entryMember, ctx) {
20407
20878
  if (key === null) return null;
20408
20879
  return storedSetEntries(set, entryMember, ctx).get(key) ?? null;
20409
20880
  }
20410
- function applyLocalCollectionMutation(targetValue, mutation, args, ctx, unique = false, resolveJoinedRemovalEntries = false, reference = false) {
20881
+ function applyLocalCollectionMutation(targetValue, mutation, args, ctx, unique = false, resolveRemovalEntries = false, reference = false) {
20882
+ if (targetValue instanceof RuntimeSet) {
20883
+ (ctx.__dirtyRuntimeSets ??= /* @__PURE__ */ new Set()).add(targetValue);
20884
+ switch (mutation) {
20885
+ case "Add" /* Add */:
20886
+ targetValue.add(
20887
+ runtimeSetKey(args[0], targetValue, ctx),
20888
+ args[0],
20889
+ targetValue.reference
20890
+ );
20891
+ return null;
20892
+ case "Remove" /* Remove */:
20893
+ targetValue.remove(runtimeSetKey(args[0], targetValue, ctx));
20894
+ return null;
20895
+ case "Clear" /* Clear */:
20896
+ targetValue.clear();
20897
+ return null;
20898
+ default:
20899
+ throw new NSGetterRuntimeError(
20900
+ "Set only supports Add, Remove, and Clear."
20901
+ );
20902
+ }
20903
+ }
20411
20904
  validateCollectionMutation(targetValue, mutation, args);
20412
20905
  switch (mutation) {
20413
20906
  case "Insert" /* Insert */: {
@@ -20448,7 +20941,7 @@ function applyLocalCollectionMutation(targetValue, mutation, args, ctx, unique =
20448
20941
  }
20449
20942
  const referenceEntry = ctx.__unorderedListProjections?.referenceEntryIndexesByArray.get(targetValue)?.has(candidate) === true;
20450
20943
  if (jsEqual(
20451
- resolveJoinedRemovalEntries || referenceEntry ? resolveValueIfId(entry, ctx) : entry,
20944
+ resolveRemovalEntries || referenceEntry ? resolveCollectionEntry(targetValue, entry, candidate, ctx) : entry,
20452
20945
  args[0]
20453
20946
  )) {
20454
20947
  index = candidate;
@@ -20518,6 +21011,7 @@ function lookupSetSelectionValue(value, typeInfo, ctx) {
20518
21011
  return findKnownRowIdByValueReference(value, ctx) ?? value;
20519
21012
  }
20520
21013
  function validateCollectionMutation(targetValue, mutation, args) {
21014
+ if (targetValue instanceof RuntimeSet) return;
20521
21015
  if (mutation === "Insert" /* Insert */) {
20522
21016
  const list = listArg(targetValue, "Insert target");
20523
21017
  const index = numberArg(args[0], "Insert index");
@@ -20566,6 +21060,7 @@ function listIndexError(index, length) {
20566
21060
  return `List index out of bounds: ${String(index)}; list length is ${length}. Use an index from 0 to ${length - 1}.`;
20567
21061
  }
20568
21062
  function listArg(value, name) {
21063
+ if (value instanceof RuntimeSet) return value.toArray();
20569
21064
  if (Array.isArray(value)) return value;
20570
21065
  throw new NSGetterRuntimeError(`${name} must be a list`);
20571
21066
  }
@@ -20667,7 +21162,8 @@ function evalStaticMember(memberId, ctx) {
20667
21162
  }
20668
21163
  function evalPointer(pointer, scope, ctx, resultUsage = "value") {
20669
21164
  try {
20670
- return pointer.source ? evalPointerAtSource(pointer, scope, ctx, resultUsage) : evalPointerCore(pointer, scope, ctx, resultUsage);
21165
+ const value = pointer.source ? evalPointerAtSource(pointer, scope, ctx, resultUsage) : evalPointerCore(pointer, scope, ctx, resultUsage);
21166
+ return Array.isArray(value) ? ctx.__runtimeSets?.get(value) ?? value : value;
20671
21167
  } catch (error) {
20672
21168
  if (error instanceof NSGetterRuntimeError) {
20673
21169
  error.at(pointer);
@@ -20702,7 +21198,10 @@ function evalPointerCore(pointer, scope, ctx, resultUsage = "value") {
20702
21198
  return {
20703
21199
  ...value,
20704
21200
  ...ctx.thisValue === null || ctx.thisValue === void 0 ? {} : { [DELEGATE_LEXICAL_THIS]: ctx.thisValue },
20705
- [DELEGATE_LEXICAL_ROOT]: ctx.rootValue
21201
+ [DELEGATE_LEXICAL_ROOT]: ctx.rootValue,
21202
+ ...ctx.__functionTypeArguments === void 0 ? {} : {
21203
+ [DELEGATE_LEXICAL_TYPE_ARGUMENTS]: ctx.__functionTypeArguments
21204
+ }
20706
21205
  };
20707
21206
  }
20708
21207
  if (isMemberDelegateTarget(value) && value.valueId === null) {
@@ -20828,15 +21327,27 @@ function evalPointerCore(pointer, scope, ctx, resultUsage = "value") {
20828
21327
  }
20829
21328
  const args = fillCallableCallSiteArguments(suppliedArgs, member, ctx);
20830
21329
  const interceptedMemberId = member?.id ?? pointer.memberId ?? pointer.memberKey ?? pointer.callSiteId;
21330
+ const typeArguments = member === null ? void 0 : calleeTypeArguments(pointer.typeArguments, member, ctx);
20831
21331
  checkDeadline(ctx);
20832
21332
  const intercepted = ctx.callInterceptor?.({
20833
21333
  resultUsage,
20834
21334
  memberId: interceptedMemberId,
20835
21335
  member,
20836
21336
  receiver: innerThis,
20837
- args,
21337
+ get args() {
21338
+ return args.map((value) => exportRuntimeSetValue(value, ctx));
21339
+ },
20838
21340
  callSiteId: pointer.callSiteId,
20839
- invokeDelegate: (delegate, delegateArgs = []) => invokeDelegateValue(delegate, delegateArgs, ctx, pointer.callSiteId)
21341
+ typeArguments,
21342
+ invokeDelegate: (delegate, delegateArgs = []) => exportRuntimeSetValue(
21343
+ invokeDelegateValue(
21344
+ delegate,
21345
+ delegateArgs,
21346
+ ctx,
21347
+ pointer.callSiteId
21348
+ ),
21349
+ ctx
21350
+ )
20840
21351
  });
20841
21352
  if (intercepted?.handled === true)
20842
21353
  return hostCallResult(member, intercepted.value, ctx);
@@ -20858,7 +21369,8 @@ function evalPointerCore(pointer, scope, ctx, resultUsage = "value") {
20858
21369
  member.id,
20859
21370
  innerThis,
20860
21371
  args,
20861
- ctx
21372
+ ctx,
21373
+ typeArguments
20862
21374
  );
20863
21375
  if (systemResult.handled) return systemResult.value;
20864
21376
  const hosted = ctx.unavailableNativeHandler?.({
@@ -20866,13 +21378,18 @@ function evalPointerCore(pointer, scope, ctx, resultUsage = "value") {
20866
21378
  memberId: member.id,
20867
21379
  member,
20868
21380
  receiver: innerThis,
20869
- args,
21381
+ get args() {
21382
+ return args.map((value) => exportRuntimeSetValue(value, ctx));
21383
+ },
20870
21384
  callSiteId: pointer.callSiteId,
20871
- invokeDelegate: (delegate, delegateArgs = []) => invokeDelegateValue(
20872
- delegate,
20873
- delegateArgs,
20874
- ctx,
20875
- pointer.callSiteId
21385
+ invokeDelegate: (delegate, delegateArgs = []) => exportRuntimeSetValue(
21386
+ invokeDelegateValue(
21387
+ delegate,
21388
+ delegateArgs,
21389
+ ctx,
21390
+ pointer.callSiteId
21391
+ ),
21392
+ ctx
20876
21393
  )
20877
21394
  });
20878
21395
  if (hosted?.handled === true)
@@ -20917,7 +21434,12 @@ function evalPointerCore(pointer, scope, ctx, resultUsage = "value") {
20917
21434
  `NSFunction call stack exceeded 64 frames: ${chain.join(" -> ")}.`
20918
21435
  );
20919
21436
  }
20920
- const runtimeSignature = pointer.receiver.kind === "static" ? signature : substituteCallableSignatureForReceiver(signature, innerThis, ctx);
21437
+ const boundSignature = typeArguments === void 0 ? signature : bindSignatureTypeArguments(signature, typeArguments);
21438
+ const runtimeSignature = pointer.receiver.kind === "static" ? boundSignature : substituteCallableSignatureForReceiver(
21439
+ boundSignature,
21440
+ innerThis,
21441
+ ctx
21442
+ );
20921
21443
  state.functionStack.push({
20922
21444
  name: member.name,
20923
21445
  deferred: signature.deferred
@@ -20925,7 +21447,7 @@ function evalPointerCore(pointer, scope, ctx, resultUsage = "value") {
20925
21447
  try {
20926
21448
  return executeCompiledFunction(
20927
21449
  action,
20928
- bindThisValue(ctx, innerThis),
21450
+ withFrameTypeArguments(bindThisValue(ctx, innerThis), typeArguments),
20929
21451
  args,
20930
21452
  runtimeSignature.returnTypeInfo.type === NS_TYPE_VOID,
20931
21453
  runtimeSignature
@@ -21020,7 +21542,8 @@ function evalPointerCore(pointer, scope, ctx, resultUsage = "value") {
21020
21542
  (capture) => evalPointer(capture, scope, ctx)
21021
21543
  ),
21022
21544
  ...ctx.thisValue === null || ctx.thisValue === void 0 ? {} : { [DELEGATE_LEXICAL_THIS]: ctx.thisValue },
21023
- [DELEGATE_LEXICAL_ROOT]: ctx.rootValue
21545
+ [DELEGATE_LEXICAL_ROOT]: ctx.rootValue,
21546
+ ...ctx.__functionTypeArguments === void 0 ? {} : { [DELEGATE_LEXICAL_TYPE_ARGUMENTS]: ctx.__functionTypeArguments }
21024
21547
  };
21025
21548
  case "toBool" /* toBool */: {
21026
21549
  const v = evalPointer(pointer.pointer, scope, ctx);
@@ -21088,7 +21611,8 @@ function invokeDelegateValue(value, args, ctx, callSiteId, ownerReceiver, result
21088
21611
  {
21089
21612
  ...ctx,
21090
21613
  thisValue,
21091
- rootValue: closure[DELEGATE_LEXICAL_ROOT] ?? ctx.rootValue
21614
+ rootValue: closure[DELEGATE_LEXICAL_ROOT] ?? ctx.rootValue,
21615
+ __functionTypeArguments: closure[DELEGATE_LEXICAL_TYPE_ARGUMENTS]
21092
21616
  },
21093
21617
  [...args, ...captures],
21094
21618
  value.action.typeInfo.type === 0 /* Null */
@@ -21162,9 +21686,15 @@ function invokeDelegateValue(value, args, ctx, callSiteId, ownerReceiver, result
21162
21686
  memberId: member.id,
21163
21687
  member,
21164
21688
  receiver,
21165
- args,
21689
+ get args() {
21690
+ return args.map((value2) => exportRuntimeSetValue(value2, ctx));
21691
+ },
21166
21692
  callSiteId,
21167
- invokeDelegate: (delegate, delegateArgs = []) => invokeDelegateValue(delegate, delegateArgs, ctx, callSiteId)
21693
+ typeArguments: calleeTypeArguments(void 0, member, ctx),
21694
+ invokeDelegate: (delegate, delegateArgs = []) => exportRuntimeSetValue(
21695
+ invokeDelegateValue(delegate, delegateArgs, ctx, callSiteId),
21696
+ ctx
21697
+ )
21168
21698
  });
21169
21699
  if (onCompleted === void 0) {
21170
21700
  const intercepted = intercept();
@@ -21192,9 +21722,14 @@ function invokeDelegateValue(value, args, ctx, callSiteId, ownerReceiver, result
21192
21722
  memberId: member.id,
21193
21723
  member,
21194
21724
  receiver,
21195
- args,
21725
+ get args() {
21726
+ return args.map((value2) => exportRuntimeSetValue(value2, ctx));
21727
+ },
21196
21728
  callSiteId,
21197
- invokeDelegate: (delegate, delegateArgs = []) => invokeDelegateValue(delegate, delegateArgs, ctx, callSiteId)
21729
+ invokeDelegate: (delegate, delegateArgs = []) => exportRuntimeSetValue(
21730
+ invokeDelegateValue(delegate, delegateArgs, ctx, callSiteId),
21731
+ ctx
21732
+ )
21198
21733
  });
21199
21734
  if (hosted?.handled === true)
21200
21735
  return hostCallResult(member, hosted.value, ctx);
@@ -21213,11 +21748,17 @@ function invokeDelegateValue(value, args, ctx, callSiteId, ownerReceiver, result
21213
21748
  `NeoDelegate target NSFunction '${member.name}' has no valid compiled body.`
21214
21749
  );
21215
21750
  }
21216
- const runtimeSignature = receiver === null ? signature : substituteCallableSignatureForReceiver(signature, receiver, ctx);
21751
+ const typeArguments = calleeTypeArguments(void 0, member, ctx);
21752
+ const boundSignature = typeArguments === void 0 ? signature : bindSignatureTypeArguments(signature, typeArguments);
21753
+ const runtimeSignature = receiver === null ? boundSignature : substituteCallableSignatureForReceiver(
21754
+ boundSignature,
21755
+ receiver,
21756
+ ctx
21757
+ );
21217
21758
  try {
21218
21759
  return executeCompiledFunction(
21219
21760
  action,
21220
- bindThisValue(ctx, receiver),
21761
+ withFrameTypeArguments(bindThisValue(ctx, receiver), typeArguments),
21221
21762
  args,
21222
21763
  runtimeSignature.returnTypeInfo.type === NS_TYPE_VOID,
21223
21764
  runtimeSignature
@@ -21479,8 +22020,8 @@ function resolveCallableSignature(memberId, memberKind, ctx) {
21479
22020
  return resolved;
21480
22021
  }
21481
22022
  function substituteCallableSignatureForReceiver(signature, receiver, ctx) {
21482
- if (!typeInfoContainsGeneric(signature.returnTypeInfo) && !signature.argumentTypes.some(
21483
- (typeInfo) => typeInfoContainsGeneric(typeInfo)
22023
+ if (!typeInfoContainsGeneric2(signature.returnTypeInfo) && !signature.argumentTypes.some(
22024
+ (typeInfo) => typeInfoContainsGeneric2(typeInfo)
21484
22025
  )) {
21485
22026
  return signature;
21486
22027
  }
@@ -21500,7 +22041,7 @@ function substituteCallableSignatureForReceiver(signature, receiver, ctx) {
21500
22041
  ctx
21501
22042
  ),
21502
22043
  argumentTypes: signature.argumentTypes.map((argument2) => {
21503
- if (!typeInfoContainsGeneric(argument2)) return argument2;
22044
+ if (!typeInfoContainsGeneric2(argument2)) return argument2;
21504
22045
  const substituted = substituteRuntimeTypeInfo(argument2, env, ctx);
21505
22046
  if (substituted.type === NS_TYPE_VOID) {
21506
22047
  throw new NSGetterRuntimeError(
@@ -21524,7 +22065,66 @@ function substituteCallableSignatureForReceiver(signature, receiver, ctx) {
21524
22065
  );
21525
22066
  }
21526
22067
  }
21527
- function typeInfoContainsGeneric(typeInfo, visited = /* @__PURE__ */ new Set()) {
22068
+ function calleeTypeArguments(written, member, ctx) {
22069
+ const parameters = member.genericParams;
22070
+ if (parameters === void 0) return void 0;
22071
+ if (written !== void 0 && written.length === parameters.length && !typeArgumentsForward(written)) {
22072
+ return written;
22073
+ }
22074
+ return parameters.map((parameter3, index) => {
22075
+ const argument2 = written?.[index];
22076
+ if (argument2 !== void 0) {
22077
+ return ctx.__functionTypeArguments === void 0 ? argument2 : bindFunctionTypeArguments(argument2, ctx.__functionTypeArguments);
22078
+ }
22079
+ if (parameter3.defaultType !== void 0) return parameter3.defaultType;
22080
+ throw new NSGetterRuntimeError(
22081
+ `Call to '${member.name}' supplies no type argument for '${parameter3.name}', and it has no default.`
22082
+ );
22083
+ });
22084
+ }
22085
+ var FORWARDING_TYPE_ARGUMENTS = /* @__PURE__ */ new WeakMap();
22086
+ function typeArgumentsForward(written) {
22087
+ let forwards = FORWARDING_TYPE_ARGUMENTS.get(written);
22088
+ if (forwards === void 0) {
22089
+ forwards = written.some(typeInfoHasFunctionGeneric);
22090
+ FORWARDING_TYPE_ARGUMENTS.set(written, forwards);
22091
+ }
22092
+ return forwards;
22093
+ }
22094
+ function withFrameTypeArguments(ctx, table) {
22095
+ if (ctx.__functionTypeArguments === table) return ctx;
22096
+ return { ...ctx, __functionTypeArguments: table };
22097
+ }
22098
+ function functionTypeArgument(typeInfo, ctx) {
22099
+ const bound = ctx.__functionTypeArguments?.[typeInfo.index];
22100
+ if (bound !== void 0) return bound;
22101
+ const owner = evalMemberById(ctx.vm, typeInfo.ownerMemberId);
22102
+ const parameter3 = functionGenericParamsOf(owner)?.[typeInfo.index];
22103
+ if (parameter3?.defaultType !== void 0) return parameter3.defaultType;
22104
+ throw new NSGetterRuntimeError(
22105
+ `Type parameter ${typeInfo.index} of function '${owner?.name ?? typeInfo.ownerMemberId}' has no type argument in this frame and no default.`
22106
+ );
22107
+ }
22108
+ function bindSignatureTypeArguments(signature, table) {
22109
+ const returnTypeInfo = bindFunctionTypeArguments(
22110
+ signature.returnTypeInfo,
22111
+ table
22112
+ );
22113
+ let argumentTypes;
22114
+ for (let index = 0; index < signature.argumentTypes.length; index++) {
22115
+ const argument2 = signature.argumentTypes[index];
22116
+ const bound = bindArgumentTypeArguments(argument2, table);
22117
+ if (bound === argument2) continue;
22118
+ argumentTypes ??= [...signature.argumentTypes];
22119
+ argumentTypes[index] = bound;
22120
+ }
22121
+ return returnTypeInfo === signature.returnTypeInfo && argumentTypes === void 0 ? signature : {
22122
+ ...signature,
22123
+ returnTypeInfo,
22124
+ argumentTypes: argumentTypes ?? signature.argumentTypes
22125
+ };
22126
+ }
22127
+ function typeInfoContainsGeneric2(typeInfo, visited = /* @__PURE__ */ new Set()) {
21528
22128
  if (visited.has(typeInfo)) {
21529
22129
  throw new NSGetterRuntimeError(
21530
22130
  "Corrupt NSFunction signature contains a cyclic type-info graph."
@@ -21534,11 +22134,11 @@ function typeInfoContainsGeneric(typeInfo, visited = /* @__PURE__ */ new Set())
21534
22134
  nextVisited.add(typeInfo);
21535
22135
  if (typeInfo.type === 21 /* Generic */) return true;
21536
22136
  if (typeInfo.type === 6 /* List */ || typeInfo.type === 28 /* Set */ || typeInfo.type === 5 /* Dictionary */ || typeInfo.type === 9 /* Lookup */) {
21537
- return typeInfoContainsGeneric(typeInfo.entryTypeInfo, nextVisited);
22137
+ return typeInfoContainsGeneric2(typeInfo.entryTypeInfo, nextVisited);
21538
22138
  }
21539
22139
  if (typeInfo.type !== 7 /* Class */) return false;
21540
22140
  return Object.values(typeInfo.typeArguments ?? {}).some(
21541
- (argument2) => typeInfoContainsGeneric(argument2, nextVisited)
22141
+ (argument2) => typeInfoContainsGeneric2(argument2, nextVisited)
21542
22142
  );
21543
22143
  }
21544
22144
  function runtimeGenericEnvForValueRow(row, ctx, visited = /* @__PURE__ */ new Set(), readRow) {
@@ -21602,7 +22202,7 @@ function overlayConcreteGenericEntries(target, source) {
21602
22202
  }
21603
22203
  function genericParametersConcretelyBound(typeInfo, env) {
21604
22204
  if (typeInfo.type === 21 /* Generic */) {
21605
- return env.get(typeInfo.genericParamId)?.kind === "member";
22205
+ return isClassGenericParamTypeInfo(typeInfo) && env.get(typeInfo.genericParamId)?.kind === "member";
21606
22206
  }
21607
22207
  if (typeInfo.type === 6 /* List */ || typeInfo.type === 28 /* Set */ || typeInfo.type === 5 /* Dictionary */ || typeInfo.type === 9 /* Lookup */) {
21608
22208
  return genericParametersConcretelyBound(typeInfo.entryTypeInfo, env);
@@ -21619,6 +22219,10 @@ function genericParametersConcretelyBound(typeInfo, env) {
21619
22219
  return true;
21620
22220
  }
21621
22221
  function substituteRuntimeTypeInfo(typeInfo, env, ctx) {
22222
+ if (typeInfo.type === 21 /* Generic */ && !isClassGenericParamTypeInfo(typeInfo)) {
22223
+ const bound = functionTypeArgument(typeInfo, ctx);
22224
+ return { ...bound, required: bound.required && typeInfo.required };
22225
+ }
21622
22226
  if (typeInfo.type === 21 /* Generic */) {
21623
22227
  const binding = env.get(typeInfo.genericParamId);
21624
22228
  if (binding?.kind !== "member") {
@@ -22074,6 +22678,20 @@ function runtimeTypeCheck(value, checkType, ctx, seenCollections = /* @__PURE__
22074
22678
  case 6 /* List */:
22075
22679
  case 28 /* Set */:
22076
22680
  case 9 /* Lookup */: {
22681
+ if (value instanceof RuntimeSet) {
22682
+ if (seenCollections.has(value)) return false;
22683
+ const seen2 = new Set(seenCollections);
22684
+ seen2.add(value);
22685
+ return value.matches(
22686
+ checkType,
22687
+ (entry) => runtimeCollectionEntryMatchesType(
22688
+ value.enumEntries && typeof entry === "string" ? [entry] : entry,
22689
+ checkType.entryTypeInfo,
22690
+ ctx,
22691
+ seen2
22692
+ )
22693
+ );
22694
+ }
22077
22695
  if (!Array.isArray(value)) return false;
22078
22696
  if (seenCollections.has(value)) return false;
22079
22697
  if (checkType.type === 9 /* Lookup */ && (checkType.entryTypeInfo.type === 8 /* Enum */ || checkType.entryTypeInfo.type === 18 /* DialogueLookup */)) {
@@ -22130,6 +22748,14 @@ function runtimeTypeCheck(value, checkType, ctx, seenCollections = /* @__PURE__
22130
22748
  );
22131
22749
  }
22132
22750
  case 21 /* Generic */:
22751
+ if (!isClassGenericParamTypeInfo(checkType)) {
22752
+ return runtimeTypeCheck(
22753
+ value,
22754
+ functionTypeArgument(checkType, ctx),
22755
+ ctx,
22756
+ seenCollections
22757
+ );
22758
+ }
22133
22759
  return true;
22134
22760
  default:
22135
22761
  return false;
@@ -22138,7 +22764,7 @@ function runtimeTypeCheck(value, checkType, ctx, seenCollections = /* @__PURE__
22138
22764
  function runtimeValueMatchesType(value, typeInfo, ctx, seenCollections = /* @__PURE__ */ new Set()) {
22139
22765
  if (typeInfo.type === NS_TYPE_UNKNOWN) return true;
22140
22766
  if (value === null || value === void 0) {
22141
- return typeInfo.type === 0 /* Null */ || typeInfo.type === 21 /* Generic */ || !typeInfo.required;
22767
+ return typeInfo.type === 0 /* Null */ || typeInfo.type === 21 /* Generic */ && isClassGenericParamTypeInfo(typeInfo) || !typeInfo.required;
22142
22768
  }
22143
22769
  return runtimeTypeCheck(value, typeInfo, ctx, seenCollections);
22144
22770
  }
@@ -22957,7 +23583,21 @@ function readGridQueryOffset(value) {
22957
23583
  }
22958
23584
  return value;
22959
23585
  }
22960
- function evaluateSystemNative(memberId, receiver, args, ctx) {
23586
+ function gridQueryClassFilter(typeArgument, ctx) {
23587
+ if (typeArgument === void 0) return void 0;
23588
+ if (typeArgument.type !== 7 /* Class */) {
23589
+ throw new NSGetterRuntimeError(
23590
+ `Grid query type argument must be a class, not member kind ${typeArgument.type}.`
23591
+ );
23592
+ }
23593
+ const classId = typeArgument.classId;
23594
+ if (classId === NEO_OBJECT_CLASS_ID || classId === NEO_TILE_CLASS_ID) {
23595
+ return void 0;
23596
+ }
23597
+ const schema = evaluatorSchemaIndex(ctx);
23598
+ return (candidate) => schema.classIsOrExtends(candidate, classId);
23599
+ }
23600
+ function evaluateSystemNative(memberId, receiver, args, ctx, typeArguments) {
22961
23601
  try {
22962
23602
  if (memberId === NEO_OBJECT_GRID_MEMBER_IDS.GetCell || memberId === NEO_OBJECT_GRID_MEMBER_IDS.GetObjects || memberId === NEO_OBJECT_GRID_MEMBER_IDS.GetTile || memberId === NEO_OBJECT_GRID_MEMBER_IDS.GetTiles) {
22963
23603
  const receiverRow = trackedRowForValueReference(receiver, ctx);
@@ -22975,12 +23615,14 @@ function evaluateSystemNative(memberId, receiver, args, ctx) {
22975
23615
  return { handled: true, value: { ...placement.cell } };
22976
23616
  const offsets = readCellPattern(args[0], ctx);
22977
23617
  const shift = readGridQueryOffset(args[1]);
23618
+ const accepts = gridQueryClassFilter(typeArguments?.[0], ctx);
22978
23619
  if (memberId === NEO_OBJECT_GRID_MEMBER_IDS.GetObjects) {
22979
23620
  const value = index.objects(
22980
23621
  placement,
22981
23622
  offsets,
22982
23623
  ctx.worldQueryDependencies,
22983
- shift
23624
+ shift,
23625
+ accepts
22984
23626
  );
22985
23627
  return { handled: true, value };
22986
23628
  }
@@ -22989,7 +23631,8 @@ function evaluateSystemNative(memberId, receiver, args, ctx) {
22989
23631
  placement,
22990
23632
  offsets,
22991
23633
  ctx.worldQueryDependencies,
22992
- shift
23634
+ shift,
23635
+ accepts
22993
23636
  );
22994
23637
  return { handled: true, value };
22995
23638
  }
@@ -22997,7 +23640,8 @@ function evaluateSystemNative(memberId, receiver, args, ctx) {
22997
23640
  placement,
22998
23641
  offsets,
22999
23642
  ctx.worldQueryDependencies,
23000
- shift
23643
+ shift,
23644
+ accepts
23001
23645
  );
23002
23646
  if (tile === null) return { handled: true, value: null };
23003
23647
  const row = evalValueById(
@@ -23153,12 +23797,41 @@ function applyArithmetic(op, operands, decimal, ctx, numeric) {
23153
23797
  }
23154
23798
  }
23155
23799
  function hostCallResult(member, value, ctx) {
23156
- if (typeof value !== "number" || member === null) return value;
23800
+ if (member === null || typeof value !== "number" && !Array.isArray(value))
23801
+ return value;
23157
23802
  if (member.kind !== 13 /* Function */ && member.kind !== 23 /* NSFunction */) {
23158
23803
  return value;
23159
23804
  }
23160
23805
  const signature = resolveCallableSignature(member.id, member.kind, ctx);
23161
- return signature?.returnTypeInfo.type === 4 /* Float */ ? Math.fround(value) : value;
23806
+ if (signature?.returnTypeInfo.type === 9 /* Lookup */)
23807
+ return asDeclaredRuntimeSet(value, signature.returnTypeInfo, ctx);
23808
+ return signature?.returnTypeInfo.type === 4 /* Float */ && typeof value === "number" ? Math.fround(value) : value;
23809
+ }
23810
+ function narrowGenericCallResult(value, member, typeArguments, ctx) {
23811
+ if (member.kind !== 13 /* Function */ && member.kind !== 23 /* NSFunction */) {
23812
+ return { value };
23813
+ }
23814
+ const signature = resolveCallableSignature(member.id, member.kind, ctx);
23815
+ if (signature === null) return { value };
23816
+ const returnType = bindFunctionTypeArguments(
23817
+ signature.returnTypeInfo,
23818
+ typeArguments
23819
+ );
23820
+ if (returnType === signature.returnTypeInfo) return { value };
23821
+ if (returnType.type === NS_TYPE_VOID) return { value };
23822
+ if (value === null || value === void 0) {
23823
+ return returnType.required ? { mismatch: returnType } : { value: null };
23824
+ }
23825
+ if (returnType.type === 6 /* List */ && Array.isArray(value)) {
23826
+ const entryType = returnType.entryTypeInfo;
23827
+ return {
23828
+ value: value.filter(
23829
+ (entry) => runtimeCollectionEntryMatchesType(entry, entryType, ctx, /* @__PURE__ */ new Set())
23830
+ )
23831
+ };
23832
+ }
23833
+ if (runtimeTypeCheck(value, returnType, ctx)) return { value };
23834
+ return returnType.required ? { mismatch: returnType } : { value: null };
23162
23835
  }
23163
23836
  function coerceAssignmentValue(value, targetTypeInfo, context) {
23164
23837
  if (targetTypeInfo.type === 8 /* Enum */ && typeof value === "string") {
@@ -23564,7 +24237,7 @@ function evalDeclaredListIndex(info, scope, ctx) {
23564
24237
  }
23565
24238
  const childId = row.value[info.schemaKey];
23566
24239
  const rawKey = resolveValueIfId(childId, ctx);
23567
- const normalizedKey = info.keyKind === "enum" ? Array.isArray(rawKey) && typeof rawKey[0] === "string" ? rawKey[0] : null : typeof rawKey === "string" ? rawKey : null;
24240
+ const normalizedKey = normalizeListIndexKey(rawKey, info.keyKind);
23568
24241
  if (normalizedKey === null) continue;
23569
24242
  if (info.unique) {
23570
24243
  const existing = index.get(normalizedKey);
@@ -23814,7 +24487,7 @@ function callbackBodyMayAddInvocationLocals(instructions, parameterIds) {
23814
24487
  });
23815
24488
  }
23816
24489
  function isListCollection(collection) {
23817
- if (Array.isArray(collection)) return true;
24490
+ if (isArrayCollection(collection)) return true;
23818
24491
  if (typeof collection === "object" && collection !== null) return false;
23819
24492
  throw new NSGetterRuntimeError(
23820
24493
  "Collection callback receiver must be a present List or Dictionary value."
@@ -23891,7 +24564,12 @@ function evalCollectionQuery(info, scope, ctx) {
23891
24564
  output,
23892
24565
  references
23893
24566
  );
23894
- return output;
24567
+ return info.op === "ToSet" ? runtimeSet(
24568
+ output,
24569
+ info.reference === true,
24570
+ info.enumEntries === true,
24571
+ ctx
24572
+ ) : output;
23895
24573
  };
23896
24574
  if (info.op === "OrderBy" || info.op === "OrderByDescending") {
23897
24575
  let entries = [];
@@ -24121,7 +24799,7 @@ function evalFunction(fn, scope, ctx) {
24121
24799
  return count;
24122
24800
  }
24123
24801
  case "contains" /* contains */: {
24124
- const c = evalPointer(fn.info.collectionPointer, scope, ctx);
24802
+ let c = evalPointer(fn.info.collectionPointer, scope, ctx);
24125
24803
  const target = evalPointer(fn.info.valuePointer, scope, ctx);
24126
24804
  if (typeof c === "string") {
24127
24805
  if (typeof target !== "string") {
@@ -24131,6 +24809,17 @@ function evalFunction(fn, scope, ctx) {
24131
24809
  }
24132
24810
  return c.includes(target);
24133
24811
  }
24812
+ if (Array.isArray(c)) {
24813
+ const row = trackedRowForValueReference(c, ctx);
24814
+ const member = row === null ? null : memberForValueRow(row, ctx);
24815
+ if (member !== null && (member.kind === 9 /* Lookup */ || member.kind === 8 /* Enum */ || member.kind === 18 /* DialogueLookup */))
24816
+ c = asDeclaredRuntimeSet(
24817
+ c,
24818
+ runtimeTypeInfoForMember(member, /* @__PURE__ */ new Map(), ctx, /* @__PURE__ */ new Set()),
24819
+ ctx
24820
+ );
24821
+ }
24822
+ if (c instanceof RuntimeSet) return c.has(runtimeSetKey(target, c, ctx));
24134
24823
  const setEntryMember = storedSetEntryMember(c, ctx);
24135
24824
  if (setEntryMember !== null) {
24136
24825
  return findStoredSetEntry(
@@ -24560,7 +25249,7 @@ function receiverClosedTypeArguments(typeArguments, ctx) {
24560
25249
  let env = null;
24561
25250
  let closed = null;
24562
25251
  for (const [parameterId, typeInfo] of Object.entries(typeArguments)) {
24563
- if (!typeInfoContainsGeneric(typeInfo)) continue;
25252
+ if (!typeInfoContainsGeneric2(typeInfo)) continue;
24564
25253
  if (env === null) {
24565
25254
  const row = ctx.thisValueRowId ? readNeoScriptRuntimeRow(ctx, ctx.thisValueRowId) : trackedRowForValueReference(ctx.thisValue, ctx);
24566
25255
  if (row) {
@@ -25861,6 +26550,7 @@ function encodeLookupInitializerResult(member, value, created, ctx) {
25861
26550
  function encodeLookupInitializerSelection(member, value, created, ctx) {
25862
26551
  if (value === null) return null;
25863
26552
  if (value === void 0) return null;
26553
+ if (value instanceof RuntimeSet) value = value.toArray();
25864
26554
  if (Array.isArray(value)) {
25865
26555
  if (isMultiSelectionMember(member) !== true && value.length > 1) {
25866
26556
  throw new NSGetterRuntimeError(
@@ -27466,6 +28156,8 @@ function cloneConstructorLiteralValue(value) {
27466
28156
  );
27467
28157
  }
27468
28158
  function materializeConstructorArgumentValue(args) {
28159
+ if (args.value instanceof RuntimeSet)
28160
+ args = { ...args, value: args.value.toArray() };
27469
28161
  const trackedValueId = findKnownRowIdByValueReference(args.value, args.ctx);
27470
28162
  if (args.value === null && !isRequiredMember(args.member) && isMemberWithEntries(args.member)) {
27471
28163
  return registerConstructorArgumentRow(args, null);
@@ -28176,6 +28868,7 @@ function collectionEntriesOrEmpty(value, ctx) {
28176
28868
  }
28177
28869
  }
28178
28870
  function collectionLength(c) {
28871
+ if (c instanceof RuntimeSet) return c.size;
28179
28872
  if (Array.isArray(c)) return c.length;
28180
28873
  if (typeof c === "object" && c !== null) {
28181
28874
  return Object.keys(c).length;
@@ -28204,6 +28897,17 @@ function snapshotCollectionMembership(collection, ctx) {
28204
28897
  );
28205
28898
  }
28206
28899
  function forEachRawCollectionEntry(c, callback) {
28900
+ if (c instanceof RuntimeSet) {
28901
+ for (const [key, entry] of c.membership().entries()) {
28902
+ if (callback({
28903
+ raw: entry.raw,
28904
+ key,
28905
+ valueId: entry.reference && typeof entry.raw === "string" ? entry.raw : null
28906
+ }) === 1 /* Break */)
28907
+ break;
28908
+ }
28909
+ return true;
28910
+ }
28207
28911
  if (Array.isArray(c)) {
28208
28912
  for (let key = 0; key < c.length; key += 1) {
28209
28913
  const raw = c[key];
@@ -28263,6 +28967,8 @@ function resolveCollectionEntry(collection, raw, key, ctx) {
28263
28967
  return collectionEntryUsesReferenceResolution(collection, key, ctx) ? resolveValueIfId(raw, ctx) : raw;
28264
28968
  }
28265
28969
  function collectionEntryUsesReferenceResolution(collection, key, ctx) {
28970
+ if (collection instanceof RuntimeSet && typeof key === "number")
28971
+ return collection.membership()[key]?.reference === true;
28266
28972
  if (!Array.isArray(collection) || typeof key !== "number") return true;
28267
28973
  const referenceIndexes = ctx.__unorderedListProjections?.referenceEntryIndexesByArray.get(
28268
28974
  collection
@@ -29044,6 +29750,7 @@ var MaterializedValueGraphContext = class {
29044
29750
  }
29045
29751
  resolveTypeInfo(rawTypeInfo, env) {
29046
29752
  if (rawTypeInfo.type === 21 /* Generic */) {
29753
+ if (!isClassGenericParamTypeInfo(rawTypeInfo)) return null;
29047
29754
  const binding = env.get(rawTypeInfo.genericParamId);
29048
29755
  if (binding === void 0 || binding.kind !== "member") return null;
29049
29756
  const member = this.membersById.get(binding.memberId);
@@ -29197,6 +29904,7 @@ function rowGenericEnvironment(document2, row, contextualRootMember) {
29197
29904
  }
29198
29905
  function tryResolveTypeInfo(document2, rawTypeInfo, env) {
29199
29906
  if (rawTypeInfo.type === 21 /* Generic */) {
29907
+ if (!isClassGenericParamTypeInfo(rawTypeInfo)) return null;
29200
29908
  const binding = env.get(rawTypeInfo.genericParamId);
29201
29909
  if (binding === void 0 || binding.kind !== "member") return null;
29202
29910
  const member = document2.members.find(
@@ -35605,18 +36313,42 @@ function sourcePositionMapper(source) {
35605
36313
  };
35606
36314
  }
35607
36315
 
36316
+ // ../packages/neoscript-language/src/system-record-id.ts
36317
+ var SYSTEM_RECORD_ID_PREFIX2 = "system_";
36318
+
35608
36319
  // ../packages/neoscript-language/src/type-substitution.ts
35609
36320
  function substituteTypeParameters(member, receiver, declaring) {
35610
- const parameters = declaring.typeParameters ?? [];
35611
- const argumentsList2 = receiver.typeArguments ?? [];
36321
+ const bindings = classTypeBindings({ type: receiver, declaring });
36322
+ return substituteBindings(
36323
+ member,
36324
+ (type) => type.ownerMemberId === void 0 ? bindings.get(type.id) : void 0
36325
+ );
36326
+ }
36327
+ function substituteCallTypeArguments(member, functionArguments, typeParameters, receiver) {
36328
+ const classBindings = receiver && classTypeBindings(receiver);
36329
+ const declared = typeParameters?.[0]?.type;
36330
+ const owner = declared?.kind === "typeParameter" ? declared.ownerMemberId : void 0;
36331
+ return substituteBindings(member, (type) => {
36332
+ if (type.ownerMemberId === void 0) return classBindings?.get(type.id);
36333
+ if (type.ownerMemberId !== owner) return void 0;
36334
+ if (type.index === void 0) return void 0;
36335
+ return functionArguments[type.index];
36336
+ });
36337
+ }
36338
+ function classTypeBindings(receiver) {
36339
+ const parameters = receiver.declaring.typeParameters ?? [];
36340
+ const argumentsList2 = receiver.type.typeArguments ?? [];
35612
36341
  const bindings = /* @__PURE__ */ new Map();
35613
36342
  parameters.forEach((parameter3, index) => {
35614
36343
  const value = argumentsList2[index];
35615
36344
  if (value) bindings.set(parameter3.id ?? parameter3.name, value);
35616
36345
  });
36346
+ return bindings;
36347
+ }
36348
+ function substituteBindings(member, bindingOf) {
35617
36349
  const visit = (type) => {
35618
36350
  if (type.kind === "typeParameter") {
35619
- const binding = bindings.get(type.id);
36351
+ const binding = bindingOf(type);
35620
36352
  return binding && type.nullable ? { ...binding, nullable: true } : binding ?? type;
35621
36353
  }
35622
36354
  if (type.kind === "named" && type.typeArguments) {
@@ -35983,10 +36715,6 @@ var UserSafeTypeCheck = class {
35983
36715
  }
35984
36716
  };
35985
36717
 
35986
- // ../packages/neoscript-language/src/tile-conversion.ts
35987
- var NEO_TILE_CONVERT_MEMBER_ID = "system_54ecc5a7-874d-54ed-92f4-38100a4b7465";
35988
- var NEO_TILE_CLASS_ID = "system_d7fa161b-b269-4bf1-9ec9-3aebec67e6e0";
35989
-
35990
36718
  // ../packages/neoscript-language/src/strict-resolver.ts
35991
36719
  var CONSTRUCTING_FUNCTION_KINDS = /* @__PURE__ */ new Set(
35992
36720
  [
@@ -38416,13 +39144,17 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
38416
39144
  type
38417
39145
  };
38418
39146
  }
38419
- return this.resolveExpression(expression, scope);
39147
+ return this.resolveMemberTargetReceiver(expression, scope);
38420
39148
  }
38421
39149
  requireActionListenerSignature(symbol, owner, receiverType, expected, pos) {
38422
- const substitute = (type) => {
38423
- if (receiverType?.kind !== "named" || owner === void 0) return type;
38424
- return substituteTypeParameters(type, receiverType, owner);
38425
- };
39150
+ const listenerArguments = methodGroupTypeArguments(symbol, false, pos);
39151
+ const receiver = callReceiver(receiverType, owner);
39152
+ const substitute = (type) => substituteCallTypeArguments(
39153
+ type,
39154
+ listenerArguments,
39155
+ symbol.typeParameters,
39156
+ receiver
39157
+ );
38426
39158
  const signature = actionListenerSignature(symbol);
38427
39159
  if (signature === null) {
38428
39160
  throw new CompileError(
@@ -38644,15 +39376,6 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
38644
39376
  );
38645
39377
  if (conversion !== null) return conversion;
38646
39378
  }
38647
- if (expression.typeArguments && expression.callee.kind === "member" && expression.callee.name === "GetObjects") {
38648
- return this.resolveGridObjectQuery(
38649
- expression.callee,
38650
- expression.args,
38651
- expression.typeArguments,
38652
- scope,
38653
- expression.pos
38654
- );
38655
- }
38656
39379
  if (expression.typeArguments && expression.callee.kind === "member" && expression.callee.receiver.kind === "ident" && expression.callee.receiver.name === NEOSCRIPT_LIST_TYPE_NAME) {
38657
39380
  if (expression.callee.name !== NEOSCRIPT_LIST_REPEAT_NAME) {
38658
39381
  throw new CompileError(
@@ -38684,12 +39407,6 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
38684
39407
  expression.pos
38685
39408
  );
38686
39409
  }
38687
- if (expression.typeArguments) {
38688
- throw new CompileError(
38689
- "Type arguments are not supported for this call. Remove the explicit type arguments.",
38690
- expression.pos
38691
- );
38692
- }
38693
39410
  if (expression.argumentNames) {
38694
39411
  throw new CompileError(
38695
39412
  "Named arguments are not supported for this call. Pass arguments in declaration order, without names.",
@@ -38702,7 +39419,8 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
38702
39419
  scope,
38703
39420
  expression.pos,
38704
39421
  expected,
38705
- receiverValue
39422
+ receiverValue,
39423
+ expression.typeArguments
38706
39424
  );
38707
39425
  }
38708
39426
  case "new": {
@@ -39066,6 +39784,9 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
39066
39784
  }
39067
39785
  return void 0;
39068
39786
  }
39787
+ resolveMemberTargetReceiver(expression, scope) {
39788
+ return expression.kind === "ident" && expression.name === "this" ? this.resolveIdentifier("this", scope, expression.pos, "member-target") : this.resolveExpression(expression, scope);
39789
+ }
39069
39790
  resolveDelegateMethodGroup(expression, expected, scope, options = {}) {
39070
39791
  let symbol;
39071
39792
  let receiver = null;
@@ -39079,7 +39800,12 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
39079
39800
  owner = implicit.owner;
39080
39801
  receiver = symbol.static === true ? { kind: "static", memberId: symbol.id } : {
39081
39802
  kind: "instance",
39082
- expression: this.resolveIdentifier("this", scope, expression.pos)
39803
+ expression: this.resolveIdentifier(
39804
+ "this",
39805
+ scope,
39806
+ expression.pos,
39807
+ "member-target"
39808
+ )
39083
39809
  };
39084
39810
  } else if (expression.kind === "member") {
39085
39811
  if (expression.receiver.kind === "ident" && !this.hasValueReceiver(expression.receiver.name, scope)) {
@@ -39096,7 +39822,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
39096
39822
  }
39097
39823
  receiver = { kind: "static", memberId: symbol.id };
39098
39824
  } else {
39099
- const receiverExpression = this.resolveExpression(
39825
+ const receiverExpression = this.resolveMemberTargetReceiver(
39100
39826
  expression.receiver,
39101
39827
  scope
39102
39828
  );
@@ -39119,17 +39845,29 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
39119
39845
  }
39120
39846
  if (owner !== void 0)
39121
39847
  this.assertMemberAccessible(owner, symbol, expression.pos);
39122
- let returnType = symbol.returnType ?? symbol.type;
39123
- let parameterTypes = (symbol.parameters ?? []).map(
39124
- (parameter3) => parameter3.type
39848
+ const methodGroupArguments = methodGroupTypeArguments(
39849
+ symbol,
39850
+ options.mockTarget === true,
39851
+ expression.pos
39852
+ );
39853
+ const bound = callReceiver(
39854
+ receiver?.kind === "instance" ? receiver.expression.type : void 0,
39855
+ owner
39856
+ );
39857
+ const returnType = substituteCallTypeArguments(
39858
+ symbol.returnType ?? symbol.type,
39859
+ methodGroupArguments,
39860
+ symbol.typeParameters,
39861
+ bound
39862
+ );
39863
+ const parameterTypes = (symbol.parameters ?? []).map(
39864
+ (parameter3) => substituteCallTypeArguments(
39865
+ parameter3.type,
39866
+ methodGroupArguments,
39867
+ symbol.typeParameters,
39868
+ bound
39869
+ )
39125
39870
  );
39126
- if (receiver?.kind === "instance" && receiver.expression.type.kind === "named" && owner !== void 0) {
39127
- const receiverType = receiver.expression.type;
39128
- returnType = substituteTypeParameters(returnType, receiverType, owner);
39129
- parameterTypes = parameterTypes.map(
39130
- (parameter3) => substituteTypeParameters(parameter3, receiverType, owner)
39131
- );
39132
- }
39133
39871
  const expectedVoid = isVoid(expected.returnType);
39134
39872
  const actualVoid = isVoid(returnType);
39135
39873
  if (expectedVoid !== actualVoid || !expectedVoid && !isNeoScriptTypeAssignable(returnType, expected.returnType, this.project) || parameterTypes.length !== expected.parameterTypes.length || !parameterTypes.every((parameter3, index) => {
@@ -39141,7 +39879,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
39141
39879
  expression.pos
39142
39880
  );
39143
39881
  }
39144
- if (receiver?.kind === "instance" && options.allowUnboundInstanceTarget !== true && (receiver.expression.pointer.type !== "variable" /* Variable */ || receiver.expression.pointer.variableId !== this.thisVariable.id)) {
39882
+ if (receiver?.kind === "instance" && options.mockTarget !== true && (receiver.expression.pointer.type !== "variable" /* Variable */ || receiver.expression.pointer.variableId !== this.thisVariable.id)) {
39145
39883
  throw new CompileError(
39146
39884
  "NeoDelegate method groups currently require the current 'this' receiver.",
39147
39885
  expression.pos
@@ -39174,10 +39912,10 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
39174
39912
  );
39175
39913
  if (symbol === void 0 || symbol.static !== true) return null;
39176
39914
  } else {
39177
- const receiver = this.resolveExpression(expression.receiver, scope);
39178
- if (receiver.type.kind !== "named") return null;
39179
- receiverType = receiver.type;
39180
- owner = this.project.typeById.get(receiver.type.typeId);
39915
+ const receiver2 = this.resolveExpression(expression.receiver, scope);
39916
+ if (receiver2.type.kind !== "named") return null;
39917
+ receiverType = receiver2.type;
39918
+ owner = this.project.typeById.get(receiver2.type.typeId);
39181
39919
  symbol = owner?.members.find(
39182
39920
  (candidate) => candidate.name === expression.name && (candidate.kind === "function" || candidate.kind === "method")
39183
39921
  );
@@ -39186,16 +39924,26 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
39186
39924
  } else {
39187
39925
  return null;
39188
39926
  }
39189
- let returnType = symbol.returnType ?? symbol.type;
39190
- let parameterTypes = (symbol.parameters ?? []).map(
39191
- (parameter3) => parameter3.type
39927
+ const mockArguments = methodGroupTypeArguments(
39928
+ symbol,
39929
+ true,
39930
+ expression.pos
39931
+ );
39932
+ const receiver = callReceiver(receiverType, owner);
39933
+ const returnType = substituteCallTypeArguments(
39934
+ symbol.returnType ?? symbol.type,
39935
+ mockArguments,
39936
+ symbol.typeParameters,
39937
+ receiver
39938
+ );
39939
+ const parameterTypes = (symbol.parameters ?? []).map(
39940
+ (parameter3) => substituteCallTypeArguments(
39941
+ parameter3.type,
39942
+ mockArguments,
39943
+ symbol.typeParameters,
39944
+ receiver
39945
+ )
39192
39946
  );
39193
- if (receiverType?.kind === "named" && owner !== void 0) {
39194
- returnType = substituteTypeParameters(returnType, receiverType, owner);
39195
- parameterTypes = parameterTypes.map(
39196
- (parameter3) => substituteTypeParameters(parameter3, receiverType, owner)
39197
- );
39198
- }
39199
39947
  return { kind: "delegate", returnType, parameterTypes };
39200
39948
  }
39201
39949
  resolveInterpolatedString(parts, scope) {
@@ -39378,7 +40126,13 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
39378
40126
  type
39379
40127
  };
39380
40128
  }
39381
- resolveIdentifier(name, scope, pos) {
40129
+ resolveIdentifier(name, scope, pos, usage = "value") {
40130
+ if (name === "this" && this.context.kind === "initializer" && this.delegateCaptureContexts.length === 0 && usage === "value") {
40131
+ throw new CompileError(
40132
+ "'this' is unavailable while an initializer runs. Defer instance access with a lambda or method group.",
40133
+ pos
40134
+ );
40135
+ }
39382
40136
  if (name === "base") {
39383
40137
  throw new CompileError(
39384
40138
  "'base' can only qualify a function call or getter read inside an override body.",
@@ -41038,7 +41792,14 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
41038
41792
  return result.value;
41039
41793
  };
41040
41794
  }
41041
- resolveCall(callee, argumentsList2, scope, pos, expected, receiverValue = this.callReceiver(callee, scope)) {
41795
+ resolveCall(callee, argumentsList2, scope, pos, expected, receiverValue = this.callReceiver(callee, scope), typeArguments) {
41796
+ const rejectTypeArguments = () => {
41797
+ if (typeArguments === void 0) return;
41798
+ throw new CompileError(
41799
+ "Type arguments are not supported for this call. Remove the explicit type arguments.",
41800
+ pos
41801
+ );
41802
+ };
41042
41803
  if (callee.kind === "member" && callee.receiver.kind === "ident" && callee.receiver.name === "Debug" && this.resolveDebugStatement(
41043
41804
  { kind: "call", callee, args: [...argumentsList2], pos },
41044
41805
  scope
@@ -41049,7 +41810,14 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
41049
41810
  );
41050
41811
  }
41051
41812
  if (callee.kind === "member" && callee.receiver.kind === "ident" && callee.receiver.name === "base") {
41052
- return this.resolveBaseCall(callee, argumentsList2, scope, pos);
41813
+ return this.resolveBaseCall(
41814
+ callee,
41815
+ argumentsList2,
41816
+ scope,
41817
+ pos,
41818
+ false,
41819
+ typeArguments
41820
+ );
41053
41821
  }
41054
41822
  const variantCall = this.resolveVariantCall(
41055
41823
  callee,
@@ -41058,12 +41826,16 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
41058
41826
  pos,
41059
41827
  receiverValue
41060
41828
  );
41061
- if (variantCall !== null) return variantCall;
41829
+ if (variantCall !== null) {
41830
+ rejectTypeArguments();
41831
+ return variantCall;
41832
+ }
41062
41833
  const callable2 = this.resolveCallableValueCallee(
41063
41834
  callee,
41064
41835
  scope,
41065
41836
  receiverValue
41066
41837
  );
41838
+ if (callable2 !== null) rejectTypeArguments();
41067
41839
  if (callable2?.type.kind === "delegate") {
41068
41840
  return this.resolveDelegateCall(
41069
41841
  callable2,
@@ -41081,9 +41853,12 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
41081
41853
  }
41082
41854
  if (callee.kind === "ident") {
41083
41855
  const vector3 = vectorKind(callee.name);
41084
- if (vector3)
41856
+ if (vector3) {
41857
+ rejectTypeArguments();
41085
41858
  return this.resolveVectorConstructor(vector3, argumentsList2, scope, pos);
41859
+ }
41086
41860
  if (callee.name === "VisitCount" || callee.name === "HasVisited") {
41861
+ rejectTypeArguments();
41087
41862
  return this.resolveDialogueMemoryRead(
41088
41863
  callee.name,
41089
41864
  argumentsList2,
@@ -41101,7 +41876,9 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
41101
41876
  argumentsList2,
41102
41877
  scope,
41103
41878
  pos,
41104
- false
41879
+ false,
41880
+ false,
41881
+ typeArguments
41105
41882
  );
41106
41883
  const target = this.resolveImplicitCallTarget(callee.name, scope, pos);
41107
41884
  if (target)
@@ -41111,7 +41888,9 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
41111
41888
  argumentsList2,
41112
41889
  scope,
41113
41890
  pos,
41114
- false
41891
+ false,
41892
+ false,
41893
+ typeArguments
41115
41894
  );
41116
41895
  throw new CompileError(`Unknown function '${callee.name}'`, pos);
41117
41896
  }
@@ -41123,6 +41902,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
41123
41902
  }
41124
41903
  if (callee.receiver.kind === "ident" && !this.hasValueReceiver(callee.receiver.name, scope)) {
41125
41904
  if (callee.receiver.name === MATH_NAMESPACE_NAME) {
41905
+ rejectTypeArguments();
41126
41906
  if (callee.optional) {
41127
41907
  throw new CompileError(
41128
41908
  `Optional chaining is not valid on builtin namespace '${MATH_NAMESPACE_NAME}'.`,
@@ -41159,41 +41939,44 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
41159
41939
  pos
41160
41940
  );
41161
41941
  }
41162
- const member = staticType.members.find(
41942
+ const member2 = staticType.members.find(
41163
41943
  (candidate) => candidate.name === callee.name
41164
41944
  );
41165
- if (!member) {
41945
+ if (!member2) {
41166
41946
  throw new CompileError(
41167
41947
  `Class '${staticType.name}' has no static callable member '${callee.name}'.`,
41168
41948
  pos
41169
41949
  );
41170
41950
  }
41171
- this.assertMemberAccessible(staticType, member, pos);
41172
- if (member.static !== true) {
41951
+ this.assertMemberAccessible(staticType, member2, pos);
41952
+ if (member2.static !== true) {
41173
41953
  throw new CompileError(
41174
41954
  `Member '${staticType.name}.${callee.name}' requires an instance receiver.`,
41175
41955
  pos
41176
41956
  );
41177
41957
  }
41178
- if (member.kind !== "function" && member.kind !== "method") {
41958
+ if (member2.kind !== "function" && member2.kind !== "method") {
41179
41959
  throw new CompileError(
41180
41960
  `Static member '${staticType.name}.${callee.name}' is not callable.`,
41181
41961
  pos
41182
41962
  );
41183
41963
  }
41184
41964
  return this.resolveSymbolCall(
41185
- member,
41186
- { kind: "static", memberId: member.id },
41965
+ member2,
41966
+ { kind: "static", memberId: member2.id },
41187
41967
  argumentsList2,
41188
41968
  scope,
41189
41969
  pos,
41190
- false
41970
+ false,
41971
+ false,
41972
+ typeArguments
41191
41973
  );
41192
41974
  }
41193
41975
  }
41194
41976
  const receiver = receiverValue();
41195
41977
  const optional2 = callee.optional === true;
41196
41978
  if (receiver.dialogues !== void 0) {
41979
+ rejectTypeArguments();
41197
41980
  if (optional2) {
41198
41981
  throw new CompileError(
41199
41982
  `\`?.\` is not valid on ${receiver.dialogues.path}; it is never null.`,
@@ -41214,6 +41997,12 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
41214
41997
  pos
41215
41998
  );
41216
41999
  }
42000
+ const memberReceiverType = neoScriptMemberLookupType(receiver.type);
42001
+ const namedType2 = memberReceiverType.kind === "named" ? this.project.typeById.get(memberReceiverType.typeId) : void 0;
42002
+ const member = namedType2?.members.find(
42003
+ (candidate) => (candidate.kind === "function" || candidate.kind === "method") && candidate.name === callee.name
42004
+ );
42005
+ if (member === void 0) rejectTypeArguments();
41217
42006
  if (isPrimitive(receiver.type, "NeoDialogueReference") && isDialogueRequestName(callee.name)) {
41218
42007
  return this.resolveDialogueReferenceCall(
41219
42008
  receiver,
@@ -41233,7 +42022,6 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
41233
42022
  pos
41234
42023
  );
41235
42024
  }
41236
- const memberReceiverType = neoScriptMemberLookupType(receiver.type);
41237
42025
  if (callee.name === "Equals" && memberReceiverType.kind === "typeParameter") {
41238
42026
  if (optional2) {
41239
42027
  throw new CompileError(
@@ -41266,10 +42054,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
41266
42054
  };
41267
42055
  }
41268
42056
  if (memberReceiverType.kind === "named") {
41269
- const type = this.project.typeById.get(memberReceiverType.typeId);
41270
- const member = type?.members.find(
41271
- (candidate) => (candidate.kind === "function" || candidate.kind === "method") && candidate.name === callee.name
41272
- );
42057
+ const type = namedType2;
41273
42058
  if (member) {
41274
42059
  this.validateFunctionReceiver(receiver, callee.name, optional2, pos);
41275
42060
  if (type !== void 0) this.assertMemberAccessible(type, member, pos);
@@ -41288,7 +42073,9 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
41288
42073
  argumentsList2,
41289
42074
  scope,
41290
42075
  pos,
41291
- optional2
42076
+ optional2,
42077
+ false,
42078
+ typeArguments
41292
42079
  );
41293
42080
  }
41294
42081
  if (callee.name === "Clone" && type?.kind === "class") {
@@ -42089,81 +42876,6 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
42089
42876
  type: { kind: "primitive", name: "bool" }
42090
42877
  };
42091
42878
  }
42092
- resolveGridObjectQuery(callee, args, typeArguments, scope, pos) {
42093
- const receiver = this.resolveExpression(callee.receiver, scope);
42094
- const owner = receiver.type.kind === "named" ? this.project.typeById.get(receiver.type.typeId) : void 0;
42095
- const symbol = owner?.members.find((member) => member.name === callee.name);
42096
- if (symbol?.id !== NEO_OBJECT_GRID_MEMBER_IDS.GetObjects)
42097
- throw new CompileError(
42098
- "Only NeoObject.GetObjects accepts a class filter type argument.",
42099
- pos
42100
- );
42101
- if (callee.optional || isNullable(receiver.type))
42102
- throw new CompileError(
42103
- "GetObjects<T> requires a non-null placed object receiver.",
42104
- pos
42105
- );
42106
- if (typeArguments.length !== 1)
42107
- throw new CompileError(
42108
- "GetObjects<T> requires exactly one object class type argument.",
42109
- pos
42110
- );
42111
- const target = this.resolveType(requiredAt(typeArguments, 0));
42112
- if (target.kind !== "named" || this.project.typeById.get(target.typeId)?.kind !== "class" || target.nullable || !isNeoScriptTypeAssignable(
42113
- target,
42114
- { kind: "named", typeId: NEO_OBJECT_CLASS_ID },
42115
- this.project
42116
- ))
42117
- throw new CompileError(
42118
- "GetObjects<T> requires a non-null NeoObject class or a derived class.",
42119
- pos
42120
- );
42121
- this.assertMemberAccessible(owner, symbol, pos);
42122
- const queried = this.resolveSymbolCall(
42123
- symbol,
42124
- { kind: "instance", expression: receiver },
42125
- args,
42126
- scope,
42127
- pos,
42128
- false
42129
- );
42130
- if (queried.type.kind !== "list")
42131
- throw new CompileError("NeoObject.GetObjects must return a list.", pos);
42132
- const item = variable(
42133
- "__grid_query_item__",
42134
- queried.type.elementType,
42135
- void 0,
42136
- this.project
42137
- );
42138
- const predicate = {
42139
- compilerRevision: NEOSCRIPT_COMPILER_REVISION,
42140
- source: {
42141
- name: this.debugSource.name,
42142
- uri: this.debugSource.uri,
42143
- coordinateSpace: this.debugSource.coordinateSpace
42144
- },
42145
- parameters: [item],
42146
- instructions: [
42147
- {
42148
- type: "return" /* Return */,
42149
- pointer: {
42150
- type: "isCheck" /* IsCheck */,
42151
- pointer: {
42152
- type: "variable" /* Variable */,
42153
- variableId: item.id
42154
- },
42155
- checkType: toWireType(target, this.project)
42156
- }
42157
- }
42158
- ],
42159
- typeInfo: toWireType({ kind: "primitive", name: "bool" }, this.project)
42160
- };
42161
- return intrinsic(
42162
- "where" /* Where */,
42163
- { collectionPointer: queried.pointer, function: predicate },
42164
- { kind: "list", elementType: target, readOnly: true }
42165
- );
42166
- }
42167
42879
  resolveBaseMember(name, scope, pos, optional2) {
42168
42880
  const baseClass = this.context.baseClass;
42169
42881
  if (baseClass?.kind !== "named" || this.context.staticMember === true || this.context.thisClass === void 0) {
@@ -42207,7 +42919,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
42207
42919
  }
42208
42920
  };
42209
42921
  }
42210
- resolveBaseCall(callee, args, scope, pos, allowVoid = false) {
42922
+ resolveBaseCall(callee, args, scope, pos, allowVoid = false, typeArguments) {
42211
42923
  const { symbol, receiver } = this.resolveBaseMember(
42212
42924
  callee.name,
42213
42925
  scope,
@@ -42227,17 +42939,19 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
42227
42939
  scope,
42228
42940
  pos,
42229
42941
  false,
42230
- allowVoid
42942
+ allowVoid,
42943
+ typeArguments
42231
42944
  );
42232
42945
  }
42233
- resolveSymbolCall(symbol, receiver, argumentsList2, scope, pos, optional2, allowVoid = false) {
42946
+ resolveSymbolCall(symbol, receiver, argumentsList2, scope, pos, optional2, allowVoid = false, typeArguments) {
42234
42947
  this.validateCallableInContext(symbol, pos);
42235
42948
  const resolvedCall = this.resolveCallableArguments(
42236
42949
  symbol,
42237
42950
  receiver,
42238
42951
  argumentsList2,
42239
42952
  scope,
42240
- pos
42953
+ pos,
42954
+ typeArguments
42241
42955
  );
42242
42956
  const call = {
42243
42957
  type: "callFunction" /* CallFunction */,
@@ -42247,6 +42961,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
42247
42961
  pointer: receiver?.expression.pointer ?? this.thisVariable.pointer
42248
42962
  },
42249
42963
  args: resolvedCall.args,
42964
+ ...resolvedCall.typeArguments ? { typeArguments: resolvedCall.typeArguments } : {},
42250
42965
  ...receiver?.kind === "instance" && receiver.dispatch === "base" ? { dispatch: "base" } : {},
42251
42966
  ...optional2 ? { optional: true } : {},
42252
42967
  callSiteId: this.nextCallSite(pos)
@@ -42269,8 +42984,18 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
42269
42984
  * whose type depends on the supplied value or method group. The special
42270
42985
  * cases are unreachable unless the host injected the test prelude.
42271
42986
  */
42272
- resolveCallableArguments(symbol, receiver, argumentsList2, scope, pos) {
42273
- const signature = this.callableSignatureForReceiver(symbol, receiver);
42987
+ resolveCallableArguments(symbol, receiver, argumentsList2, scope, pos, typeArguments) {
42988
+ const signature = this.callableSignatureForReceiver(
42989
+ symbol,
42990
+ receiver,
42991
+ typeArguments,
42992
+ pos
42993
+ );
42994
+ const wireTypeArguments = signature.typeArguments.length ? {
42995
+ typeArguments: signature.typeArguments.map(
42996
+ (argument2) => toWireType(argument2, this.project)
42997
+ )
42998
+ } : {};
42274
42999
  if (symbol.id === NEO_TEST_IDS.expect) {
42275
43000
  requireArgCount(symbol.name, argumentsList2, 1, pos);
42276
43001
  const argument2 = requiredAt(argumentsList2, 0);
@@ -42304,7 +43029,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
42304
43029
  scope,
42305
43030
  // Mock targets are member-identity metadata. They are never invoked as
42306
43031
  // delegates, and mockHandle.on(receiver) owns receiver scoping.
42307
- { allowUnboundInstanceTarget: true }
43032
+ { mockTarget: true }
42308
43033
  );
42309
43034
  if (target === null) {
42310
43035
  throw new CompileError(
@@ -42493,23 +43218,100 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
42493
43218
  );
42494
43219
  }
42495
43220
  }
42496
- return { args, returnType: signature.returnType };
43221
+ return { args, returnType: signature.returnType, ...wireTypeArguments };
43222
+ }
43223
+ callableSignatureForReceiver(symbol, receiver, typeArguments, pos) {
43224
+ const bound = this.genericCallReceiver(receiver);
43225
+ const functionArguments = this.resolveFunctionTypeArguments(
43226
+ symbol,
43227
+ typeArguments,
43228
+ (type) => substituteCallTypeArguments(type, [], void 0, bound),
43229
+ pos
43230
+ );
43231
+ const bind = (type) => substituteCallTypeArguments(
43232
+ type,
43233
+ functionArguments,
43234
+ symbol.typeParameters,
43235
+ bound
43236
+ );
43237
+ return {
43238
+ parameters: (symbol.parameters ?? []).map((parameter3) => ({
43239
+ ...parameter3,
43240
+ type: bind(parameter3.type)
43241
+ })),
43242
+ returnType: bind(symbol.returnType ?? symbol.type),
43243
+ typeArguments: functionArguments
43244
+ };
42497
43245
  }
42498
- callableSignatureForReceiver(symbol, receiver) {
42499
- let parameters = symbol.parameters ?? [];
42500
- let returnType = symbol.returnType ?? symbol.type;
42501
- if (receiver?.kind !== "instance") return { parameters, returnType };
43246
+ /** The instance receiver whose class type arguments a call binds, if any. */
43247
+ genericCallReceiver(receiver) {
43248
+ if (receiver?.kind !== "instance") return void 0;
42502
43249
  const receiverType = receiver.expression.type;
42503
- if (receiverType.kind !== "named") return { parameters, returnType };
42504
- if (!receiverType.typeArguments?.length) return { parameters, returnType };
42505
- const declaring = this.project.typeById.get(receiverType.typeId);
42506
- if (declaring === void 0) return { parameters, returnType };
42507
- parameters = parameters.map((parameter3) => ({
42508
- ...parameter3,
42509
- type: substituteTypeParameters(parameter3.type, receiverType, declaring)
42510
- }));
42511
- returnType = substituteTypeParameters(returnType, receiverType, declaring);
42512
- return { parameters, returnType };
43250
+ if (receiverType.kind !== "named") return void 0;
43251
+ if (!receiverType.typeArguments?.length) return void 0;
43252
+ return callReceiver(
43253
+ receiverType,
43254
+ this.project.typeById.get(receiverType.typeId)
43255
+ );
43256
+ }
43257
+ /**
43258
+ * P110 §2. The callee's full positional type-argument list: written
43259
+ * arguments, then defaults. Each written argument is non-nullable and
43260
+ * satisfies its param's constraint.
43261
+ */
43262
+ resolveFunctionTypeArguments(symbol, typeArguments, substitute, pos) {
43263
+ const parameters = symbol.typeParameters ?? [];
43264
+ if (parameters.length === 0) {
43265
+ if (typeArguments === void 0) return [];
43266
+ throw new CompileError(
43267
+ `Function '${symbol.name}' is not generic; remove the type arguments.`,
43268
+ pos
43269
+ );
43270
+ }
43271
+ const written = typeArguments ?? [];
43272
+ if (written.length > parameters.length) {
43273
+ throw new CompileError(
43274
+ `Function '${symbol.name}' takes ${parameters.length} type argument${parameters.length === 1 ? "" : "s"} but got ${written.length}.`,
43275
+ pos
43276
+ );
43277
+ }
43278
+ return parameters.map((parameter3, index) => {
43279
+ const declared = parameter3.type;
43280
+ if (declared.kind !== "typeParameter") {
43281
+ throw new Error(
43282
+ `Function '${symbol.name}' type parameter '${parameter3.name}' has no type parameter type.`
43283
+ );
43284
+ }
43285
+ const authored = written[index];
43286
+ if (authored === void 0) {
43287
+ if (declared.defaultType !== void 0) return declared.defaultType;
43288
+ throw new CompileError(
43289
+ `'${symbol.name}' needs a type argument for '${parameter3.name}'.`,
43290
+ pos
43291
+ );
43292
+ }
43293
+ const argument2 = this.resolveType(authored);
43294
+ if (argument2.nullable === true) {
43295
+ throw new CompileError(
43296
+ `Type argument '${this.describe(argument2)}' cannot be nullable; declare '${parameter3.name}?' in the signature instead.`,
43297
+ authored.pos
43298
+ );
43299
+ }
43300
+ if (symbol.native === true && !symbol.id.startsWith(SYSTEM_RECORD_ID_PREFIX2) && argument2.kind === "named" && (argument2.typeArguments?.length ?? 0) > 0) {
43301
+ throw new CompileError(
43302
+ `Native function '${symbol.name}' takes a non-generic class type argument; '${this.describe(argument2)}' is generic.`,
43303
+ authored.pos
43304
+ );
43305
+ }
43306
+ const constraint = declared.constraint === void 0 ? void 0 : substitute(declared.constraint);
43307
+ if (constraint !== void 0 && !isNeoScriptTypeAssignable(argument2, constraint, this.project)) {
43308
+ throw new CompileError(
43309
+ `Type argument '${this.describe(argument2)}' does not satisfy '${parameter3.name} extends ${this.describe(constraint)}' on '${symbol.name}'.`,
43310
+ authored.pos
43311
+ );
43312
+ }
43313
+ return argument2;
43314
+ });
42513
43315
  }
42514
43316
  delegateTypeFromMockHandle(type) {
42515
43317
  if (type.kind !== "named" || type.typeId !== NEO_TEST_IDS.mockHandleType || type.typeArguments?.[0]?.kind !== "delegate") {
@@ -43437,8 +44239,10 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
43437
44239
  resolveFunctionStatement(expression, scope) {
43438
44240
  if (expression.kind !== "call") return null;
43439
44241
  const receiverValue = this.callReceiver(expression.callee, scope);
43440
- if (expression.typeArguments) return null;
43441
44242
  if (expression.argumentNames) return null;
44243
+ const typeArguments = expression.typeArguments;
44244
+ if (typeArguments !== void 0 && expression.callee.kind === "member" && expression.callee.receiver.kind === "ident" && expression.callee.receiver.name === NEOSCRIPT_LIST_TYPE_NAME)
44245
+ return null;
43442
44246
  if (expression.callee.kind === "member" && expression.callee.name === "TryConvert") {
43443
44247
  const conversion = this.resolveTileConversion(
43444
44248
  expression.callee,
@@ -43458,7 +44262,8 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
43458
44262
  expression.args,
43459
44263
  scope,
43460
44264
  expression.pos,
43461
- true
44265
+ true,
44266
+ typeArguments
43462
44267
  );
43463
44268
  if (result.pointer.type !== "callFunction" /* CallFunction */)
43464
44269
  throw new Error("Base call did not produce a function call.");
@@ -43469,6 +44274,12 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
43469
44274
  scope,
43470
44275
  receiverValue
43471
44276
  );
44277
+ if (callable2 !== null && typeArguments !== void 0) {
44278
+ throw new CompileError(
44279
+ "Type arguments are not supported for this call. Remove the explicit type arguments.",
44280
+ expression.pos
44281
+ );
44282
+ }
43472
44283
  if (callable2?.type.kind === "action") {
43473
44284
  return this.resolveActionCall(callable2, callable2.type, expression, scope);
43474
44285
  }
@@ -43521,13 +44332,15 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
43521
44332
  null,
43522
44333
  expression.args,
43523
44334
  scope,
43524
- expression.pos
44335
+ expression.pos,
44336
+ typeArguments
43525
44337
  );
43526
44338
  return {
43527
44339
  type: "callFunction" /* CallFunction */,
43528
44340
  memberId: global.id,
43529
44341
  receiver: { kind: "static", memberId: global.id },
43530
44342
  args: resolved2.args,
44343
+ ...resolved2.typeArguments ? { typeArguments: resolved2.typeArguments } : {},
43531
44344
  callSiteId: this.nextCallSite(expression.pos)
43532
44345
  };
43533
44346
  }
@@ -43544,7 +44357,8 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
43544
44357
  scope,
43545
44358
  expression.pos,
43546
44359
  false,
43547
- true
44360
+ true,
44361
+ typeArguments
43548
44362
  );
43549
44363
  if (result.pointer.type !== "callFunction" /* CallFunction */)
43550
44364
  throw new Error("Bare call did not produce a function call.");
@@ -43585,13 +44399,15 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
43585
44399
  { kind: "static", memberId: symbol2.id },
43586
44400
  expression.args,
43587
44401
  scope,
43588
- expression.pos
44402
+ expression.pos,
44403
+ typeArguments
43589
44404
  );
43590
44405
  return {
43591
44406
  type: "callFunction" /* CallFunction */,
43592
44407
  memberId: symbol2.id,
43593
44408
  receiver: { kind: "static", memberId: symbol2.id },
43594
44409
  args: resolved2.args,
44410
+ ...resolved2.typeArguments ? { typeArguments: resolved2.typeArguments } : {},
43595
44411
  callSiteId: this.nextCallSite(expression.pos)
43596
44412
  };
43597
44413
  }
@@ -43629,13 +44445,15 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
43629
44445
  },
43630
44446
  expression.args,
43631
44447
  scope,
43632
- expression.pos
44448
+ expression.pos,
44449
+ typeArguments
43633
44450
  );
43634
44451
  return {
43635
44452
  type: "callFunction" /* CallFunction */,
43636
44453
  ...type?.kind === "interface" ? { memberKey: symbol.schemaKey ?? symbol.name } : { memberId: symbol.id },
43637
44454
  receiver: { kind: "instance", pointer: receiver.pointer },
43638
44455
  args: resolved.args,
44456
+ ...resolved.typeArguments ? { typeArguments: resolved.typeArguments } : {},
43639
44457
  ...expression.callee.optional ? { optional: true } : {},
43640
44458
  callSiteId: this.nextCallSite(expression.pos)
43641
44459
  };
@@ -45264,6 +46082,14 @@ function toWireType(type, project) {
45264
46082
  };
45265
46083
  }
45266
46084
  case "typeParameter":
46085
+ if (type.ownerMemberId !== void 0 && type.index !== void 0) {
46086
+ return {
46087
+ type: 21 /* Generic */,
46088
+ required,
46089
+ ownerMemberId: type.ownerMemberId,
46090
+ index: type.index
46091
+ };
46092
+ }
45267
46093
  return {
45268
46094
  type: 21 /* Generic */,
45269
46095
  required,
@@ -45300,6 +46126,16 @@ function fromWireType(type) {
45300
46126
  if (type.type === 8 /* Enum */)
45301
46127
  return { kind: "named", typeId: type.enumId, nullable: nullable2 };
45302
46128
  if (type.type === 21 /* Generic */) {
46129
+ if ("ownerMemberId" in type) {
46130
+ return {
46131
+ kind: "typeParameter",
46132
+ id: functionTypeParameterId(type.ownerMemberId, type.index),
46133
+ name: `T${type.index}`,
46134
+ ownerMemberId: type.ownerMemberId,
46135
+ index: type.index,
46136
+ nullable: nullable2
46137
+ };
46138
+ }
45303
46139
  return {
45304
46140
  kind: "typeParameter",
45305
46141
  id: type.genericParamId,
@@ -45938,9 +46774,8 @@ function resolveNeoScriptType(type, context, project) {
45938
46774
  }
45939
46775
  const declaringTypeRef = context.declaringType === void 0 ? context.thisClass : context.declaringType;
45940
46776
  const declaringType = declaringTypeRef?.kind === "named" ? project.typeById.get(declaringTypeRef.typeId) : void 0;
45941
- const typeParameter2 = declaringType?.typeParameters?.find(
45942
- (candidate) => candidate.name === type.name
45943
- );
46777
+ const byName = (candidate) => candidate.name === type.name;
46778
+ const typeParameter2 = context.typeParameters?.find(byName) ?? declaringType?.typeParameters?.find(byName);
45944
46779
  if (typeParameter2?.type.kind === "typeParameter") {
45945
46780
  resolved = typeParameter2.type;
45946
46781
  break;
@@ -46015,6 +46850,20 @@ function resolveNeoScriptType(type, context, project) {
46015
46850
  }
46016
46851
  return { ...resolved, nullable: !type.required };
46017
46852
  }
46853
+ function methodGroupTypeArguments(symbol, mockTarget, pos) {
46854
+ return (symbol.typeParameters ?? []).map((parameter3) => {
46855
+ const declared = parameter3.type;
46856
+ const fallback = declared.kind === "typeParameter" ? declared.defaultType : void 0;
46857
+ if (fallback !== void 0) return fallback;
46858
+ if (!mockTarget) {
46859
+ throw new CompileError(
46860
+ `Function '${symbol.name}' can be a delegate target only when every type parameter has a default; '${parameter3.name}' has none.`,
46861
+ pos
46862
+ );
46863
+ }
46864
+ return declared.kind === "typeParameter" && declared.constraint ? declared.constraint : { kind: "primitive", name: "unknown" };
46865
+ });
46866
+ }
46018
46867
  function wrappedTypeParameterMessage(target, project) {
46019
46868
  for (const argument2 of target.typeArguments ?? []) {
46020
46869
  if (argument2.kind === "typeParameter") continue;
@@ -46045,6 +46894,11 @@ function intersectCollectionWritability(left, right) {
46045
46894
  const writable = (value) => value === "local" /* Local */ || value === "save" /* Save */ || value === "session" /* Session */ || value === "runtime" /* Runtime */;
46046
46895
  return writable(left) && writable(right) ? "runtime" /* Runtime */ : "readOnly" /* ReadOnly */;
46047
46896
  }
46897
+ function callReceiver(receiverType, declaring) {
46898
+ if (receiverType?.kind !== "named") return void 0;
46899
+ if (declaring === void 0) return void 0;
46900
+ return { type: receiverType, declaring };
46901
+ }
46048
46902
 
46049
46903
  // ../packages/neoscript-language/src/compiler.ts
46050
46904
  function compileNeoScriptStrict(document2, context, options = {}) {
@@ -47957,15 +48811,30 @@ function isInterfaceFunctionMember(member) {
47957
48811
  function interfacePropertyIsSettable(member) {
47958
48812
  return member.accessors === 1 /* GetSet */;
47959
48813
  }
47960
- function containsForbiddenMemberTypeInfo(typeInfo) {
48814
+ function containsForbiddenMemberTypeInfo(typeInfo, own) {
47961
48815
  if (typeInfo.type === NS_TYPE_UNKNOWN) return true;
47962
- if (typeInfo.type === 21 /* Generic */) return true;
48816
+ if (typeInfo.type === 21 /* Generic */) {
48817
+ if (isClassGenericParamTypeInfo(typeInfo)) return true;
48818
+ if (own === null) return true;
48819
+ if (typeInfo.ownerMemberId !== own.ownerMemberId) return true;
48820
+ return typeInfo.index >= own.count;
48821
+ }
47963
48822
  if (typeInfo.type === 6 /* List */ || typeInfo.type === 28 /* Set */ || typeInfo.type === 5 /* Dictionary */ || typeInfo.type === 9 /* Lookup */) {
47964
- return containsForbiddenMemberTypeInfo(typeInfo.entryTypeInfo);
48823
+ return containsForbiddenMemberTypeInfo(typeInfo.entryTypeInfo, own);
48824
+ }
48825
+ if (typeInfo.type === 25 /* NSDelegate */) {
48826
+ return containsForbiddenMemberTypeInfo(typeInfo.returnTypeInfo, own) || typeInfo.argumentTypes.some(
48827
+ (argument2) => containsForbiddenMemberTypeInfo(argument2, own)
48828
+ );
48829
+ }
48830
+ if (typeInfo.type === 26 /* NSAction */) {
48831
+ return typeInfo.argumentTypes.some(
48832
+ (argument2) => containsForbiddenMemberTypeInfo(argument2, own)
48833
+ );
47965
48834
  }
47966
48835
  if (typeInfo.type === 7 /* Class */ && typeInfo.typeArguments) {
47967
48836
  return Object.values(typeInfo.typeArguments).some(
47968
- containsForbiddenMemberTypeInfo
48837
+ (argument2) => containsForbiddenMemberTypeInfo(argument2, own)
47969
48838
  );
47970
48839
  }
47971
48840
  return false;
@@ -47981,17 +48850,23 @@ function isNeoInterfaceMember(value) {
47981
48850
  if (member.kind === void 0 || member.kind === 0 /* Property */) {
47982
48851
  const property2 = value;
47983
48852
  if (!isNSTypeInfo(property2.typeInfo)) return false;
47984
- if (containsForbiddenMemberTypeInfo(property2.typeInfo)) return false;
48853
+ if (containsForbiddenMemberTypeInfo(property2.typeInfo, null)) return false;
47985
48854
  return property2.accessors === void 0 || property2.accessors === 0 /* Get */ || property2.accessors === 1 /* GetSet */;
47986
48855
  }
47987
48856
  if (member.kind !== 1 /* Function */) return false;
47988
48857
  const fn = value;
47989
48858
  if (!isNSFunctionReturnTypeInfo(fn.returnTypeInfo)) return false;
47990
- if (containsForbiddenMemberTypeInfo(fn.returnTypeInfo)) return false;
48859
+ if (fn.genericParams !== void 0 && !isFunctionGenericParams(fn.genericParams, isValidSchemaBindingIdentifier))
48860
+ return false;
48861
+ const own = {
48862
+ ownerMemberId: member.id,
48863
+ count: fn.genericParams?.length ?? 0
48864
+ };
48865
+ if (containsForbiddenMemberTypeInfo(fn.returnTypeInfo, own)) return false;
47991
48866
  if (!Array.isArray(fn.argumentTypes)) return false;
47992
48867
  for (const argumentType of fn.argumentTypes) {
47993
48868
  if (!isNSFunctionArgumentTypeInfo(argumentType)) return false;
47994
- if (containsForbiddenMemberTypeInfo(argumentType)) return false;
48869
+ if (containsForbiddenMemberTypeInfo(argumentType, own)) return false;
47995
48870
  }
47996
48871
  if (fn.dispatch !== void 0 && fn.dispatch !== 0 /* Synchronous */ && fn.dispatch !== 1 /* Asynchronous */)
47997
48872
  return false;
@@ -48461,6 +49336,11 @@ function createNeoScriptDocumentContextInScope(context, projectOverride) {
48461
49336
  ...baseClass ? { baseClass } : {},
48462
49337
  ...returnType ? { returnType } : {},
48463
49338
  ...parameters ? { parameters } : {},
49339
+ ...context.memberId === void 0 || documentKind !== "function" ? {} : functionTypeParameterSymbols(
49340
+ context.memberId,
49341
+ declaredFunctionGenericParams(context, context.memberId),
49342
+ context
49343
+ ),
48464
49344
  ...context.functionDeferred !== void 0 ? { deferred: context.functionDeferred } : {},
48465
49345
  ...functionName ? { functionName } : {},
48466
49346
  ...context.dialogueContext ? {
@@ -48880,6 +49760,11 @@ function memberToSymbol(record4, schemaKey, containingClass, ownerClassId, index
48880
49760
  kind: authoredCallable.kind === 23 /* NSFunction */ ? "function" : "method",
48881
49761
  type: returnType,
48882
49762
  returnType,
49763
+ ...functionTypeParameterSymbols(
49764
+ record4.id,
49765
+ authoredCallable.genericParams,
49766
+ context
49767
+ ),
48883
49768
  parameters: authoredCallable.argumentTypes.map(
48884
49769
  (argument2, argumentIndex) => ({
48885
49770
  id: `${record4.id}:argument:${argumentIndex}`,
@@ -49069,6 +49954,7 @@ function interfaceMemberToSymbol(neoInterface, key, member, context, inherited)
49069
49954
  kind: "function",
49070
49955
  type: returnType,
49071
49956
  returnType,
49957
+ ...functionTypeParameterSymbols(member.id, member.genericParams, context),
49072
49958
  parameters: member.argumentTypes.map((argument2, index) => ({
49073
49959
  id: `${neoInterface.id}:member:${key}:argument:${index}`,
49074
49960
  name: argument2.name,
@@ -49591,6 +50477,9 @@ function toLanguageType(type, context, genericEnvironment) {
49591
50477
  nullable: false
49592
50478
  };
49593
50479
  case 21 /* Generic */:
50480
+ if (!isClassGenericParamTypeInfo(type)) {
50481
+ return functionGenericLanguageType(type, required, context);
50482
+ }
49594
50483
  return genericParameterLanguageType(
49595
50484
  type.genericParamId,
49596
50485
  required,
@@ -49599,6 +50488,64 @@ function toLanguageType(type, context, genericEnvironment) {
49599
50488
  );
49600
50489
  }
49601
50490
  }
50491
+ var INTERFACE_FUNCTION_GENERICS = /* @__PURE__ */ new WeakMap();
50492
+ function declaredFunctionGenericParams(context, ownerMemberId) {
50493
+ const member = analyzerMemberById(context, ownerMemberId);
50494
+ if (member !== null) return functionGenericParamsOf(member);
50495
+ const interfaces = context.vm.interfaces ?? [];
50496
+ let byMember = INTERFACE_FUNCTION_GENERICS.get(interfaces);
50497
+ if (byMember === void 0) {
50498
+ const index = /* @__PURE__ */ new Map();
50499
+ for (const neoInterface of interfaces) {
50500
+ for (const interfaceMember of Object.values(neoInterface.members)) {
50501
+ if (!isInterfaceFunctionMember(interfaceMember)) continue;
50502
+ if (interfaceMember.genericParams === void 0) continue;
50503
+ index.set(interfaceMember.id, interfaceMember.genericParams);
50504
+ }
50505
+ }
50506
+ byMember = index;
50507
+ INTERFACE_FUNCTION_GENERICS.set(interfaces, byMember);
50508
+ }
50509
+ return byMember.get(ownerMemberId);
50510
+ }
50511
+ function functionGenericLanguageType(type, required, context) {
50512
+ return functionTypeParameterRef(
50513
+ type.ownerMemberId,
50514
+ type.index,
50515
+ declaredFunctionGenericParams(context, type.ownerMemberId)?.[type.index],
50516
+ required,
50517
+ context
50518
+ );
50519
+ }
50520
+ function functionTypeParameterRef(ownerMemberId, index, parameter3, required, context) {
50521
+ const id = functionTypeParameterId(ownerMemberId, index);
50522
+ return {
50523
+ kind: "typeParameter",
50524
+ id,
50525
+ name: parameter3?.name ?? id,
50526
+ ownerMemberId,
50527
+ index,
50528
+ ...parameter3?.constraint ? { constraint: toLanguageType(parameter3.constraint, context) } : {},
50529
+ ...parameter3?.defaultType ? { defaultType: toLanguageType(parameter3.defaultType, context) } : {},
50530
+ nullable: !required
50531
+ };
50532
+ }
50533
+ function functionTypeParameterSymbols(ownerMemberId, parameters, context) {
50534
+ if (parameters === void 0) return {};
50535
+ return {
50536
+ typeParameters: parameters.map((parameter3, index) => ({
50537
+ id: functionTypeParameterId(ownerMemberId, index),
50538
+ name: parameter3.name,
50539
+ type: functionTypeParameterRef(
50540
+ ownerMemberId,
50541
+ index,
50542
+ parameter3,
50543
+ true,
50544
+ context
50545
+ )
50546
+ }))
50547
+ };
50548
+ }
49602
50549
  function genericParameterLanguageType(genericParamId, required, context, genericEnvironment, visiting = /* @__PURE__ */ new Set()) {
49603
50550
  const environmentEntry = genericEnvironment?.get(genericParamId);
49604
50551
  if (environmentEntry?.kind === "member") {
@@ -52812,7 +53759,6 @@ var TILE_CLASS_LEVEL_KEYS = worldSystemSchemaFieldsForKind(
52812
53759
  ).flatMap(
52813
53760
  (field) => field.mutability === 1 /* ReadOnly */ ? [field.schemaKey] : []
52814
53761
  );
52815
- var WORLD_PLACEMENT_ASSET_KIND = /* @__PURE__ */ new Map([[NeoWorldSystemClassKind.Object, NeoWorldSystemClassKind.Object]]);
52816
53762
 
52817
53763
  // ../src/database/general-function-call-ir-source-recompile.ts
52818
53764
  var VOID_ACTION_TYPE_INFO = {
@@ -52986,6 +53932,7 @@ var SCHEMA_DOCUMENT_FIELD_CONTRACTS = {
52986
53932
  "setterCode",
52987
53933
  "returnTypeInfo",
52988
53934
  "argumentTypes",
53935
+ "genericParams",
52989
53936
  "dispatch",
52990
53937
  "bodyMode",
52991
53938
  "effect",
@@ -53060,6 +54007,7 @@ var SCHEMA_DOCUMENT_FIELD_CONTRACTS = {
53060
54007
  code: "nullIsAbsentOnFullMember",
53061
54008
  templateId: "nullIsAbsentOnFullMember",
53062
54009
  setterCode: "nullIsAbsentOnFullMember",
54010
+ genericParams: "nullOrEmptyArrayIsAbsent",
53063
54011
  dispatch: {
53064
54012
  kind: "absentMeansDefault",
53065
54013
  defaultValue: 0
@@ -53457,6 +54405,13 @@ function normalizeDocumentFields(recordKind, value) {
53457
54405
  normalizeTypeInfoBindings(argument2);
53458
54406
  }
53459
54407
  }
54408
+ if (Array.isArray(normalized.genericParams)) {
54409
+ for (const parameter3 of normalized.genericParams) {
54410
+ if (!isRecord2(parameter3)) continue;
54411
+ normalizeTypeInfoBindings(parameter3.constraint);
54412
+ normalizeTypeInfoBindings(parameter3.defaultType);
54413
+ }
54414
+ }
53460
54415
  stripCompiledInitializer(normalized.defaultValue);
53461
54416
  }
53462
54417
  if (recordKind === "constructor") {
@@ -54690,6 +55645,10 @@ function schemaTypeOptionsAtDepth(depth) {
54690
55645
  ownerClassId: nonEmptyString,
54691
55646
  genericParamId: nonEmptyString
54692
55647
  }),
55648
+ nullableTypeSchema("functionGeneric", {
55649
+ ownerMemberId: nonEmptyString,
55650
+ index: pipe(number(), integer2(), minValue(0))
55651
+ }),
54693
55652
  nullableTypeSchema("enum", {
54694
55653
  enumId: nonEmptyString
54695
55654
  }),
@@ -54935,10 +55894,21 @@ var schemaListColumnSchema = strictObject({
54935
55894
  frozen: boolean2(),
54936
55895
  wrapContent: boolean2()
54937
55896
  });
55897
+ var schemaFunctionGenericParameterSchema = strictObject({
55898
+ name: nonEmptyString,
55899
+ constraint: nullable(schemaTypeSchema),
55900
+ default: nullable(schemaTypeSchema)
55901
+ });
54938
55902
  var callableEntries = {
54939
55903
  returnType: schemaFunctionReturnTypeSchema,
54940
55904
  arguments: array(schemaFunctionArgumentSchema)
54941
55905
  };
55906
+ var genericCallableEntries = {
55907
+ ...callableEntries,
55908
+ genericParams: optional(
55909
+ pipe(array(schemaFunctionGenericParameterSchema), minLength(1))
55910
+ )
55911
+ };
54942
55912
  var functionEffectSchema = optional(picklist(["none", "auto"]));
54943
55913
  var schemaMemberSchema = variant("kind", [
54944
55914
  ...simpleMemberSchemas,
@@ -55018,12 +55988,12 @@ var schemaMemberSchema = variant("kind", [
55018
55988
  templateId: nullableId
55019
55989
  }),
55020
55990
  memberSchema("function", {
55021
- ...callableEntries,
55991
+ ...genericCallableEntries,
55022
55992
  deferred: boolean2(),
55023
55993
  effect: functionEffectSchema
55024
55994
  }),
55025
55995
  memberSchema("scriptFunction", {
55026
- ...callableEntries,
55996
+ ...genericCallableEntries,
55027
55997
  deferred: boolean2(),
55028
55998
  effect: functionEffectSchema,
55029
55999
  bodyMode: optional(literal2("ui")),
@@ -55486,6 +56456,10 @@ function memberFromDocument(record4, members, owners, classNames, context) {
55486
56456
  record4,
55487
56457
  source.span
55488
56458
  ),
56459
+ ...documentGenericParamsToManifest(
56460
+ field("genericParams", void 0),
56461
+ record4
56462
+ ),
55489
56463
  deferred: ordinalValue(
55490
56464
  field("dispatch", 0),
55491
56465
  FUNCTION_DISPATCH,
@@ -55776,6 +56750,11 @@ function memberToDocumentFields(member, baseData) {
55776
56750
  fields.returnTypeInfo = manifestReturnTypeToDocument(member.returnType);
55777
56751
  fields.argumentTypes = member.arguments.map(manifestArgumentToDocument);
55778
56752
  }
56753
+ if (member.genericParams !== void 0) {
56754
+ fields.genericParams = manifestGenericParamsToDocument(
56755
+ member.genericParams
56756
+ );
56757
+ }
55779
56758
  if (member.deferred || isOverride) {
55780
56759
  fields.dispatch = member.deferred ? 1 : 0;
55781
56760
  }
@@ -55923,6 +56902,32 @@ function optionalDocumentType(value, record4, path) {
55923
56902
  if (value === null || value === void 0) return null;
55924
56903
  return documentTypeToManifest(value, record4, path);
55925
56904
  }
56905
+ function documentGenericParamsToManifest(value, record4) {
56906
+ if (value === void 0) return {};
56907
+ if (!Array.isArray(value)) {
56908
+ throw invalidDocument(record4, "genericParams", "must be an array");
56909
+ }
56910
+ return {
56911
+ genericParams: value.map((entry, index) => {
56912
+ const path = `genericParams[${index}]`;
56913
+ if (!isRecord3(entry))
56914
+ throw invalidDocument(record4, path, "must be an object");
56915
+ return {
56916
+ name: requiredStringValue(entry.name, record4, `${path}.name`),
56917
+ constraint: optionalDocumentType(
56918
+ entry.constraint,
56919
+ record4,
56920
+ `${path}.constraint`
56921
+ ),
56922
+ default: optionalDocumentType(
56923
+ entry.defaultType,
56924
+ record4,
56925
+ `${path}.defaultType`
56926
+ )
56927
+ };
56928
+ })
56929
+ };
56930
+ }
55926
56931
  function documentReturnTypeToManifest(value, record4, path) {
55927
56932
  if (isRecord3(value) && value.type === "Void") {
55928
56933
  return { kind: "void", nullable: false };
@@ -55965,6 +56970,18 @@ function documentTypeToManifest(value, record4, path) {
55965
56970
  )
55966
56971
  };
55967
56972
  }
56973
+ if (kind === MEMBER_KIND.Generic && "ownerMemberId" in typeInfo) {
56974
+ return {
56975
+ kind: "functionGeneric",
56976
+ nullable: nullable2,
56977
+ ownerMemberId: requiredStringValue(
56978
+ typeInfo.ownerMemberId,
56979
+ record4,
56980
+ `${path}.ownerMemberId`
56981
+ ),
56982
+ index: requiredNumberValue(typeInfo.index, record4, `${path}.index`)
56983
+ };
56984
+ }
55968
56985
  if (kind === MEMBER_KIND.Generic) {
55969
56986
  return {
55970
56987
  kind: "generic",
@@ -56098,6 +57115,15 @@ function documentTypeToManifest(value, record4, path) {
56098
57115
  `unsupported type-info discriminator ${kind}`
56099
57116
  );
56100
57117
  }
57118
+ function manifestGenericParamsToDocument(params) {
57119
+ return params.map(
57120
+ (parameter3) => omitUndefined({
57121
+ name: parameter3.name,
57122
+ constraint: parameter3.constraint ? manifestTypeToDocument(parameter3.constraint) : void 0,
57123
+ defaultType: parameter3.default ? manifestTypeToDocument(parameter3.default) : void 0
57124
+ })
57125
+ );
57126
+ }
56101
57127
  function manifestArgumentToDocument(argument2) {
56102
57128
  return {
56103
57129
  name: argument2.name,
@@ -56141,6 +57167,14 @@ function manifestTypeToDocument(type) {
56141
57167
  genericParamId: type.genericParamId
56142
57168
  };
56143
57169
  }
57170
+ if (type.kind === "functionGeneric") {
57171
+ return {
57172
+ type: MEMBER_KIND.Generic,
57173
+ required,
57174
+ ownerMemberId: type.ownerMemberId,
57175
+ index: type.index
57176
+ };
57177
+ }
56144
57178
  if (type.kind === "enum") {
56145
57179
  return { type: MEMBER_KIND.Enum, required, enumId: type.enumId };
56146
57180
  }
@@ -56812,6 +57846,7 @@ function interfaceFromDocument(record4, context) {
56812
57846
  record4,
56813
57847
  source.span
56814
57848
  ),
57849
+ ...documentGenericParamsToManifest(member.genericParams, record4),
56815
57850
  deferred: ordinalValue(
56816
57851
  member.dispatch ?? 0,
56817
57852
  ["synchronous", "asynchronous"],
@@ -56848,6 +57883,11 @@ function interfaceToDocument(neoInterface) {
56848
57883
  ...member.docsText === void 0 ? {} : { docsText: member.docsText },
56849
57884
  returnTypeInfo: manifestReturnTypeToDocument(member.returnType),
56850
57885
  argumentTypes: member.arguments.map(manifestArgumentToDocument),
57886
+ ...member.genericParams === void 0 ? {} : {
57887
+ genericParams: manifestGenericParamsToDocument(
57888
+ member.genericParams
57889
+ )
57890
+ },
56851
57891
  ...member.deferred ? { dispatch: 1 } : {},
56852
57892
  ...accessToDocument(member.accessModifier)
56853
57893
  };
@@ -57756,7 +58796,7 @@ var INITIALIZER_KEY_PLACEHOLDER = new RegExp(
57756
58796
 
57757
58797
  // ../packages/manifest/schema-contract/registry.mjs
57758
58798
  var PROJECT_SCHEMA_CONTRACT = Object.freeze({
57759
- cliVersion: "0.79.1",
58799
+ cliVersion: "0.81.0",
57760
58800
  projectFileUploadBatchSize: 32,
57761
58801
  documentRecords: {
57762
58802
  member: {
@@ -57806,6 +58846,7 @@ var PROJECT_SCHEMA_CONTRACT = Object.freeze({
57806
58846
  "setterCode",
57807
58847
  "returnTypeInfo",
57808
58848
  "argumentTypes",
58849
+ "genericParams",
57809
58850
  "dispatch",
57810
58851
  "bodyMode",
57811
58852
  // P97 §1.1. No normalization rule, like `distribution`: absence means
@@ -57850,6 +58891,7 @@ var PROJECT_SCHEMA_CONTRACT = Object.freeze({
57850
58891
  code: "nullIsAbsentOnFullMember",
57851
58892
  templateId: "nullIsAbsentOnFullMember",
57852
58893
  setterCode: "nullIsAbsentOnFullMember",
58894
+ genericParams: "nullOrEmptyArrayIsAbsent",
57853
58895
  dispatch: { kind: "absentMeansDefault", defaultValue: 0 },
57854
58896
  bodyMode: { kind: "absentMeansDefault", defaultValue: 0 },
57855
58897
  uiAction: "nullIsAbsentOnFullMember"
@@ -59595,7 +60637,7 @@ var SCRIPT_COLLECTION_READERS = {
59595
60637
  };
59596
60638
 
59597
60639
  // ../src/models/exports/unity-codegen-revision.ts
59598
- var UNITY_CODEGEN_REVISION = "49b24ee52b3e40b147f73d6d58f5c01eacc9f304463b8689d3d92ae57b14aef0";
60640
+ var UNITY_CODEGEN_REVISION = "d4026a3848848c8507d45dd54b6d31c1a0588b17b64c35e3fe9b25c89eb2fc05";
59599
60641
 
59600
60642
  // src/export-cache.ts
59601
60643
  var CACHE_BUILD = JSON.stringify([
@@ -60042,23 +61084,53 @@ function mockResponse(environment, mock, selected, call) {
60042
61084
  if (selected.kind === "throw") {
60043
61085
  throw new NSGetterRuntimeError(selected.message);
60044
61086
  }
60045
- if (selected.kind === "implementation") {
60046
- return {
60047
- handled: true,
60048
- value: call.invokeDelegate(
60049
- bindNeoScriptDelegateToContext(
60050
- selected.delegate,
60051
- environment.context
60052
- ),
60053
- mock.isStatic ? call.args : [call.receiver, ...call.args]
60054
- )
60055
- };
60056
- }
60057
61087
  return {
60058
61088
  handled: true,
60059
- value: selected.kind === "return" ? selected.value : null
61089
+ value: narrowMockResult(
61090
+ environment,
61091
+ mock,
61092
+ call,
61093
+ mockValue(environment, mock, selected, call)
61094
+ )
60060
61095
  };
60061
61096
  }
61097
+ function mockValue(environment, mock, selected, call) {
61098
+ if (selected.kind === "implementation") {
61099
+ return call.invokeDelegate(
61100
+ bindNeoScriptDelegateToContext(
61101
+ selected.delegate,
61102
+ environment.context
61103
+ ),
61104
+ mock.isStatic ? call.args : [call.receiver, ...call.args]
61105
+ );
61106
+ }
61107
+ return selected.kind === "return" ? selected.value : null;
61108
+ }
61109
+ function narrowMockResult(environment, mock, call, value) {
61110
+ if (call.typeArguments === void 0 || call.member === null) return value;
61111
+ const narrowed = narrowGenericCallResult(
61112
+ value,
61113
+ call.member,
61114
+ call.typeArguments,
61115
+ environment.context
61116
+ );
61117
+ if ("value" in narrowed) return narrowed.value;
61118
+ const typeArguments = call.typeArguments.map((typeInfo) => typeArgumentLabel(environment, typeInfo)).join(", ");
61119
+ throw new NeoTestAssertionError(
61120
+ `Mock for Function '${mock.memberId}' returned a value that isn't the return type of '${call.member.name}<${typeArguments}>'.`
61121
+ );
61122
+ }
61123
+ function typeArgumentLabel(environment, typeInfo) {
61124
+ const vm = environment.context.vm;
61125
+ if (typeInfo.type === 7 /* Class */) {
61126
+ return vm.classes.find((schemaClass2) => schemaClass2.id === typeInfo.classId)?.name ?? typeInfo.classId;
61127
+ }
61128
+ if (typeInfo.type === 8 /* Enum */) {
61129
+ return vm.enums.find((e) => e.id === typeInfo.enumId)?.name ?? typeInfo.enumId;
61130
+ }
61131
+ if (typeInfo.type === NS_TYPE_UNKNOWN) return NS_TYPE_UNKNOWN;
61132
+ return MemberKind[typeInfo.type];
61133
+ }
60062
61134
  function partialObjectMatch(actual, expected) {
60063
61135
  if (!isRecord4(expected)) return isDeepStrictEqual(actual, expected);
60064
61136
  if (!isRecord4(actual)) return false;