@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.
@@ -15963,13 +15963,22 @@ function neoScriptMemberLookupType(type) {
15963
15963
  nullable2 ||= current.constraint.nullable === true;
15964
15964
  current = current.constraint;
15965
15965
  }
15966
+ if (current.kind === "named" && type.narrowedInterfaces !== void 0) {
15967
+ current = {
15968
+ ...current,
15969
+ narrowedInterfaces: {
15970
+ ...current.narrowedInterfaces,
15971
+ ...type.narrowedInterfaces
15972
+ }
15973
+ };
15974
+ }
15966
15975
  return nullable2 && current.nullable !== true ? { ...current, nullable: true } : current;
15967
15976
  }
15968
15977
  function neoScriptMemberReceiverType(type, memberName, project) {
15969
15978
  const primary = neoScriptMemberLookupType(type);
15970
- if (primary.kind !== "named" || primary.narrowedInterfaces === void 0)
15979
+ if (primary.kind !== "named" && primary.kind !== "typeParameter" || primary.narrowedInterfaces === void 0)
15971
15980
  return primary;
15972
- const declaration = project.typeById.get(primary.typeId);
15981
+ const declaration = primary.kind === "named" ? project.typeById.get(primary.typeId) : void 0;
15973
15982
  if (declaration?.kind === "class" && (memberName === NEOSCRIPT_CLASS_ID_MEMBER || memberName === "Clone"))
15974
15983
  return primary;
15975
15984
  if (declaration?.members.some((member) => member.name === memberName))
@@ -16304,12 +16313,12 @@ function isNeoScriptTypeAssignable(source, target, project) {
16304
16313
  if (isUnknownType(source) || isUnknownType(target)) return false;
16305
16314
  if (isNullType(source)) return isNullableType2(target);
16306
16315
  if (isNullableType2(source) && !isNullableType2(target)) return false;
16307
- if (target.kind === "named" && target.narrowedInterfaces !== void 0) {
16316
+ if ((target.kind === "named" || target.kind === "typeParameter") && target.narrowedInterfaces !== void 0) {
16308
16317
  for (const bound of Object.values(target.narrowedInterfaces)) {
16309
16318
  if (!isNeoScriptTypeAssignable(source, bound, project)) return false;
16310
16319
  }
16311
16320
  }
16312
- if (source.kind === "named" && source.narrowedInterfaces !== void 0) {
16321
+ if ((source.kind === "named" || source.kind === "typeParameter") && source.narrowedInterfaces !== void 0) {
16313
16322
  const direct = target.kind === "named" ? source.narrowedInterfaces[target.typeId] : void 0;
16314
16323
  if (direct !== void 0 && isNeoScriptTypeAssignable(direct, target, project))
16315
16324
  return true;
@@ -16337,7 +16346,7 @@ function isNeoScriptTypeAssignable(source, target, project) {
16337
16346
  project
16338
16347
  );
16339
16348
  }
16340
- if (!target.typeArguments?.length || project.typeById.get(target.typeId)?.kind !== "interface") {
16349
+ if (!target.typeArguments?.length) {
16341
16350
  return isTypeDerivedFrom(
16342
16351
  project.typeById.get(source.typeId),
16343
16352
  target.typeId,
@@ -16345,7 +16354,7 @@ function isNeoScriptTypeAssignable(source, target, project) {
16345
16354
  /* @__PURE__ */ new Set()
16346
16355
  );
16347
16356
  }
16348
- const construction = interfaceConstruction(source, target.typeId, project);
16357
+ const construction = supertypeConstruction(source, target.typeId, project);
16349
16358
  return construction !== void 0 && invariantTypeArguments(construction, target.typeArguments, project);
16350
16359
  }
16351
16360
  if (source.kind === "typeParameter" && target.kind === "typeParameter") {
@@ -16403,7 +16412,7 @@ function isNeoScriptTypeAssignable(source, target, project) {
16403
16412
  return false;
16404
16413
  }
16405
16414
  function withoutNeoScriptInterfaceProofs(type) {
16406
- if (type.kind !== "named" || type.narrowedInterfaces === void 0)
16415
+ if (type.kind !== "named" && type.kind !== "typeParameter" || type.narrowedInterfaces === void 0)
16407
16416
  return type;
16408
16417
  const { narrowedInterfaces: _proofs, ...declared } = type;
16409
16418
  return declared;
@@ -16411,7 +16420,7 @@ function withoutNeoScriptInterfaceProofs(type) {
16411
16420
  function commonNeoScriptAssignableType(left, right, project) {
16412
16421
  if (isNeoScriptTypeAssignable(left, right, project)) return right;
16413
16422
  if (isNeoScriptTypeAssignable(right, left, project)) return left;
16414
- if (left.kind === "named" && right.kind === "named" && (left.narrowedInterfaces !== void 0 || right.narrowedInterfaces !== void 0)) {
16423
+ if ((left.kind === "named" || left.kind === "typeParameter") && (right.kind === "named" || right.kind === "typeParameter") && (left.narrowedInterfaces !== void 0 || right.narrowedInterfaces !== void 0)) {
16415
16424
  const declaredLeft = withoutNeoScriptInterfaceProofs(left);
16416
16425
  const declaredRight = withoutNeoScriptInterfaceProofs(right);
16417
16426
  const common = commonNeoScriptAssignableType(
@@ -16419,7 +16428,8 @@ function commonNeoScriptAssignableType(left, right, project) {
16419
16428
  declaredRight,
16420
16429
  project
16421
16430
  );
16422
- if (common?.kind !== "named") return null;
16431
+ if (common?.kind !== "named" && common?.kind !== "typeParameter")
16432
+ return null;
16423
16433
  const proofs = {};
16424
16434
  for (const [source, other] of [
16425
16435
  [left, right],
@@ -16472,41 +16482,53 @@ function interfaceInstantiationMessage(declared, expected, project) {
16472
16482
  }
16473
16483
  return message;
16474
16484
  }
16475
- function interfaceConstruction(source, interfaceId, project, seen = /* @__PURE__ */ new Set()) {
16476
- if (source.typeId === interfaceId) return source.typeArguments ?? [];
16477
- const type = project.typeById.get(source.typeId);
16478
- if (type === void 0 || seen.has(type.id)) return void 0;
16479
- seen.add(type.id);
16480
- const bindings = /* @__PURE__ */ new Map();
16481
- type.typeParameters?.forEach((parameter3, index) => {
16482
- const argument2 = source.typeArguments?.[index];
16483
- if (argument2 !== void 0)
16484
- bindings.set(parameter3.id ?? parameter3.name, argument2);
16485
- });
16486
- for (const id of [
16487
- ...type.baseTypeIds ?? [],
16488
- ...type.interfaceTypeIds ?? []
16489
- ]) {
16490
- const supertype = {
16491
- kind: "named",
16492
- typeId: id,
16493
- typeArguments: (type.supertypeArguments?.[id] ?? []).map(
16494
- (argument2) => substituteNeoScriptTypeParameters(
16495
- argument2,
16496
- (parameter3) => bindings.get(parameter3.id),
16497
- project
16498
- )
16499
- )
16500
- };
16501
- const found = interfaceConstruction(supertype, interfaceId, project, seen);
16502
- if (found !== void 0) return found;
16485
+ function supertypeConstruction(source, supertypeId, project) {
16486
+ for (const type of constructedSupertypes(source, project)) {
16487
+ if (type.typeId === supertypeId) return type.typeArguments ?? [];
16503
16488
  }
16504
16489
  return void 0;
16505
16490
  }
16491
+ function* constructedSupertypes(source, project) {
16492
+ const pending = [source];
16493
+ const seen = /* @__PURE__ */ new Set();
16494
+ while (true) {
16495
+ const current = pending.pop();
16496
+ if (current === void 0) return;
16497
+ if (seen.has(current.typeId)) continue;
16498
+ seen.add(current.typeId);
16499
+ yield current;
16500
+ const type = project.typeById.get(current.typeId);
16501
+ if (type === void 0) continue;
16502
+ const bindings = /* @__PURE__ */ new Map();
16503
+ type.typeParameters?.forEach((parameter3, index) => {
16504
+ const argument2 = current.typeArguments?.[index];
16505
+ if (argument2 !== void 0)
16506
+ bindings.set(parameter3.id ?? parameter3.name, argument2);
16507
+ });
16508
+ const parents = [
16509
+ ...type.baseTypeIds ?? [],
16510
+ ...type.interfaceTypeIds ?? []
16511
+ ];
16512
+ for (const id of parents.reverse()) {
16513
+ if (seen.has(id)) continue;
16514
+ pending.push({
16515
+ kind: "named",
16516
+ typeId: id,
16517
+ typeArguments: (type.supertypeArguments?.[id] ?? []).map(
16518
+ (argument2) => substituteNeoScriptTypeParameters(
16519
+ argument2,
16520
+ (parameter3) => bindings.get(parameter3.id),
16521
+ project
16522
+ )
16523
+ )
16524
+ });
16525
+ }
16526
+ }
16527
+ }
16506
16528
  function interfaceUndeterminedReason(classType, interfaceType2, project) {
16507
16529
  const params = classType.typeParameters ?? [];
16508
16530
  if (params.length === 0) return null;
16509
- const construction = interfaceConstruction(
16531
+ const construction = supertypeConstruction(
16510
16532
  {
16511
16533
  kind: "named",
16512
16534
  typeId: classType.id,
@@ -17571,12 +17593,15 @@ function initializerOwnerContext(document2, valueId, rootOwners, valuesById, rec
17571
17593
  currentId = sourceValueId;
17572
17594
  lexicalRoot = rootOwners.get(sourceValueId) ?? lexicalRoot;
17573
17595
  }
17574
- if (lexicalRoot === void 0 || isStaticMember(lexicalRoot)) {
17575
- return { ownerClass: null, lexicalThisClass: null };
17596
+ if (lexicalRoot === void 0) {
17597
+ return { declaringClass: null, lexicalThisClass: null };
17576
17598
  }
17577
17599
  const lexicalRootId = getField(lexicalRoot, "id");
17578
17600
  const ownerClass = typeof lexicalRootId === "string" ? findSchemaPlacement(lexicalRootId, document2.classes)?.ownerClass ?? null : null;
17579
- return { ownerClass, lexicalThisClass: ownerClass };
17601
+ return {
17602
+ declaringClass: ownerClass,
17603
+ lexicalThisClass: isStaticMember(lexicalRoot) ? null : ownerClass
17604
+ };
17580
17605
  }
17581
17606
  function isClassRecordValue(value) {
17582
17607
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -36447,7 +36472,7 @@ function materializeMemberDefaultValue(args) {
36447
36472
  rootOwners,
36448
36473
  valuesById,
36449
36474
  (id) => args.readTracking?.valueIds.add(id)
36450
- ).ownerClass : typeof Reflect.get(member, "id") === "string" && !isStaticMember(member) ? findSchemaPlacement(
36475
+ ).lexicalThisClass : typeof Reflect.get(member, "id") === "string" && !isStaticMember(member) ? findSchemaPlacement(
36451
36476
  String(Reflect.get(member, "id")),
36452
36477
  args.document.classes
36453
36478
  )?.ownerClass ?? null : null;
@@ -43931,7 +43956,7 @@ function implementerConstruction(implementer, slotInterface, slot, project) {
43931
43956
  );
43932
43957
  if (reason !== null) return void 0;
43933
43958
  }
43934
- const implemented = interfaceConstruction(
43959
+ const implemented = supertypeConstruction(
43935
43960
  {
43936
43961
  kind: "named",
43937
43962
  typeId: implementer.id,
@@ -44123,10 +44148,12 @@ var Scope = class {
44123
44148
  constructor(parent, probe = parent?.probe ?? false) {
44124
44149
  this.parent = parent;
44125
44150
  this.probe = probe;
44151
+ this.externalRoots = parent?.externalRoots ?? /* @__PURE__ */ new Map();
44126
44152
  this.patternBindings = parent?.patternBindings ?? null;
44127
44153
  }
44128
44154
  parent;
44129
44155
  probe;
44156
+ externalRoots;
44130
44157
  entries = /* @__PURE__ */ new Map();
44131
44158
  invalidatedRoots = /* @__PURE__ */ new Set();
44132
44159
  hiddenNarrowingRoots = /* @__PURE__ */ new Set();
@@ -44149,7 +44176,15 @@ var Scope = class {
44149
44176
  lookup(name) {
44150
44177
  return this.entries.get(name) ?? this.parent?.lookup(name) ?? null;
44151
44178
  }
44179
+ registerExternalRoot(name, type) {
44180
+ if (!this.externalRoots.has(name))
44181
+ this.externalRoots.set(name, { name, type, variableId: name });
44182
+ }
44183
+ lookupFlowRoot(name) {
44184
+ return this.lookup(name) ?? this.externalRoots.get(name) ?? null;
44185
+ }
44152
44186
  containsEntry(entry) {
44187
+ if (this.externalRoots.get(entry.name) === entry) return true;
44153
44188
  for (const candidate of this.entries.values()) {
44154
44189
  if (candidate === entry) return true;
44155
44190
  }
@@ -44207,6 +44242,7 @@ var Scope = class {
44207
44242
  if (path === rootEntry.name) this.updatePatternType(rootEntry, type);
44208
44243
  }
44209
44244
  updatePatternType(entry, type) {
44245
+ if (this.externalRoots.get(entry.name) === entry) return;
44210
44246
  if (this.probe || entry.patternBinding)
44211
44247
  this.patternBindings = {
44212
44248
  name: entry.name,
@@ -44850,7 +44886,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
44850
44886
  branchExitNarrowings,
44851
44887
  this.project
44852
44888
  )) {
44853
- const rootEntry = scope.lookup(pathRoot(path));
44889
+ const rootEntry = scope.lookupFlowRoot(pathRoot(path));
44854
44890
  if (rootEntry === narrowed.rootEntry) {
44855
44891
  scope.narrow(path, rootEntry, narrowed.type);
44856
44892
  }
@@ -45783,7 +45819,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
45783
45819
  }
45784
45820
  for (const [path, narrowed] of merged) {
45785
45821
  if (!parent.containsEntry(narrowed.rootEntry)) continue;
45786
- const rootEntry = parent.lookup(pathRoot(path));
45822
+ const rootEntry = parent.lookupFlowRoot(pathRoot(path));
45787
45823
  if (rootEntry === narrowed.rootEntry) {
45788
45824
  parent.narrow(path, rootEntry, narrowed.type);
45789
45825
  }
@@ -46010,7 +46046,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
46010
46046
  scope
46011
46047
  );
46012
46048
  if (assignedPath) {
46013
- const rootEntry = scope.lookup(pathRoot(assignedPath));
46049
+ const rootEntry = scope.lookupFlowRoot(pathRoot(assignedPath));
46014
46050
  if (rootEntry) {
46015
46051
  const retainedFacts = unaffectedNarrowings(
46016
46052
  assignedPath,
@@ -46057,11 +46093,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
46057
46093
  referenceAssignment(statement, place, storageType, scope) {
46058
46094
  const source = statement.op === "=" ? statement.value ?? void 0 : void 0;
46059
46095
  const nullLiteral = source?.kind === "litNull";
46060
- const assigned = source === void 0 ? void 0 : this.resolveReferenceExpression(
46061
- source,
46062
- scope,
46063
- nullLiteral ? void 0 : neoScriptReadType(storageType)
46064
- );
46096
+ const assigned = source === void 0 ? void 0 : this.resolveReferenceAssignmentValue(source, scope, storageType);
46065
46097
  const valueAt = (type) => {
46066
46098
  if (source === void 0 || assigned === void 0) return void 0;
46067
46099
  return nullLiteral ? this.resolveReferenceExpression(source, scope, type) : this.readReferences(assigned, type);
@@ -46105,6 +46137,30 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
46105
46137
  }
46106
46138
  return { target: layer, value: valueAt(layer.type), through };
46107
46139
  }
46140
+ resolveReferenceAssignmentValue(expression, scope, storageType) {
46141
+ if (expression.kind === "conditional") {
46142
+ return this.resolveConditionalExpression(
46143
+ expression,
46144
+ scope,
46145
+ neoScriptReadType(storageType),
46146
+ storageType
46147
+ );
46148
+ }
46149
+ if (expression.kind === "coalesce") {
46150
+ return this.resolveCoalesceExpression(
46151
+ expression,
46152
+ scope,
46153
+ void 0,
46154
+ storageType
46155
+ );
46156
+ }
46157
+ const expected = neoScriptReadType(storageType);
46158
+ return this.resolveReferenceExpression(
46159
+ expression,
46160
+ scope,
46161
+ expression.kind === "litNull" ? void 0 : expected
46162
+ );
46163
+ }
46108
46164
  /** `Reference<target>` as an expression type (P112 §3.1). */
46109
46165
  referenceType(target, nullable2) {
46110
46166
  return neoScriptReferenceType(
@@ -46265,7 +46321,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
46265
46321
  false
46266
46322
  ).type;
46267
46323
  }
46268
- return resolvedTarget.type;
46324
+ return this.resolveIdentifierNatural(targetAst.name, scope, targetAst.pos).type;
46269
46325
  }
46270
46326
  if (targetAst.kind !== "member") return resolvedTarget.type;
46271
46327
  return this.resolveMemberNatural(
@@ -46508,7 +46564,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
46508
46564
  scope
46509
46565
  );
46510
46566
  if (assignedPath) {
46511
- const rootEntry = scope.lookup(pathRoot(assignedPath));
46567
+ const rootEntry = scope.lookupFlowRoot(pathRoot(assignedPath));
46512
46568
  if (rootEntry) {
46513
46569
  const retainedFacts = unaffectedNarrowings(
46514
46570
  assignedPath,
@@ -47244,34 +47300,8 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
47244
47300
  ...operand.writeRoot ? { writeRoot: operand.writeRoot } : {}
47245
47301
  };
47246
47302
  }
47247
- case "coalesce": {
47248
- const left = this.resolveExpression(expression.left, scope);
47249
- const leftOptional = { ...left.type, nullable: true };
47250
- const nullLeft = isNull(left.type);
47251
- const right = this.resolveExpression(
47252
- expression.right,
47253
- scope,
47254
- nullLeft ? expected : leftOptional
47255
- );
47256
- if (!nullLeft && !isNeoScriptTypeAssignable(right.type, leftOptional, this.project)) {
47257
- throw new CompileError(
47258
- `\`??\` right operand ${this.describe(right.type)} is not assignable to ${this.describe(leftOptional)}`,
47259
- expression.pos
47260
- );
47261
- }
47262
- const resultType = nullLeft ? right.type : {
47263
- ...left.type,
47264
- nullable: isNullable(left.type) && isNullable(right.type)
47265
- };
47266
- return {
47267
- pointer: {
47268
- type: "coalesce" /* Coalesce */,
47269
- left: left.pointer,
47270
- right: right.pointer
47271
- },
47272
- type: resultType
47273
- };
47274
- }
47303
+ case "coalesce":
47304
+ return this.resolveCoalesceExpression(expression, scope, expected);
47275
47305
  case "conditional":
47276
47306
  return this.resolveConditionalExpression(expression, scope, expected);
47277
47307
  case "is": {
@@ -47848,6 +47878,21 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
47848
47878
  };
47849
47879
  }
47850
47880
  resolveIdentifier(name, scope, pos, usage = "value") {
47881
+ const natural = this.resolveIdentifierNatural(name, scope, pos, usage);
47882
+ if (scope.lookup(name)) return natural;
47883
+ const path = this.narrowingPath(name, scope);
47884
+ const root = path === null ? null : scope.lookupFlowRoot(pathRoot(path));
47885
+ const narrowed = root && path ? scope.lookupNarrowedType(path, root) : null;
47886
+ const resolved = narrowed ? { ...natural, type: narrowed } : natural;
47887
+ this.options.onFlowScope?.({
47888
+ name,
47889
+ position: pos,
47890
+ type: resolved.type,
47891
+ bindings: scope.patternBindings
47892
+ });
47893
+ return resolved;
47894
+ }
47895
+ resolveIdentifierNatural(name, scope, pos, usage = "value") {
47851
47896
  if (name === "this" && this.context.kind === "initializer" && this.delegateCaptureContexts.length === 0 && usage === "value") {
47852
47897
  throw new CompileError(
47853
47898
  "'this' is unavailable while an initializer runs. Defer instance access with a lambda or method group.",
@@ -47880,7 +47925,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
47880
47925
  };
47881
47926
  }
47882
47927
  const global = this.context.project.globals.find(
47883
- (candidate) => candidate.name === name
47928
+ (symbol) => symbol.name === name
47884
47929
  );
47885
47930
  if (global) return this.symbolValue(global);
47886
47931
  const implicit = this.implicitMember(name);
@@ -48022,11 +48067,29 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
48022
48067
  if (path === null) return null;
48023
48068
  const root = pathRoot(path);
48024
48069
  if (scope.lookup(root)) return path;
48025
- if (this.context.project.globals.some((symbol) => symbol.name === root)) {
48026
- return path;
48070
+ const global = this.context.project.globals.find(
48071
+ (symbol) => symbol.name === root
48072
+ );
48073
+ if (global) {
48074
+ const key = `global:${root}`;
48075
+ scope.registerExternalRoot(key, global.type);
48076
+ return key + path.slice(root.length);
48027
48077
  }
48028
48078
  const implicit = this.implicitMember(root);
48029
- return implicit && implicit.symbol.static !== true ? `this.${path}` : path;
48079
+ if (implicit && implicit.symbol.static !== true) return `this.${path}`;
48080
+ const owner = implicit?.owner ?? this.project.typeByName.get(root);
48081
+ if (owner) {
48082
+ const memberName = implicit?.symbol.name ?? path.slice(root.length + 1).split(".")[0];
48083
+ const member = implicit?.symbol ?? owner.members.find((candidate) => candidate.name === memberName);
48084
+ const declaring = member?.inheritedFrom;
48085
+ const key = `static:${declaring?.typeName ?? owner.name}`;
48086
+ scope.registerExternalRoot(key, {
48087
+ kind: "named",
48088
+ typeId: declaring?.typeId ?? owner.id
48089
+ });
48090
+ return implicit ? `${key}.${path}` : key + path.slice(root.length);
48091
+ }
48092
+ return path;
48030
48093
  }
48031
48094
  conditionFacts(expression, scope, whenTrue) {
48032
48095
  const pathOf = (value) => this.narrowingPath(canonicalPath(value), scope);
@@ -48044,7 +48107,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
48044
48107
  locals
48045
48108
  )) {
48046
48109
  const path = this.narrowingPath(assignedPath, outerScope);
48047
- const outerEntry = path === null ? null : outerScope.lookup(pathRoot(path));
48110
+ const outerEntry = path === null ? null : outerScope.lookupFlowRoot(pathRoot(path));
48048
48111
  if (outerEntry && path !== null) {
48049
48112
  const retained = unaffectedNarrowings(path, outerEntry, loopEntryScope);
48050
48113
  loopEntryScope.hideInheritedNarrowing(outerEntry);
@@ -48062,7 +48125,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
48062
48125
  targetScope
48063
48126
  );
48064
48127
  const natural = this.readReferences(place, void 0);
48065
- const rootEntry = fact.path === null ? null : targetScope.lookup(pathRoot(fact.path));
48128
+ const rootEntry = fact.path === null ? null : targetScope.lookupFlowRoot(pathRoot(fact.path));
48066
48129
  if (fact.nullValue) {
48067
48130
  if (fact.path === null || rootEntry === null) continue;
48068
48131
  if (place.type.kind === "reference" && !isNullable(place.type)) {
@@ -48083,7 +48146,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
48083
48146
  const targetDefinition = target.kind === "named" ? this.project.typeById.get(target.typeId) : void 0;
48084
48147
  const naturalDefinition = natural.type.kind === "named" ? this.project.typeById.get(natural.type.typeId) : void 0;
48085
48148
  let narrowed = { ...target, nullable: false };
48086
- if (!fact.bindingName && natural.type.kind === "named" && (naturalDefinition?.kind === "class" || naturalDefinition?.kind === "interface") && target.kind === "named" && targetDefinition?.kind === "interface") {
48149
+ if ((natural.type.kind === "typeParameter" || natural.type.kind === "named" && (naturalDefinition?.kind === "class" || naturalDefinition?.kind === "interface")) && target.kind === "named" && targetDefinition?.kind === "interface") {
48087
48150
  narrowed = { ...natural.type, nullable: false };
48088
48151
  if (!isNeoScriptTypeAssignable(narrowed, target, this.project)) {
48089
48152
  narrowed = {
@@ -48095,6 +48158,22 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
48095
48158
  };
48096
48159
  }
48097
48160
  }
48161
+ if (target.kind === "named" && targetDefinition?.kind === "class") {
48162
+ const lookup = neoScriptMemberLookupType(natural.type);
48163
+ if (lookup.kind === "named" || lookup.kind === "typeParameter") {
48164
+ const { narrowedInterfaces, ...declared } = lookup;
48165
+ const proofs = declared.kind === "named" && this.project.typeById.get(declared.typeId)?.kind === "interface" ? {
48166
+ ...narrowedInterfaces,
48167
+ [declared.typeId]: declared
48168
+ } : narrowedInterfaces;
48169
+ if (proofs !== void 0)
48170
+ narrowed = {
48171
+ ...target,
48172
+ nullable: false,
48173
+ narrowedInterfaces: proofs
48174
+ };
48175
+ }
48176
+ }
48098
48177
  if (mode === "all" && fact.path !== null && rootEntry !== null && place.type.kind !== "reference") {
48099
48178
  targetScope.narrow(fact.path, rootEntry, narrowed);
48100
48179
  }
@@ -48104,7 +48183,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
48104
48183
  }
48105
48184
  targetScope.definePattern({
48106
48185
  name: fact.bindingName,
48107
- type: narrowed,
48186
+ type: { ...target, nullable: false },
48108
48187
  variableId: fact.bindingTest ? this.patternBindingId(fact.bindingTest) : fact.bindingName,
48109
48188
  writeRoot: this.expressionWriteRoot(natural, targetScope),
48110
48189
  pointer: fact.bindingTest ? {
@@ -48384,7 +48463,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
48384
48463
  return wire;
48385
48464
  }
48386
48465
  resolveMember(receiverAst, name, scope, pos, optional2, receiverValue) {
48387
- const resolved = this.resolveMemberNatural(
48466
+ let resolved = this.resolveMemberNatural(
48388
48467
  receiverAst,
48389
48468
  name,
48390
48469
  scope,
@@ -48393,21 +48472,25 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
48393
48472
  receiverValue
48394
48473
  );
48395
48474
  if (!optional2) {
48396
- const receiverPath = this.narrowingPath(
48397
- canonicalPath(receiverAst),
48475
+ const receiverPath = canonicalPath(receiverAst);
48476
+ const path = this.narrowingPath(
48477
+ receiverPath === null ? null : `${receiverPath}.${name}`,
48398
48478
  scope
48399
48479
  );
48400
- if (receiverPath) {
48401
- const rootEntry = scope.lookup(pathRoot(receiverPath));
48480
+ if (path) {
48481
+ const rootEntry = scope.lookupFlowRoot(pathRoot(path));
48402
48482
  if (rootEntry) {
48403
- const narrowed = scope.lookupNarrowedType(
48404
- `${receiverPath}.${name}`,
48405
- rootEntry
48406
- );
48407
- if (narrowed) return { ...resolved, type: narrowed };
48483
+ const narrowed = scope.lookupNarrowedType(path, rootEntry);
48484
+ if (narrowed) resolved = { ...resolved, type: narrowed };
48408
48485
  }
48409
48486
  }
48410
48487
  }
48488
+ this.options.onFlowScope?.({
48489
+ name,
48490
+ position: pos,
48491
+ type: resolved.type,
48492
+ bindings: scope.patternBindings
48493
+ });
48411
48494
  return resolved;
48412
48495
  }
48413
48496
  resolveStaticMemberValue(staticType, member, pos) {
@@ -52400,7 +52483,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
52400
52483
  scope
52401
52484
  );
52402
52485
  if (path) {
52403
- const rootEntry = scope.lookup(pathRoot(path));
52486
+ const rootEntry = scope.lookupFlowRoot(pathRoot(path));
52404
52487
  if (rootEntry) scope.invalidate(rootEntry);
52405
52488
  }
52406
52489
  const actionTypeInfo = receiver.wireType ?? toWireType(receiver.type, this.project);
@@ -52452,7 +52535,74 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
52452
52535
  pos
52453
52536
  );
52454
52537
  }
52455
- resolveConditionalExpression(expression, scope, expected) {
52538
+ referenceAssignmentBranches(left, right, storageType, operator) {
52539
+ let layer = storageType;
52540
+ while (true) {
52541
+ const expected = operator === "coalesce" ? { ...layer, nullable: true } : layer;
52542
+ const resolvedLeft = this.readReferences(left, expected);
52543
+ const resolvedRight = this.readReferences(right, expected);
52544
+ if (isNeoScriptTypeAssignable(resolvedLeft.type, expected, this.project) && isNeoScriptTypeAssignable(resolvedRight.type, expected, this.project)) {
52545
+ return { left: resolvedLeft, right: resolvedRight, type: expected };
52546
+ }
52547
+ if (layer.kind !== "reference") break;
52548
+ layer = layer.target;
52549
+ }
52550
+ return { left, right, type: neoScriptReadType(storageType) };
52551
+ }
52552
+ resolveCoalesceExpression(expression, scope, expected, assignmentType) {
52553
+ let left;
52554
+ let right;
52555
+ if (assignmentType) {
52556
+ const branches = this.referenceAssignmentBranches(
52557
+ this.resolveReferenceAssignmentValue(
52558
+ expression.left,
52559
+ scope,
52560
+ assignmentType
52561
+ ),
52562
+ this.resolveReferenceAssignmentValue(
52563
+ expression.right,
52564
+ scope,
52565
+ assignmentType
52566
+ ),
52567
+ assignmentType,
52568
+ "coalesce"
52569
+ );
52570
+ left = branches.left;
52571
+ right = branches.right;
52572
+ } else {
52573
+ left = this.resolveExpression(
52574
+ expression.left,
52575
+ scope,
52576
+ expected?.kind === "reference" ? { ...expected, nullable: true } : void 0
52577
+ );
52578
+ right = this.resolveExpression(
52579
+ expression.right,
52580
+ scope,
52581
+ isNull(left.type) ? expected : { ...left.type, nullable: true }
52582
+ );
52583
+ }
52584
+ const leftOptional = { ...left.type, nullable: true };
52585
+ const nullLeft = isNull(left.type);
52586
+ if (!nullLeft && !isNeoScriptTypeAssignable(right.type, leftOptional, this.project)) {
52587
+ throw new CompileError(
52588
+ `\`??\` right operand ${this.describe(right.type)} is not assignable to ${this.describe(leftOptional)}`,
52589
+ expression.pos
52590
+ );
52591
+ }
52592
+ const resultType = nullLeft ? right.type : {
52593
+ ...left.type,
52594
+ nullable: isNullable(left.type) && isNullable(right.type)
52595
+ };
52596
+ return {
52597
+ pointer: {
52598
+ type: "coalesce" /* Coalesce */,
52599
+ left: left.pointer,
52600
+ right: right.pointer
52601
+ },
52602
+ type: resultType
52603
+ };
52604
+ }
52605
+ resolveConditionalExpression(expression, scope, expected, assignmentType) {
52456
52606
  const condition = this.toBool(
52457
52607
  this.resolveExpression(expression.condition, scope),
52458
52608
  expression.condition.pos
@@ -52469,7 +52619,38 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
52469
52619
  );
52470
52620
  let whenTrue;
52471
52621
  let whenFalse;
52472
- if (expected) {
52622
+ if (assignmentType) {
52623
+ whenTrue = this.resolveReferenceAssignmentValue(
52624
+ expression.whenTrue,
52625
+ trueScope,
52626
+ assignmentType
52627
+ );
52628
+ whenFalse = this.resolveReferenceAssignmentValue(
52629
+ expression.whenFalse,
52630
+ falseScope,
52631
+ assignmentType
52632
+ );
52633
+ let common2 = commonNeoScriptAssignableType(
52634
+ whenTrue.type,
52635
+ whenFalse.type,
52636
+ this.project
52637
+ );
52638
+ if (isNull(whenTrue.type)) common2 = { ...whenFalse.type, nullable: true };
52639
+ if (isNull(whenFalse.type)) common2 = { ...whenTrue.type, nullable: true };
52640
+ if (common2) {
52641
+ expected = common2;
52642
+ } else {
52643
+ const branches = this.referenceAssignmentBranches(
52644
+ whenTrue,
52645
+ whenFalse,
52646
+ assignmentType,
52647
+ "conditional"
52648
+ );
52649
+ whenTrue = branches.left;
52650
+ whenFalse = branches.right;
52651
+ expected = branches.type;
52652
+ }
52653
+ } else if (expected) {
52473
52654
  whenTrue = this.resolveExpression(
52474
52655
  expression.whenTrue,
52475
52656
  trueScope,
@@ -52506,7 +52687,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
52506
52687
  expression.pos
52507
52688
  );
52508
52689
  }
52509
- if (expected) {
52690
+ if (expected && !assignmentType) {
52510
52691
  this.requireAssignable(
52511
52692
  whenTrue.type,
52512
52693
  expected,
@@ -53394,9 +53575,7 @@ function typeRefsEqual(left, right) {
53394
53575
  if (left.kind === "primitive" && right.kind === "primitive") {
53395
53576
  return left.name === right.name;
53396
53577
  }
53397
- if (left.kind === "named" && right.kind === "named") {
53398
- const leftArgs = left.typeArguments ?? [];
53399
- const rightArgs = right.typeArguments ?? [];
53578
+ if ((left.kind === "named" || left.kind === "typeParameter") && (right.kind === "named" || right.kind === "typeParameter")) {
53400
53579
  if (left.narrowedInterfaces !== right.narrowedInterfaces) {
53401
53580
  const leftBounds = Object.entries(left.narrowedInterfaces ?? {});
53402
53581
  const rightBounds = right.narrowedInterfaces ?? {};
@@ -53407,6 +53586,10 @@ function typeRefsEqual(left, right) {
53407
53586
  return false;
53408
53587
  }
53409
53588
  }
53589
+ }
53590
+ if (left.kind === "named" && right.kind === "named") {
53591
+ const leftArgs = left.typeArguments ?? [];
53592
+ const rightArgs = right.typeArguments ?? [];
53410
53593
  return left.typeId === right.typeId && leftArgs.length === rightArgs.length && leftArgs.every((item, index) => {
53411
53594
  const other = rightArgs[index];
53412
53595
  return other !== void 0 && typeRefsEqual(item, other);
@@ -54388,6 +54571,20 @@ function typesOverlap(left, right, project) {
54388
54571
  if (isNull(right)) return isNullable(left);
54389
54572
  left = neoScriptMemberLookupType(left);
54390
54573
  right = neoScriptMemberLookupType(right);
54574
+ const declaredLeft = withoutNeoScriptInterfaceProofs(left);
54575
+ const declaredRight = withoutNeoScriptInterfaceProofs(right);
54576
+ if (left.kind === "named" || left.kind === "typeParameter") {
54577
+ for (const proof of Object.values(left.narrowedInterfaces ?? {})) {
54578
+ if (!typesOverlap(proof, declaredRight, project)) return false;
54579
+ }
54580
+ }
54581
+ if (right.kind === "named" || right.kind === "typeParameter") {
54582
+ for (const proof of Object.values(right.narrowedInterfaces ?? {})) {
54583
+ if (!typesOverlap(declaredLeft, proof, project)) return false;
54584
+ }
54585
+ }
54586
+ left = declaredLeft;
54587
+ right = declaredRight;
54391
54588
  if (left.kind === "typeParameter" || right.kind === "typeParameter")
54392
54589
  return true;
54393
54590
  if (isNeoScriptTypeAssignable(left, right, project) || isNeoScriptTypeAssignable(right, left, project))
@@ -54401,11 +54598,29 @@ function typesOverlap(left, right, project) {
54401
54598
  const classDeclaration = leftDeclaration?.kind === "class" ? leftDeclaration : rightDeclaration?.kind === "class" ? rightDeclaration : null;
54402
54599
  const interfaceDeclaration = leftDeclaration?.kind === "interface" ? leftDeclaration : rightDeclaration?.kind === "interface" ? rightDeclaration : null;
54403
54600
  if (classDeclaration !== null && interfaceDeclaration !== null) {
54601
+ if (conflictingInterfaceConstructions(left, right, project)) return false;
54404
54602
  return classDeclaration.sealed !== true;
54405
54603
  }
54406
54604
  }
54407
54605
  return isNumeric(left) && isNumeric(right);
54408
54606
  }
54607
+ function conflictingInterfaceConstructions(left, right, project) {
54608
+ const constructions = /* @__PURE__ */ new Map();
54609
+ for (const type of constructedSupertypes(left, project)) {
54610
+ if (project.typeById.get(type.typeId)?.kind === "interface" && type.typeArguments?.length)
54611
+ constructions.set(type.typeId, type.typeArguments);
54612
+ }
54613
+ for (const type of constructedSupertypes(right, project)) {
54614
+ const argumentsList2 = constructions.get(type.typeId);
54615
+ if (!argumentsList2) continue;
54616
+ if (argumentsList2.some((argument2, index) => {
54617
+ const other = type.typeArguments?.[index];
54618
+ return other !== void 0 && !containsTypeParameter(argument2) && !containsTypeParameter(other) && !(isNeoScriptTypeAssignable(argument2, other, project) && isNeoScriptTypeAssignable(other, argument2, project));
54619
+ }))
54620
+ return true;
54621
+ }
54622
+ return false;
54623
+ }
54409
54624
  function isUnknown(type) {
54410
54625
  return type.kind === "primitive" && type.name === "unknown";
54411
54626
  }
@@ -59464,7 +59679,7 @@ function compileNSInitializer(code, ctx) {
59464
59679
  {
59465
59680
  ...compilerContext,
59466
59681
  thisClass: lexicalThisClass ?? null,
59467
- implicitMemberAccess: lexicalThisClass !== null,
59682
+ implicitMemberAccess: lexicalThisClass != null || declaringClass != null,
59468
59683
  staticMember: false
59469
59684
  },
59470
59685
  {
@@ -59735,7 +59950,7 @@ function compileMemberInitializerBody(args) {
59735
59950
  returnTypeInfo,
59736
59951
  initializerName: args.member.name,
59737
59952
  lexicalThisClass: parseExpression(defaultValue.init.code).kind === "lambda" ? instanceClass : null,
59738
- declaringClass: instanceClass,
59953
+ declaringClass: args.thisClass,
59739
59954
  argumentTypes: initializerArgumentTypes(
59740
59955
  instanceClass,
59741
59956
  args.constructors ?? []
@@ -59784,7 +59999,7 @@ function compileValueRowInitializerBody(args) {
59784
59999
  lexicalThisClass: args.lexicalThisClass ?? null,
59785
60000
  declaringClass: args.initializerOwnerClass,
59786
60001
  argumentTypes: initializerArgumentTypes(
59787
- args.initializerOwnerClass,
60002
+ args.lexicalThisClass === null ? null : args.initializerOwnerClass,
59788
60003
  args.constructors ?? []
59789
60004
  ),
59790
60005
  ...args.storedConstructionReplay === true ? { storedConstructionReplay: true } : {}
@@ -59989,7 +60204,7 @@ function valueInitializerCompilationSites(document2) {
59989
60204
  sites.set(row.id, {
59990
60205
  row,
59991
60206
  member,
59992
- ownerClass: ownerContext.ownerClass,
60207
+ ownerClass: ownerContext.declaringClass,
59993
60208
  lexicalThisClass: ownerContext.lexicalThisClass
59994
60209
  });
59995
60210
  }