@neocompose/cli 0.72.1 → 0.72.4

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.
package/dist/neo.mjs CHANGED
@@ -20567,11 +20567,12 @@ var init_local_values = __esm({
20567
20567
  init_formatter();
20568
20568
  init_workspace_source_path();
20569
20569
  init_executable_parser();
20570
+ init_source_text();
20570
20571
  init_language_spec();
20571
20572
  init_lower_support();
20572
20573
  LocalValueBindingsV4 = class {
20573
20574
  definitions = /* @__PURE__ */ new Map();
20574
- expressions = /* @__PURE__ */ new Map();
20575
+ initializers = /* @__PURE__ */ new Map();
20575
20576
  owners = /* @__PURE__ */ new Map();
20576
20577
  /** Static members whose initializer is a bare local name, by that name. */
20577
20578
  ownerMembers = /* @__PURE__ */ new Map();
@@ -20608,7 +20609,7 @@ var init_local_values = __esm({
20608
20609
  owners.set(valueId, source.label);
20609
20610
  this.owners.set(global.name, owners);
20610
20611
  }
20611
- text = global.initializer;
20612
+ text = step.text;
20612
20613
  expression = step.expression;
20613
20614
  source = {
20614
20615
  ...source,
@@ -20627,7 +20628,28 @@ var init_local_values = __esm({
20627
20628
  let last = null;
20628
20629
  for (const step of this.chain(name)) last = step;
20629
20630
  if (last === null) return null;
20630
- return { expression: last.expression, text: last.global.initializer };
20631
+ return { expression: last.expression, text: last.text };
20632
+ }
20633
+ initializer(global) {
20634
+ const cached = this.initializers.get(global.name);
20635
+ if (cached) return cached;
20636
+ let text = global.initializer;
20637
+ let expression = parseExpression(text);
20638
+ let construction = expression;
20639
+ while (construction.kind === "annotated")
20640
+ construction = construction.expression;
20641
+ if (construction.kind === "new" && construction.className === null) {
20642
+ const offset = new SourceText(text).offsetAt({
20643
+ line: construction.pos.line - 1,
20644
+ character: construction.pos.column - 1
20645
+ }) + 3;
20646
+ const type = typeText({ ...global.type, nullable: false });
20647
+ text = `${text.slice(0, offset)} ${type}${text.slice(offset)}`;
20648
+ expression = parseExpression(text);
20649
+ }
20650
+ const prepared = { global, expression, text };
20651
+ this.initializers.set(global.name, prepared);
20652
+ return prepared;
20631
20653
  }
20632
20654
  /** Each local an alias chain starting at `name` passes through, in order. */
20633
20655
  *chain(name) {
@@ -20637,9 +20659,9 @@ var init_local_values = __esm({
20637
20659
  if (visited.has(global.name))
20638
20660
  throw new Error(`Local initializer cycle reaches ${global.name}.`);
20639
20661
  visited.add(global.name);
20640
- const expression = this.expressions.get(global.name) ?? parseExpression(global.initializer);
20641
- this.expressions.set(global.name, expression);
20642
- yield { global, expression };
20662
+ const prepared = this.initializer(global);
20663
+ const { expression } = prepared;
20664
+ yield prepared;
20643
20665
  global = expression.kind === "ident" ? this.definitions.get(expression.name) : void 0;
20644
20666
  }
20645
20667
  }
@@ -20685,7 +20707,7 @@ var init_local_values = __esm({
20685
20707
  const placements = [];
20686
20708
  for (const [name, definition2] of this.definitions) {
20687
20709
  const valueIds = this.owners.get(name)?.keys().toArray() ?? [];
20688
- const expression = this.expressions.get(name) ?? parseExpression(definition2.initializer);
20710
+ const expression = this.initializers.get(name)?.expression ?? parseExpression(definition2.initializer);
20689
20711
  placements.push({
20690
20712
  name,
20691
20713
  type: typeText(definition2.type),
@@ -28282,6 +28304,20 @@ var init_collection_query = __esm({
28282
28304
  function neoScriptArgumentNameSetKey(names) {
28283
28305
  return [...names].map((name) => name.toLowerCase()).sort().join(",");
28284
28306
  }
28307
+ function neoScriptParameterByName(parameters, name) {
28308
+ let indexes3 = parameterNameIndexes.get(parameters);
28309
+ if (!indexes3) {
28310
+ const built = /* @__PURE__ */ new Map();
28311
+ for (let index2 = 0; index2 < parameters.length; index2++) {
28312
+ const key = parameters[index2].name.toLowerCase();
28313
+ if (!built.has(key)) built.set(key, index2);
28314
+ }
28315
+ indexes3 = built;
28316
+ parameterNameIndexes.set(parameters, indexes3);
28317
+ }
28318
+ const index = indexes3.get(name.toLowerCase());
28319
+ return index === void 0 ? void 0 : parameters[index];
28320
+ }
28285
28321
  function neoScriptCallMatchesParameters(suppliedNames, parameters) {
28286
28322
  const supplied = new Set(suppliedNames.map((name) => name.toLowerCase()));
28287
28323
  const declared = new Set(
@@ -28542,10 +28578,12 @@ function describeParameter(parameter4) {
28542
28578
  const defaulted = parameter4.defaultValue === void 0 ? "" : ` = ${parameter4.defaultValue.displayText}`;
28543
28579
  return `${parameter4.name}${nullability}${defaulted}`;
28544
28580
  }
28581
+ var parameterNameIndexes;
28545
28582
  var init_declared_constructors = __esm({
28546
28583
  "../packages/neoscript-language/src/declared-constructors.ts"() {
28547
28584
  "use strict";
28548
28585
  init_project2();
28586
+ parameterNameIndexes = /* @__PURE__ */ new WeakMap();
28549
28587
  }
28550
28588
  });
28551
28589
 
@@ -28879,12 +28917,18 @@ function identPathSegments(expression) {
28879
28917
  if (receiver === null) return null;
28880
28918
  return [...receiver, expression.name];
28881
28919
  }
28882
- function receiverNarrowings(path, rootEntry, scope) {
28920
+ function unaffectedNarrowings(path, rootEntry, scope) {
28883
28921
  const facts = [];
28884
- for (let dot = path.indexOf("."); dot !== -1; dot = path.indexOf(".", dot + 1)) {
28885
- const prefix = path.slice(0, dot);
28886
- const type = scope.lookupNarrowedType(prefix, rootEntry);
28887
- if (type !== null) facts.push([prefix, type]);
28922
+ const prefix = `${path}.`;
28923
+ const dot = path.lastIndexOf(".");
28924
+ if (dot === -1) return facts;
28925
+ const member = path.slice(dot);
28926
+ for (const [candidate, narrowed] of scope.effectiveNarrowedPaths()) {
28927
+ if (narrowed.rootEntry !== rootEntry) continue;
28928
+ if (candidate === path || candidate.startsWith(prefix)) continue;
28929
+ if (candidate.endsWith(member) || candidate.includes(`${member}.`))
28930
+ continue;
28931
+ facts.push([candidate, narrowed.type]);
28888
28932
  }
28889
28933
  return facts;
28890
28934
  }
@@ -29208,22 +29252,22 @@ function localsWithBindings(locals, expression, whenTrue) {
29208
29252
  ...facts.flatMap((fact) => fact.bindingName ? [fact.bindingName] : [])
29209
29253
  ]);
29210
29254
  }
29211
- function collectAssignedPathRoots(statements, roots = /* @__PURE__ */ new Set(), inheritedLocals = /* @__PURE__ */ new Set(), flowCache = /* @__PURE__ */ new WeakMap()) {
29255
+ function collectAssignedPaths(statements, roots = /* @__PURE__ */ new Set(), inheritedLocals = /* @__PURE__ */ new Set(), flowCache = /* @__PURE__ */ new WeakMap()) {
29212
29256
  const locals = new Set(inheritedLocals);
29213
29257
  for (const statement of statements) {
29214
29258
  if (statement.kind === "assign") {
29215
29259
  const assignedPath = canonicalPath(statement.target);
29216
29260
  if (assignedPath && !locals.has(pathRoot(assignedPath))) {
29217
- roots.add(pathRoot(assignedPath));
29261
+ roots.add(assignedPath);
29218
29262
  }
29219
- collectAssignedPathRootsInExpression(
29263
+ collectAssignedPathsInExpression(
29220
29264
  statement.target,
29221
29265
  roots,
29222
29266
  locals,
29223
29267
  flowCache
29224
29268
  );
29225
29269
  if (statement.value)
29226
- collectAssignedPathRootsInExpression(
29270
+ collectAssignedPathsInExpression(
29227
29271
  statement.value,
29228
29272
  roots,
29229
29273
  locals,
@@ -29232,7 +29276,7 @@ function collectAssignedPathRoots(statements, roots = /* @__PURE__ */ new Set(),
29232
29276
  continue;
29233
29277
  }
29234
29278
  if (statement.kind === "varDecl") {
29235
- collectAssignedPathRootsInExpression(
29279
+ collectAssignedPathsInExpression(
29236
29280
  statement.init,
29237
29281
  roots,
29238
29282
  locals,
@@ -29246,7 +29290,7 @@ function collectAssignedPathRoots(statements, roots = /* @__PURE__ */ new Set(),
29246
29290
  const falseFacts = [];
29247
29291
  const fallthroughFacts = [];
29248
29292
  for (const branch of statement.branches) {
29249
- collectAssignedPathRootsInExpression(
29293
+ collectAssignedPathsInExpression(
29250
29294
  branch.cond,
29251
29295
  roots,
29252
29296
  falseLocals,
@@ -29256,7 +29300,7 @@ function collectAssignedPathRoots(statements, roots = /* @__PURE__ */ new Set(),
29256
29300
  ...falseFacts,
29257
29301
  ...factsWhenTrue(branch.cond, canonicalPath)
29258
29302
  ];
29259
- collectAssignedPathRoots(
29303
+ collectAssignedPaths(
29260
29304
  branch.body,
29261
29305
  roots,
29262
29306
  localsWithBindings(falseLocals, branch.cond, true),
@@ -29268,12 +29312,7 @@ function collectAssignedPathRoots(statements, roots = /* @__PURE__ */ new Set(),
29268
29312
  falseLocals = localsWithBindings(falseLocals, branch.cond, false);
29269
29313
  }
29270
29314
  if (statement.elseBody) {
29271
- collectAssignedPathRoots(
29272
- statement.elseBody,
29273
- roots,
29274
- falseLocals,
29275
- flowCache
29276
- );
29315
+ collectAssignedPaths(statement.elseBody, roots, falseLocals, flowCache);
29277
29316
  if (statementFlow(statement.elseBody, flowCache).has("fallthrough"))
29278
29317
  fallthroughFacts.push(falseFacts);
29279
29318
  } else {
@@ -29285,18 +29324,18 @@ function collectAssignedPathRoots(statements, roots = /* @__PURE__ */ new Set(),
29285
29324
  continue;
29286
29325
  }
29287
29326
  if (statement.kind === "try") {
29288
- collectAssignedPathRoots(statement.body, roots, locals, flowCache);
29327
+ collectAssignedPaths(statement.body, roots, locals, flowCache);
29289
29328
  for (const clause of statement.catches) {
29290
29329
  const catchLocals = /* @__PURE__ */ new Set([...locals, clause.name]);
29291
29330
  if (clause.filter) {
29292
- collectAssignedPathRootsInExpression(
29331
+ collectAssignedPathsInExpression(
29293
29332
  clause.filter,
29294
29333
  roots,
29295
29334
  catchLocals,
29296
29335
  flowCache
29297
29336
  );
29298
29337
  }
29299
- collectAssignedPathRoots(
29338
+ collectAssignedPaths(
29300
29339
  clause.body,
29301
29340
  roots,
29302
29341
  clause.filter ? localsWithBindings(catchLocals, clause.filter, true) : catchLocals,
@@ -29306,13 +29345,13 @@ function collectAssignedPathRoots(statements, roots = /* @__PURE__ */ new Set(),
29306
29345
  continue;
29307
29346
  }
29308
29347
  if (statement.kind === "while" || statement.kind === "doWhile") {
29309
- collectAssignedPathRootsInExpression(
29348
+ collectAssignedPathsInExpression(
29310
29349
  statement.condition,
29311
29350
  roots,
29312
29351
  locals,
29313
29352
  flowCache
29314
29353
  );
29315
- collectAssignedPathRoots(
29354
+ collectAssignedPaths(
29316
29355
  statement.body,
29317
29356
  roots,
29318
29357
  statement.kind === "while" ? localsWithBindings(locals, statement.condition, true) : locals,
@@ -29321,14 +29360,14 @@ function collectAssignedPathRoots(statements, roots = /* @__PURE__ */ new Set(),
29321
29360
  continue;
29322
29361
  }
29323
29362
  if (statement.kind === "for") {
29324
- collectAssignedPathRootsInExpression(
29363
+ collectAssignedPathsInExpression(
29325
29364
  statement.initializer.init,
29326
29365
  roots,
29327
29366
  locals,
29328
29367
  flowCache
29329
29368
  );
29330
29369
  const loopLocals = /* @__PURE__ */ new Set([...locals, statement.initializer.name]);
29331
- collectAssignedPathRootsInExpression(
29370
+ collectAssignedPathsInExpression(
29332
29371
  statement.condition,
29333
29372
  roots,
29334
29373
  loopLocals,
@@ -29339,22 +29378,17 @@ function collectAssignedPathRoots(statements, roots = /* @__PURE__ */ new Set(),
29339
29378
  statement.condition,
29340
29379
  true
29341
29380
  );
29342
- collectAssignedPathRoots(
29381
+ collectAssignedPaths(
29343
29382
  [statement.iterator],
29344
29383
  roots,
29345
29384
  iterationLocals,
29346
29385
  flowCache
29347
29386
  );
29348
- collectAssignedPathRoots(
29349
- statement.body,
29350
- roots,
29351
- iterationLocals,
29352
- flowCache
29353
- );
29387
+ collectAssignedPaths(statement.body, roots, iterationLocals, flowCache);
29354
29388
  continue;
29355
29389
  }
29356
29390
  if (statement.kind === "forEach") {
29357
- collectAssignedPathRootsInExpression(
29391
+ collectAssignedPathsInExpression(
29358
29392
  statement.collection,
29359
29393
  roots,
29360
29394
  locals,
@@ -29362,11 +29396,11 @@ function collectAssignedPathRoots(statements, roots = /* @__PURE__ */ new Set(),
29362
29396
  );
29363
29397
  const loopLocals = /* @__PURE__ */ new Set([...locals, statement.name]);
29364
29398
  if (statement.key) loopLocals.add(statement.key.name);
29365
- collectAssignedPathRoots(statement.body, roots, loopLocals, flowCache);
29399
+ collectAssignedPaths(statement.body, roots, loopLocals, flowCache);
29366
29400
  continue;
29367
29401
  }
29368
29402
  if (statement.kind === "switch") {
29369
- collectAssignedPathRootsInExpression(
29403
+ collectAssignedPathsInExpression(
29370
29404
  statement.selector,
29371
29405
  roots,
29372
29406
  locals,
@@ -29375,7 +29409,7 @@ function collectAssignedPathRoots(statements, roots = /* @__PURE__ */ new Set(),
29375
29409
  for (const section of statement.sections) {
29376
29410
  for (const label of section.labels) {
29377
29411
  if (label.kind === "case") {
29378
- collectAssignedPathRootsInExpression(
29412
+ collectAssignedPathsInExpression(
29379
29413
  label.expression,
29380
29414
  roots,
29381
29415
  locals,
@@ -29383,13 +29417,13 @@ function collectAssignedPathRoots(statements, roots = /* @__PURE__ */ new Set(),
29383
29417
  );
29384
29418
  }
29385
29419
  }
29386
- collectAssignedPathRoots(section.body, roots, locals, flowCache);
29420
+ collectAssignedPaths(section.body, roots, locals, flowCache);
29387
29421
  }
29388
29422
  continue;
29389
29423
  }
29390
29424
  if (statement.kind === "return" || statement.kind === "throw") {
29391
29425
  if (statement.expr)
29392
- collectAssignedPathRootsInExpression(
29426
+ collectAssignedPathsInExpression(
29393
29427
  statement.expr,
29394
29428
  roots,
29395
29429
  locals,
@@ -29398,7 +29432,7 @@ function collectAssignedPathRoots(statements, roots = /* @__PURE__ */ new Set(),
29398
29432
  continue;
29399
29433
  }
29400
29434
  if (statement.kind === "exprStmt") {
29401
- collectAssignedPathRootsInExpression(
29435
+ collectAssignedPathsInExpression(
29402
29436
  statement.expr,
29403
29437
  roots,
29404
29438
  locals,
@@ -29408,43 +29442,28 @@ function collectAssignedPathRoots(statements, roots = /* @__PURE__ */ new Set(),
29408
29442
  }
29409
29443
  return roots;
29410
29444
  }
29411
- function collectAssignedPathRootsInExpression(expression, roots, locals, flowCache) {
29445
+ function collectAssignedPathsInExpression(expression, roots, locals, flowCache) {
29412
29446
  switch (expression.kind) {
29413
29447
  case "litInterp":
29414
29448
  for (const part of expression.parts) {
29415
29449
  if (part.kind === "expr") {
29416
- collectAssignedPathRootsInExpression(
29417
- part.expr,
29418
- roots,
29419
- locals,
29420
- flowCache
29421
- );
29450
+ collectAssignedPathsInExpression(part.expr, roots, locals, flowCache);
29422
29451
  }
29423
29452
  }
29424
29453
  return;
29425
29454
  case "litList":
29426
29455
  for (const element of expression.elements) {
29427
- collectAssignedPathRootsInExpression(element, roots, locals, flowCache);
29456
+ collectAssignedPathsInExpression(element, roots, locals, flowCache);
29428
29457
  }
29429
29458
  return;
29430
29459
  case "litDict":
29431
29460
  for (const entry of expression.entries) {
29432
- collectAssignedPathRootsInExpression(
29433
- entry.key,
29434
- roots,
29435
- locals,
29436
- flowCache
29437
- );
29438
- collectAssignedPathRootsInExpression(
29439
- entry.value,
29440
- roots,
29441
- locals,
29442
- flowCache
29443
- );
29461
+ collectAssignedPathsInExpression(entry.key, roots, locals, flowCache);
29462
+ collectAssignedPathsInExpression(entry.value, roots, locals, flowCache);
29444
29463
  }
29445
29464
  return;
29446
29465
  case "member":
29447
- collectAssignedPathRootsInExpression(
29466
+ collectAssignedPathsInExpression(
29448
29467
  expression.receiver,
29449
29468
  roots,
29450
29469
  locals,
@@ -29452,13 +29471,13 @@ function collectAssignedPathRootsInExpression(expression, roots, locals, flowCac
29452
29471
  );
29453
29472
  return;
29454
29473
  case "index":
29455
- collectAssignedPathRootsInExpression(
29474
+ collectAssignedPathsInExpression(
29456
29475
  expression.receiver,
29457
29476
  roots,
29458
29477
  locals,
29459
29478
  flowCache
29460
29479
  );
29461
- collectAssignedPathRootsInExpression(
29480
+ collectAssignedPathsInExpression(
29462
29481
  expression.index,
29463
29482
  roots,
29464
29483
  locals,
@@ -29466,32 +29485,22 @@ function collectAssignedPathRootsInExpression(expression, roots, locals, flowCac
29466
29485
  );
29467
29486
  return;
29468
29487
  case "call":
29469
- collectAssignedPathRootsInExpression(
29488
+ collectAssignedPathsInExpression(
29470
29489
  expression.callee,
29471
29490
  roots,
29472
29491
  locals,
29473
29492
  flowCache
29474
29493
  );
29475
29494
  for (const argument2 of expression.args) {
29476
- collectAssignedPathRootsInExpression(
29477
- argument2,
29478
- roots,
29479
- locals,
29480
- flowCache
29481
- );
29495
+ collectAssignedPathsInExpression(argument2, roots, locals, flowCache);
29482
29496
  }
29483
29497
  return;
29484
29498
  case "new":
29485
29499
  for (const argument2 of expression.args) {
29486
- collectAssignedPathRootsInExpression(
29487
- argument2,
29488
- roots,
29489
- locals,
29490
- flowCache
29491
- );
29500
+ collectAssignedPathsInExpression(argument2, roots, locals, flowCache);
29492
29501
  }
29493
29502
  for (const initializer of expression.initializer ?? []) {
29494
- collectAssignedPathRootsInExpression(
29503
+ collectAssignedPathsInExpression(
29495
29504
  initializer.value,
29496
29505
  roots,
29497
29506
  locals,
@@ -29502,15 +29511,10 @@ function collectAssignedPathRootsInExpression(expression, roots, locals, flowCac
29502
29511
  case "annotated":
29503
29512
  for (const annotation2 of expression.annotations) {
29504
29513
  for (const argument2 of annotation2.args) {
29505
- collectAssignedPathRootsInExpression(
29506
- argument2,
29507
- roots,
29508
- locals,
29509
- flowCache
29510
- );
29514
+ collectAssignedPathsInExpression(argument2, roots, locals, flowCache);
29511
29515
  }
29512
29516
  }
29513
- collectAssignedPathRootsInExpression(
29517
+ collectAssignedPathsInExpression(
29514
29518
  expression.expression,
29515
29519
  roots,
29516
29520
  locals,
@@ -29519,13 +29523,13 @@ function collectAssignedPathRootsInExpression(expression, roots, locals, flowCac
29519
29523
  return;
29520
29524
  case "binary":
29521
29525
  case "coalesce":
29522
- collectAssignedPathRootsInExpression(
29526
+ collectAssignedPathsInExpression(
29523
29527
  expression.left,
29524
29528
  roots,
29525
29529
  locals,
29526
29530
  flowCache
29527
29531
  );
29528
- collectAssignedPathRootsInExpression(
29532
+ collectAssignedPathsInExpression(
29529
29533
  expression.right,
29530
29534
  roots,
29531
29535
  locals,
@@ -29533,19 +29537,19 @@ function collectAssignedPathRootsInExpression(expression, roots, locals, flowCac
29533
29537
  );
29534
29538
  return;
29535
29539
  case "conditional":
29536
- collectAssignedPathRootsInExpression(
29540
+ collectAssignedPathsInExpression(
29537
29541
  expression.condition,
29538
29542
  roots,
29539
29543
  locals,
29540
29544
  flowCache
29541
29545
  );
29542
- collectAssignedPathRootsInExpression(
29546
+ collectAssignedPathsInExpression(
29543
29547
  expression.whenTrue,
29544
29548
  roots,
29545
29549
  locals,
29546
29550
  flowCache
29547
29551
  );
29548
- collectAssignedPathRootsInExpression(
29552
+ collectAssignedPathsInExpression(
29549
29553
  expression.whenFalse,
29550
29554
  roots,
29551
29555
  locals,
@@ -29554,7 +29558,7 @@ function collectAssignedPathRootsInExpression(expression, roots, locals, flowCac
29554
29558
  return;
29555
29559
  case "unary":
29556
29560
  case "force":
29557
- collectAssignedPathRootsInExpression(
29561
+ collectAssignedPathsInExpression(
29558
29562
  expression.operand,
29559
29563
  roots,
29560
29564
  locals,
@@ -29562,7 +29566,7 @@ function collectAssignedPathRootsInExpression(expression, roots, locals, flowCac
29562
29566
  );
29563
29567
  return;
29564
29568
  case "is":
29565
- collectAssignedPathRootsInExpression(
29569
+ collectAssignedPathsInExpression(
29566
29570
  expression.operand,
29567
29571
  roots,
29568
29572
  locals,
@@ -29570,7 +29574,7 @@ function collectAssignedPathRootsInExpression(expression, roots, locals, flowCac
29570
29574
  );
29571
29575
  return;
29572
29576
  case "lambda":
29573
- collectAssignedPathRoots(
29577
+ collectAssignedPaths(
29574
29578
  expression.body,
29575
29579
  roots,
29576
29580
  /* @__PURE__ */ new Set([
@@ -30564,14 +30568,17 @@ var init_strict_resolver = __esm({
30564
30568
  return this.invalidatedRoots;
30565
30569
  }
30566
30570
  effectiveNarrowedPaths() {
30567
- const effective = this.parent ? new Map(this.parent.effectiveNarrowedPaths()) : /* @__PURE__ */ new Map();
30568
- for (const invalidated of this.invalidatedRoots) {
30569
- for (const [path, narrowed] of effective) {
30570
- if (narrowed.rootEntry === invalidated) effective.delete(path);
30571
+ const effective = new Map(this.narrowedPaths);
30572
+ const invalidated = new Set(this.invalidatedRoots);
30573
+ for (const root of this.hiddenNarrowingRoots) invalidated.add(root);
30574
+ for (let current = this.parent; current; current = current.parent) {
30575
+ for (const [path, narrowed] of current.narrowedPaths) {
30576
+ if (!effective.has(path) && !invalidated.has(narrowed.rootEntry)) {
30577
+ effective.set(path, narrowed);
30578
+ }
30571
30579
  }
30572
- }
30573
- for (const [path, narrowed] of this.narrowedPaths) {
30574
- effective.set(path, narrowed);
30580
+ for (const root of current.invalidatedRoots) invalidated.add(root);
30581
+ for (const root of current.hiddenNarrowingRoots) invalidated.add(root);
30575
30582
  }
30576
30583
  return effective;
30577
30584
  }
@@ -30597,6 +30604,9 @@ var init_strict_resolver = __esm({
30597
30604
  hideInheritedNarrowing(rootEntry) {
30598
30605
  this.hiddenNarrowingRoots.add(rootEntry);
30599
30606
  this.updatePatternType(rootEntry, rootEntry.type);
30607
+ for (const [path, narrowed] of this.narrowedPaths) {
30608
+ if (narrowed.rootEntry === rootEntry) this.narrowedPaths.delete(path);
30609
+ }
30600
30610
  }
30601
30611
  invalidate(rootEntry) {
30602
30612
  this.invalidatedRoots.add(rootEntry);
@@ -31154,24 +31164,26 @@ var init_strict_resolver = __esm({
31154
31164
  const branchExitNarrowings = [];
31155
31165
  const branchExitOwnershipScopes = [];
31156
31166
  const branches = statement.branches.map((branch) => {
31167
+ const conditionScope = new Scope(scope);
31168
+ this.applyFactsToScope(conditionScope, cumulativeFalseFacts);
31157
31169
  const condition = this.toBool(
31158
- this.resolveExpression(branch.cond, scope),
31170
+ this.resolveExpression(branch.cond, conditionScope),
31159
31171
  branch.cond.pos
31160
31172
  );
31161
31173
  const child2 = new Scope(scope);
31162
31174
  const branchFacts = [
31163
31175
  ...cumulativeFalseFacts,
31164
- ...this.conditionFacts(branch.cond, scope, true)
31176
+ ...this.conditionFacts(branch.cond, conditionScope, true)
31165
31177
  ];
31166
31178
  this.applyFactsToScope(child2, branchFacts);
31167
31179
  const instructions = this.resolveStatements(branch.body, child2);
31168
31180
  if (!instructionsTerminate(instructions)) {
31169
31181
  branchExitFacts.push(branchFacts);
31170
- branchExitNarrowings.push(new Map(child2.narrowedPaths));
31182
+ branchExitNarrowings.push(child2.effectiveNarrowedPaths());
31171
31183
  branchExitOwnershipScopes.push(child2);
31172
31184
  }
31173
31185
  cumulativeFalseFacts.push(
31174
- ...this.conditionFacts(branch.cond, scope, false)
31186
+ ...this.conditionFacts(branch.cond, conditionScope, false)
31175
31187
  );
31176
31188
  return {
31177
31189
  expression: pointerToBooleanExpression(condition.pointer),
@@ -31185,14 +31197,14 @@ var init_strict_resolver = __esm({
31185
31197
  otherwise = this.resolveStatements(statement.elseBody, elseScope);
31186
31198
  if (!instructionsTerminate(otherwise)) {
31187
31199
  branchExitFacts.push([...cumulativeFalseFacts]);
31188
- branchExitNarrowings.push(new Map(elseScope.narrowedPaths));
31200
+ branchExitNarrowings.push(elseScope.effectiveNarrowedPaths());
31189
31201
  branchExitOwnershipScopes.push(elseScope);
31190
31202
  }
31191
31203
  } else {
31192
31204
  const noBranchScope = new Scope(scope);
31193
31205
  this.applyFactsToScope(noBranchScope, cumulativeFalseFacts);
31194
31206
  branchExitFacts.push([...cumulativeFalseFacts]);
31195
- branchExitNarrowings.push(new Map(noBranchScope.narrowedPaths));
31207
+ branchExitNarrowings.push(noBranchScope.effectiveNarrowedPaths());
31196
31208
  branchExitOwnershipScopes.push(noBranchScope);
31197
31209
  }
31198
31210
  mergeBranchInvalidations(scope, branchExitOwnershipScopes);
@@ -31426,12 +31438,15 @@ var init_strict_resolver = __esm({
31426
31438
  statement.body,
31427
31439
  conditionLocals
31428
31440
  );
31429
- this.invalidateLoopEntryNarrowingsAssignedBy(
31430
- loopEntryScope,
31431
- loopScope,
31432
- [statement.iterator],
31433
- conditionLocals
31434
- );
31441
+ const bodyFlow = statementFlow(statement.body, /* @__PURE__ */ new WeakMap());
31442
+ if (bodyFlow.has("fallthrough") || bodyFlow.has("continue")) {
31443
+ this.invalidateLoopEntryNarrowingsAssignedBy(
31444
+ loopEntryScope,
31445
+ loopScope,
31446
+ [statement.iterator],
31447
+ conditionLocals
31448
+ );
31449
+ }
31435
31450
  const condition = this.toBool(
31436
31451
  this.resolveExpression(statement.condition, loopEntryScope),
31437
31452
  statement.condition.pos
@@ -32298,13 +32313,13 @@ var init_strict_resolver = __esm({
32298
32313
  if (assignedPath) {
32299
32314
  const rootEntry = scope.lookup(pathRoot(assignedPath));
32300
32315
  if (rootEntry) {
32301
- const receiverFacts = receiverNarrowings(
32316
+ const retainedFacts = unaffectedNarrowings(
32302
32317
  assignedPath,
32303
32318
  rootEntry,
32304
32319
  scope
32305
32320
  );
32306
32321
  scope.invalidate(rootEntry);
32307
- for (const [path, type] of receiverFacts) {
32322
+ for (const [path, type] of retainedFacts) {
32308
32323
  scope.narrow(path, rootEntry, type);
32309
32324
  }
32310
32325
  if (statement.op === "=" && !isNullable(value.type)) {
@@ -32521,13 +32536,13 @@ var init_strict_resolver = __esm({
32521
32536
  if (assignedPath) {
32522
32537
  const rootEntry = scope.lookup(pathRoot(assignedPath));
32523
32538
  if (rootEntry) {
32524
- const receiverFacts = receiverNarrowings(
32539
+ const retainedFacts = unaffectedNarrowings(
32525
32540
  assignedPath,
32526
32541
  rootEntry,
32527
32542
  scope
32528
32543
  );
32529
32544
  scope.invalidate(rootEntry);
32530
- for (const [path, type] of receiverFacts) {
32545
+ for (const [path, type] of retainedFacts) {
32531
32546
  scope.narrow(path, rootEntry, type);
32532
32547
  }
32533
32548
  }
@@ -33142,18 +33157,19 @@ var init_strict_resolver = __esm({
33142
33157
  case "coalesce": {
33143
33158
  const left = this.resolveExpression(expression.left, scope);
33144
33159
  const leftOptional = { ...left.type, nullable: true };
33160
+ const nullLeft = isNull(left.type);
33145
33161
  const right = this.resolveExpression(
33146
33162
  expression.right,
33147
33163
  scope,
33148
- leftOptional
33164
+ nullLeft ? expected : leftOptional
33149
33165
  );
33150
- if (!isNeoScriptTypeAssignable(right.type, leftOptional, this.project)) {
33166
+ if (!nullLeft && !isNeoScriptTypeAssignable(right.type, leftOptional, this.project)) {
33151
33167
  throw new CompileError(
33152
33168
  `\`??\` right operand ${this.describe(right.type)} is not assignable to ${this.describe(leftOptional)}`,
33153
33169
  expression.pos
33154
33170
  );
33155
33171
  }
33156
- const resultType = {
33172
+ const resultType = nullLeft ? right.type : {
33157
33173
  ...left.type,
33158
33174
  nullable: isNullable(left.type) && isNullable(right.type)
33159
33175
  };
@@ -33854,20 +33870,25 @@ var init_strict_resolver = __esm({
33854
33870
  return whenTrue ? factsWhenTrue(expression, pathOf) : factsWhenFalse(expression, pathOf);
33855
33871
  }
33856
33872
  /**
33857
- * A loop body is resolved once but can execute repeatedly. Any narrowing rooted
33858
- * in an outer binding that the body or iterator may write is therefore stale
33859
- * at a later iteration entry. Invalidate those roots before resolving the
33860
- * shared iteration so only the loop's own condition can narrow them again.
33873
+ * A loop body is resolved once but can execute repeatedly. Hide facts about
33874
+ * paths it may replace before resolving the shared iteration; unrelated facts
33875
+ * still hold, and the loop condition can narrow the written paths again.
33861
33876
  */
33862
33877
  invalidateLoopEntryNarrowingsAssignedBy(loopEntryScope, outerScope, statements, locals = /* @__PURE__ */ new Set()) {
33863
- for (const rootName of collectAssignedPathRoots(
33878
+ for (const assignedPath of collectAssignedPaths(
33864
33879
  statements,
33865
33880
  /* @__PURE__ */ new Set(),
33866
33881
  locals
33867
33882
  )) {
33868
- const path = this.narrowingPath(rootName, outerScope);
33883
+ const path = this.narrowingPath(assignedPath, outerScope);
33869
33884
  const outerEntry = path === null ? null : outerScope.lookup(pathRoot(path));
33870
- if (outerEntry) loopEntryScope.hideInheritedNarrowing(outerEntry);
33885
+ if (outerEntry && path !== null) {
33886
+ const retained = unaffectedNarrowings(path, outerEntry, loopEntryScope);
33887
+ loopEntryScope.hideInheritedNarrowing(outerEntry);
33888
+ for (const [retainedPath, type] of retained) {
33889
+ loopEntryScope.narrow(retainedPath, outerEntry, type);
33890
+ }
33891
+ }
33871
33892
  }
33872
33893
  }
33873
33894
  applyFactsToScope(targetScope, facts, mode = "all") {
@@ -35304,6 +35325,7 @@ var init_strict_resolver = __esm({
35304
35325
  (candidate) => (candidate.kind === "function" || candidate.kind === "method") && candidate.name === callee.name
35305
35326
  );
35306
35327
  if (member) {
35328
+ this.validateFunctionReceiver(receiver, callee.name, optional2, pos);
35307
35329
  if (type !== void 0) this.assertMemberAccessible(type, member, pos);
35308
35330
  if (member.static === true) {
35309
35331
  throw new CompileError(
@@ -36452,12 +36474,10 @@ var init_strict_resolver = __esm({
36452
36474
  callableSignatureForReceiver(symbol, receiver) {
36453
36475
  let parameters = symbol.parameters ?? [];
36454
36476
  let returnType = symbol.returnType ?? symbol.type;
36455
- if (this.context.projectSourceKind !== "spec" && !(receiver?.kind === "instance" && receiver.dispatch === "base")) {
36456
- return { parameters, returnType };
36457
- }
36458
36477
  if (receiver?.kind !== "instance") return { parameters, returnType };
36459
36478
  const receiverType = receiver.expression.type;
36460
36479
  if (receiverType.kind !== "named") return { parameters, returnType };
36480
+ if (!receiverType.typeArguments?.length) return { parameters, returnType };
36461
36481
  const declaring = this.project.typeById.get(receiverType.typeId);
36462
36482
  if (declaring === void 0) return { parameters, returnType };
36463
36483
  parameters = parameters.map((parameter4) => ({
@@ -37361,6 +37381,21 @@ var init_strict_resolver = __esm({
37361
37381
  callSiteId: this.nextCallSite(expression.pos)
37362
37382
  };
37363
37383
  }
37384
+ validateFunctionReceiver(receiver, name, optional2, pos) {
37385
+ if (optional2 && !isNullable(receiver.type)) {
37386
+ throw new CompileError(
37387
+ `\`?.\` requires an optional receiver; got ${this.describe(receiver.type)}`,
37388
+ pos
37389
+ );
37390
+ }
37391
+ const receiverType = receiver.optionalChainType ?? receiver.type;
37392
+ if (!optional2 && isNullable(receiverType)) {
37393
+ throw new CompileError(
37394
+ `Function '${name}' is called on ${this.describe(receiverType)}, which may be null. Use optional chaining, force-unwrapping, or a null check before calling it.`,
37395
+ pos
37396
+ );
37397
+ }
37398
+ }
37364
37399
  resolveFunctionStatement(expression, scope) {
37365
37400
  if (expression.kind !== "call") return null;
37366
37401
  const receiverValue = this.callReceiver(expression.callee, scope);
@@ -37524,12 +37559,19 @@ var init_strict_resolver = __esm({
37524
37559
  }
37525
37560
  }
37526
37561
  const receiver = receiverValue();
37527
- if (receiver.type.kind !== "named") return null;
37528
- const type = this.project.typeById.get(receiver.type.typeId);
37562
+ const memberReceiverType = neoScriptMemberLookupType(receiver.type);
37563
+ if (memberReceiverType.kind !== "named") return null;
37564
+ const type = this.project.typeById.get(memberReceiverType.typeId);
37529
37565
  const symbol = type?.members.find(
37530
37566
  (candidate) => (candidate.kind === "function" || candidate.kind === "method") && candidate.name === memberName
37531
37567
  );
37532
37568
  if (!symbol) return null;
37569
+ this.validateFunctionReceiver(
37570
+ receiver,
37571
+ memberName,
37572
+ expression.callee.optional === true,
37573
+ expression.pos
37574
+ );
37533
37575
  if (type !== void 0) {
37534
37576
  this.assertMemberAccessible(type, symbol, expression.pos);
37535
37577
  }
@@ -37542,7 +37584,10 @@ var init_strict_resolver = __esm({
37542
37584
  this.validateCallableInContext(symbol, expression.pos);
37543
37585
  const resolved = this.resolveCallableArguments(
37544
37586
  symbol,
37545
- { kind: "instance", expression: receiver },
37587
+ {
37588
+ kind: "instance",
37589
+ expression: memberReceiverType === receiver.type ? receiver : { ...receiver, type: memberReceiverType }
37590
+ },
37546
37591
  expression.args,
37547
37592
  scope,
37548
37593
  expression.pos
@@ -42576,6 +42621,7 @@ function createEnvironment(documents, project) {
42576
42621
  project,
42577
42622
  projectIndex: createProjectIndex(project),
42578
42623
  listenerResolvers: /* @__PURE__ */ new Map(),
42624
+ assignability: /* @__PURE__ */ new Map(),
42579
42625
  enums,
42580
42626
  types,
42581
42627
  globals,
@@ -43854,13 +43900,19 @@ function validateExpression(expression, expected, scope, environment, uri, range
43854
43900
  );
43855
43901
  return;
43856
43902
  }
43857
- if (expected && expression.kind !== "contextualEnum" && !isReferenceCall(expression)) {
43903
+ if (expected && expression.kind !== "contextualEnum" && expression.kind !== "annotated" && !isReferenceCall(expression)) {
43858
43904
  const actual = inferExpressionType(expression, scope, environment);
43859
- if (actual && !semanticTypesAssignable(actual, expected)) {
43905
+ const explicitConstruction = expression.kind === "new" && expression.className !== null && expected.name !== "Partial";
43906
+ const assignable = actual === void 0 || (explicitConstruction ? constructionTypesAssignable(actual, expected, scope, environment) : semanticTypesAssignable(actual, expected));
43907
+ if (actual && !assignable) {
43860
43908
  pushDiagnostic(
43861
43909
  diagnostics,
43862
43910
  uri,
43863
- anchor ? anchorSpan(anchor, expression.pos, 1) : range2,
43911
+ anchor ? anchorSpan(
43912
+ anchor,
43913
+ expression.pos,
43914
+ expression.kind === "new" ? 3 : 1
43915
+ ) : range2,
43864
43916
  "project-expression-type-mismatch",
43865
43917
  `Expected ${describeType(expected)} but received ${describeType(actual)}.`
43866
43918
  );
@@ -44005,7 +44057,7 @@ function validateExpression(expression, expected, scope, environment, uri, range
44005
44057
  if (expression.kind === "coalesce") {
44006
44058
  validateExpression(
44007
44059
  expression.left,
44008
- expected,
44060
+ expected ? { ...expected, nullable: true } : void 0,
44009
44061
  scope,
44010
44062
  environment,
44011
44063
  uri,
@@ -44016,7 +44068,7 @@ function validateExpression(expression, expected, scope, environment, uri, range
44016
44068
  const left = inferExpressionType(expression.left, scope, environment);
44017
44069
  validateExpression(
44018
44070
  expression.right,
44019
- left ?? expected,
44071
+ left && left.name !== "null" ? { ...left, nullable: true } : expected,
44020
44072
  scope,
44021
44073
  environment,
44022
44074
  uri,
@@ -44134,23 +44186,26 @@ function validateExpression(expression, expected, scope, environment, uri, range
44134
44186
  }))
44135
44187
  );
44136
44188
  }
44137
- const fields = declaration?.members.filter(
44138
- (member) => member.kind === "field" && !member.modifiers.includes("static")
44139
- ) ?? [];
44140
- const overload = declaration && declaration.constructors.length > 0 ? matchingDeclaredConstructor(declaration, expression.argumentNames) : null;
44189
+ const parameters = declaration.headerParameters ?? matchingDeclaredConstructor(declaration, siteArgumentNames)?.parameters;
44190
+ const fields = [];
44191
+ const fieldsByName = /* @__PURE__ */ new Map();
44192
+ if (declaration.headerParameters === void 0 && declaration.constructors.length === 0) {
44193
+ for (const member of declaration.members) {
44194
+ if (member.kind !== "field" || member.modifiers.includes("static"))
44195
+ continue;
44196
+ fields.push(member);
44197
+ fieldsByName.set(member.name, member);
44198
+ }
44199
+ }
44141
44200
  expression.args.forEach((argument2, index) => {
44142
44201
  const authoredName = expression.argumentNames?.[index];
44143
44202
  const named = declaration.name === NEO_LOOKUP_VARIANT_FOLDER_TYPE_NAME ? authoredName ?? NEO_LOOKUP_VARIANT_FOLDER_CONSTRUCTOR_ARGUMENTS[index]?.name : authoredName;
44144
44203
  if (declaration.name === NEO_LOOKUP_VARIANT_FOLDER_TYPE_NAME && named === "collection") {
44145
44204
  return;
44146
44205
  }
44147
- const parameter4 = named ? (declaration.headerParameters ?? []).find(
44148
- (candidate) => candidate.name === named
44149
- ) ?? overload?.parameters.find((candidate) => candidate.name === named) : void 0;
44206
+ const parameter4 = named && parameters ? neoScriptParameterByName(parameters, named) : parameters?.[index];
44150
44207
  const variantMember = named === void 0 || named === null ? void 0 : variantSite === null ? void 0 : NEO_VARIANT_MEMBER_ARGUMENTS.get(named);
44151
- const field = named ? fields.find(
44152
- (candidate) => candidate.name === (variantMember ?? named)
44153
- ) : fields[index];
44208
+ const field = named ? fieldsByName.get(variantMember ?? named) : fields[index];
44154
44209
  const expectedType = parameter4?.type ?? field?.type;
44155
44210
  const expectedSemanticType = declaration.name === NEO_LOOKUP_VARIANT_FOLDER_TYPE_NAME && named === "collectionValue" ? { name: "string" } : expectedType ? substituteSemanticType(semanticType(expectedType), siteBindings) : void 0;
44156
44211
  validateExpression(
@@ -44450,6 +44505,41 @@ function commonSemanticAssignableType(left, right) {
44450
44505
  if (semanticTypesAssignable(right, left)) return left;
44451
44506
  return void 0;
44452
44507
  }
44508
+ function constructionTypesAssignable(actual, expected, scope, environment) {
44509
+ if (actual.name === expected.name && !actual.arguments?.length && !expected.arguments?.length)
44510
+ return true;
44511
+ const owner = scope.get("this")?.name ?? "";
44512
+ const key = `${owner}:${describeType(actual)}>${describeType(expected)}`;
44513
+ const cached = environment.assignability.get(key);
44514
+ if (cached !== void 0) return cached;
44515
+ const declaration = environment.projectIndex.typeByName.get(owner);
44516
+ const context = {
44517
+ project: environment.project,
44518
+ kind: "initializerExpression",
44519
+ ...declaration ? { declaringType: { kind: "named", typeId: declaration.id } } : {}
44520
+ };
44521
+ const pos = { line: 1, column: 1 };
44522
+ let assignable = true;
44523
+ try {
44524
+ assignable = isNeoScriptTypeAssignable(
44525
+ resolveNeoScriptType(
44526
+ semanticAst(actual, pos),
44527
+ context,
44528
+ environment.projectIndex
44529
+ ),
44530
+ resolveNeoScriptType(
44531
+ semanticAst(expected, pos),
44532
+ context,
44533
+ environment.projectIndex
44534
+ ),
44535
+ environment.projectIndex
44536
+ );
44537
+ } catch (error) {
44538
+ if (!(error instanceof CompileError)) throw error;
44539
+ }
44540
+ environment.assignability.set(key, assignable);
44541
+ return assignable;
44542
+ }
44453
44543
  function semanticNumericRank(name) {
44454
44544
  if (name === "int") return 0;
44455
44545
  if (name === "float") return 1;
@@ -44599,11 +44689,24 @@ function inferExpressionType(expression, scope, environment) {
44599
44689
  if (expression.kind === "litString" || expression.kind === "litInterp" || expression.kind === "litTripleString")
44600
44690
  return primitiveType("string");
44601
44691
  if (expression.kind === "new")
44602
- return expression.className ? { name: expression.className } : void 0;
44692
+ return expression.className ? {
44693
+ name: expression.className,
44694
+ ...expression.typeArguments ? { arguments: expression.typeArguments.map(semanticAstType) } : {}
44695
+ } : void 0;
44603
44696
  if (expression.kind === "force") {
44604
44697
  const operand = inferExpressionType(expression.operand, scope, environment);
44605
44698
  return operand ? { ...operand, nullable: false } : void 0;
44606
44699
  }
44700
+ if (expression.kind === "coalesce") {
44701
+ const left = inferExpressionType(expression.left, scope, environment);
44702
+ const right = inferExpressionType(expression.right, scope, environment);
44703
+ if (left?.name === "null") return right;
44704
+ if (!left || !right) return void 0;
44705
+ return {
44706
+ ...left,
44707
+ nullable: left.nullable === true && right.nullable === true
44708
+ };
44709
+ }
44607
44710
  if (expression.kind === "index") {
44608
44711
  const receiver = inferExpressionType(
44609
44712
  expression.receiver,
@@ -44874,14 +44977,19 @@ function classExtends(actual, expected, environment, visited) {
44874
44977
  );
44875
44978
  }
44876
44979
  function matchingDeclaredConstructor(declaration, argumentNames) {
44877
- const names = (argumentNames ?? []).filter(
44878
- (name) => name !== null
44879
- );
44880
- const key = [...names].map((name) => name.toLowerCase()).sort().join(",");
44881
- const matches = declaration.constructors.filter(
44882
- (constructor2) => constructor2.parameters.map((parameter4) => parameter4.name.toLowerCase()).sort().join(",") === key
44980
+ if (declaration.constructors.length === 1)
44981
+ return declaration.constructors[0] ?? null;
44982
+ if (argumentNames.some((name) => name === null)) return null;
44983
+ const names = argumentNames.filter((name) => name !== null);
44984
+ const resolution = resolveNeoScriptNamedOverload(
44985
+ declaration.constructors,
44986
+ names,
44987
+ (constructor2) => constructor2.parameters.map((parameter4) => ({
44988
+ name: parameter4.name,
44989
+ defaulted: parameter4.defaultValue !== void 0
44990
+ }))
44883
44991
  );
44884
- return matches.length === 1 ? matches[0] ?? null : null;
44992
+ return resolution.kind === "resolved" ? resolution.overload : null;
44885
44993
  }
44886
44994
  function semanticType(type) {
44887
44995
  return {
@@ -45230,6 +45338,7 @@ var init_project_source_semantics = __esm({
45230
45338
  init_strict_compile_error();
45231
45339
  init_executable_parser();
45232
45340
  init_project_source_construction_diagnostics();
45341
+ init_declared_constructors();
45233
45342
  init_project_source_variants();
45234
45343
  init_language_spec();
45235
45344
  init_project_source_settlement();
@@ -50866,7 +50975,7 @@ var init_registry = __esm({
50866
50975
  "../packages/manifest/schema-contract/registry.mjs"() {
50867
50976
  "use strict";
50868
50977
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
50869
- cliVersion: "0.72.1",
50978
+ cliVersion: "0.72.4",
50870
50979
  projectFileUploadBatchSize: 32,
50871
50980
  documentRecords: {
50872
50981
  member: {
@@ -110681,7 +110790,8 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
110681
110790
  continue;
110682
110791
  const key = `${change.recordKind}:${change.recordId}`;
110683
110792
  const base = baseScriptRecords.get(key);
110684
- if (base && canonicallyEqual2(
110793
+ if (base && // Rollout-tolerated bodies still need recompilation before reuse.
110794
+ firstRejectedNeoScriptCompiledBody(base, null) === null && !hasPendingNeoScriptDerivation(change.recordKind, base) && canonicallyEqual2(
110685
110795
  authoredScriptRecord(change.recordKind, base),
110686
110796
  authoredScriptRecord(change.recordKind, change.nextData)
110687
110797
  ))
@@ -110733,12 +110843,14 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
110733
110843
  if (kind === "member")
110734
110844
  remappedMembers.set(record7.id, {
110735
110845
  ...moved,
110736
- ...stripClientDerivedBodies("member", record7)
110846
+ createdAt: record7.createdAt,
110847
+ updatedAt: record7.updatedAt
110737
110848
  });
110738
110849
  else
110739
110850
  remappedConstructors.set(record7.id, {
110740
110851
  ...moved,
110741
- ...stripConstructorDerivedBodies(record7)
110852
+ createdAt: record7.createdAt,
110853
+ updatedAt: record7.updatedAt
110742
110854
  });
110743
110855
  }
110744
110856
  }
@@ -114517,6 +114629,7 @@ var init_project_version_schema_commit = __esm({
114517
114629
  "../src/database/project-version-schema-commit.ts"() {
114518
114630
  "use strict";
114519
114631
  init_dialogue_logic_compile_pure();
114632
+ init_neoscript_compiler_revision();
114520
114633
  init_neoscript_source_catalog();
114521
114634
  init_prepared_collection_bindings();
114522
114635
  init_stored_closure_captures();
@@ -124897,6 +125010,7 @@ function buildValueLowerContext(state, manifest, options = {}) {
124897
125010
  localizationConversionValueIds: registry.localizationConversionValueIds,
124898
125011
  loweredMemberIdByValueId: /* @__PURE__ */ new Map(),
124899
125012
  storedClassSchemaMemberIds: /* @__PURE__ */ new Map(),
125013
+ renamedSchemaKeys: /* @__PURE__ */ new Map(),
124900
125014
  ordinaryMoveFields: /* @__PURE__ */ new Map(),
124901
125015
  pendingBindingMembersByClassId: registry.pendingBindingMembersByClassId,
124902
125016
  declaredConstructors: declaredConstructorIndex,
@@ -126165,7 +126279,11 @@ function lowerRowBackedDefault(context, member, backed, baseData3, binding) {
126165
126279
  environment,
126166
126280
  binding.label
126167
126281
  );
126168
- const baseBody = backed.body;
126282
+ const baseBody = retainedStoredClassBody(
126283
+ context,
126284
+ currentClassId,
126285
+ backed.body
126286
+ );
126169
126287
  const body = {};
126170
126288
  lowerConstructorProjections(
126171
126289
  context,
@@ -126565,12 +126683,43 @@ function pendingSeedGraphRows(args) {
126565
126683
  function retainedStoredClassBody(context, storedClassId, baseBody) {
126566
126684
  const storedMemberIds = storedClassSchemaMemberIds(context, storedClassId);
126567
126685
  const body = {};
126686
+ const renames = renamedSchemaKeys(context, storedClassId);
126568
126687
  for (const [key, childId] of Object.entries(baseBody)) {
126569
126688
  if (storedMemberRemoved(context, storedMemberIds, key)) continue;
126570
- body[key] = childId;
126689
+ body[renames.get(key) ?? key] = childId;
126571
126690
  }
126572
126691
  return body;
126573
126692
  }
126693
+ function renamedSchemaKeys(context, classId) {
126694
+ const cached = context.renamedSchemaKeys.get(classId);
126695
+ if (cached !== void 0) return cached;
126696
+ const currentMembers = /* @__PURE__ */ new Map();
126697
+ for (const schemaClass2 of classInheritanceChain(context.classes, classId)) {
126698
+ for (const [key, memberId] of Object.entries(schemaClass2.schema)) {
126699
+ if (!currentMembers.has(key)) currentMembers.set(key, memberId);
126700
+ }
126701
+ }
126702
+ const renamed = schemaKeyRenamesByMemberId(
126703
+ storedClassSchemaMemberIds(context, classId),
126704
+ currentMembers
126705
+ );
126706
+ context.renamedSchemaKeys.set(classId, renamed);
126707
+ return renamed;
126708
+ }
126709
+ function schemaKeyRenamesByMemberId(before, after) {
126710
+ const currentKeys = /* @__PURE__ */ new Map();
126711
+ for (const [key, memberId] of after) {
126712
+ if (memberId !== null && !currentKeys.has(memberId))
126713
+ currentKeys.set(memberId, key);
126714
+ }
126715
+ const renamed = /* @__PURE__ */ new Map();
126716
+ for (const [key, memberId] of before) {
126717
+ const currentKey = memberId === null ? void 0 : currentKeys.get(memberId);
126718
+ if (currentKey !== void 0 && currentKey !== key)
126719
+ renamed.set(key, currentKey);
126720
+ }
126721
+ return renamed;
126722
+ }
126574
126723
  function storedMemberRemoved(context, storedMemberIds, key) {
126575
126724
  const storedMemberId = storedMemberIds.get(key);
126576
126725
  return storedMemberId !== void 0 && !context.members.has(storedMemberId);
@@ -127812,7 +127961,7 @@ function lowerValueBody(context, member, expression, base, source, environment,
127812
127961
  );
127813
127962
  }
127814
127963
  }
127815
- function authoredResetSchemaKeys(context, base, baseBody, expression, partial) {
127964
+ function authoredResetSchemaKeys(context, base, baseBody, expression, partial, classId) {
127816
127965
  if (partial) return /* @__PURE__ */ new Set();
127817
127966
  if (expression.kind !== "new") return /* @__PURE__ */ new Set();
127818
127967
  if (typeof base.id !== "string") return /* @__PURE__ */ new Set();
@@ -127820,15 +127969,17 @@ function authoredResetSchemaKeys(context, base, baseBody, expression, partial) {
127820
127969
  (expression.initializer ?? []).map((assignment) => assignment.name)
127821
127970
  );
127822
127971
  const expressions = context.materializedConstructorExpressions;
127972
+ const renames = renamedSchemaKeys(context, classId);
127823
127973
  if (Object.keys(baseBody).every(
127824
- (key) => authored.has(key) || expressions.declaresSchemaKey?.(key) === false
127974
+ (key) => authored.has(renames.get(key) ?? key) || expressions.declaresSchemaKey?.(key) === false
127825
127975
  )) {
127826
127976
  return /* @__PURE__ */ new Set();
127827
127977
  }
127828
127978
  const canonicalOverrideKeys = expressions.overrideSchemaKeys?.(base.id);
127829
127979
  if (canonicalOverrideKeys === void 0) return /* @__PURE__ */ new Set();
127830
127980
  const resets = /* @__PURE__ */ new Set();
127831
- for (const schemaKey of canonicalOverrideKeys) {
127981
+ for (const storedKey of canonicalOverrideKeys) {
127982
+ const schemaKey = renames.get(storedKey) ?? storedKey;
127832
127983
  if (!authored.has(schemaKey)) resets.add(schemaKey);
127833
127984
  }
127834
127985
  return resets;
@@ -127885,7 +128036,7 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
127885
128036
  schemaClass2,
127886
128037
  expression,
127887
128038
  base,
127888
- baseBody,
128039
+ body,
127889
128040
  body,
127890
128041
  source,
127891
128042
  environment,
@@ -127955,7 +128106,8 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
127955
128106
  base,
127956
128107
  baseBody,
127957
128108
  expression,
127958
- partial
128109
+ partial,
128110
+ currentClassId
127959
128111
  );
127960
128112
  for (const schemaKey of resetSchemaKeys) delete body[schemaKey];
127961
128113
  {
@@ -127963,10 +128115,12 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
127963
128115
  (expression.initializer ?? []).map((assignment) => assignment.name)
127964
128116
  );
127965
128117
  const storedMemberIds = storedClassSchemaMemberIds(context, currentClassId);
127966
- for (const [schemaKey, childId] of Object.entries(baseBody)) {
128118
+ const renames = renamedSchemaKeys(context, currentClassId);
128119
+ for (const [storedKey, childId] of Object.entries(baseBody)) {
128120
+ const schemaKey = renames.get(storedKey) ?? storedKey;
127967
128121
  if (typeof childId !== "string") continue;
127968
128122
  if (resetSchemaKeys.has(schemaKey)) continue;
127969
- if (storedMemberRemoved(context, storedMemberIds, schemaKey)) continue;
128123
+ if (storedMemberRemoved(context, storedMemberIds, storedKey)) continue;
127970
128124
  if (materializedConstruction === "lower" && authoredKeys.has(schemaKey)) {
127971
128125
  continue;
127972
128126
  }
@@ -127975,7 +128129,7 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
127975
128129
  childId,
127976
128130
  source.source,
127977
128131
  /* @__PURE__ */ new Set(),
127978
- memberById(context, storedMemberIds.get(schemaKey)),
128132
+ memberById(context, storedMemberIds.get(storedKey)),
127979
128133
  environment
127980
128134
  );
127981
128135
  }
@@ -128075,14 +128229,18 @@ function retainStoredValueSubgraph(context, valueId, source, visited, member, en
128075
128229
  visited.add(valueId);
128076
128230
  const state = context.state[`value:${valueId}`];
128077
128231
  if (state === void 0 || !isObjectRecord2(state.data)) return;
128078
- addReconstructed(
128079
- context,
128080
- "value",
128081
- valueId,
128082
- valueFileFields(state.data),
128083
- source,
128084
- { retained: true }
128085
- );
128232
+ const storedClassId = stringOrNull2(state.data.classId);
128233
+ const fields = valueFileFields(state.data);
128234
+ if (storedClassId !== null && isObjectRecord2(state.data.value) && renamedSchemaKeys(context, storedClassId).size > 0) {
128235
+ fields.value = retainedStoredClassBody(
128236
+ context,
128237
+ storedClassId,
128238
+ state.data.value
128239
+ );
128240
+ }
128241
+ addReconstructed(context, "value", valueId, fields, source, {
128242
+ retained: true
128243
+ });
128086
128244
  const rawOwningMember = member ?? storedRowPlacementMember(context, valueId);
128087
128245
  const owningMember = rawOwningMember === null ? null : resolveGenericSchemaMember(context, rawOwningMember, environment);
128088
128246
  if (owningMember?.kind === "string" && owningMember.localizable) {
@@ -128130,7 +128288,6 @@ function retainStoredValueSubgraph(context, valueId, source, visited, member, en
128130
128288
  for (const entry of Object.values(value)) collect(entry, childMember);
128131
128289
  };
128132
128290
  const body = state.data.value;
128133
- const storedClassId = stringOrNull2(state.data.classId);
128134
128291
  let childEnvironment = environment;
128135
128292
  if (storedClassId !== null) {
128136
128293
  if (owningMember?.kind === "class") {
@@ -128275,13 +128432,14 @@ function classProjectsEveryStoredConstructorRow(context, classId, argumentCount,
128275
128432
  if (projections2.length === 0 || projections2.length !== argumentCount) {
128276
128433
  return false;
128277
128434
  }
128435
+ const body = renamedSchemaKeys(context, classId).size === 0 ? storedBody : retainedStoredClassBody(context, classId, storedBody);
128278
128436
  return projections2.every((projection) => {
128279
128437
  const schemaKey = inheritedProjectionSchemaKey(
128280
128438
  context.classes,
128281
128439
  classId,
128282
128440
  projection.memberId
128283
128441
  );
128284
- return schemaKey !== null && typeof storedBody[schemaKey] === "string";
128442
+ return schemaKey !== null && typeof body[schemaKey] === "string";
128285
128443
  });
128286
128444
  }
128287
128445
  function requiredConstructorProjectionMap(classes, constructors, members, classId, visited) {
@@ -138573,7 +138731,7 @@ function materializedInitializerReconciliationFailuresV4(args) {
138573
138731
  continue;
138574
138732
  }
138575
138733
  assertPulledConstructorsCompiled(replayDocument, replayContext);
138576
- currentRows ??= new Map(currentDocument.values.map((row) => [row.id, row]));
138734
+ currentRows ??= storedRowsWithRenamedKeys(currentDocument, replayDocument);
138577
138735
  currentReader ??= new EffectiveValueReader(replayDocument, currentRows);
138578
138736
  const replay = replayRows.get(reconciliation.valueId);
138579
138737
  const replayArgs = replay !== void 0 && isLiteralValueContent(replay) ? replay.constructorArgs : void 0;
@@ -138605,6 +138763,41 @@ function materializedInitializerReconciliationFailuresV4(args) {
138605
138763
  }
138606
138764
  return failures;
138607
138765
  }
138766
+ function storedRowsWithRenamedKeys(before, after) {
138767
+ const renamesByClass = /* @__PURE__ */ new Map();
138768
+ const rows = /* @__PURE__ */ new Map();
138769
+ for (const row of before.values) {
138770
+ let renamed = row;
138771
+ if (typeof row.classId === "string" && isObjectRecord2(row.value)) {
138772
+ const classId = row.classId;
138773
+ let renames = renamesByClass.get(classId);
138774
+ if (renames === void 0) {
138775
+ const entries = (document) => mergeInstanceSurfaceSchema(
138776
+ classId,
138777
+ document.classes,
138778
+ document.members
138779
+ ).map((entry) => [entry.schemaKey, entry.memberId]);
138780
+ renames = schemaKeyRenamesByMemberId(entries(before), entries(after));
138781
+ renamesByClass.set(row.classId, renames);
138782
+ }
138783
+ if (renames.size > 0) {
138784
+ const value = {};
138785
+ let collision = false;
138786
+ for (const [key, child2] of Object.entries(row.value)) {
138787
+ const target = renames.get(key) ?? key;
138788
+ if (target !== key && Object.hasOwn(row.value, target) && !renames.has(target)) {
138789
+ collision = true;
138790
+ break;
138791
+ }
138792
+ value[target] = child2;
138793
+ }
138794
+ if (!collision) renamed = { ...row, value };
138795
+ }
138796
+ }
138797
+ rows.set(row.id, renamed);
138798
+ }
138799
+ return rows;
138800
+ }
138608
138801
  function withoutSharedArguments(stored, replayed) {
138609
138802
  const storedRest = { ...stored };
138610
138803
  const replayedRest = { ...replayed };
@@ -138988,6 +139181,7 @@ var init_local_initializer_materialization = __esm({
138988
139181
  init_variant_value_graph();
138989
139182
  init_members();
138990
139183
  init_member_value_id();
139184
+ init_inheritance();
138991
139185
  init_effective_value_reader();
138992
139186
  init_virtual_instance_values();
138993
139187
  init_value_graph();
@@ -140199,33 +140393,35 @@ function computeWorkspaceStatus(workspace, options) {
140199
140393
  )
140200
140394
  );
140201
140395
  }
140202
- try {
140203
- parseErrors.push(
140204
- ...materializedInitializerReconciliationFailuresV4({
140205
- workspace,
140206
- changes,
140207
- authoredValueSeeds,
140208
- reconciliations: valueLowerRegistry.initializerReconciliations,
140209
- canonicalConstructions: valueLowerRegistry.materializedConstructorExpressions,
140210
- localizedTextDependencies,
140211
- manifest,
140212
- analysis: projectAnalysisV4,
140213
- forceRecompile: options.forceRecompile,
140214
- useBuildCaches: options.useBuildCaches,
140215
- sourceTextByUri: new Map(
140216
- sourceEntries.map((entry) => [entry.relPath, entry.source])
140396
+ if (!parseErrors.some(isBlockingSchemaSourceError)) {
140397
+ try {
140398
+ parseErrors.push(
140399
+ ...materializedInitializerReconciliationFailuresV4({
140400
+ workspace,
140401
+ changes,
140402
+ authoredValueSeeds,
140403
+ reconciliations: valueLowerRegistry.initializerReconciliations,
140404
+ canonicalConstructions: valueLowerRegistry.materializedConstructorExpressions,
140405
+ localizedTextDependencies,
140406
+ manifest,
140407
+ analysis: projectAnalysisV4,
140408
+ forceRecompile: options.forceRecompile,
140409
+ useBuildCaches: options.useBuildCaches,
140410
+ sourceTextByUri: new Map(
140411
+ sourceEntries.map((entry) => [entry.relPath, entry.source])
140412
+ )
140413
+ })
140414
+ );
140415
+ } catch (error) {
140416
+ parseErrors.push(
140417
+ error instanceof SchemaSourceError ? error : new SchemaSourceError(
140418
+ error instanceof Error ? error.message : String(error),
140419
+ "<initializer-materialization>",
140420
+ 1,
140421
+ 1
140217
140422
  )
140218
- })
140219
- );
140220
- } catch (error) {
140221
- parseErrors.push(
140222
- error instanceof SchemaSourceError ? error : new SchemaSourceError(
140223
- error instanceof Error ? error.message : String(error),
140224
- "<initializer-materialization>",
140225
- 1,
140226
- 1
140227
- )
140228
- );
140423
+ );
140424
+ }
140229
140425
  }
140230
140426
  reportPhase("initializer-reconciliation", "Checking project files\u2026");
140231
140427
  for (const fileId of options.trustedPendingProjectFiles?.keys() ?? []) {
@@ -140290,7 +140486,7 @@ function computeWorkspaceStatus(workspace, options) {
140290
140486
  )) {
140291
140487
  parseErrors.push(new SchemaSourceError(message, "<project-files>", 1, 1));
140292
140488
  }
140293
- if (animationValidationInputsChanged(changes, authoredValueSeeds)) {
140489
+ if (!parseErrors.some(isBlockingSchemaSourceError) && animationValidationInputsChanged(changes, authoredValueSeeds)) {
140294
140490
  try {
140295
140491
  const animationRecords = prospectiveAnimationRecords(
140296
140492
  workspace.state.records,
@@ -148410,6 +148606,14 @@ function projectCompletions(analysis, document, position) {
148410
148606
  }))
148411
148607
  };
148412
148608
  }
148609
+ const contextualEnum = projectContextualEnumCompletions(
148610
+ analysis,
148611
+ document,
148612
+ position
148613
+ );
148614
+ if (contextualEnum) {
148615
+ return { isIncomplete: false, items: contextualEnum };
148616
+ }
148413
148617
  const constructorFields = projectConstructorArgumentCompletions(
148414
148618
  analysis,
148415
148619
  document,
@@ -148436,14 +148640,6 @@ function projectCompletions(analysis, document, position) {
148436
148640
  if (initializerMembers) {
148437
148641
  return { isIncomplete: false, items: initializerMembers };
148438
148642
  }
148439
- const contextualEnum = projectContextualEnumCompletions(
148440
- analysis,
148441
- document,
148442
- position
148443
- );
148444
- if (contextualEnum) {
148445
- return { isIncomplete: false, items: contextualEnum };
148446
- }
148447
148643
  return projectFallbackCompletions(analysis, document, position);
148448
148644
  }
148449
148645
  function projectListenerContext(analysis, document, position) {
@@ -149775,11 +149971,19 @@ function projectCallArguments(tokens, openIndex, delimiterEnds) {
149775
149971
  result.push({
149776
149972
  start: token.range.start,
149777
149973
  named: token.kind === "identifier" && tokens[index + 1]?.text === ":",
149974
+ name: token.kind === "identifier" && tokens[index + 1]?.text === ":" ? token.text : null,
149778
149975
  ...token.kind === "identifier" && (tokens[index + 1]?.text === "," || tokens[index + 1]?.text === ")") ? { identifier: token.text } : {}
149779
149976
  });
149780
149977
  atArgumentStart = false;
149781
149978
  }
149782
- if (token.text === "(" || token.text === "[" || token.text === "{") {
149979
+ if (token.text === "new" && tokens[index + 2]?.text === "<") {
149980
+ let depth = 0;
149981
+ index += 2;
149982
+ for (; index < tokens.length; index++) {
149983
+ if (tokens[index].text === "<") depth++;
149984
+ else if (tokens[index].text === ">" && --depth === 0) break;
149985
+ }
149986
+ } else if (token.text === "(" || token.text === "[" || token.text === "{") {
149783
149987
  index = delimiterEnds.get(index) ?? tokens.length;
149784
149988
  }
149785
149989
  }
@@ -150387,6 +150591,7 @@ function indexConstructionSites(analysis, document, root) {
150387
150591
  while (end < allTokens.length && positionCompare(allTokens[end].range.start, root.range.end) <= 0)
150388
150592
  end++;
150389
150593
  const tokens = allTokens.slice(start, end).filter((token) => token.kind !== "comment" && token.kind !== "eof");
150594
+ let delimiterEnds;
150390
150595
  const language = listenerSourceContext(analysis, document, root.range.start);
150391
150596
  const resolveSourceType = (type) => {
150392
150597
  if (!type) return null;
@@ -150427,15 +150632,17 @@ function indexConstructionSites(analysis, document, root) {
150427
150632
  const declaration = language.project.typeById.get(frame.typeRef.typeId);
150428
150633
  if (!declaration) return null;
150429
150634
  const constructors = declaration.declaredConstructors;
150430
- const parameters = constructors?.length === 1 ? constructors[0]?.parameters : declaration.constructorSignature?.parameters;
150431
- const parameter4 = frame.argumentName ? parameters?.find(
150432
- (candidate) => candidate.name === frame.argumentName
150433
- ) : parameters?.[frame.argumentIndex];
150434
- frame.expectedTypeRef = parameter4 ? substituteTypeParameters(
150435
- "type" in parameter4 ? parameter4.type : parameter4.valueType,
150436
- frame.typeRef,
150437
- declaration
150438
- ) : fieldType(frame.typeRef, frame.argumentName);
150635
+ const parameters = constructors?.length ? constructors[frame.constructorIndex]?.parameters : declaration.constructorSignature?.parameters;
150636
+ const parameter4 = frame.argumentName ? parameters && neoScriptParameterByName(parameters, frame.argumentName) : parameters?.[frame.argumentIndex];
150637
+ if (parameter4) {
150638
+ frame.expectedTypeRef = substituteTypeParameters(
150639
+ "type" in parameter4 ? parameter4.type : parameter4.valueType,
150640
+ frame.typeRef,
150641
+ declaration
150642
+ );
150643
+ } else if (!constructors?.length) {
150644
+ frame.expectedTypeRef = fieldType(frame.typeRef, frame.argumentName);
150645
+ }
150439
150646
  return frame.expectedTypeRef;
150440
150647
  }
150441
150648
  }
@@ -150458,14 +150665,16 @@ function indexConstructionSites(analysis, document, root) {
150458
150665
  const objects = [];
150459
150666
  const snapshot = () => {
150460
150667
  const expected = expectedType();
150668
+ const resolvedExpected = expectedTypeRef();
150669
+ const expectedTypeName = resolvedExpected?.kind === "named" ? language.project.typeById.get(resolvedExpected.typeId)?.name ?? expected?.name : expected?.name;
150461
150670
  const innermost = stack.at(-1);
150462
150671
  const directly = innermost?.kind === "object" ? innermost : null;
150463
150672
  const keys = directly?.keys ?? [];
150464
150673
  const keyCount = keys.length;
150465
150674
  return {
150466
150675
  expectedType: expected,
150467
- expectedTypeRef: expectedTypeRef(),
150468
- expectedTypeName: expected?.name ?? null,
150676
+ expectedTypeRef: resolvedExpected,
150677
+ expectedTypeName: expectedTypeName ?? null,
150469
150678
  enclosingTypeName: objects.at(-1)?.typeName ?? null,
150470
150679
  initializerTypeName: directly?.typeName ?? null,
150471
150680
  get initializerKeys() {
@@ -150581,8 +150790,20 @@ function indexConstructionSites(analysis, document, root) {
150581
150790
  }
150582
150791
  if (token.text === "(") {
150583
150792
  if (sawNew) {
150793
+ const declaration = pendingNewTypeName ? findTypeDeclaration(analysis, pendingNewTypeName) : null;
150794
+ let constructorIndex = 0;
150795
+ if (declaration?.kind === "class" && declaration.constructors.length > 1) {
150796
+ const names = projectCallArguments(
150797
+ tokens,
150798
+ index,
150799
+ delimiterEnds ??= projectDelimiterEnds(tokens)
150800
+ ).map((argument2) => argument2.name);
150801
+ const constructor2 = matchingDeclaredConstructor(declaration, names);
150802
+ constructorIndex = constructor2 ? declaration.constructors.indexOf(constructor2) : -1;
150803
+ }
150584
150804
  stack.push({
150585
150805
  kind: "call",
150806
+ constructorIndex,
150586
150807
  typeName: pendingNewTypeName,
150587
150808
  typeRef: pendingNewTypeRef,
150588
150809
  argumentIndex: 0,
@@ -150669,6 +150890,14 @@ function constructorArgumentType(analysis, frame) {
150669
150890
  if (!declaration || declaration.kind === "global" || declaration.kind === "enum") {
150670
150891
  return null;
150671
150892
  }
150893
+ if (declaration.kind === "class") {
150894
+ const parameters = declaration.headerParameters ?? declaration.constructors[frame.constructorIndex]?.parameters;
150895
+ if (parameters) {
150896
+ const parameter4 = frame.argumentName === null ? parameters[frame.argumentIndex] : neoScriptParameterByName(parameters, frame.argumentName);
150897
+ return parameter4?.type ?? null;
150898
+ }
150899
+ if (declaration.constructors.length > 0) return null;
150900
+ }
150672
150901
  const fields = declarationFields(declaration);
150673
150902
  if (frame.argumentName !== null) {
150674
150903
  return fields.assignableByName.get(frame.argumentName)?.type ?? null;
@@ -150925,6 +151154,7 @@ var init_project_source_language_features = __esm({
150925
151154
  init_project_listener_annotations();
150926
151155
  init_strict_resolver();
150927
151156
  init_type_substitution();
151157
+ init_declared_constructors();
150928
151158
  init_executable_parser();
150929
151159
  init_strict_compile_error();
150930
151160
  init_analyzer();
@@ -190289,7 +190519,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
190289
190519
  async function main() {
190290
190520
  const args = parseArgs(process.argv.slice(2));
190291
190521
  if (args.command === "--version") {
190292
- console.log("0.72.1");
190522
+ console.log("0.72.4");
190293
190523
  return;
190294
190524
  }
190295
190525
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {