@neocompose/cli 0.84.3 → 0.84.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3100,14 +3100,14 @@ function isNSFunctionContains(value) {
3100
3100
  if (v?.type !== "contains" /* contains */) return false;
3101
3101
  const info = v.info;
3102
3102
  if (typeof info !== "object" || info === null) return false;
3103
- return isNSPointer(info.collectionPointer) && isNSPointer(info.valuePointer) && isReferenceFlag(info.reference);
3103
+ return isNSPointer(info.collectionPointer) && isNSPointer(info.valuePointer) && isReferenceFlag(info.reference) && (info.float === void 0 || info.float === true) && (info.decimal === void 0 || info.decimal === true);
3104
3104
  }
3105
3105
  function isNSFunctionIndexOf(value) {
3106
3106
  const v = value;
3107
3107
  if (v?.type !== "indexOf" /* indexOf */) return false;
3108
3108
  const info = v.info;
3109
3109
  if (typeof info !== "object" || info === null) return false;
3110
- return isNSPointer(info.collectionPointer) && isNSPointer(info.valuePointer) && isReferenceFlag(info.reference);
3110
+ return isNSPointer(info.collectionPointer) && isNSPointer(info.valuePointer) && isReferenceFlag(info.reference) && (info.float === void 0 || info.float === true) && (info.decimal === void 0 || info.decimal === true);
3111
3111
  }
3112
3112
  function isNSFunctionStringOp(value) {
3113
3113
  const v = value;
@@ -3255,7 +3255,7 @@ function isNSFunctionCollectionQuery(value) {
3255
3255
  case "Reverse":
3256
3256
  return true;
3257
3257
  case "ToSet":
3258
- return info.reference === void 0 || info.reference === true;
3258
+ return (info.reference === void 0 || info.reference === true) && (info.decimalEntries === void 0 || info.decimalEntries === true);
3259
3259
  default:
3260
3260
  return false;
3261
3261
  }
@@ -17587,7 +17587,7 @@ var init_registry = __esm({
17587
17587
  "../packages/manifest/schema-contract/registry.mjs"() {
17588
17588
  "use strict";
17589
17589
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
17590
- cliVersion: "0.84.3",
17590
+ cliVersion: "0.84.5",
17591
17591
  projectFileUploadBatchSize: 32,
17592
17592
  documentRecords: {
17593
17593
  member: {
@@ -31651,13 +31651,22 @@ function neoScriptMemberLookupType(type) {
31651
31651
  nullable2 ||= current.constraint.nullable === true;
31652
31652
  current = current.constraint;
31653
31653
  }
31654
+ if (current.kind === "named" && type.narrowedInterfaces !== void 0) {
31655
+ current = {
31656
+ ...current,
31657
+ narrowedInterfaces: {
31658
+ ...current.narrowedInterfaces,
31659
+ ...type.narrowedInterfaces
31660
+ }
31661
+ };
31662
+ }
31654
31663
  return nullable2 && current.nullable !== true ? { ...current, nullable: true } : current;
31655
31664
  }
31656
31665
  function neoScriptMemberReceiverType(type, memberName, project) {
31657
31666
  const primary = neoScriptMemberLookupType(type);
31658
- if (primary.kind !== "named" || primary.narrowedInterfaces === void 0)
31667
+ if (primary.kind !== "named" && primary.kind !== "typeParameter" || primary.narrowedInterfaces === void 0)
31659
31668
  return primary;
31660
- const declaration = project.typeById.get(primary.typeId);
31669
+ const declaration = primary.kind === "named" ? project.typeById.get(primary.typeId) : void 0;
31661
31670
  if (declaration?.kind === "class" && (memberName === NEOSCRIPT_CLASS_ID_MEMBER || memberName === "Clone"))
31662
31671
  return primary;
31663
31672
  if (declaration?.members.some((member) => member.name === memberName))
@@ -31986,12 +31995,12 @@ function isNeoScriptTypeAssignable(source, target, project) {
31986
31995
  if (isUnknownType(source) || isUnknownType(target)) return false;
31987
31996
  if (isNullType(source)) return isNullableType2(target);
31988
31997
  if (isNullableType2(source) && !isNullableType2(target)) return false;
31989
- if (target.kind === "named" && target.narrowedInterfaces !== void 0) {
31998
+ if ((target.kind === "named" || target.kind === "typeParameter") && target.narrowedInterfaces !== void 0) {
31990
31999
  for (const bound of Object.values(target.narrowedInterfaces)) {
31991
32000
  if (!isNeoScriptTypeAssignable(source, bound, project)) return false;
31992
32001
  }
31993
32002
  }
31994
- if (source.kind === "named" && source.narrowedInterfaces !== void 0) {
32003
+ if ((source.kind === "named" || source.kind === "typeParameter") && source.narrowedInterfaces !== void 0) {
31995
32004
  const direct = target.kind === "named" ? source.narrowedInterfaces[target.typeId] : void 0;
31996
32005
  if (direct !== void 0 && isNeoScriptTypeAssignable(direct, target, project))
31997
32006
  return true;
@@ -32019,7 +32028,7 @@ function isNeoScriptTypeAssignable(source, target, project) {
32019
32028
  project
32020
32029
  );
32021
32030
  }
32022
- if (!target.typeArguments?.length || project.typeById.get(target.typeId)?.kind !== "interface") {
32031
+ if (!target.typeArguments?.length) {
32023
32032
  return isTypeDerivedFrom(
32024
32033
  project.typeById.get(source.typeId),
32025
32034
  target.typeId,
@@ -32027,7 +32036,7 @@ function isNeoScriptTypeAssignable(source, target, project) {
32027
32036
  /* @__PURE__ */ new Set()
32028
32037
  );
32029
32038
  }
32030
- const construction = interfaceConstruction(source, target.typeId, project);
32039
+ const construction = supertypeConstruction(source, target.typeId, project);
32031
32040
  return construction !== void 0 && invariantTypeArguments(construction, target.typeArguments, project);
32032
32041
  }
32033
32042
  if (source.kind === "typeParameter" && target.kind === "typeParameter") {
@@ -32085,7 +32094,7 @@ function isNeoScriptTypeAssignable(source, target, project) {
32085
32094
  return false;
32086
32095
  }
32087
32096
  function withoutNeoScriptInterfaceProofs(type) {
32088
- if (type.kind !== "named" || type.narrowedInterfaces === void 0)
32097
+ if (type.kind !== "named" && type.kind !== "typeParameter" || type.narrowedInterfaces === void 0)
32089
32098
  return type;
32090
32099
  const { narrowedInterfaces: _proofs, ...declared } = type;
32091
32100
  return declared;
@@ -32093,7 +32102,7 @@ function withoutNeoScriptInterfaceProofs(type) {
32093
32102
  function commonNeoScriptAssignableType(left, right, project) {
32094
32103
  if (isNeoScriptTypeAssignable(left, right, project)) return right;
32095
32104
  if (isNeoScriptTypeAssignable(right, left, project)) return left;
32096
- if (left.kind === "named" && right.kind === "named" && (left.narrowedInterfaces !== void 0 || right.narrowedInterfaces !== void 0)) {
32105
+ if ((left.kind === "named" || left.kind === "typeParameter") && (right.kind === "named" || right.kind === "typeParameter") && (left.narrowedInterfaces !== void 0 || right.narrowedInterfaces !== void 0)) {
32097
32106
  const declaredLeft = withoutNeoScriptInterfaceProofs(left);
32098
32107
  const declaredRight = withoutNeoScriptInterfaceProofs(right);
32099
32108
  const common = commonNeoScriptAssignableType(
@@ -32101,7 +32110,8 @@ function commonNeoScriptAssignableType(left, right, project) {
32101
32110
  declaredRight,
32102
32111
  project
32103
32112
  );
32104
- if (common?.kind !== "named") return null;
32113
+ if (common?.kind !== "named" && common?.kind !== "typeParameter")
32114
+ return null;
32105
32115
  const proofs = {};
32106
32116
  for (const [source, other] of [
32107
32117
  [left, right],
@@ -32154,41 +32164,53 @@ function interfaceInstantiationMessage(declared, expected, project) {
32154
32164
  }
32155
32165
  return message;
32156
32166
  }
32157
- function interfaceConstruction(source, interfaceId, project, seen = /* @__PURE__ */ new Set()) {
32158
- if (source.typeId === interfaceId) return source.typeArguments ?? [];
32159
- const type = project.typeById.get(source.typeId);
32160
- if (type === void 0 || seen.has(type.id)) return void 0;
32161
- seen.add(type.id);
32162
- const bindings = /* @__PURE__ */ new Map();
32163
- type.typeParameters?.forEach((parameter4, index) => {
32164
- const argument2 = source.typeArguments?.[index];
32165
- if (argument2 !== void 0)
32166
- bindings.set(parameter4.id ?? parameter4.name, argument2);
32167
- });
32168
- for (const id2 of [
32169
- ...type.baseTypeIds ?? [],
32170
- ...type.interfaceTypeIds ?? []
32171
- ]) {
32172
- const supertype = {
32173
- kind: "named",
32174
- typeId: id2,
32175
- typeArguments: (type.supertypeArguments?.[id2] ?? []).map(
32176
- (argument2) => substituteNeoScriptTypeParameters(
32177
- argument2,
32178
- (parameter4) => bindings.get(parameter4.id),
32179
- project
32180
- )
32181
- )
32182
- };
32183
- const found = interfaceConstruction(supertype, interfaceId, project, seen);
32184
- if (found !== void 0) return found;
32167
+ function supertypeConstruction(source, supertypeId, project) {
32168
+ for (const type of constructedSupertypes(source, project)) {
32169
+ if (type.typeId === supertypeId) return type.typeArguments ?? [];
32185
32170
  }
32186
32171
  return void 0;
32187
32172
  }
32173
+ function* constructedSupertypes(source, project) {
32174
+ const pending = [source];
32175
+ const seen = /* @__PURE__ */ new Set();
32176
+ while (true) {
32177
+ const current = pending.pop();
32178
+ if (current === void 0) return;
32179
+ if (seen.has(current.typeId)) continue;
32180
+ seen.add(current.typeId);
32181
+ yield current;
32182
+ const type = project.typeById.get(current.typeId);
32183
+ if (type === void 0) continue;
32184
+ const bindings = /* @__PURE__ */ new Map();
32185
+ type.typeParameters?.forEach((parameter4, index) => {
32186
+ const argument2 = current.typeArguments?.[index];
32187
+ if (argument2 !== void 0)
32188
+ bindings.set(parameter4.id ?? parameter4.name, argument2);
32189
+ });
32190
+ const parents = [
32191
+ ...type.baseTypeIds ?? [],
32192
+ ...type.interfaceTypeIds ?? []
32193
+ ];
32194
+ for (const id2 of parents.reverse()) {
32195
+ if (seen.has(id2)) continue;
32196
+ pending.push({
32197
+ kind: "named",
32198
+ typeId: id2,
32199
+ typeArguments: (type.supertypeArguments?.[id2] ?? []).map(
32200
+ (argument2) => substituteNeoScriptTypeParameters(
32201
+ argument2,
32202
+ (parameter4) => bindings.get(parameter4.id),
32203
+ project
32204
+ )
32205
+ )
32206
+ });
32207
+ }
32208
+ }
32209
+ }
32188
32210
  function interfaceUndeterminedReason(classType, interfaceType2, project) {
32189
32211
  const params = classType.typeParameters ?? [];
32190
32212
  if (params.length === 0) return null;
32191
- const construction = interfaceConstruction(
32213
+ const construction = supertypeConstruction(
32192
32214
  {
32193
32215
  kind: "named",
32194
32216
  typeId: classType.id,
@@ -33971,7 +33993,7 @@ function implementerConstruction(implementer, slotInterface, slot, project) {
33971
33993
  );
33972
33994
  if (reason !== null) return void 0;
33973
33995
  }
33974
- const implemented = interfaceConstruction(
33996
+ const implemented = supertypeConstruction(
33975
33997
  {
33976
33998
  kind: "named",
33977
33999
  typeId: implementer.id,
@@ -34422,9 +34444,7 @@ function typeRefsEqual(left, right) {
34422
34444
  if (left.kind === "primitive" && right.kind === "primitive") {
34423
34445
  return left.name === right.name;
34424
34446
  }
34425
- if (left.kind === "named" && right.kind === "named") {
34426
- const leftArgs = left.typeArguments ?? [];
34427
- const rightArgs = right.typeArguments ?? [];
34447
+ if ((left.kind === "named" || left.kind === "typeParameter") && (right.kind === "named" || right.kind === "typeParameter")) {
34428
34448
  if (left.narrowedInterfaces !== right.narrowedInterfaces) {
34429
34449
  const leftBounds = Object.entries(left.narrowedInterfaces ?? {});
34430
34450
  const rightBounds = right.narrowedInterfaces ?? {};
@@ -34435,6 +34455,10 @@ function typeRefsEqual(left, right) {
34435
34455
  return false;
34436
34456
  }
34437
34457
  }
34458
+ }
34459
+ if (left.kind === "named" && right.kind === "named") {
34460
+ const leftArgs = left.typeArguments ?? [];
34461
+ const rightArgs = right.typeArguments ?? [];
34438
34462
  return left.typeId === right.typeId && leftArgs.length === rightArgs.length && leftArgs.every((item, index) => {
34439
34463
  const other = rightArgs[index];
34440
34464
  return other !== void 0 && typeRefsEqual(item, other);
@@ -35416,6 +35440,20 @@ function typesOverlap(left, right, project) {
35416
35440
  if (isNull(right)) return isNullable(left);
35417
35441
  left = neoScriptMemberLookupType(left);
35418
35442
  right = neoScriptMemberLookupType(right);
35443
+ const declaredLeft = withoutNeoScriptInterfaceProofs(left);
35444
+ const declaredRight = withoutNeoScriptInterfaceProofs(right);
35445
+ if (left.kind === "named" || left.kind === "typeParameter") {
35446
+ for (const proof of Object.values(left.narrowedInterfaces ?? {})) {
35447
+ if (!typesOverlap(proof, declaredRight, project)) return false;
35448
+ }
35449
+ }
35450
+ if (right.kind === "named" || right.kind === "typeParameter") {
35451
+ for (const proof of Object.values(right.narrowedInterfaces ?? {})) {
35452
+ if (!typesOverlap(declaredLeft, proof, project)) return false;
35453
+ }
35454
+ }
35455
+ left = declaredLeft;
35456
+ right = declaredRight;
35419
35457
  if (left.kind === "typeParameter" || right.kind === "typeParameter")
35420
35458
  return true;
35421
35459
  if (isNeoScriptTypeAssignable(left, right, project) || isNeoScriptTypeAssignable(right, left, project))
@@ -35429,11 +35467,29 @@ function typesOverlap(left, right, project) {
35429
35467
  const classDeclaration = leftDeclaration?.kind === "class" ? leftDeclaration : rightDeclaration?.kind === "class" ? rightDeclaration : null;
35430
35468
  const interfaceDeclaration = leftDeclaration?.kind === "interface" ? leftDeclaration : rightDeclaration?.kind === "interface" ? rightDeclaration : null;
35431
35469
  if (classDeclaration !== null && interfaceDeclaration !== null) {
35470
+ if (conflictingInterfaceConstructions(left, right, project)) return false;
35432
35471
  return classDeclaration.sealed !== true;
35433
35472
  }
35434
35473
  }
35435
35474
  return isNumeric(left) && isNumeric(right);
35436
35475
  }
35476
+ function conflictingInterfaceConstructions(left, right, project) {
35477
+ const constructions = /* @__PURE__ */ new Map();
35478
+ for (const type of constructedSupertypes(left, project)) {
35479
+ if (project.typeById.get(type.typeId)?.kind === "interface" && type.typeArguments?.length)
35480
+ constructions.set(type.typeId, type.typeArguments);
35481
+ }
35482
+ for (const type of constructedSupertypes(right, project)) {
35483
+ const argumentsList2 = constructions.get(type.typeId);
35484
+ if (!argumentsList2) continue;
35485
+ if (argumentsList2.some((argument2, index) => {
35486
+ const other = type.typeArguments?.[index];
35487
+ return other !== void 0 && !containsTypeParameter(argument2) && !containsTypeParameter(other) && !(isNeoScriptTypeAssignable(argument2, other, project) && isNeoScriptTypeAssignable(other, argument2, project));
35488
+ }))
35489
+ return true;
35490
+ }
35491
+ return false;
35492
+ }
35437
35493
  function isUnknown(type) {
35438
35494
  return type.kind === "primitive" && type.name === "unknown";
35439
35495
  }
@@ -36144,10 +36200,12 @@ var init_strict_resolver = __esm({
36144
36200
  constructor(parent, probe = parent?.probe ?? false) {
36145
36201
  this.parent = parent;
36146
36202
  this.probe = probe;
36203
+ this.externalRoots = parent?.externalRoots ?? /* @__PURE__ */ new Map();
36147
36204
  this.patternBindings = parent?.patternBindings ?? null;
36148
36205
  }
36149
36206
  parent;
36150
36207
  probe;
36208
+ externalRoots;
36151
36209
  entries = /* @__PURE__ */ new Map();
36152
36210
  invalidatedRoots = /* @__PURE__ */ new Set();
36153
36211
  hiddenNarrowingRoots = /* @__PURE__ */ new Set();
@@ -36170,7 +36228,15 @@ var init_strict_resolver = __esm({
36170
36228
  lookup(name) {
36171
36229
  return this.entries.get(name) ?? this.parent?.lookup(name) ?? null;
36172
36230
  }
36231
+ registerExternalRoot(name, type) {
36232
+ if (!this.externalRoots.has(name))
36233
+ this.externalRoots.set(name, { name, type, variableId: name });
36234
+ }
36235
+ lookupFlowRoot(name) {
36236
+ return this.lookup(name) ?? this.externalRoots.get(name) ?? null;
36237
+ }
36173
36238
  containsEntry(entry) {
36239
+ if (this.externalRoots.get(entry.name) === entry) return true;
36174
36240
  for (const candidate of this.entries.values()) {
36175
36241
  if (candidate === entry) return true;
36176
36242
  }
@@ -36228,6 +36294,7 @@ var init_strict_resolver = __esm({
36228
36294
  if (path === rootEntry.name) this.updatePatternType(rootEntry, type);
36229
36295
  }
36230
36296
  updatePatternType(entry, type) {
36297
+ if (this.externalRoots.get(entry.name) === entry) return;
36231
36298
  if (this.probe || entry.patternBinding)
36232
36299
  this.patternBindings = {
36233
36300
  name: entry.name,
@@ -36871,7 +36938,7 @@ var init_strict_resolver = __esm({
36871
36938
  branchExitNarrowings,
36872
36939
  this.project
36873
36940
  )) {
36874
- const rootEntry = scope.lookup(pathRoot(path));
36941
+ const rootEntry = scope.lookupFlowRoot(pathRoot(path));
36875
36942
  if (rootEntry === narrowed.rootEntry) {
36876
36943
  scope.narrow(path, rootEntry, narrowed.type);
36877
36944
  }
@@ -37804,7 +37871,7 @@ var init_strict_resolver = __esm({
37804
37871
  }
37805
37872
  for (const [path, narrowed] of merged) {
37806
37873
  if (!parent.containsEntry(narrowed.rootEntry)) continue;
37807
- const rootEntry = parent.lookup(pathRoot(path));
37874
+ const rootEntry = parent.lookupFlowRoot(pathRoot(path));
37808
37875
  if (rootEntry === narrowed.rootEntry) {
37809
37876
  parent.narrow(path, rootEntry, narrowed.type);
37810
37877
  }
@@ -38031,7 +38098,7 @@ var init_strict_resolver = __esm({
38031
38098
  scope
38032
38099
  );
38033
38100
  if (assignedPath) {
38034
- const rootEntry = scope.lookup(pathRoot(assignedPath));
38101
+ const rootEntry = scope.lookupFlowRoot(pathRoot(assignedPath));
38035
38102
  if (rootEntry) {
38036
38103
  const retainedFacts = unaffectedNarrowings(
38037
38104
  assignedPath,
@@ -38078,11 +38145,7 @@ var init_strict_resolver = __esm({
38078
38145
  referenceAssignment(statement, place, storageType, scope) {
38079
38146
  const source = statement.op === "=" ? statement.value ?? void 0 : void 0;
38080
38147
  const nullLiteral = source?.kind === "litNull";
38081
- const assigned = source === void 0 ? void 0 : this.resolveReferenceExpression(
38082
- source,
38083
- scope,
38084
- nullLiteral ? void 0 : neoScriptReadType(storageType)
38085
- );
38148
+ const assigned = source === void 0 ? void 0 : this.resolveReferenceAssignmentValue(source, scope, storageType);
38086
38149
  const valueAt = (type) => {
38087
38150
  if (source === void 0 || assigned === void 0) return void 0;
38088
38151
  return nullLiteral ? this.resolveReferenceExpression(source, scope, type) : this.readReferences(assigned, type);
@@ -38126,6 +38189,30 @@ var init_strict_resolver = __esm({
38126
38189
  }
38127
38190
  return { target: layer, value: valueAt(layer.type), through };
38128
38191
  }
38192
+ resolveReferenceAssignmentValue(expression, scope, storageType) {
38193
+ if (expression.kind === "conditional") {
38194
+ return this.resolveConditionalExpression(
38195
+ expression,
38196
+ scope,
38197
+ neoScriptReadType(storageType),
38198
+ storageType
38199
+ );
38200
+ }
38201
+ if (expression.kind === "coalesce") {
38202
+ return this.resolveCoalesceExpression(
38203
+ expression,
38204
+ scope,
38205
+ void 0,
38206
+ storageType
38207
+ );
38208
+ }
38209
+ const expected = neoScriptReadType(storageType);
38210
+ return this.resolveReferenceExpression(
38211
+ expression,
38212
+ scope,
38213
+ expression.kind === "litNull" ? void 0 : expected
38214
+ );
38215
+ }
38129
38216
  /** `Reference<target>` as an expression type (P112 §3.1). */
38130
38217
  referenceType(target, nullable2) {
38131
38218
  return neoScriptReferenceType(
@@ -38286,7 +38373,7 @@ var init_strict_resolver = __esm({
38286
38373
  false
38287
38374
  ).type;
38288
38375
  }
38289
- return resolvedTarget.type;
38376
+ return this.resolveIdentifierNatural(targetAst.name, scope, targetAst.pos).type;
38290
38377
  }
38291
38378
  if (targetAst.kind !== "member") return resolvedTarget.type;
38292
38379
  return this.resolveMemberNatural(
@@ -38529,7 +38616,7 @@ var init_strict_resolver = __esm({
38529
38616
  scope
38530
38617
  );
38531
38618
  if (assignedPath) {
38532
- const rootEntry = scope.lookup(pathRoot(assignedPath));
38619
+ const rootEntry = scope.lookupFlowRoot(pathRoot(assignedPath));
38533
38620
  if (rootEntry) {
38534
38621
  const retainedFacts = unaffectedNarrowings(
38535
38622
  assignedPath,
@@ -39265,34 +39352,8 @@ var init_strict_resolver = __esm({
39265
39352
  ...operand.writeRoot ? { writeRoot: operand.writeRoot } : {}
39266
39353
  };
39267
39354
  }
39268
- case "coalesce": {
39269
- const left = this.resolveExpression(expression.left, scope);
39270
- const leftOptional = { ...left.type, nullable: true };
39271
- const nullLeft = isNull(left.type);
39272
- const right = this.resolveExpression(
39273
- expression.right,
39274
- scope,
39275
- nullLeft ? expected : leftOptional
39276
- );
39277
- if (!nullLeft && !isNeoScriptTypeAssignable(right.type, leftOptional, this.project)) {
39278
- throw new CompileError(
39279
- `\`??\` right operand ${this.describe(right.type)} is not assignable to ${this.describe(leftOptional)}`,
39280
- expression.pos
39281
- );
39282
- }
39283
- const resultType = nullLeft ? right.type : {
39284
- ...left.type,
39285
- nullable: isNullable(left.type) && isNullable(right.type)
39286
- };
39287
- return {
39288
- pointer: {
39289
- type: "coalesce" /* Coalesce */,
39290
- left: left.pointer,
39291
- right: right.pointer
39292
- },
39293
- type: resultType
39294
- };
39295
- }
39355
+ case "coalesce":
39356
+ return this.resolveCoalesceExpression(expression, scope, expected);
39296
39357
  case "conditional":
39297
39358
  return this.resolveConditionalExpression(expression, scope, expected);
39298
39359
  case "is": {
@@ -39869,6 +39930,21 @@ var init_strict_resolver = __esm({
39869
39930
  };
39870
39931
  }
39871
39932
  resolveIdentifier(name, scope, pos, usage2 = "value") {
39933
+ const natural = this.resolveIdentifierNatural(name, scope, pos, usage2);
39934
+ if (scope.lookup(name)) return natural;
39935
+ const path = this.narrowingPath(name, scope);
39936
+ const root = path === null ? null : scope.lookupFlowRoot(pathRoot(path));
39937
+ const narrowed = root && path ? scope.lookupNarrowedType(path, root) : null;
39938
+ const resolved = narrowed ? { ...natural, type: narrowed } : natural;
39939
+ this.options.onFlowScope?.({
39940
+ name,
39941
+ position: pos,
39942
+ type: resolved.type,
39943
+ bindings: scope.patternBindings
39944
+ });
39945
+ return resolved;
39946
+ }
39947
+ resolveIdentifierNatural(name, scope, pos, usage2 = "value") {
39872
39948
  if (name === "this" && this.context.kind === "initializer" && this.delegateCaptureContexts.length === 0 && usage2 === "value") {
39873
39949
  throw new CompileError(
39874
39950
  "'this' is unavailable while an initializer runs. Defer instance access with a lambda or method group.",
@@ -39901,7 +39977,7 @@ var init_strict_resolver = __esm({
39901
39977
  };
39902
39978
  }
39903
39979
  const global = this.context.project.globals.find(
39904
- (candidate) => candidate.name === name
39980
+ (symbol) => symbol.name === name
39905
39981
  );
39906
39982
  if (global) return this.symbolValue(global);
39907
39983
  const implicit = this.implicitMember(name);
@@ -40043,11 +40119,29 @@ var init_strict_resolver = __esm({
40043
40119
  if (path === null) return null;
40044
40120
  const root = pathRoot(path);
40045
40121
  if (scope.lookup(root)) return path;
40046
- if (this.context.project.globals.some((symbol) => symbol.name === root)) {
40047
- return path;
40122
+ const global = this.context.project.globals.find(
40123
+ (symbol) => symbol.name === root
40124
+ );
40125
+ if (global) {
40126
+ const key = `global:${root}`;
40127
+ scope.registerExternalRoot(key, global.type);
40128
+ return key + path.slice(root.length);
40048
40129
  }
40049
40130
  const implicit = this.implicitMember(root);
40050
- return implicit && implicit.symbol.static !== true ? `this.${path}` : path;
40131
+ if (implicit && implicit.symbol.static !== true) return `this.${path}`;
40132
+ const owner = implicit?.owner ?? this.project.typeByName.get(root);
40133
+ if (owner) {
40134
+ const memberName = implicit?.symbol.name ?? path.slice(root.length + 1).split(".")[0];
40135
+ const member = implicit?.symbol ?? owner.members.find((candidate) => candidate.name === memberName);
40136
+ const declaring = member?.inheritedFrom;
40137
+ const key = `static:${declaring?.typeName ?? owner.name}`;
40138
+ scope.registerExternalRoot(key, {
40139
+ kind: "named",
40140
+ typeId: declaring?.typeId ?? owner.id
40141
+ });
40142
+ return implicit ? `${key}.${path}` : key + path.slice(root.length);
40143
+ }
40144
+ return path;
40051
40145
  }
40052
40146
  conditionFacts(expression, scope, whenTrue) {
40053
40147
  const pathOf = (value) => this.narrowingPath(canonicalPath(value), scope);
@@ -40065,7 +40159,7 @@ var init_strict_resolver = __esm({
40065
40159
  locals
40066
40160
  )) {
40067
40161
  const path = this.narrowingPath(assignedPath, outerScope);
40068
- const outerEntry = path === null ? null : outerScope.lookup(pathRoot(path));
40162
+ const outerEntry = path === null ? null : outerScope.lookupFlowRoot(pathRoot(path));
40069
40163
  if (outerEntry && path !== null) {
40070
40164
  const retained = unaffectedNarrowings(path, outerEntry, loopEntryScope);
40071
40165
  loopEntryScope.hideInheritedNarrowing(outerEntry);
@@ -40083,7 +40177,7 @@ var init_strict_resolver = __esm({
40083
40177
  targetScope
40084
40178
  );
40085
40179
  const natural = this.readReferences(place, void 0);
40086
- const rootEntry = fact.path === null ? null : targetScope.lookup(pathRoot(fact.path));
40180
+ const rootEntry = fact.path === null ? null : targetScope.lookupFlowRoot(pathRoot(fact.path));
40087
40181
  if (fact.nullValue) {
40088
40182
  if (fact.path === null || rootEntry === null) continue;
40089
40183
  if (place.type.kind === "reference" && !isNullable(place.type)) {
@@ -40104,7 +40198,7 @@ var init_strict_resolver = __esm({
40104
40198
  const targetDefinition = target.kind === "named" ? this.project.typeById.get(target.typeId) : void 0;
40105
40199
  const naturalDefinition = natural.type.kind === "named" ? this.project.typeById.get(natural.type.typeId) : void 0;
40106
40200
  let narrowed = { ...target, nullable: false };
40107
- if (!fact.bindingName && natural.type.kind === "named" && (naturalDefinition?.kind === "class" || naturalDefinition?.kind === "interface") && target.kind === "named" && targetDefinition?.kind === "interface") {
40201
+ if ((natural.type.kind === "typeParameter" || natural.type.kind === "named" && (naturalDefinition?.kind === "class" || naturalDefinition?.kind === "interface")) && target.kind === "named" && targetDefinition?.kind === "interface") {
40108
40202
  narrowed = { ...natural.type, nullable: false };
40109
40203
  if (!isNeoScriptTypeAssignable(narrowed, target, this.project)) {
40110
40204
  narrowed = {
@@ -40116,6 +40210,22 @@ var init_strict_resolver = __esm({
40116
40210
  };
40117
40211
  }
40118
40212
  }
40213
+ if (target.kind === "named" && targetDefinition?.kind === "class") {
40214
+ const lookup = neoScriptMemberLookupType(natural.type);
40215
+ if (lookup.kind === "named" || lookup.kind === "typeParameter") {
40216
+ const { narrowedInterfaces, ...declared } = lookup;
40217
+ const proofs = declared.kind === "named" && this.project.typeById.get(declared.typeId)?.kind === "interface" ? {
40218
+ ...narrowedInterfaces,
40219
+ [declared.typeId]: declared
40220
+ } : narrowedInterfaces;
40221
+ if (proofs !== void 0)
40222
+ narrowed = {
40223
+ ...target,
40224
+ nullable: false,
40225
+ narrowedInterfaces: proofs
40226
+ };
40227
+ }
40228
+ }
40119
40229
  if (mode === "all" && fact.path !== null && rootEntry !== null && place.type.kind !== "reference") {
40120
40230
  targetScope.narrow(fact.path, rootEntry, narrowed);
40121
40231
  }
@@ -40125,7 +40235,7 @@ var init_strict_resolver = __esm({
40125
40235
  }
40126
40236
  targetScope.definePattern({
40127
40237
  name: fact.bindingName,
40128
- type: narrowed,
40238
+ type: { ...target, nullable: false },
40129
40239
  variableId: fact.bindingTest ? this.patternBindingId(fact.bindingTest) : fact.bindingName,
40130
40240
  writeRoot: this.expressionWriteRoot(natural, targetScope),
40131
40241
  pointer: fact.bindingTest ? {
@@ -40405,7 +40515,7 @@ var init_strict_resolver = __esm({
40405
40515
  return wire;
40406
40516
  }
40407
40517
  resolveMember(receiverAst, name, scope, pos, optional2, receiverValue) {
40408
- const resolved = this.resolveMemberNatural(
40518
+ let resolved = this.resolveMemberNatural(
40409
40519
  receiverAst,
40410
40520
  name,
40411
40521
  scope,
@@ -40414,21 +40524,25 @@ var init_strict_resolver = __esm({
40414
40524
  receiverValue
40415
40525
  );
40416
40526
  if (!optional2) {
40417
- const receiverPath = this.narrowingPath(
40418
- canonicalPath(receiverAst),
40527
+ const receiverPath = canonicalPath(receiverAst);
40528
+ const path = this.narrowingPath(
40529
+ receiverPath === null ? null : `${receiverPath}.${name}`,
40419
40530
  scope
40420
40531
  );
40421
- if (receiverPath) {
40422
- const rootEntry = scope.lookup(pathRoot(receiverPath));
40532
+ if (path) {
40533
+ const rootEntry = scope.lookupFlowRoot(pathRoot(path));
40423
40534
  if (rootEntry) {
40424
- const narrowed = scope.lookupNarrowedType(
40425
- `${receiverPath}.${name}`,
40426
- rootEntry
40427
- );
40428
- if (narrowed) return { ...resolved, type: narrowed };
40535
+ const narrowed = scope.lookupNarrowedType(path, rootEntry);
40536
+ if (narrowed) resolved = { ...resolved, type: narrowed };
40429
40537
  }
40430
40538
  }
40431
40539
  }
40540
+ this.options.onFlowScope?.({
40541
+ name,
40542
+ position: pos,
40543
+ type: resolved.type,
40544
+ bindings: scope.patternBindings
40545
+ });
40432
40546
  return resolved;
40433
40547
  }
40434
40548
  resolveStaticMemberValue(staticType, member, pos) {
@@ -42195,7 +42309,7 @@ var init_strict_resolver = __esm({
42195
42309
  scope
42196
42310
  )
42197
42311
  );
42198
- const schemaClassInfo = toWireType(targetType, this.project);
42312
+ const schemaClassInfo = this.constructorWireType(targetType, expression);
42199
42313
  if (schemaClassInfo.type !== 7 /* Class */) {
42200
42314
  throw new Error(
42201
42315
  `NeoScript constructor ${className} has non-Class return type ${this.describe(signature.returnType)}.`
@@ -42213,6 +42327,16 @@ var init_strict_resolver = __esm({
42213
42327
  writability: "session" /* Session */
42214
42328
  };
42215
42329
  }
42330
+ /** Constructor storage arguments stay distinct from their expression read types. */
42331
+ constructorWireType(target, expression) {
42332
+ const typeArguments = expression.typeArguments?.map(
42333
+ (argument2) => resolveStoredReferenceTarget(argument2, this.context, this.project)
42334
+ );
42335
+ return toWireType(
42336
+ typeArguments === void 0 ? target : { ...target, typeArguments },
42337
+ this.project
42338
+ );
42339
+ }
42216
42340
  constructorTargetType(schemaClass2, expression, expected) {
42217
42341
  const typeArguments = expression.typeArguments?.map(
42218
42342
  (argument2) => this.resolveType(argument2)
@@ -42343,7 +42467,7 @@ var init_strict_resolver = __esm({
42343
42467
  scope
42344
42468
  );
42345
42469
  const classType = targetType;
42346
- const schemaClassInfo = toWireType(classType, this.project);
42470
+ const schemaClassInfo = this.constructorWireType(classType, expression);
42347
42471
  if (schemaClassInfo.type !== 7 /* Class */) {
42348
42472
  throw new Error(
42349
42473
  `NeoScript declared constructor ${className} projected a non-Class wire type.`
@@ -43206,6 +43330,8 @@ var init_strict_resolver = __esm({
43206
43330
  {
43207
43331
  collectionPointer: receiver.pointer,
43208
43332
  valuePointer: value.pointer,
43333
+ ...isPrimitive(expectedValueType, "float") ? { float: true } : {},
43334
+ ...isPrimitive(expectedValueType, "decimal") ? { decimal: true } : {},
43209
43335
  ...hasReferenceEquality(collection.valueType, this.project) ? { reference: true } : {}
43210
43336
  },
43211
43337
  { kind: "primitive", name: "int" }
@@ -43235,6 +43361,8 @@ var init_strict_resolver = __esm({
43235
43361
  {
43236
43362
  collectionPointer: receiver.pointer,
43237
43363
  valuePointer: value.pointer,
43364
+ ...isPrimitive(expectedValueType, "float") ? { float: true } : {},
43365
+ ...isPrimitive(expectedValueType, "decimal") ? { decimal: true } : {},
43238
43366
  ...hasReferenceEquality(collection.valueType, this.project) ? { reference: true } : {}
43239
43367
  },
43240
43368
  { kind: "primitive", name: "bool" }
@@ -43467,6 +43595,7 @@ var init_strict_resolver = __esm({
43467
43595
  info = {
43468
43596
  ...base,
43469
43597
  op: name,
43598
+ ...isPrimitive(collection.valueType, "decimal") ? { decimalEntries: true } : {},
43470
43599
  ...hasReferenceEquality(collection.valueType, this.project) ? { reference: true } : {}
43471
43600
  };
43472
43601
  resultType = {
@@ -44406,7 +44535,7 @@ var init_strict_resolver = __esm({
44406
44535
  scope
44407
44536
  );
44408
44537
  if (path) {
44409
- const rootEntry = scope.lookup(pathRoot(path));
44538
+ const rootEntry = scope.lookupFlowRoot(pathRoot(path));
44410
44539
  if (rootEntry) scope.invalidate(rootEntry);
44411
44540
  }
44412
44541
  const actionTypeInfo = receiver.wireType ?? toWireType(receiver.type, this.project);
@@ -44458,7 +44587,74 @@ var init_strict_resolver = __esm({
44458
44587
  pos
44459
44588
  );
44460
44589
  }
44461
- resolveConditionalExpression(expression, scope, expected) {
44590
+ referenceAssignmentBranches(left, right, storageType, operator) {
44591
+ let layer = storageType;
44592
+ while (true) {
44593
+ const expected = operator === "coalesce" ? { ...layer, nullable: true } : layer;
44594
+ const resolvedLeft = this.readReferences(left, expected);
44595
+ const resolvedRight = this.readReferences(right, expected);
44596
+ if (isNeoScriptTypeAssignable(resolvedLeft.type, expected, this.project) && isNeoScriptTypeAssignable(resolvedRight.type, expected, this.project)) {
44597
+ return { left: resolvedLeft, right: resolvedRight, type: expected };
44598
+ }
44599
+ if (layer.kind !== "reference") break;
44600
+ layer = layer.target;
44601
+ }
44602
+ return { left, right, type: neoScriptReadType(storageType) };
44603
+ }
44604
+ resolveCoalesceExpression(expression, scope, expected, assignmentType) {
44605
+ let left;
44606
+ let right;
44607
+ if (assignmentType) {
44608
+ const branches = this.referenceAssignmentBranches(
44609
+ this.resolveReferenceAssignmentValue(
44610
+ expression.left,
44611
+ scope,
44612
+ assignmentType
44613
+ ),
44614
+ this.resolveReferenceAssignmentValue(
44615
+ expression.right,
44616
+ scope,
44617
+ assignmentType
44618
+ ),
44619
+ assignmentType,
44620
+ "coalesce"
44621
+ );
44622
+ left = branches.left;
44623
+ right = branches.right;
44624
+ } else {
44625
+ left = this.resolveExpression(
44626
+ expression.left,
44627
+ scope,
44628
+ expected?.kind === "reference" ? { ...expected, nullable: true } : void 0
44629
+ );
44630
+ right = this.resolveExpression(
44631
+ expression.right,
44632
+ scope,
44633
+ isNull(left.type) ? expected : { ...left.type, nullable: true }
44634
+ );
44635
+ }
44636
+ const leftOptional = { ...left.type, nullable: true };
44637
+ const nullLeft = isNull(left.type);
44638
+ if (!nullLeft && !isNeoScriptTypeAssignable(right.type, leftOptional, this.project)) {
44639
+ throw new CompileError(
44640
+ `\`??\` right operand ${this.describe(right.type)} is not assignable to ${this.describe(leftOptional)}`,
44641
+ expression.pos
44642
+ );
44643
+ }
44644
+ const resultType = nullLeft ? right.type : {
44645
+ ...left.type,
44646
+ nullable: isNullable(left.type) && isNullable(right.type)
44647
+ };
44648
+ return {
44649
+ pointer: {
44650
+ type: "coalesce" /* Coalesce */,
44651
+ left: left.pointer,
44652
+ right: right.pointer
44653
+ },
44654
+ type: resultType
44655
+ };
44656
+ }
44657
+ resolveConditionalExpression(expression, scope, expected, assignmentType) {
44462
44658
  const condition = this.toBool(
44463
44659
  this.resolveExpression(expression.condition, scope),
44464
44660
  expression.condition.pos
@@ -44475,7 +44671,38 @@ var init_strict_resolver = __esm({
44475
44671
  );
44476
44672
  let whenTrue;
44477
44673
  let whenFalse;
44478
- if (expected) {
44674
+ if (assignmentType) {
44675
+ whenTrue = this.resolveReferenceAssignmentValue(
44676
+ expression.whenTrue,
44677
+ trueScope,
44678
+ assignmentType
44679
+ );
44680
+ whenFalse = this.resolveReferenceAssignmentValue(
44681
+ expression.whenFalse,
44682
+ falseScope,
44683
+ assignmentType
44684
+ );
44685
+ let common2 = commonNeoScriptAssignableType(
44686
+ whenTrue.type,
44687
+ whenFalse.type,
44688
+ this.project
44689
+ );
44690
+ if (isNull(whenTrue.type)) common2 = { ...whenFalse.type, nullable: true };
44691
+ if (isNull(whenFalse.type)) common2 = { ...whenTrue.type, nullable: true };
44692
+ if (common2) {
44693
+ expected = common2;
44694
+ } else {
44695
+ const branches = this.referenceAssignmentBranches(
44696
+ whenTrue,
44697
+ whenFalse,
44698
+ assignmentType,
44699
+ "conditional"
44700
+ );
44701
+ whenTrue = branches.left;
44702
+ whenFalse = branches.right;
44703
+ expected = branches.type;
44704
+ }
44705
+ } else if (expected) {
44479
44706
  whenTrue = this.resolveExpression(
44480
44707
  expression.whenTrue,
44481
44708
  trueScope,
@@ -44512,7 +44739,7 @@ var init_strict_resolver = __esm({
44512
44739
  expression.pos
44513
44740
  );
44514
44741
  }
44515
- if (expected) {
44742
+ if (expected && !assignmentType) {
44516
44743
  this.requireAssignable(
44517
44744
  whenTrue.type,
44518
44745
  expected,
@@ -50824,6 +51051,27 @@ function validateStatements(statements, returnType, scope, environment, uri, ran
50824
51051
  }
50825
51052
  }
50826
51053
  function validateExpression(expression, expected, scope, environment, uri, range2, diagnostics, anchor) {
51054
+ if (expression.kind === "new" && expression.typeArguments?.length) {
51055
+ const { context } = initializerResolver(
51056
+ environment,
51057
+ scope.get("this")?.name ?? "",
51058
+ environment.staticMember
51059
+ );
51060
+ for (const argument2 of expression.typeArguments) {
51061
+ try {
51062
+ resolveNeoScriptType(argument2, context, environment.projectIndex);
51063
+ } catch (error) {
51064
+ if (!(error instanceof CompileError)) throw error;
51065
+ pushDiagnostic(
51066
+ diagnostics,
51067
+ uri,
51068
+ anchor ? anchorSpan(anchor, error, 1) : range2,
51069
+ "invalid-construction-type-argument",
51070
+ error.message.replace(/^\d+:\d+: /, "")
51071
+ );
51072
+ }
51073
+ }
51074
+ }
50827
51075
  if (expected?.name === "NeoDelegate" && validateDelegateMethodGroup(
50828
51076
  expression,
50829
51077
  expected,
@@ -52181,7 +52429,9 @@ function subscriptKeyType(receiver) {
52181
52429
  return void 0;
52182
52430
  }
52183
52431
  function validateReferenceExpression(expression, declared, scope, environment, uri, range2, diagnostics) {
52184
- const expected = declared?.name === "NeoDialogueReference" ? { ...declared, name: "NeoDialogue" } : declared;
52432
+ let expected = declared?.name === "Reference" ? declared.arguments?.[0] : declared;
52433
+ if (expected?.name === "NeoDialogueReference")
52434
+ expected = { ...expected, name: "NeoDialogue" };
52185
52435
  const typeArguments = expression.typeArguments ?? [];
52186
52436
  const names = expression.argumentNames ?? [];
52187
52437
  const idIndex = names.findIndex((name) => name === "id");
@@ -60950,7 +61200,7 @@ function parseSlotPathSpellingV4(expression, isStaticSymbol) {
60950
61200
  return steps[0]?.kind === "member" ? { spelling: "slotPath", head: "root", steps } : null;
60951
61201
  }
60952
61202
  const first = steps[0];
60953
- if (first?.kind !== "member" || steps.length < 2) return null;
61203
+ if (first?.kind !== "member") return null;
60954
61204
  const head = `${current.name}.${first.name}`;
60955
61205
  return isStaticSymbol(head) ? { spelling: "slotPath", head, steps: steps.slice(1) } : null;
60956
61206
  }
@@ -77662,7 +77912,7 @@ function compileNSInitializer(code, ctx) {
77662
77912
  {
77663
77913
  ...compilerContext,
77664
77914
  thisClass: lexicalThisClass ?? null,
77665
- implicitMemberAccess: lexicalThisClass !== null,
77915
+ implicitMemberAccess: lexicalThisClass != null || declaringClass2 != null,
77666
77916
  staticMember: false
77667
77917
  },
77668
77918
  {
@@ -78144,7 +78394,7 @@ function compileMemberInitializerBody(args) {
78144
78394
  returnTypeInfo,
78145
78395
  initializerName: args.member.name,
78146
78396
  lexicalThisClass: parseExpression(defaultValue.init.code).kind === "lambda" ? instanceClass : null,
78147
- declaringClass: instanceClass,
78397
+ declaringClass: args.thisClass,
78148
78398
  argumentTypes: initializerArgumentTypes(
78149
78399
  instanceClass,
78150
78400
  args.constructors ?? []
@@ -78193,7 +78443,7 @@ function compileValueRowInitializerBody(args) {
78193
78443
  lexicalThisClass: args.lexicalThisClass ?? null,
78194
78444
  declaringClass: args.initializerOwnerClass,
78195
78445
  argumentTypes: initializerArgumentTypes(
78196
- args.initializerOwnerClass,
78446
+ args.lexicalThisClass === null ? null : args.initializerOwnerClass,
78197
78447
  args.constructors ?? []
78198
78448
  ),
78199
78449
  ...args.storedConstructionReplay === true ? { storedConstructionReplay: true } : {}
@@ -79252,16 +79502,18 @@ var init_runtime_set = __esm({
79252
79502
  "../packages/neoscript-runtime/src/neoscript/runtime-set.ts"() {
79253
79503
  "use strict";
79254
79504
  RuntimeSet = class {
79255
- constructor(source, reference2, enumEntries, slotReferences = null) {
79505
+ constructor(source, reference2, enumEntries, slotReferences = null, decimalEntries = false) {
79256
79506
  this.source = source;
79257
79507
  this.reference = reference2;
79258
79508
  this.enumEntries = enumEntries;
79259
79509
  this.slotReferences = slotReferences;
79510
+ this.decimalEntries = decimalEntries;
79260
79511
  }
79261
79512
  source;
79262
79513
  reference;
79263
79514
  enumEntries;
79264
79515
  slotReferences;
79516
+ decimalEntries;
79265
79517
  entries = /* @__PURE__ */ new Map();
79266
79518
  validations = /* @__PURE__ */ new Map();
79267
79519
  snapshot;
@@ -79271,6 +79523,9 @@ var init_runtime_set = __esm({
79271
79523
  has(key) {
79272
79524
  return this.entries.has(key);
79273
79525
  }
79526
+ *values() {
79527
+ for (const entry of this.entries.values()) yield entry.raw;
79528
+ }
79274
79529
  add(key, raw, reference2) {
79275
79530
  if (this.entries.has(key)) return;
79276
79531
  this.entries.set(key, { raw, reference: reference2 });
@@ -79857,12 +80112,15 @@ function initializerOwnerContext(document, valueId, rootOwners, valuesById, reco
79857
80112
  currentId = sourceValueId;
79858
80113
  lexicalRoot = rootOwners.get(sourceValueId) ?? lexicalRoot;
79859
80114
  }
79860
- if (lexicalRoot === void 0 || isStaticMember(lexicalRoot)) {
79861
- return { ownerClass: null, lexicalThisClass: null };
80115
+ if (lexicalRoot === void 0) {
80116
+ return { declaringClass: null, lexicalThisClass: null };
79862
80117
  }
79863
80118
  const lexicalRootId = getField(lexicalRoot, "id");
79864
80119
  const ownerClass = typeof lexicalRootId === "string" ? findSchemaPlacement(lexicalRootId, document.classes)?.ownerClass ?? null : null;
79865
- return { ownerClass, lexicalThisClass: ownerClass };
80120
+ return {
80121
+ declaringClass: ownerClass,
80122
+ lexicalThisClass: isStaticMember(lexicalRoot) ? null : ownerClass
80123
+ };
79866
80124
  }
79867
80125
  function isClassRecordValue(value) {
79868
80126
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -82925,7 +83183,14 @@ function evaluateNSGetterWithEffects(getter, ctx, argumentValues = [], options =
82925
83183
  for (let index = 0; index < argumentValues.length; index += 1) {
82926
83184
  const parameter4 = parameters[index];
82927
83185
  if (parameter4 === void 0) continue;
82928
- scope.setLocal(parameter4.id, argumentValues[index]);
83186
+ scope.setLocal(
83187
+ parameter4.id,
83188
+ coerceAssignmentValue(
83189
+ argumentValues[index],
83190
+ parameter4.typeInfo,
83191
+ "getter argument"
83192
+ )
83193
+ );
82929
83194
  }
82930
83195
  try {
82931
83196
  const result = evalBody(
@@ -82935,9 +83200,11 @@ function evaluateNSGetterWithEffects(getter, ctx, argumentValues = [], options =
82935
83200
  evaluationOptions(runtimeCtx, false)
82936
83201
  );
82937
83202
  if (result.kind === "return") {
82938
- if (getter.typeInfo.type === 20 /* Decimal */ && typeof result.value === "number") {
82939
- result.value = coerceDecimalOperand(result.value, "return");
82940
- }
83203
+ result.value = coerceAssignmentValue(
83204
+ result.value,
83205
+ getter.typeInfo,
83206
+ "return"
83207
+ );
82941
83208
  if (ownsInvocationState) {
82942
83209
  flushRuntimeSets(runtimeCtx);
82943
83210
  result.value = exportRuntimeSetValue(result.value, runtimeCtx);
@@ -83772,7 +84039,11 @@ function executeCompiledFunction(action, ctx, args, allowFallthroughReturn, runt
83772
84039
  const parameter4 = action.parameters[index + 2];
83773
84040
  const runtimeTypeInfo = runtimeArgumentTypes[index];
83774
84041
  const value2 = asDeclaredRuntimeSet(
83775
- restoreExportedReferences(filledArgs[index], runtimeTypeInfo, ctx),
84042
+ coerceAssignmentValue(
84043
+ restoreExportedReferences(filledArgs[index], runtimeTypeInfo, ctx),
84044
+ runtimeTypeInfo,
84045
+ "function argument"
84046
+ ),
83776
84047
  runtimeTypeInfo,
83777
84048
  ctx
83778
84049
  );
@@ -83806,9 +84077,7 @@ function executeCompiledFunction(action, ctx, args, allowFallthroughReturn, runt
83806
84077
  }
83807
84078
  return null;
83808
84079
  }
83809
- if (runtimeReturnType.type === 20 /* Decimal */ && typeof value === "number") {
83810
- value = coerceDecimalOperand(value, "function return");
83811
- }
84080
+ value = coerceAssignmentValue(value, runtimeReturnType, "function return");
83812
84081
  if (!runtimeValueMatchesType(value, runtimeReturnType, ctx)) {
83813
84082
  throw new NSGetterRuntimeError(
83814
84083
  "NSFunction returned a value that does not match its compiled return type."
@@ -84147,9 +84416,11 @@ function evalInstructions(instructions, scope, ctx, options) {
84147
84416
  }
84148
84417
  case "variable" /* variable */: {
84149
84418
  let value = evalPointer(ins.variable.pointer, scope, ctx);
84150
- if (ins.variable.typeInfo.type === 20 /* Decimal */ && typeof value === "number") {
84151
- value = coerceDecimalOperand(value, "variable initialization");
84152
- }
84419
+ value = coerceAssignmentValue(
84420
+ value,
84421
+ ins.variable.typeInfo,
84422
+ "variable initialization"
84423
+ );
84153
84424
  value = asDeclaredRuntimeSet(value, ins.variable.typeInfo, ctx);
84154
84425
  scope.setLocal(ins.variable.id, value);
84155
84426
  break;
@@ -84185,9 +84456,11 @@ function evalInstructions(instructions, scope, ctx, options) {
84185
84456
  }
84186
84457
  case "assign" /* assign */: {
84187
84458
  let value = evalPointer(ins.pointer, scope, ctx);
84188
- if (ins.target.typeInfo.type === 20 /* Decimal */ && typeof value === "number") {
84189
- value = coerceDecimalOperand(value, "assignment");
84190
- }
84459
+ value = coerceAssignmentValue(
84460
+ value,
84461
+ ins.target.typeInfo,
84462
+ "assignment"
84463
+ );
84191
84464
  if (ins.target.pointer.type === "variable" /* variable */) {
84192
84465
  assertVariableBindingWritable(scope, ins.target.pointer.variableId);
84193
84466
  scope.setLocal(ins.target.pointer.variableId, value);
@@ -85961,6 +86234,21 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
85961
86234
  );
85962
86235
  }
85963
86236
  const args = ins.args.map((arg) => evalPointer(arg, scope, ctx));
86237
+ const decimalEntries = "entryTypeInfo" in ins.target.typeInfo && ins.target.typeInfo.entryTypeInfo.type === 20 /* Decimal */;
86238
+ let entryArgumentIndex = null;
86239
+ const dictionary = ins.target.typeInfo.type === 5 /* Dictionary */;
86240
+ if (ins.mutation === "Add" /* Add */)
86241
+ entryArgumentIndex = dictionary ? 1 : 0;
86242
+ if (ins.mutation === "Insert" /* Insert */) entryArgumentIndex = 1;
86243
+ if (ins.mutation === "Remove" /* Remove */ && !dictionary)
86244
+ entryArgumentIndex = 0;
86245
+ if (entryArgumentIndex !== null && "entryTypeInfo" in ins.target.typeInfo) {
86246
+ args[entryArgumentIndex] = coerceAssignmentValue(
86247
+ args[entryArgumentIndex],
86248
+ ins.target.typeInfo.entryTypeInfo,
86249
+ "collection mutation entry"
86250
+ );
86251
+ }
85964
86252
  const setEntryMember = mutatesLocalVariable ? null : storedSetEntryMember(targetValue, ctx);
85965
86253
  const isLookupSet = setEntryMember === null && ins.target.typeInfo.type === 9 /* Lookup */;
85966
86254
  if (isLookupSet && Array.isArray(targetValue)) {
@@ -85968,7 +86256,8 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
85968
86256
  targetValue,
85969
86257
  ins.reference === true,
85970
86258
  ins.target.typeInfo.type === 9 /* Lookup */ && (ins.target.typeInfo.entryTypeInfo.type === 8 /* Enum */ || ins.target.typeInfo.entryTypeInfo.type === 18 /* DialogueLookup */),
85971
- ctx
86259
+ ctx,
86260
+ decimalEntries
85972
86261
  );
85973
86262
  }
85974
86263
  const setMatch = setEntryMember !== null && Array.isArray(targetValue) && (ins.mutation === "Add" /* Add */ || ins.mutation === "Remove" /* Remove */) ? findStoredSetEntry(targetValue, args[0], setEntryMember, ctx) : null;
@@ -85987,7 +86276,8 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
85987
86276
  ctx,
85988
86277
  isLookupSet,
85989
86278
  false,
85990
- ins.reference === true
86279
+ ins.reference === true,
86280
+ decimalEntries
85991
86281
  );
85992
86282
  updateCollectionReferenceProvenance(
85993
86283
  targetValue,
@@ -86065,7 +86355,8 @@ function evalCollectionMutationInstruction(ins, scope, ctx, options) {
86065
86355
  ctx,
86066
86356
  isLookupSet,
86067
86357
  ins.reference !== true && ins.mutation === "Remove" /* Remove */ && isArrayCollection(targetValue) && setEntryMember === null && !isLookupSet && findKnownRowIdByValueReference(args[0], ctx) === null,
86068
- ins.reference === true
86358
+ ins.reference === true,
86359
+ setEntryMember === null && decimalEntries
86069
86360
  );
86070
86361
  updateCollectionReferenceProvenance(
86071
86362
  targetValue,
@@ -86341,21 +86632,28 @@ function asDeclaredRuntimeSet(value, type, ctx) {
86341
86632
  value,
86342
86633
  entry === 7 /* Class */ || entry === 22 /* Interface */ || entry === 6 /* List */ || entry === 5 /* Dictionary */ || entry === 9 /* Lookup */,
86343
86634
  entry === 8 /* Enum */ || entry === 18 /* DialogueLookup */,
86344
- ctx
86635
+ ctx,
86636
+ entry === 20 /* Decimal */
86345
86637
  );
86346
86638
  }
86347
86639
  function runtimeSetKey(value, set, ctx) {
86348
86640
  if (set.slotReferences !== null) return slotReferenceKey(value);
86349
86641
  if (set.enumEntries && Array.isArray(value) && value.length === 1)
86350
86642
  value = value[0];
86351
- return toSetEntryKey(value, null, set.reference, ctx);
86643
+ return toSetEntryKey(value, null, set.reference, ctx, set.decimalEntries);
86352
86644
  }
86353
- function runtimeSet(array3, reference2, enumEntries, ctx) {
86645
+ function runtimeSet(array3, reference2, enumEntries, ctx, decimalEntries = false) {
86354
86646
  const sets = ctx.__runtimeSets ??= /* @__PURE__ */ new WeakMap();
86355
86647
  ctx.__dirtyRuntimeSets ??= /* @__PURE__ */ new Set();
86356
86648
  const existing = sets.get(array3);
86357
86649
  if (existing !== void 0) return existing;
86358
- const set = new RuntimeSet(array3, reference2, enumEntries);
86650
+ const set = new RuntimeSet(
86651
+ array3,
86652
+ reference2,
86653
+ enumEntries,
86654
+ null,
86655
+ decimalEntries
86656
+ );
86359
86657
  const references = collectionReferences(array3, ctx);
86360
86658
  for (let index = 0; index < array3.length; index++) {
86361
86659
  const raw = array3[index];
@@ -86474,7 +86772,7 @@ function removableEntryRowIds(targetValue, mutation, args, ctx) {
86474
86772
  }
86475
86773
  return rowIds;
86476
86774
  }
86477
- function applyLocalCollectionMutation(targetValue, mutation, args, ctx, unique = false, resolveRemovalEntries = false, reference2 = false) {
86775
+ function applyLocalCollectionMutation(targetValue, mutation, args, ctx, unique = false, resolveRemovalEntries = false, reference2 = false, decimal2 = false) {
86478
86776
  if (targetValue instanceof RuntimeSet) {
86479
86777
  (ctx.__dirtyRuntimeSets ??= /* @__PURE__ */ new Set()).add(targetValue);
86480
86778
  switch (mutation) {
@@ -86526,6 +86824,7 @@ function applyLocalCollectionMutation(targetValue, mutation, args, ctx, unique =
86526
86824
  case "Remove" /* Remove */:
86527
86825
  if (Array.isArray(targetValue)) {
86528
86826
  const references = resolveRemovalEntries ? collectionReferences(targetValue, ctx) : recordedReferenceEntries(targetValue, ctx) ?? 1 /* Values */;
86827
+ const targetKey = decimal2 ? decimalCollectionKey(args[0]) : args[0];
86529
86828
  let index = -1;
86530
86829
  for (let candidate = 0; candidate < targetValue.length; candidate += 1) {
86531
86830
  const entry = targetValue[candidate];
@@ -86536,10 +86835,8 @@ function applyLocalCollectionMutation(targetValue, mutation, args, ctx, unique =
86536
86835
  }
86537
86836
  continue;
86538
86837
  }
86539
- if (jsEqual(
86540
- typeof entry === "string" && isReferenceEntry(references, candidate) ? resolveValueIfId(entry, ctx) : entry,
86541
- args[0]
86542
- )) {
86838
+ const value = typeof entry === "string" && isReferenceEntry(references, candidate) ? resolveValueIfId(entry, ctx) : entry;
86839
+ if (jsEqual(decimal2 ? decimalCollectionKey(value) : value, targetKey)) {
86543
86840
  index = candidate;
86544
86841
  break;
86545
86842
  }
@@ -87026,12 +87323,22 @@ function evalPointerCore(pointer, scope, ctx, resultUsage = "value") {
87026
87323
  case "function" /* function */:
87027
87324
  return evalFunction(pointer.function, scope, ctx);
87028
87325
  case "listLiteral" /* listLiteral */:
87029
- return pointer.entries.map((e) => evalPointer(e, scope, ctx));
87326
+ return pointer.entries.map(
87327
+ (entry) => coerceAssignmentValue(
87328
+ evalPointer(entry, scope, ctx),
87329
+ pointer.typeInfo.entryTypeInfo,
87330
+ "list entry"
87331
+ )
87332
+ );
87030
87333
  case "dictLiteral" /* dictLiteral */: {
87031
87334
  const out = {};
87032
87335
  for (const e of pointer.entries) {
87033
87336
  const k = evalPointer(e.key, scope, ctx);
87034
- out[String(k)] = evalPointer(e.value, scope, ctx);
87337
+ out[String(k)] = coerceAssignmentValue(
87338
+ evalPointer(e.value, scope, ctx),
87339
+ pointer.typeInfo.entryTypeInfo,
87340
+ "dictionary entry"
87341
+ );
87035
87342
  }
87036
87343
  return out;
87037
87344
  }
@@ -88693,9 +89000,9 @@ function readRecordKey(receiver, k, memberId, ctx) {
88693
89000
  if (receiver === ctx.thisValue && typeof ctx.thisValueRowId === "string") {
88694
89001
  return ctx.thisValueRowId;
88695
89002
  }
88696
- const rowId = findKnownRowIdByValueReference(receiver, ctx);
88697
- if (rowId) return rowId;
88698
- throw new NSGetterRuntimeError("Class value has no backing row id.");
89003
+ const row = trackedRowForValueReference(receiver, ctx);
89004
+ if (row !== null && classIdForValueRow(row, ctx) !== void 0)
89005
+ return row.id;
88699
89006
  }
88700
89007
  const assetMember = resolveAssetRuntimeMember(receiver, k, ctx);
88701
89008
  if (assetMember.kind === "ok") return assetMember.value;
@@ -89993,7 +90300,11 @@ function evalDecimalMathOp(info, fn, scope, ctx) {
89993
90300
  }
89994
90301
  }
89995
90302
  function evalListRepeat(info, scope, ctx) {
89996
- const value = evalPointer(info.valuePointer, scope, ctx);
90303
+ const value = coerceAssignmentValue(
90304
+ evalPointer(info.valuePointer, scope, ctx),
90305
+ info.entryTypeInfo,
90306
+ "List.Repeat entry"
90307
+ );
89997
90308
  const count = numberArg(
89998
90309
  evalPointer(info.countPointer, scope, ctx),
89999
90310
  "List.Repeat count"
@@ -90081,13 +90392,18 @@ function jsEqual(a, b) {
90081
90392
  return a instanceof NSSlotReference && b instanceof NSSlotReference && a.targetId === b.targetId;
90082
90393
  }
90083
90394
  if (a === b) return true;
90084
- if (Array.isArray(a) && Array.isArray(b)) {
90085
- if (a.length !== b.length) return false;
90086
- for (let i2 = 0; i2 < a.length; i2++) {
90087
- if (!jsEqual(a[i2], b[i2])) return false;
90395
+ if (Array.isArray(a) || a instanceof RuntimeSet) {
90396
+ if (!Array.isArray(b) && !(b instanceof RuntimeSet)) return false;
90397
+ const aSize = a instanceof RuntimeSet ? a.size : a.length;
90398
+ const bSize = b instanceof RuntimeSet ? b.size : b.length;
90399
+ if (aSize !== bSize) return false;
90400
+ const other = b.values();
90401
+ for (const entry of a.values()) {
90402
+ if (!jsEqual(entry, other.next().value)) return false;
90088
90403
  }
90089
90404
  return true;
90090
90405
  }
90406
+ if (b instanceof RuntimeSet) return false;
90091
90407
  if (typeof a === "object" && typeof b === "object" && a !== null && b !== null && !Array.isArray(a) && !Array.isArray(b)) {
90092
90408
  const aKeys = Object.keys(a);
90093
90409
  const bKeys = Object.keys(b);
@@ -90523,7 +90839,8 @@ function evalCollectionQuery(info, scope, ctx) {
90523
90839
  output,
90524
90840
  info.reference === true,
90525
90841
  info.enumEntries === true,
90526
- ctx
90842
+ ctx,
90843
+ info.decimalEntries === true
90527
90844
  ) : output;
90528
90845
  };
90529
90846
  if (info.op === "OrderBy" || info.op === "OrderByDescending") {
@@ -90575,7 +90892,8 @@ function evalCollectionQuery(info, scope, ctx) {
90575
90892
  entry,
90576
90893
  valueId,
90577
90894
  info.reference === true,
90578
- ctx
90895
+ ctx,
90896
+ info.decimalEntries === true
90579
90897
  );
90580
90898
  if (seenSetKeys.has(setKey)) return 0 /* Continue */;
90581
90899
  seenSetKeys.add(setKey);
@@ -90630,10 +90948,15 @@ function evalCollectionQuery(info, scope, ctx) {
90630
90948
  }
90631
90949
  return finish();
90632
90950
  }
90633
- function toSetEntryKey(entry, valueId, reference2, ctx) {
90951
+ function toSetEntryKey(entry, valueId, reference2, ctx, decimal2 = false) {
90634
90952
  if (reference2) return valueId ?? referenceIdOf(entry, ctx) ?? entry;
90953
+ if (decimal2) return decimalCollectionKey(entry);
90635
90954
  return typeof entry === "object" && entry !== null ? canonicalJsonStringify(entry) : entry;
90636
90955
  }
90956
+ function decimalCollectionKey(value) {
90957
+ if (value === null) return null;
90958
+ return decimalKey(coerceDecimalOperand(value, "decimal collection entry"));
90959
+ }
90637
90960
  function compareCollectionKeys(left, right, keyType) {
90638
90961
  if (left === null) return right === null ? 0 : -1;
90639
90962
  if (right === null) return 1;
@@ -90751,7 +91074,11 @@ function evalFunction(fn, scope, ctx) {
90751
91074
  }
90752
91075
  case "contains" /* contains */: {
90753
91076
  let c = evalPointer(fn.info.collectionPointer, scope, ctx);
90754
- const target = evalPointer(fn.info.valuePointer, scope, ctx);
91077
+ let target = evalPointer(fn.info.valuePointer, scope, ctx);
91078
+ if (fn.info.float === true && typeof target === "number")
91079
+ target = Math.fround(target);
91080
+ if (fn.info.decimal === true && target !== null)
91081
+ target = coerceDecimalOperand(target, "collection search");
90755
91082
  if (typeof c === "string") {
90756
91083
  if (typeof target !== "string") {
90757
91084
  throw new NSGetterRuntimeError(
@@ -90784,9 +91111,13 @@ function evalFunction(fn, scope, ctx) {
90784
91111
  return referenceIndexOf(c, target, ctx) !== null;
90785
91112
  }
90786
91113
  const targetReferenceId = typeof target === "string" ? null : findKnownRowIdByValueReference(target, ctx);
91114
+ const targetKey = fn.info.decimal ? decimalCollectionKey(target) : target;
90787
91115
  let containsResolvedEntry = false;
90788
91116
  iterateCollection(c, ctx, (entry, _key, valueId) => {
90789
- if (valueId !== null && valueId === targetReferenceId || jsEqual(entry, target)) {
91117
+ if (valueId !== null && valueId === targetReferenceId || jsEqual(
91118
+ fn.info.decimal ? decimalCollectionKey(entry) : entry,
91119
+ targetKey
91120
+ )) {
90790
91121
  containsResolvedEntry = true;
90791
91122
  return 1 /* Break */;
90792
91123
  }
@@ -90799,15 +91130,21 @@ function evalFunction(fn, scope, ctx) {
90799
91130
  evalPointer(fn.info.collectionPointer, scope, ctx),
90800
91131
  "IndexOf receiver"
90801
91132
  );
90802
- const target = evalPointer(fn.info.valuePointer, scope, ctx);
91133
+ let target = evalPointer(fn.info.valuePointer, scope, ctx);
91134
+ if (fn.info.float === true && typeof target === "number")
91135
+ target = Math.fround(target);
90803
91136
  if (fn.info.reference === true) {
90804
91137
  const index = referenceIndexOf(collection, target, ctx);
90805
91138
  return index === null ? -1 : numberArg(index, "IndexOf index");
90806
91139
  }
90807
91140
  const targetReferenceId = typeof target === "string" ? null : findKnownRowIdByValueReference(target, ctx);
91141
+ const targetKey = fn.info.decimal ? decimalCollectionKey(target) : target;
90808
91142
  let found = -1;
90809
91143
  iterateCollection(collection, ctx, (entry, key, valueId) => {
90810
- if (valueId !== null && valueId === targetReferenceId || jsEqual(entry, target)) {
91144
+ if (valueId !== null && valueId === targetReferenceId || jsEqual(
91145
+ fn.info.decimal ? decimalCollectionKey(entry) : entry,
91146
+ targetKey
91147
+ )) {
90811
91148
  found = numberArg(key, "IndexOf index");
90812
91149
  return 1 /* Break */;
90813
91150
  }
@@ -91015,7 +91352,19 @@ function evalFunction(fn, scope, ctx) {
91015
91352
  );
91016
91353
  iterateCollection(c, ctx, callback);
91017
91354
  }
91018
- if (found !== sentinel) return found;
91355
+ if (found !== sentinel) {
91356
+ if (typeof found === "string") {
91357
+ if (c instanceof RuntimeSet) {
91358
+ if (c.enumEntries) return [found];
91359
+ } else {
91360
+ const row = trackedRowForValueReference(c, ctx);
91361
+ const member = row === null ? null : memberForValueRow(row, ctx);
91362
+ if (member?.kind === 8 /* Enum */ || member?.kind === 18 /* DialogueLookup */)
91363
+ return [found];
91364
+ }
91365
+ }
91366
+ return found;
91367
+ }
91019
91368
  if (fn.type === "first" /* first */) {
91020
91369
  throw new NSGetterRuntimeError(
91021
91370
  innerFn ? "First() found no matching entry. Use FirstOrDefault() and handle null if no match is expected." : "First() called on an empty collection. Check that it has entries, or use FirstOrDefault() and handle null."
@@ -92228,10 +92577,19 @@ function constructionInitEvaluator(ctx, createdValues, argumentScopes, construct
92228
92577
  }
92229
92578
  return null;
92230
92579
  };
92580
+ const defaultScopeMemberId = (memberId) => walkExtendsMemberChain(
92581
+ memberId,
92582
+ ctx.vm.members,
92583
+ (declaration) => declaration.defaultValue === void 0 ? void 0 : declaration.id,
92584
+ {
92585
+ memberById: (id2) => indexes4.schemaIndex.member(id2) ?? null,
92586
+ maxHops: ctx.vm.members.length
92587
+ }
92588
+ );
92231
92589
  return (member, init, sourceValueId, genericEnv = instanceEnv) => {
92232
92590
  const memberId = Reflect.get(member, "id");
92233
92591
  const effectiveMemberId = typeof memberId === "string" ? memberId : null;
92234
- const scopeMemberId = indexes4.initializerScopeMemberIds.get(init) ?? (typeof sourceValueId !== "string" ? void 0 : indexes4.initializerScopeMemberIdsByValueId.get(sourceValueId)) ?? effectiveMemberId;
92592
+ const scopeMemberId = indexes4.initializerScopeMemberIds.get(init) ?? (typeof sourceValueId !== "string" ? void 0 : indexes4.initializerScopeMemberIdsByValueId.get(sourceValueId)) ?? (sourceValueId === void 0 && effectiveMemberId !== null ? defaultScopeMemberId(effectiveMemberId) : void 0) ?? effectiveMemberId;
92235
92593
  const compiled = ensureInitializerCompiled({
92236
92594
  init,
92237
92595
  member,
@@ -97315,7 +97673,7 @@ function materializeMemberDefaultValue(args) {
97315
97673
  rootOwners,
97316
97674
  valuesById,
97317
97675
  (id2) => args.readTracking?.valueIds.add(id2)
97318
- ).ownerClass : typeof Reflect.get(member, "id") === "string" && !isStaticMember(member) ? findSchemaPlacement(
97676
+ ).lexicalThisClass : typeof Reflect.get(member, "id") === "string" && !isStaticMember(member) ? findSchemaPlacement(
97319
97677
  String(Reflect.get(member, "id")),
97320
97678
  args.document.classes
97321
97679
  )?.ownerClass ?? null : null;
@@ -108437,15 +108795,19 @@ function deferredReferenceDefault(context, expression) {
108437
108795
  if (elements.length === 0) return null;
108438
108796
  const placeholders = [];
108439
108797
  for (const element of elements) {
108440
- const spelling = parseIndexPathSpellingV4(element) ?? parseSlotPathSpellingV4(
108441
- element,
108442
- (symbol) => context.staticValueIdsBySymbol.has(symbol)
108443
- );
108444
- if (spelling === null) return null;
108445
- placeholders.push(encodeMemberDefaultKeyReferenceV4(spelling));
108798
+ const placeholder = deferredReferenceValue(context, element);
108799
+ if (placeholder === null) return null;
108800
+ placeholders.push(placeholder);
108446
108801
  }
108447
108802
  return placeholders;
108448
108803
  }
108804
+ function deferredReferenceValue(context, expression) {
108805
+ const spelling = parseIndexPathSpellingV4(expression) ?? parseSlotPathSpellingV4(
108806
+ expression,
108807
+ (symbol) => context.staticValueIdsBySymbol.has(symbol) || context.classIdsByName.has(symbol.slice(0, symbol.indexOf(".")))
108808
+ );
108809
+ return spelling === null ? null : encodeMemberDefaultKeyReferenceV4(spelling);
108810
+ }
108449
108811
  function slotReferenceType(readType) {
108450
108812
  if (readType.name === "Reference") return readType;
108451
108813
  const element = readType.name === "Set" ? readType.arguments[0] : void 0;
@@ -108692,6 +109054,10 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
108692
109054
  sourceText
108693
109055
  );
108694
109056
  }
109057
+ if (expected.name === "Reference") {
109058
+ const deferred = deferredReferenceValue(context, expression);
109059
+ if (deferred !== null) return deferred;
109060
+ }
108695
109061
  if (expected.name === "NeoAction") {
108696
109062
  return lowerActionDefault(context, expression, ownerClass, path);
108697
109063
  }
@@ -117729,7 +118095,7 @@ function valueInitializerCompilationSites(document) {
117729
118095
  sites.set(row.id, {
117730
118096
  row,
117731
118097
  member,
117732
- ownerClass: ownerContext.ownerClass,
118098
+ ownerClass: ownerContext.declaringClass,
117733
118099
  lexicalThisClass: ownerContext.lexicalThisClass
117734
118100
  });
117735
118101
  }
@@ -118854,21 +119220,25 @@ function projectValueHeadPlacementGraph(args) {
118854
119220
  );
118855
119221
  return { ...substituteMember(member, bindings, genericMembers, member) };
118856
119222
  };
118857
- const instanceBindings = (classId, member) => {
119223
+ const instanceBindings = (classId, member, value) => {
118858
119224
  if (classId === null || !genericClassIds.has(classId)) return emptyBindings;
118859
- if (isInterfaceTypedMember(member)) {
118860
- return resolveInstanceEnv(
118861
- classId,
118862
- slotClassArguments(member, classId, implementerIndex()),
118863
- genericClasses
118864
- );
118865
- }
118866
- const arguments_ = member.classArguments;
119225
+ const arguments_ = isInterfaceTypedMember(member) ? slotClassArguments(member, classId, implementerIndex()) : member.classArguments;
118867
119226
  if (arguments_ != null && !isGenericBindingsRecord(arguments_))
118868
119227
  throw new Error(
118869
119228
  `Class placement "${classId}" has malformed generic arguments.`
118870
119229
  );
118871
- return resolveInstanceEnv(classId, arguments_, genericClasses);
119230
+ const env = resolveInstanceEnv(classId, arguments_, genericClasses);
119231
+ const stamp = value?.genericBindings;
119232
+ if (stamp !== void 0) {
119233
+ if (!isStringRecord7(stamp))
119234
+ throw new Error(
119235
+ `Class value "${String(value?.id)}" has malformed genericBindings.`
119236
+ );
119237
+ for (const [paramId, entry] of envFromStamp(stamp))
119238
+ env.set(paramId, entry);
119239
+ closeForwardedGenericParams(env);
119240
+ }
119241
+ return env;
118872
119242
  };
118873
119243
  const unorderedByContainer = /* @__PURE__ */ new Map();
118874
119244
  for (const value of values.values()) {
@@ -119013,7 +119383,7 @@ function projectValueHeadPlacementGraph(args) {
119013
119383
  }
119014
119384
  result.set(item.valueId, projection);
119015
119385
  args.contextualMembers?.set(item.valueId, member);
119016
- const childBindings = classId === null ? item.bindings ?? emptyBindings : instanceBindings(classId, member);
119386
+ const childBindings = classId === null ? item.bindings ?? emptyBindings : instanceBindings(classId, member, value);
119017
119387
  if ((member.kind === 5 /* Dictionary */ || member.kind === 6 /* List */ || member.kind === 28 /* Set */) && childBindings.size > 0) {
119018
119388
  if (!isMemberBase(member))
119019
119389
  throw new Error(
@@ -119213,6 +119583,9 @@ function joinPath(parent, child2) {
119213
119583
  function placementsEqual(left, right) {
119214
119584
  return JSON.stringify(left) === JSON.stringify(right);
119215
119585
  }
119586
+ function isStringRecord7(value) {
119587
+ return isRecord6(value) && Object.values(value).every((entry) => typeof entry === "string");
119588
+ }
119216
119589
  function isRecord6(value) {
119217
119590
  return typeof value === "object" && value !== null && !Array.isArray(value);
119218
119591
  }
@@ -124498,6 +124871,61 @@ var init_stored_closure_captures = __esm({
124498
124871
  }
124499
124872
  });
124500
124873
 
124874
+ // ../src/database/construction-replay-equality.ts
124875
+ function createConstructionReplayComparer(reader, ownedValueIds) {
124876
+ let graph;
124877
+ return (args) => {
124878
+ if (!isLiteralValueContent(args.currentRoot)) return false;
124879
+ if (!isLiteralValueContent(args.replayRoot)) return false;
124880
+ if (args.currentRoot.instanceConstructorId !== args.replayRoot.instanceConstructorId)
124881
+ return false;
124882
+ const replayArgs = args.replayRoot.constructorArgs;
124883
+ if (replayArgs === void 0 || replayArgs === null) return true;
124884
+ if (args.currentArguments === void 0 || args.currentArguments === null)
124885
+ return false;
124886
+ graph ??= new MaterializedValueGraphContext(reader.documentView);
124887
+ let owned;
124888
+ for (const edge of graph.constructorEdges(
124889
+ args.currentRoot,
124890
+ args.rootMember
124891
+ )) {
124892
+ const replayed2 = replayArgs[edge.parameterId];
124893
+ if (replayed2 === edge.targetValueId) continue;
124894
+ if (typeof replayed2 === "string" && !args.replayRows.has(replayed2))
124895
+ return false;
124896
+ owned ??= new Set(ownedValueIds(args.currentRoot, args.rootMember));
124897
+ if (!owned.has(edge.targetValueId)) return false;
124898
+ }
124899
+ const stored = { ...args.currentArguments };
124900
+ const replayed = { ...replayArgs };
124901
+ for (const [slot, value] of Object.entries(stored)) {
124902
+ if (typeof value !== "string" || replayed[slot] !== value) continue;
124903
+ delete stored[slot];
124904
+ delete replayed[slot];
124905
+ }
124906
+ return effectiveValuesEqual(
124907
+ reader.normalizeConstructorArguments(
124908
+ stored,
124909
+ args.currentRoot,
124910
+ args.rootMember
124911
+ ),
124912
+ reader.withRowOverrides(args.replayRows).normalizeConstructorArguments(
124913
+ replayed,
124914
+ args.replayRoot,
124915
+ args.rootMember
124916
+ )
124917
+ );
124918
+ };
124919
+ }
124920
+ var init_construction_replay_equality = __esm({
124921
+ "../src/database/construction-replay-equality.ts"() {
124922
+ "use strict";
124923
+ init_effective_value_comparison();
124924
+ init_constructor_argument_ownership();
124925
+ init_members();
124926
+ }
124927
+ });
124928
+
124501
124929
  // ../src/models/project/world-layer-compatibility-error.ts
124502
124930
  var WorldLayerCompatibilityError;
124503
124931
  var init_world_layer_compatibility_error = __esm({
@@ -126505,9 +126933,9 @@ function assertNumberRange(member, value, path) {
126505
126933
  }
126506
126934
  }
126507
126935
  function stringRecord3(value) {
126508
- return isStringRecord7(value) ? value : null;
126936
+ return isStringRecord8(value) ? value : null;
126509
126937
  }
126510
- function isStringRecord7(value) {
126938
+ function isStringRecord8(value) {
126511
126939
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
126512
126940
  return false;
126513
126941
  }
@@ -128143,8 +128571,7 @@ function materializePreparedInstanceInitializers(args) {
128143
128571
  compiledDocument,
128144
128572
  compiledDocument.variants ?? []
128145
128573
  );
128146
- let currentReader = null;
128147
- const requireCurrentReader = () => currentReader ??= new EffectiveValueReader(materializationScope.document);
128574
+ let compareConstruction;
128148
128575
  let ownedValueCollector;
128149
128576
  let valueHashes;
128150
128577
  const liveValueHashes = () => valueHashes ??= indexLiveContentHashesByRecordId(
@@ -128210,16 +128637,28 @@ function materializePreparedInstanceInitializers(args) {
128210
128637
  `construction-arguments-conflict: Value "${valueId}" is already materialized as class "${String(existingConstructedRoot.classId)}", and this construction builds class "${String(materialized.root.classId)}". Delete and recreate the value to change its class.`
128211
128638
  );
128212
128639
  }
128213
- if (replayedCreationDataMatches({
128214
- // The synthetic variant binding members are part of the ownership
128215
- // scope that compiled and evaluated this initializer. Stored replay
128216
- // closes its generic slot from the same ephemeral member id, so its
128217
- // expansion must read that scoped document too.
128218
- currentReader: requireCurrentReader(),
128640
+ compareConstruction ??= createConstructionReplayComparer(
128641
+ new EffectiveValueReader(materializationScope.document),
128642
+ (root, rootMember) => {
128643
+ ownedValueCollector ??= createOwnedValueDeletionCollector(
128644
+ args.document
128645
+ );
128646
+ return ownedValueCollector.collect({
128647
+ rootIds: [root.id],
128648
+ rootMembers: /* @__PURE__ */ new Map([[root.id, rootMember]])
128649
+ });
128650
+ }
128651
+ );
128652
+ const replayRows = new Map(
128653
+ materialized.createdValues.map((row) => [row.id, row])
128654
+ );
128655
+ replayRows.set(materialized.root.id, materialized.root);
128656
+ if (compareConstruction({
128219
128657
  currentRoot: existingConstructedRoot,
128658
+ currentArguments: isLiteralValueContent(existingConstructedRoot) ? existingConstructedRoot.constructorArgs : void 0,
128220
128659
  rootMember: member,
128221
128660
  replayRoot: materialized.root,
128222
- replayCreated: materialized.createdValues
128661
+ replayRows
128223
128662
  })) {
128224
128663
  replayOnlyIndexes.push(site.index);
128225
128664
  batch.upsert([existingConstructedRoot]);
@@ -128340,46 +128779,6 @@ function materializePreparedInstanceInitializers(args) {
128340
128779
  args.prepared.splice(index, 1);
128341
128780
  }
128342
128781
  }
128343
- function replayedCreationDataMatches(args) {
128344
- if (!isLiteralValueContent(args.currentRoot) || !isLiteralValueContent(args.replayRoot)) {
128345
- return false;
128346
- }
128347
- const replayArgs = args.replayRoot.constructorArgs;
128348
- if (replayArgs !== void 0 && replayArgs !== null) {
128349
- const currentArgs = args.currentRoot.constructorArgs;
128350
- if (currentArgs === void 0 || currentArgs === null || !constructorArgumentsSemanticallyEqual({
128351
- currentReader: args.currentReader,
128352
- currentRoot: args.currentRoot,
128353
- rootMember: args.rootMember,
128354
- current: currentArgs,
128355
- replayRoot: args.replayRoot,
128356
- replayCreated: args.replayCreated,
128357
- replay: replayArgs
128358
- })) {
128359
- return false;
128360
- }
128361
- }
128362
- return true;
128363
- }
128364
- function constructorArgumentsSemanticallyEqual(args) {
128365
- const current = args.currentReader;
128366
- const replayRows = /* @__PURE__ */ new Map([
128367
- [args.replayRoot.id, args.replayRoot]
128368
- ]);
128369
- for (const row of args.replayCreated) replayRows.set(row.id, row);
128370
- const replay = current.withRowOverrides(replayRows);
128371
- const currentNormalized = current.normalizeConstructorArguments(
128372
- args.current,
128373
- args.currentRoot,
128374
- args.rootMember
128375
- );
128376
- const replayNormalized = replay.normalizeConstructorArguments(
128377
- args.replay,
128378
- args.replayRoot,
128379
- args.rootMember
128380
- );
128381
- return effectiveValuesEqual(currentNormalized, replayNormalized);
128382
- }
128383
128782
  function completeLocalizedTextCreateEnvelopes(args) {
128384
128783
  const createsLocalizedText = args.changes.some(
128385
128784
  (change) => change.recordKind === "localized-text" && change.operation === "create"
@@ -130368,7 +130767,7 @@ function compileOwnedValueRowInitializer(args) {
130368
130767
  member,
130369
130768
  valueRow: row,
130370
130769
  valueId: row.id,
130371
- initializerOwnerClass: ownerContext.ownerClass,
130770
+ initializerOwnerClass: ownerContext.declaringClass,
130372
130771
  lexicalThisClass: ownerContext.lexicalThisClass,
130373
130772
  // A value-row initializer is source for a persisted construction, never
130374
130773
  // an ad-hoc runtime `new`. The CLI replay compiler uses this same mode;
@@ -131423,7 +131822,7 @@ var init_project_version_schema_commit = __esm({
131423
131822
  init_declared_binding_targets();
131424
131823
  init_stored_closure_captures();
131425
131824
  init_document_initializer_compiler();
131426
- init_effective_value_comparison();
131825
+ init_construction_replay_equality();
131427
131826
  init_classes();
131428
131827
  init_constructor_parameter_settlement();
131429
131828
  init_generics();
@@ -131679,7 +132078,11 @@ function resolveDeclarationListenerTemplate(args) {
131679
132078
  typeId: row.classId,
131680
132079
  nullable: type.nullable
131681
132080
  };
131682
- if (!isNeoScriptTypeAssignable(selectedType, type, projectIndex))
132081
+ if (!isNeoScriptTypeAssignable(
132082
+ selectedType,
132083
+ { kind: "named", typeId: type.typeId, nullable: type.nullable },
132084
+ projectIndex
132085
+ ))
131683
132086
  throw new Error(
131684
132087
  `Listener template ${id2} selects a class that is not assignable to its declared type.`
131685
132088
  );
@@ -137913,7 +138316,7 @@ function toWorldReferenceClassRecord(value) {
137913
138316
  return {
137914
138317
  id: id2,
137915
138318
  extendsClassId: nullableStringField(value, "extendsClassId"),
137916
- schema: isStringRecord8(value.schema) ? value.schema : void 0,
138319
+ schema: isStringRecord9(value.schema) ? value.schema : void 0,
137917
138320
  system: isPlainRecord8(value.system) ? value.system : null
137918
138321
  };
137919
138322
  }
@@ -137931,7 +138334,7 @@ function worldReferenceValueClassId(value) {
137931
138334
  if (value === void 0) return null;
137932
138335
  return typeof value.classId === "string" && value.classId.length > 0 ? value.classId : null;
137933
138336
  }
137934
- function isStringRecord8(value) {
138337
+ function isStringRecord9(value) {
137935
138338
  if (!isPlainRecord8(value)) return false;
137936
138339
  return Object.values(value).every((entry) => typeof entry === "string");
137937
138340
  }
@@ -143807,6 +144210,33 @@ function lowerMemberDefaultSourcesV4(state, analysis, manifest, options = {}) {
143807
144210
  seeds
143808
144211
  };
143809
144212
  }
144213
+ function prepareValueReferencePathsV4(state, manifest, options) {
144214
+ const paths = options.registry.referenceObligations.filter(
144215
+ (obligation) => obligation.kind === "reference" && (obligation.target.spelling === "slotPath" || obligation.target.spelling === "indexPath")
144216
+ );
144217
+ if (paths.length === 0) return;
144218
+ const context = buildValueLowerContext(state, manifest, {
144219
+ analysis: options.analysis,
144220
+ registry: options.registry,
144221
+ valuePlacements: indexValuePlacements(state, {
144222
+ pendingValues: options.registry.pendingValues
144223
+ })
144224
+ });
144225
+ const deletedValueIds = /* @__PURE__ */ new Set();
144226
+ for (const obligation of paths) {
144227
+ const failure = settleReferenceObligation(
144228
+ context,
144229
+ obligation,
144230
+ deletedValueIds,
144231
+ options.resolveRootPath
144232
+ );
144233
+ if (failure !== null)
144234
+ options.registry.loweringFailures.push({
144235
+ message: failure,
144236
+ site: obligation.site
144237
+ });
144238
+ }
144239
+ }
143810
144240
  function drainValueReferenceObligationsV4(state, manifest, options) {
143811
144241
  const deletedValueIds = options.deletedValueIds ?? /* @__PURE__ */ new Set();
143812
144242
  const survivingState = withoutDeletedValues(state, deletedValueIds);
@@ -144280,6 +144710,8 @@ function keyIndexSchemaKey(context, member, collection, spelling) {
144280
144710
  }
144281
144711
  function collectionEntryIds(context, collection, collectionValueId) {
144282
144712
  if (isUnorderedList(collection)) {
144713
+ const authored = context.authoredListEntries.get(collectionValueId);
144714
+ if (authored !== void 0) return authored;
144283
144715
  return [
144284
144716
  ...context.valuePlacements.valueIdsByContainerId.get(
144285
144717
  collectionValueId
@@ -145118,16 +145550,62 @@ function lowerRowBackedDefault(context, member, backed, baseData3, binding) {
145118
145550
  );
145119
145551
  }
145120
145552
  function foreignDelegateCopy(context, member, expression, binding) {
145121
- if (member.kind !== "delegate") return null;
145122
- const path = memberPath2(annotatedValue(expression).expression);
145123
- const parts = path?.split(".");
145124
- if (path === null || parts?.length !== 2) return null;
145125
- const owner = context.classesByName.get(parts[0]);
145126
- if (owner === void 0 || owner.id === binding.ownerClassId) return null;
145127
- const targetId = classSchemaMemberId(context, owner.id, parts[1]);
145128
- if (targetId === null) return null;
145129
- const target = context.members.get(targetId);
145130
- return target?.kind === "delegate" && target.modifier === "static" ? path : null;
145553
+ let runtimeNames;
145554
+ const declaringClass2 = binding.ownerClassId === void 0 ? void 0 : context.classes.get(binding.ownerClassId);
145555
+ const visit = (source) => {
145556
+ const value = annotatedValue(source).expression;
145557
+ if (value.kind === "new") {
145558
+ for (const argument2 of value.args) {
145559
+ const copy = visit(argument2);
145560
+ if (copy !== null) return copy;
145561
+ }
145562
+ for (const field of value.initializer ?? []) {
145563
+ const copy = visit(field.value);
145564
+ if (copy !== null) return copy;
145565
+ }
145566
+ return null;
145567
+ }
145568
+ if (value.kind === "litList") {
145569
+ for (const entry of value.elements) {
145570
+ const copy = visit(entry);
145571
+ if (copy !== null) return copy;
145572
+ }
145573
+ return null;
145574
+ }
145575
+ if (value.kind === "litDict") {
145576
+ for (const entry of value.entries) {
145577
+ const copy = visit(entry.value);
145578
+ if (copy !== null) return copy;
145579
+ }
145580
+ return null;
145581
+ }
145582
+ if (value.kind === "conditional")
145583
+ return visit(value.whenTrue) ?? visit(value.whenFalse);
145584
+ if (value.kind === "coalesce")
145585
+ return visit(value.left) ?? visit(value.right);
145586
+ if (value.kind === "force") return visit(value.operand);
145587
+ const path = memberPath2(value);
145588
+ if (path === null) return null;
145589
+ const parts = path.split(".");
145590
+ let ownerId;
145591
+ let name;
145592
+ if (parts.length === 1) {
145593
+ if (member.modifier !== "static" && (runtimeNames ??= bindingRuntimeIdentifiers(context, binding)).has(path))
145594
+ return null;
145595
+ ownerId = binding.ownerClassId;
145596
+ name = path;
145597
+ } else if (parts.length === 2) {
145598
+ ownerId = context.classesByName.get(parts[0])?.id;
145599
+ name = parts[1];
145600
+ } else return null;
145601
+ if (ownerId === void 0) return null;
145602
+ const targetId = classSchemaMemberId(context, ownerId, name);
145603
+ if (targetId === null) return null;
145604
+ if (declaringClass2?.schema[name] === targetId) return null;
145605
+ const target = context.members.get(targetId);
145606
+ return target?.kind === "delegate" && target.modifier === "static" ? { path, expression: value } : null;
145607
+ };
145608
+ return visit(expression);
145131
145609
  }
145132
145610
  function lowerStoredBinding(context, binding, memberValueIds, seeds) {
145133
145611
  const member = context.members.get(binding.memberId);
@@ -145155,8 +145633,8 @@ function lowerStoredBinding(context, binding, memberValueIds, seeds) {
145155
145633
  const foreign = foreignDelegateCopy(context, member, expression, binding);
145156
145634
  if (foreign !== null) {
145157
145635
  context.loweringFailures.push({
145158
- message: `Static delegate ${member.name} cannot copy ${foreign} from another Class; write () => ${foreign}() instead.`,
145159
- site: referenceSite(binding, expression)
145636
+ message: `Initializer ${binding.label} cannot copy static delegate ${foreign.path} from another Class; write () => ${foreign.path}() instead.`,
145637
+ site: referenceSite(binding, foreign.expression)
145160
145638
  });
145161
145639
  memberValueIds.set(
145162
145640
  binding.memberId,
@@ -147051,15 +147529,27 @@ function retainConstructionArguments(context, row, schemaClass2, expression, sou
147051
147529
  const constructorArgs2 = row.constructorArgs;
147052
147530
  if (!isObjectRecord(constructorArgs2)) return;
147053
147531
  if (row.instanceConstructorId === null) return;
147054
- const constructor2 = storedValueConstructor(
147055
- context,
147056
- schemaClass2,
147057
- recordedStoredConstructorId(row, schemaClass2)
147532
+ const constructorId = recordedStoredConstructorId(row, schemaClass2);
147533
+ const stored = context.state[`constructor:${constructorId}`]?.data;
147534
+ if (!isObjectRecord(stored)) {
147535
+ throw new Error(
147536
+ `Stored construction for ${schemaClass2.name} names missing pulled constructor ${constructorId}.`
147537
+ );
147538
+ }
147539
+ if (stored.classId !== schemaClass2.id) {
147540
+ throw new Error(
147541
+ `Stored constructor ${constructorId} does not belong to ${schemaClass2.name}.`
147542
+ );
147543
+ }
147544
+ const argumentsValue = documentArgumentsToManifest(
147545
+ stored.argumentTypes,
147546
+ { recordKind: "constructor", recordId: constructorId, data: stored },
147547
+ schemaClass2.source.span
147058
147548
  );
147059
147549
  const authoredArguments = constructorArgumentExpressions(expression);
147060
147550
  const argumentEnvironment = valueGenericEnvironment(row, environment);
147061
- for (let index = 0; index < constructor2.arguments.length; index += 1) {
147062
- const argument2 = constructor2.arguments[index];
147551
+ for (let index = 0; index < argumentsValue.length; index += 1) {
147552
+ const argument2 = argumentsValue[index];
147063
147553
  if (argument2 === void 0) continue;
147064
147554
  const valueId = constructorArgs2[`__arg_${index}__`];
147065
147555
  if (typeof valueId !== "string") continue;
@@ -147845,6 +148335,7 @@ function lowerRawMemberTypeName(context, memberId) {
147845
148335
  if (member.kind === 8 /* Enum */ && typeof member.enumId === "string") {
147846
148336
  return context.enumNames.get(member.enumId) ?? null;
147847
148337
  }
148338
+ if (member.kind === 9 /* Lookup */) return "Reference";
147848
148339
  if (member.kind === 6 /* List */) return "List";
147849
148340
  if (member.kind === 28 /* Set */) return "Set";
147850
148341
  if (member.kind === 5 /* Dictionary */) return "Dictionary";
@@ -147859,6 +148350,8 @@ function lowerSchemaMemberTypeName(context, member) {
147859
148350
  return context.referenceTypes().interfaceImplementers().interface(member.interfaceId)?.name ?? null;
147860
148351
  case "enum":
147861
148352
  return context.enumNames.get(member.enumId) ?? null;
148353
+ case "lookup":
148354
+ return "Reference";
147862
148355
  case "list":
147863
148356
  return "List";
147864
148357
  case "set":
@@ -150859,10 +151352,15 @@ function storedConstructorArgumentSource(context, type, value, environment, visi
150859
151352
  throw new Error(
150860
151353
  `Stored constructor argument cannot be typed by interface type parameter ${type.genericParamId} of ${type.ownerInterfaceId}.`
150861
151354
  );
150862
- case "generic":
151355
+ case "generic": {
151356
+ const binding = storedGenericArgumentType(context, type, environment);
151357
+ const argumentType = binding.kind === "reference" ? withSchemaTypeNullability(
151358
+ referenceReadType2(context, binding.target),
151359
+ binding.nullable
151360
+ ) : binding;
150863
151361
  return storedConstructorArgumentSource(
150864
151362
  context,
150865
- storedGenericArgumentType(context, type, environment),
151363
+ argumentType,
150866
151364
  value,
150867
151365
  environment,
150868
151366
  visited,
@@ -150870,6 +151368,7 @@ function storedConstructorArgumentSource(context, type, value, environment, visi
150870
151368
  partial,
150871
151369
  constructorOwnsGraph
150872
151370
  );
151371
+ }
150873
151372
  case "interface":
150874
151373
  case "list":
150875
151374
  case "set":
@@ -151066,8 +151565,14 @@ function schemaTypeForBindingMember(context, memberId, environment, visited = /*
151066
151565
  };
151067
151566
  case "lookup": {
151068
151567
  if (member.declaredType !== null) {
151069
- const target = referenceReadType2(context, member.declaredType);
151070
- return member.collectionMemberId === null && member.multiselect ? { kind: "lookup", nullable: nullable2, entryType: target } : withSchemaTypeNullability(target, nullable2);
151568
+ if (member.collectionMemberId === null && member.multiselect) {
151569
+ return {
151570
+ kind: "lookup",
151571
+ nullable: nullable2,
151572
+ entryType: referenceReadType2(context, member.declaredType)
151573
+ };
151574
+ }
151575
+ return { kind: "reference", nullable: nullable2, target: member.declaredType };
151071
151576
  }
151072
151577
  if (member.collectionMemberId === null) {
151073
151578
  throw new Error(
@@ -151636,7 +152141,8 @@ function resolveGenericValueMember(context, member, environment) {
151636
152141
  }
151637
152142
  return {
151638
152143
  ...bindingMember,
151639
- id: member.id,
152144
+ // Lookup emission reads the binding's declared target and collection.
152145
+ id: bindingMember.kind === 9 /* Lookup */ ? bindingMemberId : member.id,
151640
152146
  name: member.name,
151641
152147
  defaultValue: member.defaultValue,
151642
152148
  ...member.payload === 1 /* Partial */ ? { payload: 1 /* Partial */ } : {}
@@ -151714,7 +152220,8 @@ function resolveGenericSchemaMember(context, member, environment) {
151714
152220
  }
151715
152221
  const resolved = {
151716
152222
  ...bindingMember,
151717
- id: member.id,
152223
+ // Deferred reference checks resolve this concrete lookup declaration.
152224
+ id: bindingMember.kind === "lookup" ? bindingMemberId : member.id,
151718
152225
  name: member.name,
151719
152226
  defaultValue: member.defaultValue
151720
152227
  };
@@ -153373,8 +153880,15 @@ function reconcileMaterializedInitializersV4(args) {
153373
153880
  );
153374
153881
  }
153375
153882
  let currentRows;
153376
- let currentReader;
153883
+ let compareConstruction;
153377
153884
  let ownedValues;
153885
+ const storedOwnedValues = () => {
153886
+ if (ownedValues !== void 0) return ownedValues;
153887
+ const storedDocument = currentState().document;
153888
+ compilePulledUncompiledConstructorsV4(storedDocument);
153889
+ assertPulledConstructorsCompiled(storedDocument);
153890
+ return ownedValues = createOwnedValueDeletionCollector(storedDocument);
153891
+ };
153378
153892
  const rebuilds = [];
153379
153893
  for (const reconciliation of constructions.values()) {
153380
153894
  if (!replayableValueIds.has(reconciliation.valueId)) continue;
@@ -153426,8 +153940,14 @@ function reconcileMaterializedInitializersV4(args) {
153426
153940
  currentState().document,
153427
153941
  replayDocument
153428
153942
  );
153429
- currentReader ??= new EffectiveValueReader(
153430
- storedRowsDocument(replayDocument, currentRows)
153943
+ compareConstruction ??= createConstructionReplayComparer(
153944
+ new EffectiveValueReader(storedRowsDocument(replayDocument, currentRows)),
153945
+ (root, member) => {
153946
+ return storedOwnedValues().collect({
153947
+ rootIds: [root.id],
153948
+ rootMembers: /* @__PURE__ */ new Map([[root.id, member]])
153949
+ });
153950
+ }
153431
153951
  );
153432
153952
  const replay = replayRows.get(reconciliation.valueId);
153433
153953
  if (replay === void 0) {
@@ -153457,13 +153977,12 @@ function reconcileMaterializedInitializersV4(args) {
153457
153977
  );
153458
153978
  continue;
153459
153979
  }
153460
- if (reconciliation.kind === "storedArguments" && storedArgumentsMatch({
153461
- reader: currentReader,
153462
- stored: reconciliation.storedConstructorArgs,
153980
+ if (reconciliation.kind === "storedArguments" && compareConstruction({
153463
153981
  currentRoot,
153464
- replay,
153982
+ currentArguments: reconciliation.storedConstructorArgs,
153983
+ replayRoot: replay,
153465
153984
  replayRows,
153466
- owner
153985
+ rootMember: owner
153467
153986
  })) {
153468
153987
  continue;
153469
153988
  }
@@ -153475,11 +153994,10 @@ function reconcileMaterializedInitializersV4(args) {
153475
153994
  `Cannot rebuild construction for value "${reconciliation.valueId}": its pulled row is missing.`
153476
153995
  );
153477
153996
  }
153478
- ownedValues ??= createOwnedValueDeletionCollector(replayDocument);
153479
153997
  rebuilds.push({
153480
153998
  valueId: reconciliation.valueId,
153481
153999
  row: rebuiltConstructionRow(stored, reconciliation.code),
153482
- ownedValueIds: ownedValues.collect({
154000
+ ownedValueIds: storedOwnedValues().collect({
153483
154001
  rootIds: [reconciliation.valueId],
153484
154002
  rootMembers: /* @__PURE__ */ new Map([[reconciliation.valueId, owner]])
153485
154003
  })
@@ -153522,22 +154040,6 @@ function sameCompiledProgram(left, right) {
153522
154040
  return literal3 && key === "value" ? isDeepStrictEqual(left[key], right[key]) : sameCompiledProgram(left[key], right[key]);
153523
154041
  });
153524
154042
  }
153525
- function storedArgumentsMatch(args) {
153526
- const replayArgs = isLiteralValueContent(args.replay) ? args.replay.constructorArgs : void 0;
153527
- if (!isObjectRecord(replayArgs)) return false;
153528
- const [storedArgs, replayedArgs] = withoutSharedArguments(
153529
- args.stored,
153530
- replayArgs
153531
- );
153532
- return effectiveValuesEqual(
153533
- args.reader.normalizeConstructorArguments(
153534
- storedArgs,
153535
- args.currentRoot,
153536
- args.owner
153537
- ),
153538
- args.reader.withRowOverrides(args.replayRows).normalizeConstructorArguments(replayedArgs, args.replay, args.owner)
153539
- );
153540
- }
153541
154043
  function rebuiltConstructionRow(data, code) {
153542
154044
  return { ...withoutMaterializedInstanceFields(data), init: { code } };
153543
154045
  }
@@ -153565,7 +154067,7 @@ function retainedLiteralCompiles(document, retained, owners, rootOwners, stored)
153565
154067
  );
153566
154068
  const key = JSON.stringify([
153567
154069
  getField(member, "id") ?? member,
153568
- ownerContext.ownerClass?.id ?? null,
154070
+ ownerContext.declaringClass?.id ?? null,
153569
154071
  ownerContext.lexicalThisClass?.id ?? null,
153570
154072
  code
153571
154073
  ]);
@@ -153592,7 +154094,7 @@ function retainedLiteralFailure(args, records3, document, replayContext, compile
153592
154094
  valueId: compile.valueId,
153593
154095
  code: compile.code,
153594
154096
  member: compile.member,
153595
- initializerOwnerClass: compile.ownerContext.ownerClass,
154097
+ initializerOwnerClass: compile.ownerContext.declaringClass,
153596
154098
  lexicalThisClass: compile.ownerContext.lexicalThisClass,
153597
154099
  evaluate: false,
153598
154100
  compilationProject
@@ -153652,16 +154154,6 @@ function storedRowsWithRenamedKeys(before, after) {
153652
154154
  }
153653
154155
  return rows;
153654
154156
  }
153655
- function withoutSharedArguments(stored, replayed) {
153656
- const storedRest = { ...stored };
153657
- const replayedRest = { ...replayed };
153658
- for (const [slot, value] of Object.entries(stored)) {
153659
- if (typeof value !== "string" || replayed[slot] !== value) continue;
153660
- delete storedRest[slot];
153661
- delete replayedRest[slot];
153662
- }
153663
- return [storedRest, replayedRest];
153664
- }
153665
154157
  function pulledStateDocumentV4(workspace) {
153666
154158
  const state = workspace.state.records;
153667
154159
  const remembered = pulledStateDocuments.get(state);
@@ -153817,6 +154309,12 @@ function materializeInitializersLocallyV4(args) {
153817
154309
  valuesById: batch.valuesById
153818
154310
  });
153819
154311
  for (const id2 of pendingRoots) {
154312
+ const ownerContext = initializerOwnerContext(
154313
+ authoredDocument,
154314
+ id2,
154315
+ walkedRootOwners,
154316
+ batch.valuesById
154317
+ );
153820
154318
  replayStoredConstructionV4({
153821
154319
  records: records3,
153822
154320
  document: authoredDocument,
@@ -153825,6 +154323,8 @@ function materializeInitializersLocallyV4(args) {
153825
154323
  compilationProject,
153826
154324
  replayContext: templateContext,
153827
154325
  member: rootOwners.get(id2),
154326
+ initializerOwnerClass: ownerContext.declaringClass,
154327
+ lexicalThisClass: ownerContext.lexicalThisClass,
153828
154328
  evaluate: false,
153829
154329
  onCompiledInitializer: (init) => compiledInitializers.set(id2, init)
153830
154330
  });
@@ -154128,7 +154628,7 @@ var init_local_initializer_materialization = __esm({
154128
154628
  init_stored_closure_captures();
154129
154629
  init_initializer_dependencies();
154130
154630
  init_initializer_replay();
154131
- init_effective_value_comparison();
154631
+ init_construction_replay_equality();
154132
154632
  init_constructor_argument_ownership();
154133
154633
  init_neo_script_recompile_scope();
154134
154634
  init_compiler_adapter();
@@ -161004,6 +161504,11 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
161004
161504
  unavailableSlots: rootValues.unavailableSlots,
161005
161505
  registry: valueLowerRegistry
161006
161506
  });
161507
+ prepareValueReferencePathsV4(rootPathResolutionState, manifest, {
161508
+ registry: valueLowerRegistry,
161509
+ analysis: projectAnalysisV4,
161510
+ resolveRootPath
161511
+ });
161007
161512
  if (collectionBindings !== void 0 && !(collectionBindings instanceof SchemaSourceError)) {
161008
161513
  const bindings = collectionBindings;
161009
161514
  const templateInitializer = (id2) => {
@@ -161016,10 +161521,19 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
161016
161521
  const rootRecordsById = new Map(
161017
161522
  rootRecords.filter((record7) => record7.recordKind === "value").map((record7) => [record7.recordId, record7])
161018
161523
  );
161019
- const rootMembers = /* @__PURE__ */ new Map();
161524
+ const rootBindings = /* @__PURE__ */ new Map();
161020
161525
  for (const record7 of Object.values(rootPathResolutionState)) {
161021
161526
  if (record7.recordKind === "member" && isObjectRecord(record7.data) && typeof record7.data.valueId === "string")
161022
- rootMembers.set(record7.data.valueId, record7.recordId);
161527
+ rootBindings.set(record7.data.valueId, {
161528
+ memberId: record7.recordId,
161529
+ rootId: record7.data.valueId
161530
+ });
161531
+ }
161532
+ for (const [memberId, seed] of authoredValueSeeds) {
161533
+ if (seed.valueId === void 0) continue;
161534
+ const binding = { memberId, rootId: seed.valueId };
161535
+ rootBindings.set(seed.valueId, binding);
161536
+ for (const row of seed.values ?? []) rootBindings.set(row.id, binding);
161023
161537
  }
161024
161538
  for (const row of collectionBindings.rows.values()) {
161025
161539
  if (rootPathResolutionState[`value:${row.id}`] === void 0) continue;
@@ -161035,11 +161549,21 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
161035
161549
  fileFields: { ...row }
161036
161550
  });
161037
161551
  }
161038
- for (const [rootId, rowIds] of collectionBindings.pathRowsByRootId) {
161039
- const memberId = rootMembers.get(rootId);
161552
+ const pathsByBinding = /* @__PURE__ */ new Map();
161553
+ for (const [pathRootId, rowIds] of collectionBindings.pathRowsByRootId) {
161554
+ const binding = rootBindings.get(pathRootId);
161555
+ const rootId = binding?.rootId ?? pathRootId;
161556
+ let paths = pathsByBinding.get(rootId);
161557
+ if (paths === void 0) {
161558
+ paths = { memberId: binding?.memberId, rowIds: /* @__PURE__ */ new Set() };
161559
+ pathsByBinding.set(rootId, paths);
161560
+ }
161561
+ for (const id2 of rowIds) paths.rowIds.add(id2);
161562
+ }
161563
+ for (const [rootId, { memberId, rowIds }] of pathsByBinding) {
161040
161564
  const root = collectionBindings.rowForValue(rootId);
161041
- if (memberId === void 0 || root === void 0) continue;
161042
- const seed = authoredValueSeeds.get(memberId);
161565
+ if (root === void 0) continue;
161566
+ const seed = memberId === void 0 ? void 0 : bindingSeeds.get(memberId);
161043
161567
  const rows = new Map((seed?.values ?? []).map((row) => [row.id, row]));
161044
161568
  const copiedById = /* @__PURE__ */ new Map();
161045
161569
  const insideInitializerCopy = (id2) => {
@@ -161065,7 +161589,8 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
161065
161589
  for (const id2 of rowIds) {
161066
161590
  if (id2 === rootId) continue;
161067
161591
  const location3 = collectionBindings.locationForValue(id2);
161068
- if (location3 === void 0) continue;
161592
+ const rowMemberId = location3?.memberId ?? rows.get(id2)?.memberId;
161593
+ if (rowMemberId === void 0) continue;
161069
161594
  if (insideInitializerCopy(id2)) continue;
161070
161595
  const row = collectionBindings.rowForValue(id2);
161071
161596
  if (row === void 0)
@@ -161082,13 +161607,13 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
161082
161607
  containerId: row.containerId,
161083
161608
  genericBindings: row.genericBindings
161084
161609
  },
161085
- location3.memberId
161610
+ rowMemberId
161086
161611
  );
161087
161612
  rows.set(id2, authored2);
161088
161613
  if (isNew) valueLowerRegistry.pendingValues.set(id2, authored2);
161089
161614
  continue;
161090
161615
  }
161091
- const classId = row.classId ?? (isClassTypedMember(location3.member) ? location3.member.classId : null);
161616
+ const classId = row.classId ?? (location3 !== void 0 && isClassTypedMember(location3.member) ? location3.member.classId : null);
161092
161617
  const authored = staticValueSeedRow(
161093
161618
  {
161094
161619
  ...row,
@@ -161098,11 +161623,25 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
161098
161623
  instanceConstructorId: row.instanceConstructorId ?? null
161099
161624
  } : {}
161100
161625
  },
161101
- location3.memberId
161626
+ rowMemberId
161102
161627
  );
161103
161628
  rows.set(id2, authored);
161104
161629
  if (isNew) valueLowerRegistry.pendingValues.set(id2, authored);
161105
161630
  }
161631
+ if (memberId === void 0) {
161632
+ for (const row of rows.values()) {
161633
+ if (rootPathResolutionState[`value:${row.id}`] !== void 0)
161634
+ continue;
161635
+ rootRecords.push({
161636
+ recordKind: "value",
161637
+ recordId: row.id,
161638
+ file: "Root.neo",
161639
+ line: 1,
161640
+ fileFields: { id: row.id, ...encodeStoredValueRowFields(row) }
161641
+ });
161642
+ }
161643
+ continue;
161644
+ }
161106
161645
  bindingSeeds.set(memberId, {
161107
161646
  ...seed,
161108
161647
  nodeType: "literal",
@@ -161830,8 +162369,9 @@ function replayAnimationDeclarationInitializersV4(records3, document, fallbackVa
161830
162369
  rootOwners,
161831
162370
  valuesById
161832
162371
  );
161833
- const initializerOwnerClass = ownerContext.ownerClass;
161834
- const requiredConstructor = initializerOwnerClass?.requiredConstructorId === void 0 || initializerOwnerClass.requiredConstructorId === null ? void 0 : constructorsById.get(initializerOwnerClass.requiredConstructorId);
162372
+ const initializerOwnerClass = ownerContext.declaringClass;
162373
+ const requiredConstructorId2 = ownerContext.lexicalThisClass?.requiredConstructorId;
162374
+ const requiredConstructor = requiredConstructorId2 == null ? void 0 : constructorsById.get(requiredConstructorId2);
161835
162375
  const requiredArgumentNames = new Set(
161836
162376
  requiredConstructor?.argumentTypes.map((argument2) => argument2.name) ?? []
161837
162377
  );
@@ -167945,11 +168485,11 @@ function membersForType(snapshot, type) {
167945
168485
  (member) => member.id === cloneId ? cloneSymbol(named, type) : member
167946
168486
  );
167947
168487
  }
167948
- if (type.kind === "named") {
167949
- const named = snapshot.project.typeById.get(type.typeId);
167950
- if (!named) return [];
167951
- let members = named.members.filter((member) => member.static !== true);
167952
- if (type.typeArguments?.length)
168488
+ if (type.kind === "named" || type.kind === "typeParameter") {
168489
+ const named = type.kind === "named" ? snapshot.project.typeById.get(type.typeId) : void 0;
168490
+ if (type.kind === "named" && !named) return [];
168491
+ let members = named?.members.filter((member) => member.static !== true) ?? [];
168492
+ if (type.kind === "named" && type.typeArguments?.length && named)
167953
168493
  members = members.map((member) => {
167954
168494
  return {
167955
168495
  ...member,
@@ -167996,7 +168536,7 @@ function membersForType(snapshot, type) {
167996
168536
  }
167997
168537
  }
167998
168538
  }
167999
- if (named.kind === "class") {
168539
+ if (named?.kind === "class") {
168000
168540
  members = members.filter(
168001
168541
  (member) => member.name !== NEOSCRIPT_CLASS_ID_MEMBER
168002
168542
  );
@@ -168060,8 +168600,16 @@ function resolveMemberOf(snapshot, reference2, receiver) {
168060
168600
  const symbol = enumMemberNamed(receiver.type, reference2.name);
168061
168601
  return symbol ? { type: symbol.type, symbol } : null;
168062
168602
  }
168063
- const member = resolveMember3(snapshot, receiver.resolution, reference2.name);
168064
- const call = scriptFeatureIndex(snapshot).calls.get(reference2.start);
168603
+ const index = scriptFeatureIndex(snapshot);
168604
+ const tokenIndex = index.tokenIndexes.get(reference2.start);
168605
+ const dotOffset = tokenIndex === void 0 ? void 0 : index.tokens[tokenIndex - 1]?.start;
168606
+ const member = resolveMember3(
168607
+ snapshot,
168608
+ receiver.resolution,
168609
+ reference2.name,
168610
+ dotOffset
168611
+ );
168612
+ const call = index.calls.get(reference2.start);
168065
168613
  return specializeGenericCall(snapshot, member, call?.typeArgumentTokens);
168066
168614
  }
168067
168615
  function isKnownMemberReceiver(snapshot, receiver) {
@@ -168275,7 +168823,12 @@ function resolveChain(snapshot, tokens, offset, expectedType) {
168275
168823
  if (token.kind === "punctuation" && token.text === "." || token.kind === "operator" && token.text === "?.") {
168276
168824
  const member = tokens[cursor + 1];
168277
168825
  if (!member || member.kind !== "identifier") break;
168278
- const resolved = resolveMember3(snapshot, current, member.text);
168826
+ const resolved = resolveMember3(
168827
+ snapshot,
168828
+ current,
168829
+ member.text,
168830
+ token.start
168831
+ );
168279
168832
  if (!resolved) {
168280
168833
  const nextRoot = member.range.start.line > token.range.end.line ? resolveRoot(snapshot, member.text, member.start) : null;
168281
168834
  if (!nextRoot) return null;
@@ -168517,7 +169070,7 @@ function contextualTypeParameters(snapshot) {
168517
169070
  if (thisClass?.kind !== "named") return [];
168518
169071
  return snapshot.project.typeById.get(thisClass.typeId)?.typeParameters ?? [];
168519
169072
  }
168520
- function resolveMember3(snapshot, receiver, name) {
169073
+ function resolveMember3(snapshot, receiver, name, flowOffset) {
168521
169074
  if (receiver.indexSurface) {
168522
169075
  const index = indexesFor(snapshot, receiver.indexSurface.memberId).find(
168523
169076
  (candidate) => candidate.name === name
@@ -168538,10 +169091,9 @@ function resolveMember3(snapshot, receiver, name) {
168538
169091
  ) : membersForType(snapshot, receiver.type)).find((candidate) => candidate.name === name);
168539
169092
  if (!member || receiver.symbol?.name === "base" && !isConcreteBaseMember(member))
168540
169093
  return null;
168541
- return {
168542
- type: member.returnType ?? member.type,
168543
- symbol: member
168544
- };
169094
+ const flow = flowOffset === void 0 ? void 0 : flowProbe(snapshot).locals.get(flowOffset);
169095
+ const type = flow?.name === name ? flow.type : member.returnType ?? member.type;
169096
+ return { type, symbol: { ...member, type } };
168545
169097
  }
168546
169098
  function scopeAt(snapshot, offset, name) {
168547
169099
  const result = [];
@@ -182029,7 +182581,7 @@ function collectUnityReferencedProjectFileIds(args) {
182029
182581
  )) {
182030
182582
  instanceEnv.set(paramId, { kind: "member", memberId: boundMemberId });
182031
182583
  }
182032
- const childValueIds = isStringRecord9(storedValue) ? storedValue : {};
182584
+ const childValueIds = isStringRecord10(storedValue) ? storedValue : {};
182033
182585
  for (const entry of schema) {
182034
182586
  if (entry.memberId === null) continue;
182035
182587
  const childMember = substituteWalkMember(
@@ -182092,7 +182644,7 @@ function collectUnityReferencedProjectFileIds(args) {
182092
182644
  return;
182093
182645
  }
182094
182646
  if (isMemberDictionaryBase(member)) {
182095
- const childValueIds = isStringRecord9(storedValue) ? storedValue : {};
182647
+ const childValueIds = isStringRecord10(storedValue) ? storedValue : {};
182096
182648
  const substitutedEntryMember = substituteWalkMember(
182097
182649
  member.entryMemberId,
182098
182650
  args.genericEnv,
@@ -182126,7 +182678,7 @@ function readGenericBindingsFromValue(value) {
182126
182678
  if (value == null) return {};
182127
182679
  if (!isLiteralValueContent(value)) return {};
182128
182680
  const bindings = Reflect.get(value, "genericBindings");
182129
- return isStringRecord9(bindings) ? bindings : {};
182681
+ return isStringRecord10(bindings) ? bindings : {};
182130
182682
  }
182131
182683
  function readClassIdFromMemberValueBase(value) {
182132
182684
  if (value === null) return null;
@@ -182146,7 +182698,7 @@ function readFileIdFromMemberValue(value) {
182146
182698
  if (fileId.trim().length === 0) return null;
182147
182699
  return fileId;
182148
182700
  }
182149
- function isStringRecord9(value) {
182701
+ function isStringRecord10(value) {
182150
182702
  if (value === null) return false;
182151
182703
  if (typeof value !== "object") return false;
182152
182704
  return Object.values(value).every((entry) => typeof entry === "string");
@@ -185868,7 +186420,7 @@ function spellClassInterfaceConstructions(ctx, classId, env) {
185868
186420
  path
185869
186421
  );
185870
186422
  if (saved === null) continue;
185871
- const list = [interfaceConstruction2(ctx, interfaceId, name, saved, false)];
186423
+ const list = [interfaceConstruction(ctx, interfaceId, name, saved, false)];
185872
186424
  const inherited = parentClassId === void 0 ? void 0 : index.construction(parentClassId, interfaceId);
185873
186425
  const readOnly = inherited === void 0 ? null : interfaceConstructionArguments(
185874
186426
  ctx,
@@ -185880,13 +186432,13 @@ function spellClassInterfaceConstructions(ctx, classId, env) {
185880
186432
  false
185881
186433
  );
185882
186434
  if (readOnly !== null && readOnly.join() !== saved.join()) {
185883
- list.push(interfaceConstruction2(ctx, interfaceId, name, readOnly, true));
186435
+ list.push(interfaceConstruction(ctx, interfaceId, name, readOnly, true));
185884
186436
  }
185885
186437
  result.set(interfaceId, list);
185886
186438
  }
185887
186439
  return result;
185888
186440
  }
185889
- function interfaceConstruction2(ctx, interfaceId, name, args, readOnlyView) {
186441
+ function interfaceConstruction(ctx, interfaceId, name, args, readOnlyView) {
185890
186442
  const params = ctx.exportData.interfaces[interfaceId]?.genericParams ?? [];
185891
186443
  const suffix = args.length === 0 ? "" : `<${args.join(", ")}>`;
185892
186444
  return {
@@ -186683,18 +187235,36 @@ function generateInheritedPropertyInterfaceAdapters(ctx, classDef, genericEnv) {
186683
187235
  continue;
186684
187236
  }
186685
187237
  const source = `((${receiverType})this).${memberName}`;
186686
- const getter = isMemberWithEntries(member) ? collectionReadExpression(
187238
+ const memberSaved = memberSavedForStorage(
186687
187239
  ctx,
186688
- member,
186689
- `node.Get<${neoMemberNodeType(member)}>("${escapeCSharpString(schemaKey)}")`,
186690
- schemaKey,
186691
- resolveMemberById(ctx, member.entryMemberId, "entryMemberId"),
186692
- memberSavedForStorage(ctx, memberId, false, declarationClass.id),
186693
- null,
186694
- genericEnv,
186695
- interfaceValueType,
186696
- false
186697
- ) : [`return (${interfaceValueType})(object)${source}!;`];
187240
+ memberId,
187241
+ false,
187242
+ declarationClass.id
187243
+ );
187244
+ const getter = isMemberWithEntries(member) ? [
187245
+ ...detachedReadExpression(
187246
+ ctx,
187247
+ member,
187248
+ schemaKey,
187249
+ memberSaved,
187250
+ null,
187251
+ genericEnv,
187252
+ declarationClass.id,
187253
+ false
187254
+ ),
187255
+ ...collectionReadExpression(
187256
+ ctx,
187257
+ member,
187258
+ `node.Get<${neoMemberNodeType(member)}>("${escapeCSharpString(schemaKey)}")`,
187259
+ schemaKey,
187260
+ resolveMemberById(ctx, member.entryMemberId, "entryMemberId"),
187261
+ memberSaved,
187262
+ null,
187263
+ genericEnv,
187264
+ interfaceValueType,
187265
+ false
187266
+ )
187267
+ ] : [`return (${interfaceValueType})(object)${source}!;`];
186698
187268
  const hasSetter = isMemberNSPropertyBase(member) && typeof member.setterCode === "string";
186699
187269
  const adapter = [
186700
187270
  `${interfaceValueType} ${interfaceType2}.${memberName}`,
@@ -190637,7 +191207,7 @@ function readExpression(ctx, member, schemaKey, nodeType, saved, ownerClassName,
190637
191207
  )
190638
191208
  ];
190639
191209
  }
190640
- function detachedReadExpression(ctx, member, schemaKey, saved, writeGuardMemberName, genericEnv, ownerClassId) {
191210
+ function detachedReadExpression(ctx, member, schemaKey, saved, writeGuardMemberName, genericEnv, ownerClassId, genericBindingSaved = saved) {
190641
191211
  if (ownerClassId === void 0 || !classSupportsDetachedViews(ctx, ownerClassId)) {
190642
191212
  return [];
190643
191213
  }
@@ -190667,7 +191237,13 @@ function detachedReadExpression(ctx, member, schemaKey, saved, writeGuardMemberN
190667
191237
  saved,
190668
191238
  genericEnv
190669
191239
  );
190670
- const entryType = csharpValueType(ctx, entryMember, saved, genericEnv);
191240
+ const entryType = csharpValueType(
191241
+ ctx,
191242
+ entryMember,
191243
+ saved,
191244
+ genericEnv,
191245
+ genericBindingSaved
191246
+ );
190671
191247
  if (readEntry2 === null || entryType === null) return [];
190672
191248
  const guardArguments = collectionGuardArguments(
190673
191249
  member,
@@ -190675,10 +191251,10 @@ function detachedReadExpression(ctx, member, schemaKey, saved, writeGuardMemberN
190675
191251
  );
190676
191252
  const [viewType, view] = saved ? [
190677
191253
  `NeoList<${entryType}>`,
190678
- `DetachedList<${entryType}>("${key}", entry => ${readEntry2}, (client, child) => ${childConverter(ctx, entryMember, true, writeGuardMemberName != null, genericEnv)}, item => ${entrySerializeExpression(ctx, entryMember, `writableNode.Get<NeoMemberListWritable>("${key}")`, member.name, genericEnv)}${guardArguments})`
191254
+ `DetachedList<${entryType}>("${key}", entry => ${readEntry2}, (client, child) => ${childConverter(ctx, entryMember, true, writeGuardMemberName != null, genericEnv, genericBindingSaved)}, item => ${entrySerializeExpression(ctx, entryMember, `writableNode.Get<NeoMemberListWritable>("${key}")`, member.name, genericEnv, genericBindingSaved)}${guardArguments})`
190679
191255
  ] : [
190680
191256
  `NeoReadOnlyList<${entryType}>`,
190681
- `DetachedReadOnlyList<${entryType}>("${key}", entry => ${readEntry2}, (client, child) => ${childConverter(ctx, entryMember, false, false, genericEnv)})`
191257
+ `DetachedReadOnlyList<${entryType}>("${key}", entry => ${readEntry2}, (client, child) => ${childConverter(ctx, entryMember, false, false, genericEnv, genericBindingSaved)})`
190682
191258
  ];
190683
191259
  return [
190684
191260
  `if (TryReadDetached("${key}", out _))`,
@@ -191556,7 +192132,13 @@ function childConverter(ctx, member, saved = false, branchOnReadOnly = false, ge
191556
192132
  }
191557
192133
  if (isClassTypedMember(member)) {
191558
192134
  const typeName = ctx.typeNames.get(member.classId) ?? "NeoNode";
191559
- const constructedSuffix = constructedTypeArgumentsSuffix(ctx, member, true, genericEnv) ?? "";
192135
+ const constructedSuffix = constructedTypeArgumentsSuffix(
192136
+ ctx,
192137
+ member,
192138
+ true,
192139
+ genericEnv,
192140
+ genericBindingSaved
192141
+ ) ?? "";
191560
192142
  const savedTypeRef = `${qualifyGeneratedType(ctx, savedTypeName(typeName))}${constructedSuffix}`;
191561
192143
  const hasWritableFamily = schemaClassHasWritableFamily(ctx, member.classId);
191562
192144
  if (saved && branchOnReadOnly && hasWritableFamily) {
@@ -195138,7 +195720,7 @@ var UNITY_CODEGEN_REVISION;
195138
195720
  var init_unity_codegen_revision = __esm({
195139
195721
  "../src/models/exports/unity-codegen-revision.ts"() {
195140
195722
  "use strict";
195141
- UNITY_CODEGEN_REVISION = "e875228ee779f868c2c818eb9e245604cd074598712ffd3f8394f460317b1a28";
195723
+ UNITY_CODEGEN_REVISION = "f748ddae5544d547b4d1139dcdbc86b86b01ab0aae4a9a24656ad8858258b460";
195142
195724
  }
195143
195725
  });
195144
195726
 
@@ -216276,7 +216858,7 @@ var releaseWorkspaceLock = () => void 0;
216276
216858
  async function main() {
216277
216859
  const args = parseArgs(process.argv.slice(2));
216278
216860
  if (args.command === "--version") {
216279
- console.log("0.84.3");
216861
+ console.log("0.84.5");
216280
216862
  return;
216281
216863
  }
216282
216864
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {