@neocompose/cli 0.76.3 → 0.77.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1461,36 +1461,36 @@ function isNeoSchemaClass(value) {
1461
1461
  }
1462
1462
 
1463
1463
  // ../packages/models/src/members/member-kind-enum.ts
1464
- var MemberKind = /* @__PURE__ */ ((MemberKind8) => {
1465
- MemberKind8[MemberKind8["Null"] = 0] = "Null";
1466
- MemberKind8[MemberKind8["Bool"] = 1] = "Bool";
1467
- MemberKind8[MemberKind8["Int"] = 2] = "Int";
1468
- MemberKind8[MemberKind8["String"] = 3] = "String";
1469
- MemberKind8[MemberKind8["Float"] = 4] = "Float";
1470
- MemberKind8[MemberKind8["Dictionary"] = 5] = "Dictionary";
1471
- MemberKind8[MemberKind8["List"] = 6] = "List";
1472
- MemberKind8[MemberKind8["Class"] = 7] = "Class";
1473
- MemberKind8[MemberKind8["Enum"] = 8] = "Enum";
1474
- MemberKind8[MemberKind8["Lookup"] = 9] = "Lookup";
1475
- MemberKind8[MemberKind8["NSProperty"] = 10] = "NSProperty";
1476
- MemberKind8[MemberKind8["Sprite"] = 11] = "Sprite";
1477
- MemberKind8[MemberKind8["Audio"] = 12] = "Audio";
1478
- MemberKind8[MemberKind8["Function"] = 13] = "Function";
1479
- MemberKind8[MemberKind8["Vector2"] = 14] = "Vector2";
1480
- MemberKind8[MemberKind8["Vector2Int"] = 15] = "Vector2Int";
1481
- MemberKind8[MemberKind8["Vector3"] = 16] = "Vector3";
1482
- MemberKind8[MemberKind8["Vector3Int"] = 17] = "Vector3Int";
1483
- MemberKind8[MemberKind8["DialogueLookup"] = 18] = "DialogueLookup";
1484
- MemberKind8[MemberKind8["Color"] = 19] = "Color";
1485
- MemberKind8[MemberKind8["Decimal"] = 20] = "Decimal";
1486
- MemberKind8[MemberKind8["Generic"] = 21] = "Generic";
1487
- MemberKind8[MemberKind8["Interface"] = 22] = "Interface";
1488
- MemberKind8[MemberKind8["NSFunction"] = 23] = "NSFunction";
1489
- MemberKind8[MemberKind8["FunctionRef"] = 24] = "FunctionRef";
1490
- MemberKind8[MemberKind8["NSDelegate"] = 25] = "NSDelegate";
1491
- MemberKind8[MemberKind8["NSAction"] = 26] = "NSAction";
1492
- MemberKind8[MemberKind8["Variant"] = 27] = "Variant";
1493
- return MemberKind8;
1464
+ var MemberKind = /* @__PURE__ */ ((MemberKind7) => {
1465
+ MemberKind7[MemberKind7["Null"] = 0] = "Null";
1466
+ MemberKind7[MemberKind7["Bool"] = 1] = "Bool";
1467
+ MemberKind7[MemberKind7["Int"] = 2] = "Int";
1468
+ MemberKind7[MemberKind7["String"] = 3] = "String";
1469
+ MemberKind7[MemberKind7["Float"] = 4] = "Float";
1470
+ MemberKind7[MemberKind7["Dictionary"] = 5] = "Dictionary";
1471
+ MemberKind7[MemberKind7["List"] = 6] = "List";
1472
+ MemberKind7[MemberKind7["Class"] = 7] = "Class";
1473
+ MemberKind7[MemberKind7["Enum"] = 8] = "Enum";
1474
+ MemberKind7[MemberKind7["Lookup"] = 9] = "Lookup";
1475
+ MemberKind7[MemberKind7["NSProperty"] = 10] = "NSProperty";
1476
+ MemberKind7[MemberKind7["Sprite"] = 11] = "Sprite";
1477
+ MemberKind7[MemberKind7["Audio"] = 12] = "Audio";
1478
+ MemberKind7[MemberKind7["Function"] = 13] = "Function";
1479
+ MemberKind7[MemberKind7["Vector2"] = 14] = "Vector2";
1480
+ MemberKind7[MemberKind7["Vector2Int"] = 15] = "Vector2Int";
1481
+ MemberKind7[MemberKind7["Vector3"] = 16] = "Vector3";
1482
+ MemberKind7[MemberKind7["Vector3Int"] = 17] = "Vector3Int";
1483
+ MemberKind7[MemberKind7["DialogueLookup"] = 18] = "DialogueLookup";
1484
+ MemberKind7[MemberKind7["Color"] = 19] = "Color";
1485
+ MemberKind7[MemberKind7["Decimal"] = 20] = "Decimal";
1486
+ MemberKind7[MemberKind7["Generic"] = 21] = "Generic";
1487
+ MemberKind7[MemberKind7["Interface"] = 22] = "Interface";
1488
+ MemberKind7[MemberKind7["NSFunction"] = 23] = "NSFunction";
1489
+ MemberKind7[MemberKind7["FunctionRef"] = 24] = "FunctionRef";
1490
+ MemberKind7[MemberKind7["NSDelegate"] = 25] = "NSDelegate";
1491
+ MemberKind7[MemberKind7["NSAction"] = 26] = "NSAction";
1492
+ MemberKind7[MemberKind7["Variant"] = 27] = "Variant";
1493
+ return MemberKind7;
1494
1494
  })(MemberKind || {});
1495
1495
 
1496
1496
  // ../packages/models/src/members/member-kind-taxonomy.ts
@@ -4046,6 +4046,13 @@ function isNSVoidBody(value) {
4046
4046
  function parameterHasDefault(argument2) {
4047
4047
  return argument2.defaultValue !== void 0;
4048
4048
  }
4049
+ function unnamedArgumentTypes(argumentTypes) {
4050
+ return argumentTypes.map((argument2) => {
4051
+ const { name, ...typeInfo } = argument2;
4052
+ void name;
4053
+ return typeInfo;
4054
+ });
4055
+ }
4049
4056
  function hasAnyParameterDefault(argumentTypes) {
4050
4057
  return argumentTypes.some(parameterHasDefault);
4051
4058
  }
@@ -4124,6 +4131,15 @@ function typeInfosInvariantlyEqual(left, right) {
4124
4131
  if (left.keyEnumId !== right.keyEnumId) return false;
4125
4132
  return typeInfosInvariantlyEqual(left.entryTypeInfo, right.entryTypeInfo);
4126
4133
  }
4134
+ if (left.type === 25 /* NSDelegate */ && right.type === 25 /* NSDelegate */) {
4135
+ if (!typeInfosInvariantlyEqual(left.returnTypeInfo, right.returnTypeInfo)) {
4136
+ return false;
4137
+ }
4138
+ if (left.argumentTypes.length !== right.argumentTypes.length) return false;
4139
+ return left.argumentTypes.every(
4140
+ (argument2, index) => typeInfosInvariantlyEqual(argument2, right.argumentTypes[index])
4141
+ );
4142
+ }
4127
4143
  if (left.type === 26 /* NSAction */ && right.type === 26 /* NSAction */) {
4128
4144
  if (left.argumentTypes.length !== right.argumentTypes.length) return false;
4129
4145
  return left.argumentTypes.every(
@@ -4587,7 +4603,10 @@ function isMemberEnum(value) {
4587
4603
  if (!isWithId(value)) return false;
4588
4604
  return isWithId(value);
4589
4605
  }
4590
- function isMemberLookupBase(value) {
4606
+ function isLookupSelection(selection) {
4607
+ return selection === void 0 || selection === 0 /* Single */ || selection === 1 /* Multi */;
4608
+ }
4609
+ function isMemberCollectionLookupBase(value) {
4591
4610
  const v = asMemberBaseForKind(value, 9 /* Lookup */);
4592
4611
  if (v === null) return false;
4593
4612
  if (typeof v.collectionMemberId !== "string") return false;
@@ -4598,7 +4617,22 @@ function isMemberLookupBase(value) {
4598
4617
  if (v.declaredTypeInfo !== void 0 && v.declaredTypeInfo !== null && !isNSTypeInfo(v.declaredTypeInfo)) {
4599
4618
  return false;
4600
4619
  }
4601
- return v.selection === void 0 || v.selection === 0 /* Single */ || v.selection === 1 /* Multi */;
4620
+ return isLookupSelection(v.selection);
4621
+ }
4622
+ function isMemberTypeLookupBase(value) {
4623
+ const v = asMemberBaseForKind(value, 9 /* Lookup */);
4624
+ if (v === null) return false;
4625
+ if (v.collectionMemberId !== void 0) return false;
4626
+ if (v.collectionValueId !== void 0) return false;
4627
+ if (!isLookupTargetTypeInfo(v.declaredTypeInfo)) return false;
4628
+ return isLookupSelection(v.selection);
4629
+ }
4630
+ function isLookupTargetTypeInfo(value) {
4631
+ if (!isNSTypeInfo(value)) return false;
4632
+ return value.type === 7 /* Class */ || value.type === 21 /* Generic */;
4633
+ }
4634
+ function isMemberLookupBase(value) {
4635
+ return isMemberCollectionLookupBase(value) || isMemberTypeLookupBase(value);
4602
4636
  }
4603
4637
  function isMemberLookup(value) {
4604
4638
  if (!isMemberLookupBase(value)) return false;
@@ -8614,12 +8648,6 @@ function resolveParamAtChainIndex(chain, declarerIndex, paramId) {
8614
8648
  }
8615
8649
  return { kind: "unbound", paramId: cursor };
8616
8650
  }
8617
- function isClosedClass(classId, classes, draft) {
8618
- for (const entry of resolveGenericEnv(classId, classes, draft).values()) {
8619
- if (entry.kind === "unbound") return false;
8620
- }
8621
- return true;
8622
- }
8623
8651
  function resolveInstanceEnv(effectiveClassId, classArguments2, classes) {
8624
8652
  const env = resolveGenericEnv(effectiveClassId, classes);
8625
8653
  if (classArguments2 === void 0 || classArguments2 === null) {
@@ -8631,6 +8659,10 @@ function resolveInstanceEnv(effectiveClassId, classArguments2, classes) {
8631
8659
  if (existing !== void 0 && existing.kind !== "unbound") continue;
8632
8660
  env.set(paramId, { kind: "member", memberId: arg.memberId });
8633
8661
  }
8662
+ closeForwardedGenericParams(env);
8663
+ return env;
8664
+ }
8665
+ function closeForwardedGenericParams(env) {
8634
8666
  for (const [paramId, entry] of env) {
8635
8667
  if (entry.kind !== "unbound") continue;
8636
8668
  const seen = /* @__PURE__ */ new Set([paramId]);
@@ -8646,7 +8678,6 @@ function resolveInstanceEnv(effectiveClassId, classArguments2, classes) {
8646
8678
  targetParamId = target.paramId;
8647
8679
  }
8648
8680
  }
8649
- return env;
8650
8681
  }
8651
8682
  function firstUnboundParamId(env) {
8652
8683
  for (const entry of env.values()) {
@@ -9080,10 +9111,13 @@ function typeInfoFromArgumentSignature(signature) {
9080
9111
  ...dictionarySignature.keyEnumId === void 0 ? {} : { keyEnumId: dictionarySignature.keyEnumId }
9081
9112
  };
9082
9113
  }
9114
+ if (signature.type === 25 /* NSDelegate */) {
9115
+ return signature;
9116
+ }
9083
9117
  const typeInfo = { type: signature.type, required: signature.required };
9084
9118
  if (!isNSTypeInfo(typeInfo)) {
9085
9119
  throw new Error(
9086
- `substituteMember: generic binding kind ${signature.type} cannot appear in a NeoScript callable type.`
9120
+ `substituteMember: generic binding kind ${MemberKind[signature.type] ?? signature.type} cannot appear in a NeoScript callable type.`
9087
9121
  );
9088
9122
  }
9089
9123
  return typeInfo;
@@ -9173,6 +9207,20 @@ function typeArgumentSignatureOfMember(member, env, members, seen = /* @__PURE__
9173
9207
  entry: entrySignature(resolved.entryMemberId, env, members, seen)
9174
9208
  };
9175
9209
  }
9210
+ if (isMemberDelegateBase(resolved)) {
9211
+ return {
9212
+ type: 25 /* NSDelegate */,
9213
+ required,
9214
+ returnTypeInfo: substituteNestedTypeInfo(
9215
+ resolved.returnTypeInfo,
9216
+ env,
9217
+ members
9218
+ ),
9219
+ argumentTypes: unnamedArgumentTypes(resolved.argumentTypes).map(
9220
+ (argument2) => substituteNestedTypeInfo(argument2, env, members)
9221
+ )
9222
+ };
9223
+ }
9176
9224
  if (isMemberStringBase(resolved)) {
9177
9225
  return {
9178
9226
  type: 3 /* String */,
@@ -9260,6 +9308,12 @@ function signaturesEqual(a, b) {
9260
9308
  if (ad.keyEnumId !== bd.keyEnumId) return false;
9261
9309
  return signaturesEqual(ad.entry, bd.entry);
9262
9310
  }
9311
+ if (a.type === 25 /* NSDelegate */ && b.type === 25 /* NSDelegate */) {
9312
+ return typeInfosInvariantlyEqual(
9313
+ a,
9314
+ b
9315
+ );
9316
+ }
9263
9317
  return true;
9264
9318
  }
9265
9319
  function constructedSlotAccepts(slotMember, valueClassId, contextEnv, classes, members) {
@@ -9714,6 +9768,14 @@ function suppliedValueSettlesConstruction(member, value, context, path) {
9714
9768
  }
9715
9769
  return valueSettlesConstruction(member, { value }, context, path);
9716
9770
  }
9771
+ function genericParameterName(parameterId, classes) {
9772
+ for (const neoClass of classes) {
9773
+ for (const parameter3 of neoClass.genericParams ?? []) {
9774
+ if (parameter3.id === parameterId) return parameter3.name;
9775
+ }
9776
+ }
9777
+ return void 0;
9778
+ }
9717
9779
  function resolveConstructionTypeArguments(typeArguments, document2) {
9718
9780
  if (typeArguments === void 0) return void 0;
9719
9781
  const bindings = {};
@@ -9738,8 +9800,10 @@ function resolveConstructionTypeArguments(typeArguments, document2) {
9738
9800
  }
9739
9801
  }
9740
9802
  if (binding === void 0) {
9803
+ const parameter3 = genericParameterName(parameterId, document2.classes) ?? parameterId;
9804
+ const kind = typeof typeInfo.type === "number" ? MemberKind[typeInfo.type] : typeInfo.type;
9741
9805
  throw new Error(
9742
- `Construction type argument "${parameterId}" has no matching type descriptor in the document.`
9806
+ `Construction type argument "${parameter3}" (${kind}) has no matching type descriptor in the document.`
9743
9807
  );
9744
9808
  }
9745
9809
  bindings[parameterId] = {
@@ -12925,10 +12989,10 @@ function compiledConstructionTypeMembers(members, bodies, projectId) {
12925
12989
  } else if (type.type === 25 /* NSDelegate */) {
12926
12990
  return {
12927
12991
  returnTypeInfo: type.returnTypeInfo,
12928
- argumentTypes: type.argumentTypes
12992
+ argumentTypes: namedArguments(type.argumentTypes)
12929
12993
  };
12930
12994
  } else if (type.type === 26 /* NSAction */) {
12931
- return { argumentTypes: type.argumentTypes };
12995
+ return { argumentTypes: namedArguments(type.argumentTypes) };
12932
12996
  } else if (type.type === 22 /* Interface */ || type.type === 9 /* Lookup */ || type.type === 18 /* DialogueLookup */) {
12933
12997
  return null;
12934
12998
  } else {
@@ -12959,6 +13023,12 @@ function compiledConstructionTypeMembers(members, bodies, projectId) {
12959
13023
  for (const body of bodies) visit(body);
12960
13024
  return created;
12961
13025
  }
13026
+ function namedArguments(argumentTypes) {
13027
+ return argumentTypes.map((type, index) => ({
13028
+ ...type,
13029
+ name: `p${index + 1}`
13030
+ }));
13031
+ }
12962
13032
  function withCompiledConstructionTypes(document2, body) {
12963
13033
  const members = document2.members;
12964
13034
  const projectId = getField(document2.project, "id");
@@ -13905,6 +13975,132 @@ function changeListenerWriteEdit(write) {
13905
13975
  return write.operation === "clear" ? { kind: "replace", targets: [] } : { kind: write.operation, target: write.listener };
13906
13976
  }
13907
13977
 
13978
+ // ../packages/models/src/classes/constructor-parameter-settlement.ts
13979
+ function createConstructorSettlementResolver(view) {
13980
+ const classesById = new Map(
13981
+ view.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
13982
+ );
13983
+ const membersById = new Map(
13984
+ view.members.map((member) => [member.id, member])
13985
+ );
13986
+ const constructorsById = new Map(
13987
+ (view.constructors ?? []).map((constructor) => [
13988
+ constructor.id,
13989
+ constructor
13990
+ ])
13991
+ );
13992
+ const directResultByClassAndParameter = /* @__PURE__ */ new Map();
13993
+ const recordedResultByConstructorAndParameter = /* @__PURE__ */ new Map();
13994
+ const directSettlement = (classId, parameterName) => {
13995
+ const cacheKey = `${classId}\0${parameterName}`;
13996
+ if (directResultByClassAndParameter.has(cacheKey)) {
13997
+ return directResultByClassAndParameter.get(cacheKey) ?? null;
13998
+ }
13999
+ const visited = /* @__PURE__ */ new Set();
14000
+ let currentId = classId;
14001
+ while (currentId !== null && !visited.has(currentId)) {
14002
+ visited.add(currentId);
14003
+ const schemaClass2 = classesById.get(currentId);
14004
+ if (schemaClass2 === void 0) break;
14005
+ for (const [schemaKey, memberId] of Object.entries(
14006
+ schemaClass2.schema ?? {}
14007
+ )) {
14008
+ if (typeof memberId !== "string") continue;
14009
+ const member = membersById.get(memberId);
14010
+ const defaultRecord = asRecord(member?.defaultValue);
14011
+ const initRecord = asRecord(defaultRecord?.init);
14012
+ if (initRecord !== null && typeof initRecord.code === "string" && initRecord.code.trim() === parameterName) {
14013
+ const result = { schemaKey, memberId };
14014
+ directResultByClassAndParameter.set(cacheKey, result);
14015
+ return result;
14016
+ }
14017
+ }
14018
+ currentId = schemaClass2.extendsClassId ?? null;
14019
+ }
14020
+ directResultByClassAndParameter.set(cacheKey, null);
14021
+ return null;
14022
+ };
14023
+ const memberIdForSchemaKey = (classId, schemaKey) => {
14024
+ const visited = /* @__PURE__ */ new Set();
14025
+ let currentId = classId;
14026
+ while (currentId !== null && !visited.has(currentId)) {
14027
+ visited.add(currentId);
14028
+ const schemaClass2 = classesById.get(currentId);
14029
+ if (schemaClass2 === void 0) return null;
14030
+ const memberId = schemaClass2.schema?.[schemaKey];
14031
+ if (typeof memberId === "string") return memberId;
14032
+ currentId = schemaClass2.extendsClassId ?? null;
14033
+ }
14034
+ return null;
14035
+ };
14036
+ const recordedSettlement = (classId, parameterName, constructorId, resolving) => {
14037
+ const cacheKey = `${classId}\0${constructorId}\0${parameterName}`;
14038
+ if (recordedResultByConstructorAndParameter.has(cacheKey)) {
14039
+ return recordedResultByConstructorAndParameter.get(cacheKey) ?? null;
14040
+ }
14041
+ if (resolving.has(cacheKey)) return null;
14042
+ const constructor = constructorsById.get(constructorId);
14043
+ if (constructor?.classId !== classId) {
14044
+ recordedResultByConstructorAndParameter.set(cacheKey, null);
14045
+ return null;
14046
+ }
14047
+ const direct = directSettlement(classId, parameterName);
14048
+ if (direct !== null) {
14049
+ recordedResultByConstructorAndParameter.set(cacheKey, direct);
14050
+ return direct;
14051
+ }
14052
+ const schemaClass2 = classesById.get(classId);
14053
+ const baseClassId = schemaClass2?.extendsClassId;
14054
+ if (typeof baseClassId !== "string") {
14055
+ recordedResultByConstructorAndParameter.set(cacheKey, null);
14056
+ return null;
14057
+ }
14058
+ for (const field of constructor.baseInitializerFields ?? []) {
14059
+ const record4 = asRecord(field);
14060
+ if (typeof record4?.name !== "string" || typeof record4.code !== "string" || record4.code.trim() !== parameterName) {
14061
+ continue;
14062
+ }
14063
+ const memberId = memberIdForSchemaKey(baseClassId, record4.name);
14064
+ if (memberId !== null) {
14065
+ const result = { schemaKey: record4.name, memberId };
14066
+ recordedResultByConstructorAndParameter.set(cacheKey, result);
14067
+ return result;
14068
+ }
14069
+ }
14070
+ const baseConstructorId = classesById.get(baseClassId)?.requiredConstructorId;
14071
+ if (typeof baseConstructorId !== "string") {
14072
+ recordedResultByConstructorAndParameter.set(cacheKey, null);
14073
+ return null;
14074
+ }
14075
+ resolving.add(cacheKey);
14076
+ for (const argument2 of constructor.baseArguments ?? []) {
14077
+ const record4 = asRecord(argument2);
14078
+ if (typeof record4?.name !== "string" || typeof record4.code !== "string" || record4.code.trim() !== parameterName) {
14079
+ continue;
14080
+ }
14081
+ const result = recordedSettlement(
14082
+ baseClassId,
14083
+ record4.name,
14084
+ baseConstructorId,
14085
+ resolving
14086
+ );
14087
+ resolving.delete(cacheKey);
14088
+ recordedResultByConstructorAndParameter.set(cacheKey, result);
14089
+ return result;
14090
+ }
14091
+ resolving.delete(cacheKey);
14092
+ recordedResultByConstructorAndParameter.set(cacheKey, null);
14093
+ return null;
14094
+ };
14095
+ return (classId, parameterName, constructorId) => constructorId === void 0 ? directSettlement(classId, parameterName) : recordedSettlement(classId, parameterName, constructorId, /* @__PURE__ */ new Set());
14096
+ }
14097
+ function asRecord(value) {
14098
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
14099
+ return null;
14100
+ }
14101
+ return value;
14102
+ }
14103
+
13908
14104
  // ../packages/neoscript-runtime/src/neoscript/typed-aggregate-row-references.ts
13909
14105
  function visitTypedAggregateRowReferences(value, rawType, visitor) {
13910
14106
  visitor.beforeVisit?.();
@@ -13995,15 +14191,12 @@ function initializerOwnerContext(document2, valueId, rootOwners, valuesById, rec
13995
14191
  currentId = sourceValueId;
13996
14192
  lexicalRoot = rootOwners.get(sourceValueId) ?? lexicalRoot;
13997
14193
  }
13998
- if (lexicalRoot === void 0) {
14194
+ if (lexicalRoot === void 0 || isStaticMember(lexicalRoot)) {
13999
14195
  return { ownerClass: null, lexicalThisClass: null };
14000
14196
  }
14001
14197
  const lexicalRootId = getField(lexicalRoot, "id");
14002
14198
  const ownerClass = typeof lexicalRootId === "string" ? findSchemaPlacement(lexicalRootId, document2.classes)?.ownerClass ?? null : null;
14003
- return {
14004
- ownerClass,
14005
- lexicalThisClass: isStaticMember(lexicalRoot) === true ? null : ownerClass
14006
- };
14199
+ return { ownerClass, lexicalThisClass: ownerClass };
14007
14200
  }
14008
14201
  function isRecordValue(value) {
14009
14202
  if (value === null) return false;
@@ -18677,7 +18870,11 @@ function evalInstructions(instructions, scope, ctx, options) {
18677
18870
  }
18678
18871
  let targetTypeInfo = ins.target.typeInfo;
18679
18872
  if (lookupAssignment && targetTypeInfo.type !== 9 /* Lookup */ && targetTypeInfo.type !== 18 /* DialogueLookup */) {
18680
- targetTypeInfo = {
18873
+ targetTypeInfo = member.collectionMemberId === void 0 ? {
18874
+ type: 9 /* Lookup */,
18875
+ required: targetTypeInfo.required,
18876
+ entryTypeInfo: targetTypeInfo
18877
+ } : {
18681
18878
  type: 9 /* Lookup */,
18682
18879
  required: targetTypeInfo.required,
18683
18880
  entryTypeInfo: targetTypeInfo,
@@ -21172,6 +21369,7 @@ function runtimeGenericEnvForValueRow(row, ctx, visited = /* @__PURE__ */ new Se
21172
21369
  );
21173
21370
  overlayConcreteGenericEntries(env, parentEnv);
21174
21371
  overlayConcreteGenericEntries(env, envFromStamp(row.genericBindings));
21372
+ closeForwardedGenericParams(env);
21175
21373
  return env;
21176
21374
  }
21177
21375
  function runtimeParentGenericEnv(row, ctx, visited, readRow) {
@@ -21362,6 +21560,13 @@ function runtimeTypeInfoForMember(rawMember, env, ctx, seen) {
21362
21560
  };
21363
21561
  }
21364
21562
  if (isMemberLookup(member)) {
21563
+ if (member.collectionMemberId === void 0) {
21564
+ const entryTypeInfo2 = {
21565
+ ...substituteRuntimeTypeInfo(member.declaredTypeInfo, env, ctx),
21566
+ required: isMultiSelectionMember(member) ? true : false
21567
+ };
21568
+ return isMultiSelectionMember(member) ? { type: 9 /* Lookup */, required, entryTypeInfo: entryTypeInfo2 } : entryTypeInfo2;
21569
+ }
21365
21570
  const collection = evalMemberById(ctx.vm, member.collectionMemberId);
21366
21571
  if (collection === null) {
21367
21572
  throw new NSGetterRuntimeError(
@@ -21405,6 +21610,18 @@ function runtimeTypeInfoForMember(rawMember, env, ctx, seen) {
21405
21610
  ctx
21406
21611
  );
21407
21612
  }
21613
+ if (isMemberDelegateBase(member)) {
21614
+ return substituteRuntimeTypeInfo(
21615
+ {
21616
+ type: 25 /* NSDelegate */,
21617
+ required,
21618
+ returnTypeInfo: member.returnTypeInfo,
21619
+ argumentTypes: unnamedArgumentTypes(member.argumentTypes)
21620
+ },
21621
+ env,
21622
+ ctx
21623
+ );
21624
+ }
21408
21625
  if (member.kind === 13 /* Function */ || member.kind === 23 /* NSFunction */ || member.kind === 22 /* Interface */) {
21409
21626
  throw new NSGetterRuntimeError(
21410
21627
  `Member '${member.name}' cannot be used as a concrete generic value type.`
@@ -21910,8 +22127,17 @@ function dispatchSchemaMember(receiver, schemaKey, ctx) {
21910
22127
  return { kind: "ok", value: null };
21911
22128
  case "declaration": {
21912
22129
  const value = readDeclarationDefault(member, ctx);
21913
- if (value.matched) return { kind: "ok", value: value.value };
21914
- return { kind: "no-info", matchedMember: true };
22130
+ if (!value.matched) return { kind: "no-info", matchedMember: true };
22131
+ if (!isNSDelegateClosureValue(value.value))
22132
+ return { kind: "ok", value: value.value };
22133
+ return {
22134
+ kind: "ok",
22135
+ value: {
22136
+ ...value.value,
22137
+ [DELEGATE_LEXICAL_THIS]: receiver,
22138
+ [DELEGATE_LEXICAL_ROOT]: ctx.rootValue
22139
+ }
22140
+ };
21915
22141
  }
21916
22142
  case "missing":
21917
22143
  return { kind: "no-info", matchedMember: true };
@@ -24063,8 +24289,9 @@ function validateClassConstructorDescriptor(info, ctx, requireEveryRequiredField
24063
24289
  }
24064
24290
  const genericSlot = ctx.__constructionGenericSlots?.toReversed().find((slot) => slot.classId === classId) ?? ctx.__storedConstructionReplaySlot;
24065
24291
  const slotArguments = genericSlot?.classId === classId ? genericSlot.classArguments : void 0;
24292
+ const typeArguments = slotArguments === void 0 ? receiverClosedTypeArguments(info.schemaClassInfo.typeArguments, ctx) : void 0;
24066
24293
  const descriptorCache = evaluatorValueGeneration(ctx).constructorDescriptors;
24067
- const descriptorCacheKey = `${requireEveryRequiredField}:${ctx.storedConstructionReplay === true}:${JSON.stringify(slotArguments ?? info.schemaClassInfo.typeArguments ?? null)}`;
24294
+ const descriptorCacheKey = `${requireEveryRequiredField}:${ctx.storedConstructionReplay === true}:${JSON.stringify(slotArguments ?? typeArguments ?? null)}`;
24068
24295
  const cachedDescriptor = descriptorCache.get(info)?.get(descriptorCacheKey);
24069
24296
  if (cachedDescriptor !== void 0) return cachedDescriptor;
24070
24297
  const constructionDocument = {
@@ -24075,10 +24302,7 @@ function validateClassConstructorDescriptor(info, ctx, requireEveryRequiredField
24075
24302
  valueById: ctx.vm.databaseVM?.defaultValueById ?? ctx.vm.databaseVM?.valueById,
24076
24303
  memberById: evaluatorDefaultValueDocument(ctx).memberById
24077
24304
  };
24078
- const classArguments2 = slotArguments ?? resolveConstructionTypeArguments(
24079
- info.schemaClassInfo.typeArguments,
24080
- constructionDocument
24081
- );
24305
+ const classArguments2 = slotArguments ?? resolveConstructionTypeArguments(typeArguments, constructionDocument);
24082
24306
  const cacheDescriptor = (descriptor) => {
24083
24307
  const complete = {
24084
24308
  ...descriptor,
@@ -24190,6 +24414,33 @@ function validateClassConstructorDescriptor(info, ctx, requireEveryRequiredField
24190
24414
  }
24191
24415
  return cacheDescriptor({ schemaClass: schemaClass2, fields, instanceEnv, classArguments: classArguments2 });
24192
24416
  }
24417
+ function receiverClosedTypeArguments(typeArguments, ctx) {
24418
+ if (typeArguments === void 0) return void 0;
24419
+ let env = null;
24420
+ let closed = null;
24421
+ for (const [parameterId, typeInfo] of Object.entries(typeArguments)) {
24422
+ if (!typeInfoContainsGeneric(typeInfo)) continue;
24423
+ if (env === null) {
24424
+ const row = ctx.thisValueRowId ? readNeoScriptRuntimeRow(ctx, ctx.thisValueRowId) : trackedRowForValueReference(ctx.thisValue, ctx);
24425
+ if (row) {
24426
+ env = runtimeGenericEnvForValueRow(row, ctx, /* @__PURE__ */ new Set());
24427
+ } else if (ctx.__initializerGenericEnv !== void 0) {
24428
+ env = ctx.__initializerGenericEnv;
24429
+ } else {
24430
+ throw new NSGetterRuntimeError(
24431
+ "Cannot close a generic construction's type arguments without its Class receiver."
24432
+ );
24433
+ }
24434
+ }
24435
+ closed ??= { ...typeArguments };
24436
+ closed[parameterId] = substituteRuntimeTypeInfo(
24437
+ typeInfo,
24438
+ env,
24439
+ ctx
24440
+ );
24441
+ }
24442
+ return closed ?? typeArguments;
24443
+ }
24193
24444
  function validateConstructorFieldSlot(args) {
24194
24445
  const { schemaKey, ctx } = args;
24195
24446
  const rawMember = evalMemberById(ctx.vm, args.memberId);
@@ -24417,8 +24668,7 @@ function applyConstructorFields(args) {
24417
24668
  const existingId = rootRecord[schemaKey];
24418
24669
  const existing = typeof existingId === "string" ? createdById.get(existingId) : void 0;
24419
24670
  if (existing !== void 0 && isLiteralValueContent(existing) && !isMemberClassBase(member) && !isMemberListBase(member) && !isMemberDictionaryBase(member)) {
24420
- existing.value = value;
24421
- existing.updatedAt = Date.now();
24671
+ overwriteConstructedLiteral(existing, value, ctx);
24422
24672
  continue;
24423
24673
  }
24424
24674
  const materialized = materializeConstructorArgumentValue({
@@ -24433,6 +24683,14 @@ function applyConstructorFields(args) {
24433
24683
  rootRecord[schemaKey] = materialized.id;
24434
24684
  }
24435
24685
  }
24686
+ function overwriteConstructedLiteral(row, value, ctx) {
24687
+ const references = ctx.__indexes?.rowByValueReference;
24688
+ if (typeof row.value === "object" && row.value !== null)
24689
+ references?.delete(row.value);
24690
+ if (typeof value === "object" && value !== null) references?.set(value, row);
24691
+ row.value = value;
24692
+ row.updatedAt = Date.now();
24693
+ }
24436
24694
  function applyExplicitNullConstructorField(args) {
24437
24695
  const { schemaKey, member } = args.validated;
24438
24696
  if (isRequiredMember(member)) {
@@ -24443,8 +24701,7 @@ function applyExplicitNullConstructorField(args) {
24443
24701
  const existingId = args.rootRecord[schemaKey];
24444
24702
  const existing = typeof existingId === "string" ? args.createdById.get(existingId) : void 0;
24445
24703
  if (existing !== void 0 && isLiteralValueContent(existing) && !isMemberClassBase(member) && !isMemberListBase(member) && !isMemberDictionaryBase(member)) {
24446
- existing.value = null;
24447
- existing.updatedAt = Date.now();
24704
+ overwriteConstructedLiteral(existing, null, args.ctx);
24448
24705
  return;
24449
24706
  }
24450
24707
  const cleared = registerConstructorArgumentRow(
@@ -25350,9 +25607,11 @@ function evaluateInitializerInContext(init, member, ctx, createdValues, argument
25350
25607
  compileMemberId
25351
25608
  });
25352
25609
  const closeFrame = pushConstructionFrame(ctx, `${member.name} initializer`);
25610
+ const initializerCtx = ctx.thisValue === null ? ctx : bindThisValue(ctx, null);
25611
+ const previousGenericEnv = initializerCtx.__initializerGenericEnv;
25612
+ initializerCtx.__initializerGenericEnv = genericEnv;
25353
25613
  let result;
25354
25614
  try {
25355
- const initializerCtx = ctx.thisValue === null ? ctx : bindThisValue(ctx, null);
25356
25615
  result = evaluateNSGetterWithEffects(
25357
25616
  compiled,
25358
25617
  initializerCtx,
@@ -25368,6 +25627,7 @@ function evaluateInitializerInContext(init, member, ctx, createdValues, argument
25368
25627
  error.sourceOwnerId ??= ownerId;
25369
25628
  throw error;
25370
25629
  } finally {
25630
+ initializerCtx.__initializerGenericEnv = previousGenericEnv;
25371
25631
  closeFrame();
25372
25632
  }
25373
25633
  const created = result.createdSessionValues ?? [];
@@ -25567,6 +25827,21 @@ function retargetConstructorGroupDependencies(provisionalRootId, replacementRoot
25567
25827
  replacementDependencies.add(dependencyRootId);
25568
25828
  }
25569
25829
  }
25830
+ function settledConstructorParameterMember(classId, parameterName, constructorId, ctx) {
25831
+ const cache = evaluatorResolutionCache(ctx);
25832
+ cache.constructorSettlement ??= createConstructorSettlementResolver({
25833
+ classes: ctx.vm.classes,
25834
+ constructors: ctx.vm.constructors,
25835
+ members: ctx.vm.members
25836
+ });
25837
+ const settled = cache.constructorSettlement(
25838
+ classId,
25839
+ parameterName,
25840
+ constructorId
25841
+ );
25842
+ if (settled === null) return void 0;
25843
+ return evalMemberById(ctx.vm, settled.memberId) ?? void 0;
25844
+ }
25570
25845
  function encodeRequiredConstructorArgument(args) {
25571
25846
  const trackedId = findKnownRowIdByValueReference(args.value, args.ctx);
25572
25847
  const replayedAggregateId = trackedId === null && args.ctx.storedConstructionReplay === true && typeof args.value === "string" && evalValueById(
@@ -25612,6 +25887,14 @@ function encodeRequiredConstructorArgument(args) {
25612
25887
  const aggregateId = trackedId ?? replayedAggregateId;
25613
25888
  if (aggregateId !== null) return adoptTracked(aggregateId, "root");
25614
25889
  const collectionType = args.typeInfo;
25890
+ const settled = args.member;
25891
+ const registerCollectionRow = (value) => {
25892
+ const row2 = registerRow(value);
25893
+ const genericBindings = settled === void 0 ? void 0 : rowGenericBindings({ ...args, member: settled });
25894
+ if (genericBindings !== void 0) row2.genericBindings = genericBindings;
25895
+ return row2;
25896
+ };
25897
+ const entryMember = settled !== void 0 && (isMemberListBase(settled) || isMemberDictionaryBase(settled)) ? evalMemberById(args.ctx.vm, settled.entryMemberId) ?? void 0 : void 0;
25615
25898
  const registerRow = (value, containerId) => {
25616
25899
  args.ctx.beforeValueAllocation?.();
25617
25900
  const row2 = buildNewValue(args.ctx.vm.project.id, { value });
@@ -25643,7 +25926,8 @@ function encodeRequiredConstructorArgument(args) {
25643
25926
  ...args,
25644
25927
  value,
25645
25928
  typeInfo: entryType,
25646
- parameterId: `${args.parameterId}:${suffix}`
25929
+ parameterId: `${args.parameterId}:${suffix}`,
25930
+ member: entryMember
25647
25931
  });
25648
25932
  if (typeof nested !== "string") {
25649
25933
  throw new NSGetterRuntimeError(
@@ -25660,7 +25944,7 @@ function encodeRequiredConstructorArgument(args) {
25660
25944
  `Constructor argument '${args.parameterId}' must be a List.`
25661
25945
  );
25662
25946
  }
25663
- const row2 = registerRow([]);
25947
+ const row2 = registerCollectionRow([]);
25664
25948
  row2.value = args.value.map(
25665
25949
  (entry, index) => encodeEntry(entry, collectionType.entryTypeInfo, `index:${index}`)
25666
25950
  );
@@ -25671,7 +25955,7 @@ function encodeRequiredConstructorArgument(args) {
25671
25955
  `Constructor argument '${args.parameterId}' must be a Dictionary.`
25672
25956
  );
25673
25957
  }
25674
- const row = registerRow({});
25958
+ const row = registerCollectionRow({});
25675
25959
  row.value = Object.fromEntries(
25676
25960
  Object.entries(args.value).map(([key, entry]) => [
25677
25961
  key,
@@ -26504,6 +26788,14 @@ function constructDeclaredClassValueWithinFrame(descriptor, record4, info, scope
26504
26788
  ownerRootId: root.id,
26505
26789
  createdValues,
26506
26790
  storageKeyDeclarations,
26791
+ // Only collection rows carry a stamp from the settled member.
26792
+ member: resolvedArgumentType.type === 6 /* List */ || resolvedArgumentType.type === 5 /* Dictionary */ ? settledConstructorParameterMember(
26793
+ classId,
26794
+ argumentType.name,
26795
+ record4.id,
26796
+ ctx
26797
+ ) : void 0,
26798
+ genericEnv: descriptor.instanceEnv,
26507
26799
  ctx
26508
26800
  });
26509
26801
  }
@@ -27848,132 +28140,6 @@ function declarationDefaultSource(id, stored, resolveGraph) {
27848
28140
  return defaultSourceWithListeners(graph?.rowsById.get(id) ?? stored, graph);
27849
28141
  }
27850
28142
 
27851
- // ../packages/models/src/classes/constructor-parameter-settlement.ts
27852
- function createConstructorSettlementResolver(view) {
27853
- const classesById = new Map(
27854
- view.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
27855
- );
27856
- const membersById = new Map(
27857
- view.members.map((member) => [member.id, member])
27858
- );
27859
- const constructorsById = new Map(
27860
- (view.constructors ?? []).map((constructor) => [
27861
- constructor.id,
27862
- constructor
27863
- ])
27864
- );
27865
- const directResultByClassAndParameter = /* @__PURE__ */ new Map();
27866
- const recordedResultByConstructorAndParameter = /* @__PURE__ */ new Map();
27867
- const directSettlement = (classId, parameterName) => {
27868
- const cacheKey = `${classId}\0${parameterName}`;
27869
- if (directResultByClassAndParameter.has(cacheKey)) {
27870
- return directResultByClassAndParameter.get(cacheKey) ?? null;
27871
- }
27872
- const visited = /* @__PURE__ */ new Set();
27873
- let currentId = classId;
27874
- while (currentId !== null && !visited.has(currentId)) {
27875
- visited.add(currentId);
27876
- const schemaClass2 = classesById.get(currentId);
27877
- if (schemaClass2 === void 0) break;
27878
- for (const [schemaKey, memberId] of Object.entries(
27879
- schemaClass2.schema ?? {}
27880
- )) {
27881
- if (typeof memberId !== "string") continue;
27882
- const member = membersById.get(memberId);
27883
- const defaultRecord = asRecord(member?.defaultValue);
27884
- const initRecord = asRecord(defaultRecord?.init);
27885
- if (initRecord !== null && typeof initRecord.code === "string" && initRecord.code.trim() === parameterName) {
27886
- const result = { schemaKey, memberId };
27887
- directResultByClassAndParameter.set(cacheKey, result);
27888
- return result;
27889
- }
27890
- }
27891
- currentId = schemaClass2.extendsClassId ?? null;
27892
- }
27893
- directResultByClassAndParameter.set(cacheKey, null);
27894
- return null;
27895
- };
27896
- const memberIdForSchemaKey = (classId, schemaKey) => {
27897
- const visited = /* @__PURE__ */ new Set();
27898
- let currentId = classId;
27899
- while (currentId !== null && !visited.has(currentId)) {
27900
- visited.add(currentId);
27901
- const schemaClass2 = classesById.get(currentId);
27902
- if (schemaClass2 === void 0) return null;
27903
- const memberId = schemaClass2.schema?.[schemaKey];
27904
- if (typeof memberId === "string") return memberId;
27905
- currentId = schemaClass2.extendsClassId ?? null;
27906
- }
27907
- return null;
27908
- };
27909
- const recordedSettlement = (classId, parameterName, constructorId, resolving) => {
27910
- const cacheKey = `${classId}\0${constructorId}\0${parameterName}`;
27911
- if (recordedResultByConstructorAndParameter.has(cacheKey)) {
27912
- return recordedResultByConstructorAndParameter.get(cacheKey) ?? null;
27913
- }
27914
- if (resolving.has(cacheKey)) return null;
27915
- const constructor = constructorsById.get(constructorId);
27916
- if (constructor?.classId !== classId) {
27917
- recordedResultByConstructorAndParameter.set(cacheKey, null);
27918
- return null;
27919
- }
27920
- const direct = directSettlement(classId, parameterName);
27921
- if (direct !== null) {
27922
- recordedResultByConstructorAndParameter.set(cacheKey, direct);
27923
- return direct;
27924
- }
27925
- const schemaClass2 = classesById.get(classId);
27926
- const baseClassId = schemaClass2?.extendsClassId;
27927
- if (typeof baseClassId !== "string") {
27928
- recordedResultByConstructorAndParameter.set(cacheKey, null);
27929
- return null;
27930
- }
27931
- for (const field of constructor.baseInitializerFields ?? []) {
27932
- const record4 = asRecord(field);
27933
- if (typeof record4?.name !== "string" || typeof record4.code !== "string" || record4.code.trim() !== parameterName) {
27934
- continue;
27935
- }
27936
- const memberId = memberIdForSchemaKey(baseClassId, record4.name);
27937
- if (memberId !== null) {
27938
- const result = { schemaKey: record4.name, memberId };
27939
- recordedResultByConstructorAndParameter.set(cacheKey, result);
27940
- return result;
27941
- }
27942
- }
27943
- const baseConstructorId = classesById.get(baseClassId)?.requiredConstructorId;
27944
- if (typeof baseConstructorId !== "string") {
27945
- recordedResultByConstructorAndParameter.set(cacheKey, null);
27946
- return null;
27947
- }
27948
- resolving.add(cacheKey);
27949
- for (const argument2 of constructor.baseArguments ?? []) {
27950
- const record4 = asRecord(argument2);
27951
- if (typeof record4?.name !== "string" || typeof record4.code !== "string" || record4.code.trim() !== parameterName) {
27952
- continue;
27953
- }
27954
- const result = recordedSettlement(
27955
- baseClassId,
27956
- record4.name,
27957
- baseConstructorId,
27958
- resolving
27959
- );
27960
- resolving.delete(cacheKey);
27961
- recordedResultByConstructorAndParameter.set(cacheKey, result);
27962
- return result;
27963
- }
27964
- resolving.delete(cacheKey);
27965
- recordedResultByConstructorAndParameter.set(cacheKey, null);
27966
- return null;
27967
- };
27968
- return (classId, parameterName, constructorId) => constructorId === void 0 ? directSettlement(classId, parameterName) : recordedSettlement(classId, parameterName, constructorId, /* @__PURE__ */ new Set());
27969
- }
27970
- function asRecord(value) {
27971
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
27972
- return null;
27973
- }
27974
- return value;
27975
- }
27976
-
27977
28143
  // ../packages/models/src/members/stored-value-placement-index.ts
27978
28144
  function buildStoredValuePlacementIndex(args) {
27979
28145
  return createStoredValuePlacementTraversal(args)();
@@ -28225,17 +28391,21 @@ function projectListenerEndpoint(args) {
28225
28391
 
28226
28392
  // ../packages/models/src/members/lookup-declared-type.ts
28227
28393
  function lookupDeclaredTypeInfo(member, collectionTypeInfo) {
28228
- if (collectionTypeInfo === null) return null;
28229
- if (collectionTypeInfo.type !== 6 /* List */ && collectionTypeInfo.type !== 5 /* Dictionary */) {
28230
- return null;
28231
- }
28232
- const entryTypeInfo = member.declaredTypeInfo ?? collectionTypeInfo.entryTypeInfo;
28394
+ const entryTypeInfo = lookupEntryTypeInfo(member, collectionTypeInfo);
28395
+ if (entryTypeInfo === null) return null;
28233
28396
  if (isMultiSelectionMember(member) !== true) {
28234
28397
  return {
28235
28398
  ...entryTypeInfo,
28236
28399
  required: isRequiredMember(member)
28237
28400
  };
28238
28401
  }
28402
+ if (member.collectionMemberId === void 0) {
28403
+ return {
28404
+ type: 9 /* Lookup */,
28405
+ required: isRequiredMember(member),
28406
+ entryTypeInfo
28407
+ };
28408
+ }
28239
28409
  return {
28240
28410
  type: 9 /* Lookup */,
28241
28411
  required: isRequiredMember(member),
@@ -28244,18 +28414,28 @@ function lookupDeclaredTypeInfo(member, collectionTypeInfo) {
28244
28414
  collectionValueId: member.collectionValueId ?? null
28245
28415
  };
28246
28416
  }
28417
+ function lookupEntryTypeInfo(member, collectionTypeInfo) {
28418
+ if (member.collectionMemberId === void 0) return member.declaredTypeInfo;
28419
+ const collection = collectionTypeInfo(member.collectionMemberId);
28420
+ if (collection === null) return null;
28421
+ if (collection.type !== 6 /* List */ && collection.type !== 5 /* Dictionary */) {
28422
+ return null;
28423
+ }
28424
+ return member.declaredTypeInfo ?? collection.entryTypeInfo;
28425
+ }
28247
28426
 
28248
28427
  // ../packages/neoscript-runtime/src/values/member-declared-type-info.ts
28249
- function resolveMemberDeclaredTypeInfo(member, members, ownerClass = null) {
28428
+ function resolveMemberDeclaredTypeInfo(member, members, ownerClass = null, env) {
28250
28429
  return resolveMemberDeclaredTypeInfoInternal(
28251
28430
  member,
28252
28431
  members,
28253
28432
  /* @__PURE__ */ new Set(),
28254
- ownerClass
28433
+ ownerClass,
28434
+ env
28255
28435
  );
28256
28436
  }
28257
- function resolveMemberDeclaredTypeInfoInternal(member, members, seen, ownerClass) {
28258
- const resolved = resolveMember(member, members);
28437
+ function resolveMemberDeclaredTypeInfoInternal(member, members, seen, ownerClass, env) {
28438
+ const resolved = env === void 0 ? resolveMember(member, members) : substituteMember(member, env, members);
28259
28439
  const memberId = getField(resolved, "id");
28260
28440
  if (typeof memberId === "string" && seen.has(memberId)) return null;
28261
28441
  const nextSeen = typeof memberId === "string" ? /* @__PURE__ */ new Set([...seen, memberId]) : new Set(seen);
@@ -28264,7 +28444,14 @@ function resolveMemberDeclaredTypeInfoInternal(member, members, seen, ownerClass
28264
28444
  const typeArguments = Object.fromEntries(
28265
28445
  Object.entries(resolved.classArguments ?? {}).flatMap(
28266
28446
  ([genericParamId, binding]) => {
28267
- if (!isMemberGenericBinding(binding)) return [];
28447
+ if (!isMemberGenericBinding(binding)) {
28448
+ const forwarded = genericParamTypeInfo(
28449
+ ownerClass,
28450
+ binding.genericParamId,
28451
+ true
28452
+ );
28453
+ return forwarded === null ? [] : [[genericParamId, forwarded]];
28454
+ }
28268
28455
  const argumentMember = members.find(
28269
28456
  (candidate) => candidate.id === binding.memberId
28270
28457
  );
@@ -28273,7 +28460,8 @@ function resolveMemberDeclaredTypeInfoInternal(member, members, seen, ownerClass
28273
28460
  argumentMember,
28274
28461
  members,
28275
28462
  nextSeen,
28276
- ownerClass
28463
+ ownerClass,
28464
+ env
28277
28465
  );
28278
28466
  return argumentType === null ? [] : [[genericParamId, argumentType]];
28279
28467
  }
@@ -28313,22 +28501,14 @@ function resolveMemberDeclaredTypeInfoInternal(member, members, seen, ownerClass
28313
28501
  type: 25 /* NSDelegate */,
28314
28502
  required: isRequiredMember(resolved),
28315
28503
  returnTypeInfo: resolved.returnTypeInfo,
28316
- argumentTypes: resolved.argumentTypes.map((argument2) => {
28317
- const { name, ...typeInfo } = argument2;
28318
- void name;
28319
- return typeInfo;
28320
- })
28504
+ argumentTypes: unnamedArgumentTypes(resolved.argumentTypes)
28321
28505
  };
28322
28506
  }
28323
28507
  if (isMemberActionBase(resolved)) {
28324
28508
  return {
28325
28509
  type: 26 /* NSAction */,
28326
28510
  required: false,
28327
- argumentTypes: resolved.argumentTypes.map((argument2) => {
28328
- const { name, ...typeInfo } = argument2;
28329
- void name;
28330
- return typeInfo;
28331
- })
28511
+ argumentTypes: unnamedArgumentTypes(resolved.argumentTypes)
28332
28512
  };
28333
28513
  }
28334
28514
  if (isMemberListBase(resolved) || isMemberDictionaryBase(resolved)) {
@@ -28340,7 +28520,8 @@ function resolveMemberDeclaredTypeInfoInternal(member, members, seen, ownerClass
28340
28520
  entry,
28341
28521
  members,
28342
28522
  nextSeen,
28343
- ownerClass
28523
+ ownerClass,
28524
+ env
28344
28525
  );
28345
28526
  if (entryTypeInfo === null) return null;
28346
28527
  return {
@@ -28351,40 +28532,47 @@ function resolveMemberDeclaredTypeInfoInternal(member, members, seen, ownerClass
28351
28532
  };
28352
28533
  }
28353
28534
  if (isMemberLookupBase(resolved)) {
28354
- const collection = members.find(
28355
- (candidate) => candidate.id === resolved.collectionMemberId
28356
- );
28357
- if (collection === void 0) return null;
28358
- return lookupDeclaredTypeInfo(
28359
- resolved,
28360
- resolveMemberDeclaredTypeInfoInternal(
28535
+ return lookupDeclaredTypeInfo(resolved, (collectionMemberId) => {
28536
+ const collection = members.find(
28537
+ (candidate) => candidate.id === collectionMemberId
28538
+ );
28539
+ if (collection === void 0) return null;
28540
+ return resolveMemberDeclaredTypeInfoInternal(
28361
28541
  collection,
28362
28542
  members,
28363
28543
  nextSeen,
28364
- ownerClass
28365
- )
28366
- );
28544
+ ownerClass,
28545
+ env
28546
+ );
28547
+ });
28367
28548
  }
28368
28549
  if (resolved.kind === 9 /* Lookup */) return null;
28369
28550
  if (!memberKindSupportsStorage(resolved.kind)) return null;
28370
28551
  if (isMemberGenericBase(resolved)) {
28371
- if (ownerClass === null) return null;
28372
- const declaration = ownerClass.genericParams?.find(
28373
- (parameter3) => parameter3.id === resolved.genericParamId
28552
+ return genericParamTypeInfo(
28553
+ ownerClass,
28554
+ resolved.genericParamId,
28555
+ isRequiredMember(resolved)
28374
28556
  );
28375
- if (declaration === void 0) return null;
28376
- return {
28377
- type: 21 /* Generic */,
28378
- required: isRequiredMember(resolved),
28379
- ownerClassId: ownerClass.id,
28380
- genericParamId: declaration.id
28381
- };
28382
28557
  }
28383
28558
  return {
28384
28559
  type: resolved.kind,
28385
28560
  required: isRequiredMember(resolved)
28386
28561
  };
28387
28562
  }
28563
+ function genericParamTypeInfo(ownerClass, genericParamId, required) {
28564
+ if (ownerClass === null) return null;
28565
+ const declaration = ownerClass.genericParams?.find(
28566
+ (parameter3) => parameter3.id === genericParamId
28567
+ );
28568
+ if (declaration === void 0) return null;
28569
+ return {
28570
+ type: 21 /* Generic */,
28571
+ required,
28572
+ ownerClassId: ownerClass.id,
28573
+ genericParamId: declaration.id
28574
+ };
28575
+ }
28388
28576
 
28389
28577
  // ../packages/neoscript-runtime/src/values/constructor-argument-ownership.ts
28390
28578
  var MaterializedValueGraphContext = class {
@@ -31217,7 +31405,7 @@ function materializeMemberDefaultValue(args) {
31217
31405
  rootOwners,
31218
31406
  valuesById,
31219
31407
  (id) => args.readTracking?.valueIds.add(id)
31220
- ).ownerClass : typeof Reflect.get(member, "id") === "string" ? findSchemaPlacement(
31408
+ ).ownerClass : typeof Reflect.get(member, "id") === "string" && !isStaticMember(member) ? findSchemaPlacement(
31221
31409
  String(Reflect.get(member, "id")),
31222
31410
  args.document.classes
31223
31411
  )?.ownerClass ?? null : null;
@@ -33556,22 +33744,25 @@ function virtualReadRecorder(reads) {
33556
33744
  recordGlobalRead: reads.recordUnattributableValueRead
33557
33745
  };
33558
33746
  }
33559
- function evaluateMemberInitializer(args) {
33560
- const databaseVM = initializerEvaluatorLookups(
33561
- args.document,
33562
- args.readTracking
33563
- );
33747
+ function compileMemberInitializer(args, databaseVM = initializerEvaluatorLookups(args.document)) {
33564
33748
  const initializerIndexes = databaseVM.constructorInitializerIndexes;
33565
33749
  const compileMemberId = initializerIndexes?.initializerScopeMemberIds.get(args.init) ?? (args.sourceValueId === null || args.sourceValueId === void 0 ? void 0 : initializerIndexes?.initializerScopeMemberIdsByValueId.get(
33566
33750
  args.sourceValueId
33567
33751
  ));
33568
- const compiled = ensureInitializerCompiled({
33752
+ return ensureInitializerCompiled({
33569
33753
  init: args.init,
33570
33754
  member: args.member,
33571
33755
  initializerCompiler: args.document.initializerCompiler,
33572
33756
  sourceValueId: args.sourceValueId ?? null,
33573
33757
  compileMemberId
33574
33758
  });
33759
+ }
33760
+ function evaluateMemberInitializer(args) {
33761
+ const databaseVM = initializerEvaluatorLookups(
33762
+ args.document,
33763
+ args.readTracking
33764
+ );
33765
+ const compiled = compileMemberInitializer(args, databaseVM);
33575
33766
  const ctx = {
33576
33767
  ...args.document.evaluationLimits,
33577
33768
  debugSink: args.document.debugSink,
@@ -35066,6 +35257,25 @@ function substituteTypeParameters(member, receiver, declaring) {
35066
35257
  };
35067
35258
  return visit(member);
35068
35259
  }
35260
+ function containsTypeParameter(type) {
35261
+ switch (type.kind) {
35262
+ case "typeParameter":
35263
+ return true;
35264
+ case "named":
35265
+ return type.typeArguments?.some(containsTypeParameter) ?? false;
35266
+ case "list":
35267
+ case "set":
35268
+ return containsTypeParameter(type.elementType);
35269
+ case "dictionary":
35270
+ return containsTypeParameter(type.keyType) || containsTypeParameter(type.valueType);
35271
+ case "delegate":
35272
+ return containsTypeParameter(type.returnType) || type.parameterTypes.some(containsTypeParameter);
35273
+ case "action":
35274
+ return type.parameterTypes.some(containsTypeParameter);
35275
+ default:
35276
+ return false;
35277
+ }
35278
+ }
35069
35279
 
35070
35280
  // ../packages/neoscript-language/src/listener-annotation.ts
35071
35281
  function inspectListenerAnnotation(annotation2, parameters) {
@@ -35783,6 +35993,18 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
35783
35993
  }
35784
35994
  return { fields, errors, deferredReferences: [...deferredReferences] };
35785
35995
  }
35996
+ /**
35997
+ * P60 §2.3. A persisted delegate method group, graded exactly as the same
35998
+ * expression assigned to `expected` in a body.
35999
+ */
36000
+ resolvePersistedMethodGroup(expression, expected) {
36001
+ const resolved = this.resolveExpression(
36002
+ expression,
36003
+ this.initialScope(),
36004
+ expected
36005
+ );
36006
+ this.requireAssignable(resolved.type, expected, expression.pos, "value");
36007
+ }
35786
36008
  persistedListenerCompletions(receiver, expected) {
35787
36009
  const scope = this.initialScope();
35788
36010
  let receiverType = this.context.thisClass;
@@ -36073,7 +36295,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
36073
36295
  local,
36074
36296
  localType,
36075
36297
  "local" /* Local */,
36076
- initial.writability ?? "local" /* Local */,
36298
+ localOwnership(initial),
36077
36299
  this.localWriteTargetRoot(initial, scope)
36078
36300
  )
36079
36301
  );
@@ -39326,6 +39548,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
39326
39548
  } : {}
39327
39549
  };
39328
39550
  }
39551
+ const writability = member.writability ? toWritability(member.writability, this.writesUserData) : void 0;
39329
39552
  return {
39330
39553
  pointer: {
39331
39554
  type: "staticMember" /* StaticMember */,
@@ -39333,8 +39556,10 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
39333
39556
  },
39334
39557
  type: member.type,
39335
39558
  symbol: member,
39336
- ...member.writability ? {
39337
- writability: toWritability(member.writability, this.writesUserData)
39559
+ ...writability ? { writability } : {},
39560
+ ...member.lookup ? {
39561
+ entryWritability: this.lookupEntryWritability(member, writability),
39562
+ entryUserData: this.lookupEntryUserData(member)
39338
39563
  } : {}
39339
39564
  };
39340
39565
  }
@@ -39634,7 +39859,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
39634
39859
  const readonlySlot = member.readonlyDeclaration === true;
39635
39860
  const storageWritability = this.memberWritability(member, receiver);
39636
39861
  const writability = readonlySlot ? "readOnly" /* ReadOnly */ : storageWritability;
39637
- const entryWritability = member.lookup ? this.lookupEntryWritability(member, receiver) : readonlySlot ? storageWritability : void 0;
39862
+ const entryWritability = member.lookup ? this.lookupEntryWritability(member, receiver.writability) : readonlySlot ? storageWritability : void 0;
39638
39863
  const userData = this.memberUserData(member, receiver);
39639
39864
  const entryUserData = member.lookup ? this.lookupEntryUserData(member) : readonlySlot && userData;
39640
39865
  const lookupWire = member.lookup?.multiselect === true && memberType2.kind === "set" ? {
@@ -39644,7 +39869,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
39644
39869
  { ...memberType2.elementType, nullable: false },
39645
39870
  this.project
39646
39871
  ),
39647
- collectionMemberId: member.lookup.collectionMemberId,
39872
+ ...member.lookup.collectionMemberId !== void 0 ? { collectionMemberId: member.lookup.collectionMemberId } : {},
39648
39873
  ...member.lookup.collectionValueId !== void 0 ? { collectionValueId: member.lookup.collectionValueId } : {}
39649
39874
  } : void 0;
39650
39875
  return {
@@ -39768,16 +39993,18 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
39768
39993
  }
39769
39994
  lookupEntryUserData(member) {
39770
39995
  if (!member.lookup) return false;
39771
- const collectionWritability = member.lookup.collectionWritability ?? this.project.symbolById.get(member.lookup.collectionMemberId)?.writability;
39996
+ const collectionMemberId = member.lookup.collectionMemberId;
39997
+ if (collectionMemberId === void 0) return false;
39998
+ const collectionWritability = member.lookup.collectionWritability ?? this.project.symbolById.get(collectionMemberId)?.writability;
39772
39999
  return collectionWritability === "user";
39773
40000
  }
39774
- lookupEntryWritability(member, receiver) {
40001
+ lookupEntryWritability(member, receiverWritability) {
39775
40002
  if (!member.lookup) return "readOnly" /* ReadOnly */;
39776
- const target = this.project.symbolById.get(
39777
- member.lookup.collectionMemberId
39778
- );
40003
+ const collectionMemberId = member.lookup.collectionMemberId;
40004
+ if (collectionMemberId === void 0) return "runtime" /* Runtime */;
40005
+ const target = this.project.symbolById.get(collectionMemberId);
39779
40006
  const targetWritability = member.lookup.collectionWritability ? toWritability(member.lookup.collectionWritability, this.writesUserData) : target?.writability ? toWritability(target.writability, this.writesUserData) : target?.writable ? "runtime" /* Runtime */ : "readOnly" /* ReadOnly */;
39780
- if (receiver.writability === "immutable" /* Immutable */) {
40007
+ if (receiverWritability === "immutable" /* Immutable */) {
39781
40008
  if (targetWritability === "save" /* Save */) {
39782
40009
  return "immutableToSaveLookup" /* ImmutableToSaveLookup */;
39783
40010
  }
@@ -40799,7 +41026,8 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
40799
41026
  resolveExecutableObjectInitializer(schemaClass2, expression, scope, expected) {
40800
41027
  const settling = this.generatedConstructorSettlingEntries(
40801
41028
  schemaClass2,
40802
- expression
41029
+ expression,
41030
+ expected
40803
41031
  );
40804
41032
  const constructed = settling.length > 0 ? this.resolveClassConstructor(
40805
41033
  schemaClass2.name,
@@ -40878,7 +41106,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
40878
41106
  };
40879
41107
  }
40880
41108
  /** Block entries naming a required parameter the positional arguments skip. */
40881
- generatedConstructorSettlingEntries(schemaClass2, expression) {
41109
+ generatedConstructorSettlingEntries(schemaClass2, expression, expected) {
40882
41110
  const signature = schemaClass2.constructorSignature;
40883
41111
  if (signature === void 0) return [];
40884
41112
  const generated = isGeneratedPositionalCall(schemaClass2, expression) || (schemaClass2.declaredConstructors?.length ?? 0) === 0 && expression.argumentNames === void 0;
@@ -40886,7 +41114,11 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
40886
41114
  const required = new Set(
40887
41115
  requiredMembersAfterArguments(
40888
41116
  schemaClass2,
40889
- signature.parameters,
41117
+ closedConstructorParameters(
41118
+ signature.parameters,
41119
+ this.constructorTargetType(schemaClass2, expression, expected),
41120
+ schemaClass2
41121
+ ),
40890
41122
  expression.args.length
40891
41123
  ).map((name) => name.toLowerCase())
40892
41124
  );
@@ -40923,9 +41155,8 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
40923
41155
  }
40924
41156
  const signature = replayingStoredConstruction ? schemaClass2.storedConstructionReplaySignature ?? schemaClass2.constructorSignature : schemaClass2.constructorSignature;
40925
41157
  if (!signature) {
40926
- const open = (schemaClass2.typeParameters?.length ?? 0) > 0;
40927
41158
  throw new CompileError(
40928
- open ? `Cannot construct open generic Class '${className}'; construct a closed named descendant.` : `Class '${className}' does not expose a generated public constructor.`,
41159
+ `Class '${className}' does not expose a generated public constructor.`,
40929
41160
  pos
40930
41161
  );
40931
41162
  }
@@ -40934,19 +41165,11 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
40934
41165
  expression,
40935
41166
  expected
40936
41167
  );
40937
- const parameters = signature.parameters.map((parameter3) => ({
40938
- ...parameter3,
40939
- valueType: substituteTypeParameters(
40940
- parameter3.valueType,
40941
- targetType,
40942
- schemaClass2
40943
- ),
40944
- parameterType: substituteTypeParameters(
40945
- parameter3.parameterType,
40946
- targetType,
40947
- schemaClass2
40948
- )
40949
- }));
41168
+ const parameters = closedConstructorParameters(
41169
+ signature.parameters,
41170
+ targetType,
41171
+ schemaClass2
41172
+ );
40950
41173
  const argumentsList2 = expression.args;
40951
41174
  if (expression.argumentNames !== void 0) {
40952
41175
  throw new CompileError(
@@ -41035,15 +41258,34 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
41035
41258
  );
41036
41259
  }
41037
41260
  if (typeArguments !== void 0) {
41038
- return {
41261
+ const target = {
41039
41262
  kind: "named",
41040
41263
  typeId: schemaClass2.id,
41041
41264
  typeArguments
41042
41265
  };
41266
+ assertTypeArgumentConstraints(
41267
+ schemaClass2,
41268
+ target,
41269
+ expression.pos,
41270
+ this.project
41271
+ );
41272
+ assertDirectTypeParameterArguments(target, expression.pos, this.project);
41273
+ return target;
41043
41274
  }
41044
41275
  if (expected?.kind === "named" && expected.typeId === schemaClass2.id) {
41276
+ assertDirectTypeParameterArguments(
41277
+ expected,
41278
+ expression.pos,
41279
+ this.project
41280
+ );
41045
41281
  return { ...expected, nullable: false };
41046
41282
  }
41283
+ if ((schemaClass2.typeParameters?.length ?? 0) > 0) {
41284
+ throw new CompileError(
41285
+ `Cannot construct open generic Class '${schemaClass2.name}'; pass its type arguments.`,
41286
+ expression.pos
41287
+ );
41288
+ }
41047
41289
  return {
41048
41290
  kind: "named",
41049
41291
  typeId: schemaClass2.id
@@ -43923,6 +44165,25 @@ function variable(id, type, pointer, project) {
43923
44165
  function isGeneratedPositionalCall(target, expression) {
43924
44166
  return neoScriptRequiredConstructor(target) === null && target.constructorSignature !== void 0 && expression.argumentNames === void 0 && callHasPositionalArguments(expression);
43925
44167
  }
44168
+ function closedConstructorParameters(parameters, targetType, schemaClass2) {
44169
+ return parameters.map((parameter3) => {
44170
+ const valueType = substituteTypeParameters(
44171
+ parameter3.valueType,
44172
+ targetType,
44173
+ schemaClass2
44174
+ );
44175
+ return {
44176
+ ...parameter3,
44177
+ valueType,
44178
+ parameterType: substituteTypeParameters(
44179
+ parameter3.parameterType,
44180
+ targetType,
44181
+ schemaClass2
44182
+ ),
44183
+ required: parameter3.required && valueType.nullable !== true
44184
+ };
44185
+ });
44186
+ }
43926
44187
  function requiredMembersAfterArguments(schemaClass2, parameters, positionalCount) {
43927
44188
  const names = [];
43928
44189
  for (const parameter3 of parameters.slice(positionalCount)) {
@@ -43974,6 +44235,12 @@ function bindConstructorArgumentNames(className, declared, argumentNames, pos) {
43974
44235
  return parameter3.name;
43975
44236
  });
43976
44237
  }
44238
+ function localOwnership(initial) {
44239
+ if (initial.entryWritability !== void 0 && (initial.type.kind === "named" || initial.type.kind === "typeParameter")) {
44240
+ return initial.entryWritability;
44241
+ }
44242
+ return initial.writability ?? "local" /* Local */;
44243
+ }
43977
44244
  function scopeVariable(name, value, sourceType, writability, ownership, writeRoot, readonlyBinding) {
43978
44245
  return {
43979
44246
  name,
@@ -45251,6 +45518,7 @@ function resolveNeoScriptType(type, context, project) {
45251
45518
  )
45252
45519
  } : {}
45253
45520
  };
45521
+ assertTypeArgumentConstraints(named, resolved, type.pos, project);
45254
45522
  break;
45255
45523
  }
45256
45524
  case "list":
@@ -45283,6 +45551,31 @@ function resolveNeoScriptType(type, context, project) {
45283
45551
  }
45284
45552
  return { ...resolved, nullable: !type.required };
45285
45553
  }
45554
+ function wrappedTypeParameterMessage(target, project) {
45555
+ for (const argument2 of target.typeArguments ?? []) {
45556
+ if (argument2.kind === "typeParameter") continue;
45557
+ if (!containsTypeParameter(argument2)) continue;
45558
+ return `Cannot construct '${formatType(target, project)}': type argument '${formatType(argument2, project)}' wraps a type parameter. Pass the type parameter itself or a closed type.`;
45559
+ }
45560
+ return null;
45561
+ }
45562
+ function assertDirectTypeParameterArguments(target, pos, project) {
45563
+ const message = wrappedTypeParameterMessage(target, project);
45564
+ if (message !== null) throw new CompileError(message, pos);
45565
+ }
45566
+ function assertTypeArgumentConstraints(declaring, type, pos, project) {
45567
+ declaring.typeParameters?.forEach((parameter3, index) => {
45568
+ const argument2 = type.typeArguments?.[index];
45569
+ const constraint = parameter3.type.kind === "typeParameter" ? parameter3.type.constraint : void 0;
45570
+ if (argument2 === void 0 || constraint === void 0) return;
45571
+ const expected = substituteTypeParameters(constraint, type, declaring);
45572
+ if (isNeoScriptTypeAssignable(argument2, expected, project)) return;
45573
+ throw new CompileError(
45574
+ `Type argument '${formatType(argument2, project)}' does not satisfy '${parameter3.name} extends ${formatType(expected, project)}' on '${declaring.name}'.`,
45575
+ pos
45576
+ );
45577
+ });
45578
+ }
45286
45579
  function intersectCollectionWritability(left, right) {
45287
45580
  if (left === right) return left;
45288
45581
  const writable = (value) => value === "local" /* Local */ || value === "save" /* Save */ || value === "session" /* Session */ || value === "runtime" /* Runtime */;
@@ -45687,9 +45980,6 @@ function attachConstructorSignature(type, environment) {
45687
45980
  type.id,
45688
45981
  environment
45689
45982
  );
45690
- for (const binding of genericEnvironment.values()) {
45691
- if (binding.kind === "unbound") return type;
45692
- }
45693
45983
  return {
45694
45984
  ...type,
45695
45985
  ...buildNeoScriptConstructionSignatures(
@@ -45702,7 +45992,7 @@ function attachConstructorSignature(type, environment) {
45702
45992
  environment
45703
45993
  );
45704
45994
  return member ? {
45705
- required: boolean(member.required, `member ${memberId}.required`),
45995
+ required: member.kind === "generic" || boolean(member.required, `member ${memberId}.required`),
45706
45996
  defaultValue: member.defaultValue,
45707
45997
  immutable: declaredStorage(
45708
45998
  environment.members.get(memberId),
@@ -46055,12 +46345,10 @@ function memberSymbol(member, schemaKey, environment, field) {
46055
46345
  environment
46056
46346
  );
46057
46347
  }
46058
- const lookupCollectionMemberId = kind === "lookup" ? string(member.collectionMemberId, `${field}.collectionMemberId`) : null;
46059
- const lookupCollectionWritability = lookupCollectionMemberId === null ? void 0 : environment.effectiveWritabilityByMemberId.get(
46060
- lookupCollectionMemberId
46061
- );
46348
+ const lookupCollection = kind === "lookup" ? lookupCollectionMemberId(member, field) : null;
46349
+ const lookupCollectionWritability = lookupCollection === null ? void 0 : environment.effectiveWritabilityByMemberId.get(lookupCollection);
46062
46350
  const lookup = kind === "lookup" ? {
46063
- collectionMemberId: lookupCollectionMemberId,
46351
+ ...lookupCollection === null ? {} : { collectionMemberId: lookupCollection },
46064
46352
  ...member.collectionValueId === null || typeof member.collectionValueId === "string" ? { collectionValueId: member.collectionValueId } : {},
46065
46353
  multiselect: boolean(member.multiselect, `${field}.multiselect`),
46066
46354
  ...lookupCollectionWritability === void 0 ? {} : { collectionWritability: lookupCollectionWritability }
@@ -46074,6 +46362,10 @@ function memberSymbol(member, schemaKey, environment, field) {
46074
46362
  ...lookup ? { lookup } : {}
46075
46363
  };
46076
46364
  }
46365
+ function lookupCollectionMemberId(member, field) {
46366
+ if (member.collectionMemberId === null) return null;
46367
+ return string(member.collectionMemberId, `${field}.collectionMemberId`);
46368
+ }
46077
46369
  function interfaceType(value, environment, field) {
46078
46370
  const id = string(value.id, `${field}.id`);
46079
46371
  return {
@@ -46542,9 +46834,8 @@ function memberType(member, environment, visiting, field) {
46542
46834
  };
46543
46835
  }
46544
46836
  if (kind === "lookup") {
46545
- const collection = environment.members.get(
46546
- string(member.collectionMemberId, `${field}.collectionMemberId`)
46547
- );
46837
+ const collectionMemberId = lookupCollectionMemberId(member, field);
46838
+ const collection = collectionMemberId === null ? void 0 : environment.members.get(collectionMemberId);
46548
46839
  const collectionType = collection ? memberType(collection, environment, next, `${field}.collection`) : unknownType();
46549
46840
  const declared = optionalRecord(member.declaredType);
46550
46841
  const declaredType = declared ? manifestType(declared, environment, `${field}.declaredType`) : null;
@@ -47978,9 +48269,6 @@ function classToLanguageType(schemaClass2, context) {
47978
48269
  }
47979
48270
  function constructorSignature(schemaClass2, members, context, genericEnvironment) {
47980
48271
  if (isAbstractClass(schemaClass2)) return {};
47981
- if (!isClosedClass(schemaClass2.id, context.vm.classes)) {
47982
- return {};
47983
- }
47984
48272
  return buildNeoScriptConstructionSignatures(
47985
48273
  schemaClass2.id,
47986
48274
  members,
@@ -47988,14 +48276,16 @@ function constructorSignature(schemaClass2, members, context, genericEnvironment
47988
48276
  const record4 = analyzerMemberById(context, memberId);
47989
48277
  if (!record4) return null;
47990
48278
  try {
47991
- const resolved = substituteMember(
48279
+ const declared = resolveAnalyzerMember(context, record4);
48280
+ const open = isMemberGenericBase(declared) && genericEnvironment.get(declared.genericParamId)?.kind === "unbound";
48281
+ const resolved = open ? declared : substituteMember(
47992
48282
  record4,
47993
48283
  genericEnvironment,
47994
48284
  context.vm.members,
47995
- resolveAnalyzerMember(context, record4)
48285
+ declared
47996
48286
  );
47997
48287
  return {
47998
- required: isRequiredMember(resolved),
48288
+ required: open || isRequiredMember(resolved),
47999
48289
  defaultValue: "defaultValue" in resolved ? resolved.defaultValue : void 0,
48000
48290
  immutable: declaredMemberStorage(record4.id, context.vm.members) === 1 /* Immutable */
48001
48291
  };
@@ -48159,6 +48449,13 @@ function memberToSymbol(record4, schemaKey, containingClass, ownerClassId, index
48159
48449
  };
48160
48450
  }
48161
48451
  if (isMemberLookupBase(resolved)) {
48452
+ if (resolved.collectionMemberId === void 0) {
48453
+ return {
48454
+ ...common,
48455
+ kind: "property",
48456
+ lookup: { multiselect: isMultiSelectionMember(resolved) }
48457
+ };
48458
+ }
48162
48459
  const collectionWritability = uniqueEffectiveWritability(
48163
48460
  resolved.collectionMemberId,
48164
48461
  context
@@ -48520,12 +48817,12 @@ function memberRuntimeType(record4, context, seen = /* @__PURE__ */ new Set(), g
48520
48817
  if (!isMemberLookupBase(member)) return UNKNOWN_TYPE;
48521
48818
  const declared = member.declaredTypeInfo ? toLanguageType(member.declaredTypeInfo, context, genericEnvironment) : null;
48522
48819
  const narrowed = declared && !isUnknownType3(declared) ? declared : null;
48523
- const entry = narrowed ?? lookupCollectionEntryType(
48820
+ const entry = narrowed ?? (member.collectionMemberId === void 0 ? null : lookupCollectionEntryType(
48524
48821
  member.collectionMemberId,
48525
48822
  context,
48526
48823
  nextSeen,
48527
48824
  genericEnvironment
48528
- );
48825
+ ));
48529
48826
  if (!entry) return UNKNOWN_TYPE;
48530
48827
  return isMultiSelectionMember(member) ? {
48531
48828
  kind: "set",
@@ -49204,25 +49501,33 @@ function compileNSInitializer(code, ctx) {
49204
49501
  );
49205
49502
  }
49206
49503
  try {
49207
- const { lexicalThisClass, ...compilerContext } = ctx;
49504
+ const { lexicalThisClass, declaringClass, ...compilerContext } = ctx;
49505
+ const context = createContext(
49506
+ {
49507
+ ...compilerContext,
49508
+ thisClass: lexicalThisClass ?? null,
49509
+ implicitMemberAccess: lexicalThisClass !== null,
49510
+ staticMember: false
49511
+ },
49512
+ {
49513
+ scriptKind: "initializer",
49514
+ returnTypeInfo: ctx.returnTypeInfo,
49515
+ ...ctx.argumentTypes === void 0 ? {} : { functionArguments: ctx.argumentTypes },
49516
+ ...ctx.initializerName === void 0 ? {} : { functionName: ctx.initializerName },
49517
+ dialogueContext: null
49518
+ }
49519
+ );
49208
49520
  return compileStrict(
49209
49521
  `return
49210
49522
  ${code};`,
49211
- createContext(
49212
- {
49213
- ...compilerContext,
49214
- thisClass: lexicalThisClass ?? null,
49215
- implicitMemberAccess: lexicalThisClass !== null,
49216
- staticMember: false
49217
- },
49218
- {
49219
- scriptKind: "initializer",
49220
- returnTypeInfo: ctx.returnTypeInfo,
49221
- ...ctx.argumentTypes === void 0 ? {} : { functionArguments: ctx.argumentTypes },
49222
- ...ctx.initializerName === void 0 ? {} : { functionName: ctx.initializerName },
49223
- dialogueContext: null
49523
+ declaringClass ? {
49524
+ ...context,
49525
+ declaringType: {
49526
+ kind: "named",
49527
+ typeId: declaringClass.id,
49528
+ nullable: false
49224
49529
  }
49225
- )
49530
+ } : context
49226
49531
  );
49227
49532
  } catch (error) {
49228
49533
  throw withInitializerSourcePosition(error);
@@ -49459,6 +49764,7 @@ function compileMemberInitializerBody(args) {
49459
49764
  `Member "${args.member.name}" has an initializer but no resolvable declared type.`
49460
49765
  );
49461
49766
  }
49767
+ const instanceClass = isStaticMember(args.member) ? null : args.thisClass;
49462
49768
  let compiled;
49463
49769
  try {
49464
49770
  compiled = compileUnit2(
@@ -49470,8 +49776,10 @@ function compileMemberInitializerBody(args) {
49470
49776
  variantFolders: args.variantFolders ?? [],
49471
49777
  returnTypeInfo,
49472
49778
  initializerName: args.member.name,
49779
+ lexicalThisClass: parseExpression(defaultValue.init.code).kind === "lambda" ? instanceClass : null,
49780
+ declaringClass: instanceClass,
49473
49781
  argumentTypes: initializerArgumentTypes(
49474
- args.thisClass,
49782
+ instanceClass,
49475
49783
  args.constructors ?? []
49476
49784
  )
49477
49785
  })
@@ -49516,6 +49824,7 @@ function compileValueRowInitializerBody(args) {
49516
49824
  returnTypeInfo,
49517
49825
  initializerName: args.member.name,
49518
49826
  lexicalThisClass: args.lexicalThisClass ?? null,
49827
+ declaringClass: args.initializerOwnerClass,
49519
49828
  argumentTypes: initializerArgumentTypes(
49520
49829
  args.initializerOwnerClass,
49521
49830
  args.constructors ?? []
@@ -54156,12 +54465,23 @@ var schemaMemberSchema = variant("kind", [
54156
54465
  enumId: nonEmptyString,
54157
54466
  multiselect: boolean2()
54158
54467
  }),
54159
- memberSchema("lookup", {
54160
- collectionMemberId: nonEmptyString,
54161
- collectionValueId: nullableId,
54162
- multiselect: boolean2(),
54163
- declaredType: nullable(schemaTypeSchema)
54164
- }),
54468
+ pipe(
54469
+ memberSchema("lookup", {
54470
+ /** `null` on an unbound `Reference<T>` (P107), typed by `declaredType`. */
54471
+ collectionMemberId: nullable(nonEmptyString),
54472
+ collectionValueId: nullableId,
54473
+ multiselect: boolean2(),
54474
+ declaredType: nullable(schemaTypeSchema)
54475
+ }),
54476
+ check(
54477
+ (member) => member.collectionMemberId !== null || member.collectionValueId === null,
54478
+ "A lookup collection value requires a collection member."
54479
+ ),
54480
+ check(
54481
+ (member) => member.collectionMemberId !== null || member.declaredType?.kind === "class" || member.declaredType?.kind === "generic",
54482
+ "A lookup without a collection needs a class or generic declared type."
54483
+ )
54484
+ ),
54165
54485
  memberSchema("dialogueLookup", {
54166
54486
  dialogueGroupId: nullableId,
54167
54487
  multiselect: boolean2()
@@ -54559,10 +54879,8 @@ function memberFromDocument(record4, members, owners, classNames, context) {
54559
54879
  return {
54560
54880
  ...common,
54561
54881
  kind: "lookup",
54562
- collectionMemberId: requiredStringValue(
54563
- field("collectionMemberId", void 0),
54564
- record4,
54565
- "collectionMemberId"
54882
+ collectionMemberId: optionalStringOrNull(
54883
+ field("collectionMemberId", null)
54566
54884
  ),
54567
54885
  collectionValueId: optionalStringOrNull(field("collectionValueId", null)),
54568
54886
  multiselect: ordinalValue(
@@ -54880,7 +55198,9 @@ function memberToDocumentFields(member, baseData) {
54880
55198
  }
54881
55199
  }
54882
55200
  if (member.kind === "lookup") {
54883
- fields.collectionMemberId = member.collectionMemberId;
55201
+ if (member.collectionMemberId !== null) {
55202
+ fields.collectionMemberId = member.collectionMemberId;
55203
+ }
54884
55204
  if (member.collectionValueId !== null) {
54885
55205
  fields.collectionValueId = member.collectionValueId;
54886
55206
  }
@@ -56869,7 +57189,7 @@ var INITIALIZER_KEY_PLACEHOLDER = new RegExp(
56869
57189
 
56870
57190
  // ../packages/manifest/schema-contract/registry.mjs
56871
57191
  var PROJECT_SCHEMA_CONTRACT = Object.freeze({
56872
- cliVersion: "0.76.3",
57192
+ cliVersion: "0.77.1",
56873
57193
  projectFileUploadBatchSize: 32,
56874
57194
  documentRecords: {
56875
57195
  member: {