@neocompose/cli 0.84.4 → 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.
@@ -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.4",
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) {
@@ -44421,7 +44535,7 @@ var init_strict_resolver = __esm({
44421
44535
  scope
44422
44536
  );
44423
44537
  if (path) {
44424
- const rootEntry = scope.lookup(pathRoot(path));
44538
+ const rootEntry = scope.lookupFlowRoot(pathRoot(path));
44425
44539
  if (rootEntry) scope.invalidate(rootEntry);
44426
44540
  }
44427
44541
  const actionTypeInfo = receiver.wireType ?? toWireType(receiver.type, this.project);
@@ -44473,7 +44587,74 @@ var init_strict_resolver = __esm({
44473
44587
  pos
44474
44588
  );
44475
44589
  }
44476
- 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) {
44477
44658
  const condition = this.toBool(
44478
44659
  this.resolveExpression(expression.condition, scope),
44479
44660
  expression.condition.pos
@@ -44490,7 +44671,38 @@ var init_strict_resolver = __esm({
44490
44671
  );
44491
44672
  let whenTrue;
44492
44673
  let whenFalse;
44493
- 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) {
44494
44706
  whenTrue = this.resolveExpression(
44495
44707
  expression.whenTrue,
44496
44708
  trueScope,
@@ -44527,7 +44739,7 @@ var init_strict_resolver = __esm({
44527
44739
  expression.pos
44528
44740
  );
44529
44741
  }
44530
- if (expected) {
44742
+ if (expected && !assignmentType) {
44531
44743
  this.requireAssignable(
44532
44744
  whenTrue.type,
44533
44745
  expected,
@@ -50839,6 +51051,27 @@ function validateStatements(statements, returnType, scope, environment, uri, ran
50839
51051
  }
50840
51052
  }
50841
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
+ }
50842
51075
  if (expected?.name === "NeoDelegate" && validateDelegateMethodGroup(
50843
51076
  expression,
50844
51077
  expected,
@@ -60967,7 +61200,7 @@ function parseSlotPathSpellingV4(expression, isStaticSymbol) {
60967
61200
  return steps[0]?.kind === "member" ? { spelling: "slotPath", head: "root", steps } : null;
60968
61201
  }
60969
61202
  const first = steps[0];
60970
- if (first?.kind !== "member" || steps.length < 2) return null;
61203
+ if (first?.kind !== "member") return null;
60971
61204
  const head = `${current.name}.${first.name}`;
60972
61205
  return isStaticSymbol(head) ? { spelling: "slotPath", head, steps: steps.slice(1) } : null;
60973
61206
  }
@@ -77679,7 +77912,7 @@ function compileNSInitializer(code, ctx) {
77679
77912
  {
77680
77913
  ...compilerContext,
77681
77914
  thisClass: lexicalThisClass ?? null,
77682
- implicitMemberAccess: lexicalThisClass !== null,
77915
+ implicitMemberAccess: lexicalThisClass != null || declaringClass2 != null,
77683
77916
  staticMember: false
77684
77917
  },
77685
77918
  {
@@ -78161,7 +78394,7 @@ function compileMemberInitializerBody(args) {
78161
78394
  returnTypeInfo,
78162
78395
  initializerName: args.member.name,
78163
78396
  lexicalThisClass: parseExpression(defaultValue.init.code).kind === "lambda" ? instanceClass : null,
78164
- declaringClass: instanceClass,
78397
+ declaringClass: args.thisClass,
78165
78398
  argumentTypes: initializerArgumentTypes(
78166
78399
  instanceClass,
78167
78400
  args.constructors ?? []
@@ -78210,7 +78443,7 @@ function compileValueRowInitializerBody(args) {
78210
78443
  lexicalThisClass: args.lexicalThisClass ?? null,
78211
78444
  declaringClass: args.initializerOwnerClass,
78212
78445
  argumentTypes: initializerArgumentTypes(
78213
- args.initializerOwnerClass,
78446
+ args.lexicalThisClass === null ? null : args.initializerOwnerClass,
78214
78447
  args.constructors ?? []
78215
78448
  ),
78216
78449
  ...args.storedConstructionReplay === true ? { storedConstructionReplay: true } : {}
@@ -79879,12 +80112,15 @@ function initializerOwnerContext(document, valueId, rootOwners, valuesById, reco
79879
80112
  currentId = sourceValueId;
79880
80113
  lexicalRoot = rootOwners.get(sourceValueId) ?? lexicalRoot;
79881
80114
  }
79882
- if (lexicalRoot === void 0 || isStaticMember(lexicalRoot)) {
79883
- return { ownerClass: null, lexicalThisClass: null };
80115
+ if (lexicalRoot === void 0) {
80116
+ return { declaringClass: null, lexicalThisClass: null };
79884
80117
  }
79885
80118
  const lexicalRootId = getField(lexicalRoot, "id");
79886
80119
  const ownerClass = typeof lexicalRootId === "string" ? findSchemaPlacement(lexicalRootId, document.classes)?.ownerClass ?? null : null;
79887
- return { ownerClass, lexicalThisClass: ownerClass };
80120
+ return {
80121
+ declaringClass: ownerClass,
80122
+ lexicalThisClass: isStaticMember(lexicalRoot) ? null : ownerClass
80123
+ };
79888
80124
  }
79889
80125
  function isClassRecordValue(value) {
79890
80126
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -97437,7 +97673,7 @@ function materializeMemberDefaultValue(args) {
97437
97673
  rootOwners,
97438
97674
  valuesById,
97439
97675
  (id2) => args.readTracking?.valueIds.add(id2)
97440
- ).ownerClass : typeof Reflect.get(member, "id") === "string" && !isStaticMember(member) ? findSchemaPlacement(
97676
+ ).lexicalThisClass : typeof Reflect.get(member, "id") === "string" && !isStaticMember(member) ? findSchemaPlacement(
97441
97677
  String(Reflect.get(member, "id")),
97442
97678
  args.document.classes
97443
97679
  )?.ownerClass ?? null : null;
@@ -108559,15 +108795,19 @@ function deferredReferenceDefault(context, expression) {
108559
108795
  if (elements.length === 0) return null;
108560
108796
  const placeholders = [];
108561
108797
  for (const element of elements) {
108562
- const spelling = parseIndexPathSpellingV4(element) ?? parseSlotPathSpellingV4(
108563
- element,
108564
- (symbol) => context.staticValueIdsBySymbol.has(symbol)
108565
- );
108566
- if (spelling === null) return null;
108567
- placeholders.push(encodeMemberDefaultKeyReferenceV4(spelling));
108798
+ const placeholder = deferredReferenceValue(context, element);
108799
+ if (placeholder === null) return null;
108800
+ placeholders.push(placeholder);
108568
108801
  }
108569
108802
  return placeholders;
108570
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
+ }
108571
108811
  function slotReferenceType(readType) {
108572
108812
  if (readType.name === "Reference") return readType;
108573
108813
  const element = readType.name === "Set" ? readType.arguments[0] : void 0;
@@ -108814,6 +109054,10 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
108814
109054
  sourceText
108815
109055
  );
108816
109056
  }
109057
+ if (expected.name === "Reference") {
109058
+ const deferred = deferredReferenceValue(context, expression);
109059
+ if (deferred !== null) return deferred;
109060
+ }
108817
109061
  if (expected.name === "NeoAction") {
108818
109062
  return lowerActionDefault(context, expression, ownerClass, path);
108819
109063
  }
@@ -117851,7 +118095,7 @@ function valueInitializerCompilationSites(document) {
117851
118095
  sites.set(row.id, {
117852
118096
  row,
117853
118097
  member,
117854
- ownerClass: ownerContext.ownerClass,
118098
+ ownerClass: ownerContext.declaringClass,
117855
118099
  lexicalThisClass: ownerContext.lexicalThisClass
117856
118100
  });
117857
118101
  }
@@ -130523,7 +130767,7 @@ function compileOwnedValueRowInitializer(args) {
130523
130767
  member,
130524
130768
  valueRow: row,
130525
130769
  valueId: row.id,
130526
- initializerOwnerClass: ownerContext.ownerClass,
130770
+ initializerOwnerClass: ownerContext.declaringClass,
130527
130771
  lexicalThisClass: ownerContext.lexicalThisClass,
130528
130772
  // A value-row initializer is source for a persisted construction, never
130529
130773
  // an ad-hoc runtime `new`. The CLI replay compiler uses this same mode;
@@ -131834,7 +132078,11 @@ function resolveDeclarationListenerTemplate(args) {
131834
132078
  typeId: row.classId,
131835
132079
  nullable: type.nullable
131836
132080
  };
131837
- if (!isNeoScriptTypeAssignable(selectedType, type, projectIndex))
132081
+ if (!isNeoScriptTypeAssignable(
132082
+ selectedType,
132083
+ { kind: "named", typeId: type.typeId, nullable: type.nullable },
132084
+ projectIndex
132085
+ ))
131838
132086
  throw new Error(
131839
132087
  `Listener template ${id2} selects a class that is not assignable to its declared type.`
131840
132088
  );
@@ -143962,6 +144210,33 @@ function lowerMemberDefaultSourcesV4(state, analysis, manifest, options = {}) {
143962
144210
  seeds
143963
144211
  };
143964
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
+ }
143965
144240
  function drainValueReferenceObligationsV4(state, manifest, options) {
143966
144241
  const deletedValueIds = options.deletedValueIds ?? /* @__PURE__ */ new Set();
143967
144242
  const survivingState = withoutDeletedValues(state, deletedValueIds);
@@ -144435,6 +144710,8 @@ function keyIndexSchemaKey(context, member, collection, spelling) {
144435
144710
  }
144436
144711
  function collectionEntryIds(context, collection, collectionValueId) {
144437
144712
  if (isUnorderedList(collection)) {
144713
+ const authored = context.authoredListEntries.get(collectionValueId);
144714
+ if (authored !== void 0) return authored;
144438
144715
  return [
144439
144716
  ...context.valuePlacements.valueIdsByContainerId.get(
144440
144717
  collectionValueId
@@ -145273,16 +145550,62 @@ function lowerRowBackedDefault(context, member, backed, baseData3, binding) {
145273
145550
  );
145274
145551
  }
145275
145552
  function foreignDelegateCopy(context, member, expression, binding) {
145276
- if (member.kind !== "delegate") return null;
145277
- const path = memberPath2(annotatedValue(expression).expression);
145278
- const parts = path?.split(".");
145279
- if (path === null || parts?.length !== 2) return null;
145280
- const owner = context.classesByName.get(parts[0]);
145281
- if (owner === void 0 || owner.id === binding.ownerClassId) return null;
145282
- const targetId = classSchemaMemberId(context, owner.id, parts[1]);
145283
- if (targetId === null) return null;
145284
- const target = context.members.get(targetId);
145285
- 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);
145286
145609
  }
145287
145610
  function lowerStoredBinding(context, binding, memberValueIds, seeds) {
145288
145611
  const member = context.members.get(binding.memberId);
@@ -145310,8 +145633,8 @@ function lowerStoredBinding(context, binding, memberValueIds, seeds) {
145310
145633
  const foreign = foreignDelegateCopy(context, member, expression, binding);
145311
145634
  if (foreign !== null) {
145312
145635
  context.loweringFailures.push({
145313
- message: `Static delegate ${member.name} cannot copy ${foreign} from another Class; write () => ${foreign}() instead.`,
145314
- 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)
145315
145638
  });
145316
145639
  memberValueIds.set(
145317
145640
  binding.memberId,
@@ -153744,7 +154067,7 @@ function retainedLiteralCompiles(document, retained, owners, rootOwners, stored)
153744
154067
  );
153745
154068
  const key = JSON.stringify([
153746
154069
  getField(member, "id") ?? member,
153747
- ownerContext.ownerClass?.id ?? null,
154070
+ ownerContext.declaringClass?.id ?? null,
153748
154071
  ownerContext.lexicalThisClass?.id ?? null,
153749
154072
  code
153750
154073
  ]);
@@ -153771,7 +154094,7 @@ function retainedLiteralFailure(args, records3, document, replayContext, compile
153771
154094
  valueId: compile.valueId,
153772
154095
  code: compile.code,
153773
154096
  member: compile.member,
153774
- initializerOwnerClass: compile.ownerContext.ownerClass,
154097
+ initializerOwnerClass: compile.ownerContext.declaringClass,
153775
154098
  lexicalThisClass: compile.ownerContext.lexicalThisClass,
153776
154099
  evaluate: false,
153777
154100
  compilationProject
@@ -153986,6 +154309,12 @@ function materializeInitializersLocallyV4(args) {
153986
154309
  valuesById: batch.valuesById
153987
154310
  });
153988
154311
  for (const id2 of pendingRoots) {
154312
+ const ownerContext = initializerOwnerContext(
154313
+ authoredDocument,
154314
+ id2,
154315
+ walkedRootOwners,
154316
+ batch.valuesById
154317
+ );
153989
154318
  replayStoredConstructionV4({
153990
154319
  records: records3,
153991
154320
  document: authoredDocument,
@@ -153994,6 +154323,8 @@ function materializeInitializersLocallyV4(args) {
153994
154323
  compilationProject,
153995
154324
  replayContext: templateContext,
153996
154325
  member: rootOwners.get(id2),
154326
+ initializerOwnerClass: ownerContext.declaringClass,
154327
+ lexicalThisClass: ownerContext.lexicalThisClass,
153997
154328
  evaluate: false,
153998
154329
  onCompiledInitializer: (init) => compiledInitializers.set(id2, init)
153999
154330
  });
@@ -161173,6 +161504,11 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
161173
161504
  unavailableSlots: rootValues.unavailableSlots,
161174
161505
  registry: valueLowerRegistry
161175
161506
  });
161507
+ prepareValueReferencePathsV4(rootPathResolutionState, manifest, {
161508
+ registry: valueLowerRegistry,
161509
+ analysis: projectAnalysisV4,
161510
+ resolveRootPath
161511
+ });
161176
161512
  if (collectionBindings !== void 0 && !(collectionBindings instanceof SchemaSourceError)) {
161177
161513
  const bindings = collectionBindings;
161178
161514
  const templateInitializer = (id2) => {
@@ -161185,10 +161521,19 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
161185
161521
  const rootRecordsById = new Map(
161186
161522
  rootRecords.filter((record7) => record7.recordKind === "value").map((record7) => [record7.recordId, record7])
161187
161523
  );
161188
- const rootMembers = /* @__PURE__ */ new Map();
161524
+ const rootBindings = /* @__PURE__ */ new Map();
161189
161525
  for (const record7 of Object.values(rootPathResolutionState)) {
161190
161526
  if (record7.recordKind === "member" && isObjectRecord(record7.data) && typeof record7.data.valueId === "string")
161191
- 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);
161192
161537
  }
161193
161538
  for (const row of collectionBindings.rows.values()) {
161194
161539
  if (rootPathResolutionState[`value:${row.id}`] === void 0) continue;
@@ -161204,11 +161549,21 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
161204
161549
  fileFields: { ...row }
161205
161550
  });
161206
161551
  }
161207
- for (const [rootId, rowIds] of collectionBindings.pathRowsByRootId) {
161208
- 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) {
161209
161564
  const root = collectionBindings.rowForValue(rootId);
161210
- if (memberId === void 0 || root === void 0) continue;
161211
- const seed = authoredValueSeeds.get(memberId);
161565
+ if (root === void 0) continue;
161566
+ const seed = memberId === void 0 ? void 0 : bindingSeeds.get(memberId);
161212
161567
  const rows = new Map((seed?.values ?? []).map((row) => [row.id, row]));
161213
161568
  const copiedById = /* @__PURE__ */ new Map();
161214
161569
  const insideInitializerCopy = (id2) => {
@@ -161234,7 +161589,8 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
161234
161589
  for (const id2 of rowIds) {
161235
161590
  if (id2 === rootId) continue;
161236
161591
  const location3 = collectionBindings.locationForValue(id2);
161237
- if (location3 === void 0) continue;
161592
+ const rowMemberId = location3?.memberId ?? rows.get(id2)?.memberId;
161593
+ if (rowMemberId === void 0) continue;
161238
161594
  if (insideInitializerCopy(id2)) continue;
161239
161595
  const row = collectionBindings.rowForValue(id2);
161240
161596
  if (row === void 0)
@@ -161251,13 +161607,13 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
161251
161607
  containerId: row.containerId,
161252
161608
  genericBindings: row.genericBindings
161253
161609
  },
161254
- location3.memberId
161610
+ rowMemberId
161255
161611
  );
161256
161612
  rows.set(id2, authored2);
161257
161613
  if (isNew) valueLowerRegistry.pendingValues.set(id2, authored2);
161258
161614
  continue;
161259
161615
  }
161260
- 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);
161261
161617
  const authored = staticValueSeedRow(
161262
161618
  {
161263
161619
  ...row,
@@ -161267,11 +161623,25 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
161267
161623
  instanceConstructorId: row.instanceConstructorId ?? null
161268
161624
  } : {}
161269
161625
  },
161270
- location3.memberId
161626
+ rowMemberId
161271
161627
  );
161272
161628
  rows.set(id2, authored);
161273
161629
  if (isNew) valueLowerRegistry.pendingValues.set(id2, authored);
161274
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
+ }
161275
161645
  bindingSeeds.set(memberId, {
161276
161646
  ...seed,
161277
161647
  nodeType: "literal",
@@ -161999,8 +162369,9 @@ function replayAnimationDeclarationInitializersV4(records3, document, fallbackVa
161999
162369
  rootOwners,
162000
162370
  valuesById
162001
162371
  );
162002
- const initializerOwnerClass = ownerContext.ownerClass;
162003
- 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);
162004
162375
  const requiredArgumentNames = new Set(
162005
162376
  requiredConstructor?.argumentTypes.map((argument2) => argument2.name) ?? []
162006
162377
  );
@@ -168114,11 +168485,11 @@ function membersForType(snapshot, type) {
168114
168485
  (member) => member.id === cloneId ? cloneSymbol(named, type) : member
168115
168486
  );
168116
168487
  }
168117
- if (type.kind === "named") {
168118
- const named = snapshot.project.typeById.get(type.typeId);
168119
- if (!named) return [];
168120
- let members = named.members.filter((member) => member.static !== true);
168121
- 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)
168122
168493
  members = members.map((member) => {
168123
168494
  return {
168124
168495
  ...member,
@@ -168165,7 +168536,7 @@ function membersForType(snapshot, type) {
168165
168536
  }
168166
168537
  }
168167
168538
  }
168168
- if (named.kind === "class") {
168539
+ if (named?.kind === "class") {
168169
168540
  members = members.filter(
168170
168541
  (member) => member.name !== NEOSCRIPT_CLASS_ID_MEMBER
168171
168542
  );
@@ -168229,8 +168600,16 @@ function resolveMemberOf(snapshot, reference2, receiver) {
168229
168600
  const symbol = enumMemberNamed(receiver.type, reference2.name);
168230
168601
  return symbol ? { type: symbol.type, symbol } : null;
168231
168602
  }
168232
- const member = resolveMember3(snapshot, receiver.resolution, reference2.name);
168233
- 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);
168234
168613
  return specializeGenericCall(snapshot, member, call?.typeArgumentTokens);
168235
168614
  }
168236
168615
  function isKnownMemberReceiver(snapshot, receiver) {
@@ -168444,7 +168823,12 @@ function resolveChain(snapshot, tokens, offset, expectedType) {
168444
168823
  if (token.kind === "punctuation" && token.text === "." || token.kind === "operator" && token.text === "?.") {
168445
168824
  const member = tokens[cursor + 1];
168446
168825
  if (!member || member.kind !== "identifier") break;
168447
- const resolved = resolveMember3(snapshot, current, member.text);
168826
+ const resolved = resolveMember3(
168827
+ snapshot,
168828
+ current,
168829
+ member.text,
168830
+ token.start
168831
+ );
168448
168832
  if (!resolved) {
168449
168833
  const nextRoot = member.range.start.line > token.range.end.line ? resolveRoot(snapshot, member.text, member.start) : null;
168450
168834
  if (!nextRoot) return null;
@@ -168686,7 +169070,7 @@ function contextualTypeParameters(snapshot) {
168686
169070
  if (thisClass?.kind !== "named") return [];
168687
169071
  return snapshot.project.typeById.get(thisClass.typeId)?.typeParameters ?? [];
168688
169072
  }
168689
- function resolveMember3(snapshot, receiver, name) {
169073
+ function resolveMember3(snapshot, receiver, name, flowOffset) {
168690
169074
  if (receiver.indexSurface) {
168691
169075
  const index = indexesFor(snapshot, receiver.indexSurface.memberId).find(
168692
169076
  (candidate) => candidate.name === name
@@ -168707,10 +169091,9 @@ function resolveMember3(snapshot, receiver, name) {
168707
169091
  ) : membersForType(snapshot, receiver.type)).find((candidate) => candidate.name === name);
168708
169092
  if (!member || receiver.symbol?.name === "base" && !isConcreteBaseMember(member))
168709
169093
  return null;
168710
- return {
168711
- type: member.returnType ?? member.type,
168712
- symbol: member
168713
- };
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 } };
168714
169097
  }
168715
169098
  function scopeAt(snapshot, offset, name) {
168716
169099
  const result = [];
@@ -186037,7 +186420,7 @@ function spellClassInterfaceConstructions(ctx, classId, env) {
186037
186420
  path
186038
186421
  );
186039
186422
  if (saved === null) continue;
186040
- const list = [interfaceConstruction2(ctx, interfaceId, name, saved, false)];
186423
+ const list = [interfaceConstruction(ctx, interfaceId, name, saved, false)];
186041
186424
  const inherited = parentClassId === void 0 ? void 0 : index.construction(parentClassId, interfaceId);
186042
186425
  const readOnly = inherited === void 0 ? null : interfaceConstructionArguments(
186043
186426
  ctx,
@@ -186049,13 +186432,13 @@ function spellClassInterfaceConstructions(ctx, classId, env) {
186049
186432
  false
186050
186433
  );
186051
186434
  if (readOnly !== null && readOnly.join() !== saved.join()) {
186052
- list.push(interfaceConstruction2(ctx, interfaceId, name, readOnly, true));
186435
+ list.push(interfaceConstruction(ctx, interfaceId, name, readOnly, true));
186053
186436
  }
186054
186437
  result.set(interfaceId, list);
186055
186438
  }
186056
186439
  return result;
186057
186440
  }
186058
- function interfaceConstruction2(ctx, interfaceId, name, args, readOnlyView) {
186441
+ function interfaceConstruction(ctx, interfaceId, name, args, readOnlyView) {
186059
186442
  const params = ctx.exportData.interfaces[interfaceId]?.genericParams ?? [];
186060
186443
  const suffix = args.length === 0 ? "" : `<${args.join(", ")}>`;
186061
186444
  return {
@@ -216475,7 +216858,7 @@ var releaseWorkspaceLock = () => void 0;
216475
216858
  async function main() {
216476
216859
  const args = parseArgs(process.argv.slice(2));
216477
216860
  if (args.command === "--version") {
216478
- console.log("0.84.4");
216861
+ console.log("0.84.5");
216479
216862
  return;
216480
216863
  }
216481
216864
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {