@neocompose/cli 0.89.0 → 0.89.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19377,7 +19377,7 @@ var init_registry = __esm({
19377
19377
  "../packages/manifest/schema-contract/registry.mjs"() {
19378
19378
  "use strict";
19379
19379
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
19380
- cliVersion: "0.89.0",
19380
+ cliVersion: "0.89.1",
19381
19381
  projectFileUploadBatchSize: 32,
19382
19382
  documentRecords: {
19383
19383
  member: {
@@ -36679,8 +36679,12 @@ var init_function_type_inference = __esm({
36679
36679
  const value = actual.parameterTypes[index];
36680
36680
  if (value !== void 0) this.add(value, expected, "exact");
36681
36681
  });
36682
- } else if (pattern.kind === "reference" && actual.kind === "reference") {
36683
- this.add(actual.target, pattern.target, "exact");
36682
+ } else if (pattern.kind === "reference") {
36683
+ this.add(
36684
+ actual.kind === "reference" ? actual.target : actual,
36685
+ pattern.target,
36686
+ "exact"
36687
+ );
36684
36688
  }
36685
36689
  }
36686
36690
  fix(index) {
@@ -37834,6 +37838,17 @@ var init_read_class_member = __esm({
37834
37838
  });
37835
37839
 
37836
37840
  // ../packages/neoscript-language/src/declared-constructors.ts
37841
+ function neoScriptCommonParameterNames(signatures) {
37842
+ const names2 = [];
37843
+ for (const [signatureIndex, { parameters }] of signatures.entries()) {
37844
+ const length = Math.max(names2.length, parameters.length);
37845
+ for (let index = 0; index < length; index++) {
37846
+ const name = parameters[index]?.name;
37847
+ names2[index] = signatureIndex === 0 || names2[index] === name ? name ?? null : null;
37848
+ }
37849
+ }
37850
+ return names2;
37851
+ }
37837
37852
  function neoScriptArgumentNameSetKey(names2) {
37838
37853
  return [...names2].map((name) => name.toLowerCase()).sort().join(",");
37839
37854
  }
@@ -47001,11 +47016,14 @@ function resolveMemberForValueRow(row, ctx, visited) {
47001
47016
  ctx.__valueOverlay
47002
47017
  );
47003
47018
  if (parent === null) continue;
47004
- const parentMember = resolveMemberForValueRow(
47005
- parent,
47006
- ctx,
47007
- new Set(visited)
47008
- );
47019
+ let parentMember = resolveMemberForValueRow(parent, ctx, new Set(visited));
47020
+ if (parentMember?.kind === 21 /* Generic */) {
47021
+ parentMember = substituteMember(
47022
+ parentMember,
47023
+ runtimeParentGenericEnv(parent, ctx, /* @__PURE__ */ new Set()),
47024
+ ctx.vm.members
47025
+ );
47026
+ }
47009
47027
  if (parentMember !== null && isMemberTupleBase(parentMember)) {
47010
47028
  const memberId = parentMember.elementMemberIds[Number(link.key)];
47011
47029
  return memberId === void 0 ? null : evalMemberById(ctx.vm, memberId);
@@ -63402,7 +63420,9 @@ function indexCalls(tokens, pairs, lexed) {
63402
63420
  const name = tokens[index];
63403
63421
  const openIndex = callOpenParenIndex(tokens, index);
63404
63422
  const open2 = tokens[openIndex];
63405
- if (!name || name.kind !== "identifier") continue;
63423
+ if (!name) continue;
63424
+ const expression = [")", "]", "!"].includes(name.text) && openIndex === index + 1;
63425
+ if (name.kind !== "identifier" && !expression) continue;
63406
63426
  if (!open2 || open2.kind !== "punctuation" || open2.text !== "(") continue;
63407
63427
  const previous = tokens[index - 1];
63408
63428
  const targetTyped = isContextualNew(name, previous, open2);
@@ -63431,14 +63451,19 @@ function indexCalls(tokens, pairs, lexed) {
63431
63451
  segmentStart = token.end;
63432
63452
  segmentStartIndex = cursor + 1;
63433
63453
  }
63454
+ if (tokens[cursor + 1]?.text === "<") {
63455
+ const genericOpen = callOpenParenIndex(tokens, cursor);
63456
+ if (genericOpen >= 0) cursor = genericOpen - 1;
63457
+ }
63434
63458
  }
63435
63459
  if (segmentStart < (close?.start ?? lexed.end)) {
63436
63460
  ranges.push(lexed.source.range(segmentStart, close?.start ?? lexed.end));
63437
63461
  names2.push(callArgumentLabel(tokens, segmentStartIndex, limit));
63438
63462
  }
63463
+ const namedKind = contextualKeyword ? "constructor" : "function";
63439
63464
  calls.push({
63440
- kind: contextualKeyword ? "constructor" : "function",
63441
- name: name.text,
63465
+ kind: expression ? "expression" : namedKind,
63466
+ name: expression ? "delegate" : name.text,
63442
63467
  nameRange: name.range,
63443
63468
  ...contextualKeyword ? { contextualKeywordRange: contextualKeyword.range } : {},
63444
63469
  ...targetTyped ? { targetTyped: true } : {},
@@ -67495,6 +67520,7 @@ function weighedLambda(probes, expected) {
67495
67520
  if (probe === void 0 || probe.type.kind !== "delegate") return void 0;
67496
67521
  if (probe.needsReturnContext !== true && sameCompilationType(probe.type.returnType, expected.returnType))
67497
67522
  return probe;
67523
+ if (expected.returnType.kind === "reference") return void 0;
67498
67524
  return probe.retype?.(expected.returnType);
67499
67525
  }
67500
67526
  function replaceReturns(instructions, replaced) {
@@ -67616,6 +67642,9 @@ function andList(texts) {
67616
67642
  if (texts.length <= 2) return texts.join(" and ");
67617
67643
  return `${texts.slice(0, -1).join(", ")}, and ${texts[texts.length - 1]}`;
67618
67644
  }
67645
+ function isContextualReferenceExpression(expression) {
67646
+ return expression.kind === "conditional" || expression.kind === "switchExpression" || expression.kind === "coalesce" || expression.kind === "annotated";
67647
+ }
67619
67648
  function isPureArgument(expression) {
67620
67649
  switch (expression.kind) {
67621
67650
  case "litInt":
@@ -68432,6 +68461,10 @@ var init_strict_resolver = __esm({
68432
68461
  if (expected === void 0) return;
68433
68462
  this.requireAssignable(resolved.type, expected, expression.pos, "value");
68434
68463
  }
68464
+ /** Type a source expression with the same call binding rules as executable code. */
68465
+ resolveExpressionType(expression) {
68466
+ return this.resolveExpression(expression, this.initialScope()).type;
68467
+ }
68435
68468
  persistedListenerCompletions(receiver, expected) {
68436
68469
  const scope = this.initialScope();
68437
68470
  let receiverType = this.context.thisClass;
@@ -70698,8 +70731,7 @@ var init_strict_resolver = __esm({
70698
70731
  );
70699
70732
  }
70700
70733
  }
70701
- resolveMemberRowOf(place, scope) {
70702
- const optional2 = place.optional === true;
70734
+ resolveMemberRowOf(place, scope, resolved) {
70703
70735
  if ((this.context.kind === "initializer" || this.context.kind === "initializerExpression") && this.delegateCaptureContexts.length === 0 && referencePlaceRoot(place) === "this") {
70704
70736
  const text = referencePlaceText(place) ?? "this";
70705
70737
  throw new CompileError(
@@ -70707,12 +70739,12 @@ var init_strict_resolver = __esm({
70707
70739
  place.pos
70708
70740
  );
70709
70741
  }
70710
- const slot = this.resolveMemberNatural(
70742
+ const slot = resolved ?? this.resolveMemberNatural(
70711
70743
  place.receiver,
70712
70744
  place.name,
70713
70745
  scope,
70714
70746
  place.pos,
70715
- optional2
70747
+ place.optional === true
70716
70748
  );
70717
70749
  const member = slot.symbol;
70718
70750
  if (member === void 0) {
@@ -70730,19 +70762,55 @@ var init_strict_resolver = __esm({
70730
70762
  place.pos
70731
70763
  );
70732
70764
  }
70733
- const read = slot.optionalChainType ?? slot.type;
70734
- const stored = member.lookup !== void 0 && member.lookup.multiselect !== true && read.kind !== "reference" ? {
70735
- kind: "reference",
70736
- target: { ...read, nullable: false },
70737
- ...isNullable(read) ? { nullable: true } : {}
70738
- } : read;
70739
- const type2 = this.referenceType(stored, optional2);
70765
+ const type2 = this.memberReferenceType(slot, place.optional === true);
70740
70766
  if (type2.kind !== "reference") return slot;
70741
70767
  return {
70742
70768
  pointer: { type: "rowOf" /* RowOf */, place: slot.pointer },
70743
70769
  type: type2
70744
70770
  };
70745
70771
  }
70772
+ memberReferenceType(slot, optional2) {
70773
+ const read = slot.storedType ?? slot.optionalChainType ?? slot.type;
70774
+ const stored = slot.symbol?.lookup !== void 0 && slot.symbol.lookup.multiselect !== true && read.kind !== "reference" ? {
70775
+ kind: "reference",
70776
+ target: { ...read, nullable: false },
70777
+ ...isNullable(read) ? { nullable: true } : {}
70778
+ } : read;
70779
+ return this.referenceType(
70780
+ stored,
70781
+ optional2 || slot.optionalChainType !== void 0
70782
+ );
70783
+ }
70784
+ /** Only stored member slots can acquire a reference from an expected type. */
70785
+ implicitReferenceType(expression, value) {
70786
+ if (expression.kind !== "member") return void 0;
70787
+ if (value.symbol === void 0 || value.symbol.computed === true)
70788
+ return void 0;
70789
+ return this.memberReferenceType(value, expression.optional === true);
70790
+ }
70791
+ referenceInferenceType(expression, value, pattern) {
70792
+ const read = this.readReferences(value, pattern).type;
70793
+ if (pattern.kind !== "reference" || read.kind === "reference") return read;
70794
+ return this.implicitReferenceType(expression, value) ?? read;
70795
+ }
70796
+ contextualReferenceType(expression, value, expected) {
70797
+ const read = this.readReferences(value, expected).type;
70798
+ if (expected.kind !== "reference" || isNeoScriptTypeAssignable(read, expected, this.project))
70799
+ return read;
70800
+ const reference2 = this.implicitReferenceType(expression, value);
70801
+ return reference2 !== void 0 && isNeoScriptTypeAssignable(reference2, expected, this.project) ? reference2 : read;
70802
+ }
70803
+ /** Use the same slot identity for explicit and expected-type references. */
70804
+ contextualReference(expression, value, scope, expected) {
70805
+ const read = this.readReferences(value, expected);
70806
+ if (expected?.kind !== "reference" || isNeoScriptTypeAssignable(read.type, expected, this.project))
70807
+ return read;
70808
+ const reference2 = this.implicitReferenceType(expression, value);
70809
+ if (expression.kind === "member" && reference2 !== void 0 && isNeoScriptTypeAssignable(reference2, expected, this.project)) {
70810
+ return this.resolveMemberRowOf(expression, scope, value);
70811
+ }
70812
+ return read;
70813
+ }
70746
70814
  /** Whether assigning `target` rebinds a reference to a handle. */
70747
70815
  holdsHandleReference(target) {
70748
70816
  if (target.type.kind === "reference") {
@@ -71351,13 +71419,15 @@ var init_strict_resolver = __esm({
71351
71419
  });
71352
71420
  }
71353
71421
  resolveExpression(expression, scope, expected, convertSequence = true) {
71354
- const value = this.readReferences(
71422
+ const value = this.contextualReference(
71423
+ expression,
71355
71424
  this.resolveReferenceExpression(
71356
71425
  expression,
71357
71426
  scope,
71358
71427
  expected,
71359
71428
  convertSequence
71360
71429
  ),
71430
+ scope,
71361
71431
  expected
71362
71432
  );
71363
71433
  return convertSequence ? this.convertSequence(value, expected) : value;
@@ -72879,7 +72949,8 @@ var init_strict_resolver = __esm({
72879
72949
  }
72880
72950
  entryType = common;
72881
72951
  }
72882
- if (expected?.kind === "set" && this.context.kind === "initializer") {
72952
+ const referenceSelection = expected?.kind === "set" && this.context.kind === "initializer" && (expected.elementType.kind === "reference" || hasReferenceEquality(expected.elementType, this.project));
72953
+ if (expected?.kind === "set" && this.context.kind === "initializer" && !referenceSelection) {
72883
72954
  const element = expected.elementType;
72884
72955
  const spelling = element.kind === "named" && this.project.typeById.get(element.typeId)?.kind === "enum" ? `.Option or ${this.describe({ ...element, nullable: false })}.Option values` : "literal values";
72885
72956
  throw new CompileError(
@@ -72897,7 +72968,7 @@ var init_strict_resolver = __esm({
72897
72968
  "NeoScript strict compiler produced a non-list wire type for a list literal."
72898
72969
  );
72899
72970
  }
72900
- return {
72971
+ const list = {
72901
72972
  pointer: {
72902
72973
  type: "listLiteral" /* ListLiteral */,
72903
72974
  typeInfo: wire,
@@ -72906,6 +72977,18 @@ var init_strict_resolver = __esm({
72906
72977
  type: type2,
72907
72978
  entries: resolved
72908
72979
  };
72980
+ return referenceSelection ? this.resolveCollectionQuery(
72981
+ list,
72982
+ {
72983
+ kind: "list",
72984
+ keyType: { kind: "primitive", name: "int" },
72985
+ valueType: entryType
72986
+ },
72987
+ "ToSet",
72988
+ [],
72989
+ scope,
72990
+ pos
72991
+ ) : list;
72909
72992
  }
72910
72993
  resolveDictionaryLiteral(entries, scope, expected, pos) {
72911
72994
  const expectedDictionary = expected?.kind === "dictionary" ? expected : void 0;
@@ -73616,7 +73699,12 @@ var init_strict_resolver = __esm({
73616
73699
  const rootEntry = scope.lookupFlowRoot(pathRoot(path));
73617
73700
  if (rootEntry) {
73618
73701
  const narrowed = scope.lookupNarrowedType(path, rootEntry);
73619
- if (narrowed) resolved = { ...resolved, type: narrowed };
73702
+ if (narrowed)
73703
+ resolved = {
73704
+ ...resolved,
73705
+ storedType: resolved.type,
73706
+ type: narrowed
73707
+ };
73620
73708
  }
73621
73709
  }
73622
73710
  }
@@ -76335,17 +76423,28 @@ var init_strict_resolver = __esm({
76335
76423
  args,
76336
76424
  scope
76337
76425
  );
76338
- return resolveNeoScriptDeclaredConstructorOverload(
76426
+ const resolve8 = (implicit) => resolveNeoScriptDeclaredConstructorOverload(
76339
76427
  declared,
76340
76428
  named.map((name, index) => {
76341
76429
  const inferred = inferredTypes?.[index];
76342
- if (!inferred) return { name };
76430
+ const argument2 = args[index];
76431
+ if (!inferred || !argument2) return { name };
76343
76432
  return {
76344
76433
  name,
76345
- matchesParameter: (parameter4) => isNeoScriptTypeAssignable(inferred, parameter4.type, this.project)
76434
+ matchesParameter: (parameter4) => implicit && parameter4.type.kind === "reference" && isContextualReferenceExpression(argument2) ? this.targetTypedArgumentFits(argument2, parameter4.type, scope) : isNeoScriptTypeAssignable(
76435
+ implicit ? this.contextualReferenceType(
76436
+ argument2,
76437
+ inferred,
76438
+ parameter4.type
76439
+ ) : inferred.type,
76440
+ parameter4.type,
76441
+ this.project
76442
+ )
76346
76443
  };
76347
76444
  })
76348
76445
  );
76446
+ const direct = resolve8(false);
76447
+ return direct.kind === "ambiguous" ? resolve8(true) : direct;
76349
76448
  }
76350
76449
  /**
76351
76450
  * Types for the §6.1.1 step-2 tie-break, computed only when several
@@ -76366,7 +76465,9 @@ var init_strict_resolver = __esm({
76366
76465
  const argument2 = args[index];
76367
76466
  if (!argument2) return null;
76368
76467
  try {
76369
- return this.resolveExpression(argument2, scope).type;
76468
+ if (isContextualReferenceExpression(argument2))
76469
+ this.typeOverloadEntries(argument2, scope);
76470
+ return this.resolveReferenceExpression(argument2, scope);
76370
76471
  } catch (error) {
76371
76472
  if (error instanceof CompileError) return null;
76372
76473
  throw error;
@@ -76736,7 +76837,8 @@ var init_strict_resolver = __esm({
76736
76837
  (argument2) => this.overloadArgumentKind(argument2, scope)
76737
76838
  );
76738
76839
  argumentsList2.forEach((argument2, index) => {
76739
- if (kinds[index] !== "typed") this.typeOverloadEntries(argument2, scope);
76840
+ if (kinds[index] !== "typed" || isContextualReferenceExpression(argument2))
76841
+ this.typeOverloadEntries(argument2, scope);
76740
76842
  });
76741
76843
  const typed = argumentsList2.map(
76742
76844
  (argument2, index) => kinds[index] === "targetTyped" ? void 0 : this.resolveReferenceExpression(argument2, scope)
@@ -76784,11 +76886,11 @@ var init_strict_resolver = __esm({
76784
76886
  const fits = argumentsList2.every((argument2, index) => {
76785
76887
  const parameter4 = requiredAt(parameters, index).type;
76786
76888
  const resolved = typed[index];
76787
- if (resolved === void 0 || argument2.kind === "tuple" || kinds[index] === "numeric" && parameter4.kind === "tuple") {
76889
+ if (resolved === void 0 || parameter4.kind === "reference" && isContextualReferenceExpression(argument2) || argument2.kind === "tuple" || kinds[index] === "numeric" && parameter4.kind === "tuple") {
76788
76890
  return this.targetTypedArgumentFits(argument2, parameter4, scope);
76789
76891
  }
76790
76892
  return this.typedArgumentFits(
76791
- this.readReferences(resolved, parameter4).type,
76893
+ this.contextualReferenceType(argument2, resolved, parameter4),
76792
76894
  requiredAt(kinds, index),
76793
76895
  parameter4
76794
76896
  );
@@ -76960,6 +77062,12 @@ var init_strict_resolver = __esm({
76960
77062
  }
76961
77063
  case "annotated":
76962
77064
  return this.entryFits(argument2.expression, parameter4, scope);
77065
+ case "coalesce":
77066
+ return this.entryFits(
77067
+ argument2.left,
77068
+ { ...parameter4, nullable: true },
77069
+ scope
77070
+ ) && this.entryFits(argument2.right, parameter4, scope);
76963
77071
  case "conditional": {
76964
77072
  const { trueScope, falseScope } = this.conditionalBranchScopes(
76965
77073
  argument2,
@@ -77039,12 +77147,12 @@ var init_strict_resolver = __esm({
77039
77147
  */
77040
77148
  entryFits(argument2, parameter4, scope) {
77041
77149
  const kind = this.overloadArgumentKind(argument2, scope);
77042
- if (kind === "targetTyped" || argument2.kind === "tuple" || kind === "numeric" && parameter4.kind === "tuple") {
77150
+ if (kind === "targetTyped" || parameter4.kind === "reference" && isContextualReferenceExpression(argument2) || argument2.kind === "tuple" || kind === "numeric" && parameter4.kind === "tuple") {
77043
77151
  return this.targetTypedArgumentFits(argument2, parameter4, scope);
77044
77152
  }
77045
- const resolved = isPureArgument(argument2) ? this.resolveExpression(argument2, scope) : this.overloadEntries.get(argument2) ?? this.resolveReferenceExpression(argument2, scope);
77153
+ const resolved = isPureArgument(argument2) ? this.resolveReferenceExpression(argument2, scope) : this.overloadEntries.get(argument2) ?? this.resolveReferenceExpression(argument2, scope);
77046
77154
  return this.typedArgumentFits(
77047
- this.readReferences(resolved, parameter4).type,
77155
+ this.contextualReferenceType(argument2, resolved, parameter4),
77048
77156
  kind,
77049
77157
  parameter4
77050
77158
  );
@@ -77087,6 +77195,10 @@ var init_strict_resolver = __esm({
77087
77195
  case "annotated":
77088
77196
  visit(argument2.expression, scope);
77089
77197
  return;
77198
+ case "coalesce":
77199
+ visit(argument2.left, scope);
77200
+ visit(argument2.right, scope);
77201
+ return;
77090
77202
  case "conditional": {
77091
77203
  visit(argument2.condition, scope);
77092
77204
  const { trueScope, falseScope } = this.conditionalBranchScopes(
@@ -77271,19 +77383,16 @@ var init_strict_resolver = __esm({
77271
77383
  pos,
77272
77384
  inferred?.typeArguments
77273
77385
  );
77274
- if (signature2.typeArguments.length > 0)
77275
- this.options.onCallResolved?.(pos, {
77276
- ...symbol,
77277
- type: signature2.returnType,
77278
- returnType: signature2.returnType,
77279
- parameters: signature2.parameters,
77280
- typeParameters: (symbol.typeParameters ?? []).map(
77281
- (parameter4, index) => ({
77282
- ...parameter4,
77283
- type: requiredAt(signature2.typeArguments, index)
77284
- })
77285
- )
77286
- });
77386
+ this.options.onCallResolved?.(pos, {
77387
+ ...symbol,
77388
+ type: signature2.returnType,
77389
+ returnType: signature2.returnType,
77390
+ parameters: signature2.parameters,
77391
+ typeParameters: (symbol.typeParameters ?? []).map((parameter4, index) => ({
77392
+ ...parameter4,
77393
+ type: requiredAt(signature2.typeArguments, index)
77394
+ }))
77395
+ });
77287
77396
  const wireTypeArguments = signature2.typeArguments.length ? {
77288
77397
  typeArguments: signature2.typeArguments.map(
77289
77398
  (argument2) => toWireType(argument2, this.project)
@@ -77458,7 +77567,12 @@ var init_strict_resolver = __esm({
77458
77567
  const prior = choice?.preResolved[index];
77459
77568
  const cached = inferred?.resolved.get(argument2);
77460
77569
  let resolved;
77461
- if (prior !== void 0) resolved = this.readReferences(prior, target);
77570
+ if (prior !== void 0 && !(target?.kind === "reference" && isContextualReferenceExpression(argument2) && !isNeoScriptTypeAssignable(
77571
+ this.readReferences(prior, target).type,
77572
+ target,
77573
+ this.project
77574
+ )))
77575
+ resolved = this.readReferences(prior, target);
77462
77576
  else if (cached && (sameCompilationType(cached.type, expected) || cached.pointer.type === "callFunction" /* CallFunction */)) {
77463
77577
  resolved = cached;
77464
77578
  } else {
@@ -77467,6 +77581,7 @@ var init_strict_resolver = __esm({
77467
77581
  const compile = () => this.resolveExpression(argument2, scope, target);
77468
77582
  resolved = weighed ?? (argument2.kind === "lambda" && lambdas ? this.inLambdaFrame(lambdas, argument2, compile) : compile());
77469
77583
  }
77584
+ resolved = this.contextualReference(argument2, resolved, scope, target);
77470
77585
  resolved = this.convertSequence(resolved, target);
77471
77586
  if (!isUnknown(expected)) {
77472
77587
  this.requireReferenceArgument(
@@ -77541,7 +77656,10 @@ var init_strict_resolver = __esm({
77541
77656
  if (!hasIndependentTypeEvidence(argument2)) return;
77542
77657
  const prior = weighed?.typed[index];
77543
77658
  if (prior !== void 0) {
77544
- inference.add(this.readReferences(prior, void 0).type, pattern);
77659
+ inference.add(
77660
+ this.referenceInferenceType(argument2, prior, pattern),
77661
+ pattern
77662
+ );
77545
77663
  return;
77546
77664
  }
77547
77665
  const group = pattern.kind === "delegate" ? this.inferredMethodGroupTarget(argument2, probe) : null;
@@ -77552,10 +77670,13 @@ var init_strict_resolver = __esm({
77552
77670
  pattern
77553
77671
  );
77554
77672
  } else {
77555
- const resolved = weighed?.contextless.get(argument2) ?? this.resolveExpression(argument2, probe);
77673
+ const resolved = weighed?.contextless.get(argument2) ?? this.resolveReferenceExpression(argument2, probe);
77556
77674
  weighed?.contextless.set(argument2, resolved);
77557
77675
  resolvedArguments.set(argument2, resolved);
77558
- inference.add(resolved.type, pattern);
77676
+ inference.add(
77677
+ this.referenceInferenceType(argument2, resolved, pattern),
77678
+ pattern
77679
+ );
77559
77680
  }
77560
77681
  });
77561
77682
  const error = inference.solve(callbacks, (callback, inputs) => {
@@ -80625,7 +80746,7 @@ var init_strict_resolver = __esm({
80625
80746
  }
80626
80747
  return canonicalPath(target) ?? "the slot";
80627
80748
  }
80628
- /** P112 §3.1. A value never converts to a reference, since it has no row. */
80749
+ /** A transient value has no stored slot to pass by reference. */
80629
80750
  requireReferenceArgument(source, target, parameter4, pos) {
80630
80751
  if (target.kind !== "reference") return;
80631
80752
  if (source.kind === "reference") return;
@@ -80634,7 +80755,7 @@ var init_strict_resolver = __esm({
80634
80755
  const value = this.describe(source);
80635
80756
  const article = /^[aeiou]/i.test(value) ? "an" : "a";
80636
80757
  throw new CompileError(
80637
- `Argument \`${parameter4}\` needs a ${this.describe(target)}, not ${article} ${value}. Wrap a member path in Reference() to pass a stored ${this.describe(read)}.`,
80758
+ `Argument \`${parameter4}\` needs a ${this.describe(target)}, not ${article} ${value}. Pass a stored ${this.describe(read)} member instead.`,
80638
80759
  pos
80639
80760
  );
80640
80761
  }
@@ -81988,7 +82109,8 @@ function neoSourceTypeText(type2) {
81988
82109
  }
81989
82110
  function referenceReadType(type2) {
81990
82111
  const target = type2.name === "Reference" ? type2.typeArguments[0] : void 0;
81991
- if (target !== void 0) return { ...target, nullable: type2.nullable };
82112
+ if (target !== void 0)
82113
+ return { ...target, nullable: type2.nullable || target.nullable };
81992
82114
  const element = type2.name === "Set" ? type2.typeArguments[0] : void 0;
81993
82115
  if (element?.name !== "Reference" || element.typeArguments.length === 0) {
81994
82116
  return type2;
@@ -83130,7 +83252,7 @@ var init_project_source_parser = __esm({
83130
83252
  ...value ? { value } : {},
83131
83253
  range: rangeFrom(optionStart, end)
83132
83254
  });
83133
- if (!this.eat(",") && !this.at("}")) {
83255
+ if (!this.eat(",") && !this.at("}") && !this.done()) {
83134
83256
  throw this.failure(
83135
83257
  "enum-option-separator",
83136
83258
  "Enum options must be separated by a comma.",
@@ -83138,7 +83260,7 @@ var init_project_source_parser = __esm({
83138
83260
  );
83139
83261
  }
83140
83262
  }
83141
- const close = this.expect("}");
83263
+ const close = this.expectClosingBrace();
83142
83264
  return {
83143
83265
  kind: "enum",
83144
83266
  annotations,
@@ -83344,7 +83466,12 @@ var init_project_source_parser = __esm({
83344
83466
  }
83345
83467
  if (this.cursor === start) this.cursor++;
83346
83468
  }
83347
- return { members: members2, constructors, initBlocks, close: this.expect("}") };
83469
+ return {
83470
+ members: members2,
83471
+ constructors,
83472
+ initBlocks,
83473
+ close: this.expectClosingBrace()
83474
+ };
83348
83475
  }
83349
83476
  parseMember(ownerName, ownerKind) {
83350
83477
  const start = this.peek();
@@ -83817,16 +83944,19 @@ var init_project_source_parser = __esm({
83817
83944
  if (token.text === "}") depth--;
83818
83945
  }
83819
83946
  if (depth !== 0) {
83820
- throw this.failure(
83821
- "unclosed-source-body",
83822
- "Unclosed source body; add `}`.",
83823
- open2
83947
+ this.report(
83948
+ this.failure(
83949
+ "unclosed-source-body",
83950
+ "Unclosed source body; add `}`.",
83951
+ open2
83952
+ )
83824
83953
  );
83825
83954
  }
83826
- const close = this.previous();
83955
+ const close = depth === 0 ? this.previous() : this.peek();
83827
83956
  return {
83828
83957
  text: this.source.text.slice(open2.start, close.end),
83829
- range: rangeFrom(open2, close)
83958
+ range: rangeFrom(open2, close),
83959
+ ...depth === 0 ? {} : { unclosed: true }
83830
83960
  };
83831
83961
  }
83832
83962
  /**
@@ -83838,21 +83968,24 @@ var init_project_source_parser = __esm({
83838
83968
  const arrow = this.expect("=>");
83839
83969
  const expression = this.captureUntilTopLevel(/* @__PURE__ */ new Set([";"]), true);
83840
83970
  if (expression.text.trim().length === 0) {
83841
- throw this.failure(
83971
+ const error = this.failure(
83842
83972
  "empty-expression-body",
83843
83973
  `An expression-bodied ${label} needs an expression after \`=>\`.`,
83844
83974
  this.peek()
83845
83975
  );
83976
+ if (!this.done()) throw error;
83977
+ this.report(error);
83846
83978
  }
83847
- const close = this.previous();
83979
+ const close = this.done() ? this.peek() : this.previous();
83848
83980
  if (!this.at(";")) {
83849
- throw this.failure(
83981
+ const error = this.failure(
83850
83982
  "unterminated-expression-body",
83851
83983
  `An expression-bodied ${label} must end with \`;\`.`,
83852
83984
  this.peek()
83853
83985
  );
83854
- }
83855
- this.next();
83986
+ if (!this.done()) throw error;
83987
+ this.report(error);
83988
+ } else this.next();
83856
83989
  return {
83857
83990
  text: this.source.text.slice(arrow.start, close.end),
83858
83991
  range: rangeFrom(arrow, close),
@@ -83888,7 +84021,7 @@ var init_project_source_parser = __esm({
83888
84021
  if (this.cursor === startCursor) {
83889
84022
  return { text: "", range: start.range };
83890
84023
  }
83891
- const end = this.previous();
84024
+ const end = this.done() ? this.peek() : this.previous();
83892
84025
  return {
83893
84026
  text: this.source.text.slice(start.start, end.end),
83894
84027
  range: rangeFrom(start, end)
@@ -83959,6 +84092,19 @@ var init_project_source_parser = __esm({
83959
84092
  message
83960
84093
  });
83961
84094
  }
84095
+ /** Keep declarations and their editor scope when only the closing brace is missing. */
84096
+ expectClosingBrace() {
84097
+ if (!this.done()) return this.expect("}");
84098
+ const end = this.peek();
84099
+ this.report(
84100
+ this.failure(
84101
+ "unexpected-source-token",
84102
+ `Expected \`}\`, but found ${describe2(end)}.`,
84103
+ end
84104
+ )
84105
+ );
84106
+ return end;
84107
+ }
83962
84108
  expect(text) {
83963
84109
  if (!this.at(text)) {
83964
84110
  throw this.failure(
@@ -95467,49 +95613,65 @@ function annotationContextForDeclaration(declaration) {
95467
95613
  return { kind: "schema" };
95468
95614
  }
95469
95615
  function contextualAnnotationFields(document, position) {
95470
- for (const declaration of document.declarations) {
95471
- const declarationAnnotation = declaration.annotations.find(
95472
- (annotation2) => inAnnotationArguments(annotation2, position)
95473
- );
95474
- if (declarationAnnotation) {
95475
- return fieldsForAnnotation(
95476
- declarationAnnotation.name,
95477
- annotationContextForDeclaration(declaration)
95478
- );
95616
+ return contextualAnnotationSite(document, position)?.fields ?? null;
95617
+ }
95618
+ function contextualAnnotationSite(document, position) {
95619
+ let sites = ANNOTATION_SITES.get(document);
95620
+ if (!sites) {
95621
+ sites = collectAnnotationSites(document);
95622
+ ANNOTATION_SITES.set(document, sites);
95623
+ }
95624
+ let low = 0;
95625
+ let high = sites.length;
95626
+ while (low < high) {
95627
+ const middle = low + high >>> 1;
95628
+ if (compare(sites[middle].annotation.range.end, position) < 0)
95629
+ low = middle + 1;
95630
+ else high = middle;
95631
+ }
95632
+ const site = sites[low];
95633
+ return site && inAnnotationArguments(site.annotation, position) ? site : null;
95634
+ }
95635
+ function collectAnnotationSites(document) {
95636
+ const sites = [];
95637
+ const add = (annotations, context, type2) => {
95638
+ for (const annotation2 of annotations) {
95639
+ const fields = fieldsForAnnotation(annotation2.name, context);
95640
+ if (fields) sites.push({ annotation: annotation2, fields, ...type2 ? { type: type2 } : {} });
95479
95641
  }
95642
+ };
95643
+ const addType = (type2) => {
95644
+ if (type2.annotations.length > 0)
95645
+ add(type2.annotations, { kind: "type", type: semanticType(type2) }, type2);
95646
+ for (const argument2 of type2.typeArguments) addType(argument2);
95647
+ };
95648
+ for (const declaration of document.declarations) {
95649
+ add(declaration.annotations, annotationContextForDeclaration(declaration));
95480
95650
  if (declaration.kind === "global") continue;
95481
95651
  if (declaration.kind === "enum") {
95482
- for (const option of declaration.options) {
95483
- const annotation2 = option.annotations.find(
95484
- (candidate) => inAnnotationArguments(candidate, position)
95485
- );
95486
- if (annotation2)
95487
- return fieldsForAnnotation(annotation2.name, { kind: "schema" });
95488
- }
95652
+ for (const option of declaration.options)
95653
+ add(option.annotations, { kind: "schema" });
95489
95654
  continue;
95490
95655
  }
95491
95656
  for (const member of declaration.members) {
95492
- const annotation2 = member.annotations.find(
95493
- (candidate) => inAnnotationArguments(candidate, position)
95494
- );
95495
- if (annotation2) {
95496
- return fieldsForAnnotation(annotation2.name, {
95497
- kind: "member",
95498
- ownerName: declaration.name,
95499
- type: semanticType(member.type),
95500
- memberKind: member.kind
95501
- });
95502
- }
95503
- const typeAnnotation = findTypeAnnotation(member.type, position);
95504
- if (typeAnnotation) {
95505
- return fieldsForAnnotation(typeAnnotation.annotation.name, {
95506
- kind: "type",
95507
- type: semanticType(typeAnnotation.type)
95508
- });
95509
- }
95657
+ if (member.annotations.length > 0)
95658
+ add(
95659
+ member.annotations,
95660
+ {
95661
+ kind: "member",
95662
+ ownerName: declaration.name,
95663
+ type: semanticType(member.type),
95664
+ memberKind: member.kind,
95665
+ reference: member.type.name === "Reference"
95666
+ },
95667
+ member.type
95668
+ );
95669
+ addType(member.type);
95510
95670
  }
95511
95671
  }
95512
- return null;
95672
+ return sites.sort(
95673
+ (left, right) => compare(left.annotation.range.start, right.annotation.range.start)
95674
+ );
95513
95675
  }
95514
95676
  function generatedContractEnumCases(type2) {
95515
95677
  const element = /^(?:IReadOnly)?List<(.+)>$/.exec(type2)?.[1];
@@ -95525,7 +95687,6 @@ function createEnvironment(documents, project) {
95525
95687
  const enums = /* @__PURE__ */ new Map();
95526
95688
  const types = /* @__PURE__ */ new Map();
95527
95689
  const globals = /* @__PURE__ */ new Map();
95528
- const mutableFunctions = /* @__PURE__ */ new Map();
95529
95690
  const referenceTargets = /* @__PURE__ */ new Map();
95530
95691
  for (const [name, options] of Object.entries(
95531
95692
  NEO_PROJECT_SOURCE_RECORD_CONTRACT.enums
@@ -95570,17 +95731,6 @@ function createEnvironment(documents, project) {
95570
95731
  }
95571
95732
  }
95572
95733
  }
95573
- for (const member of declaration.members) {
95574
- if (member.kind !== "function") continue;
95575
- const signatures = mutableFunctions.get(member.name) ?? [];
95576
- signatures.push({
95577
- parameters: member.parameters.map(
95578
- (parameter4) => semanticType(parameter4.type)
95579
- ),
95580
- returnType: semanticType(member.type)
95581
- });
95582
- mutableFunctions.set(member.name, signatures);
95583
- }
95584
95734
  }
95585
95735
  }
95586
95736
  return {
@@ -95593,7 +95743,8 @@ function createEnvironment(documents, project) {
95593
95743
  enums,
95594
95744
  types,
95595
95745
  globals,
95596
- functions: mutableFunctions,
95746
+ callBindings: /* @__PURE__ */ new WeakMap(),
95747
+ callScopes: /* @__PURE__ */ new WeakMap(),
95597
95748
  referenceTargets,
95598
95749
  variantScopes: buildNeoVariantScopeIndex(documents),
95599
95750
  construction: buildNeoConstructionIndex(documents)
@@ -96004,6 +96155,7 @@ function validateFlowContent(uri, content, parentScope, environment, diagnostics
96004
96155
  for (const binding of content.bindings) {
96005
96156
  const type2 = parseTypeText(binding.typeText);
96006
96157
  scope.set(binding.name, type2);
96158
+ environment.callScopes.delete(scope);
96007
96159
  validateAnnotations(
96008
96160
  uri,
96009
96161
  binding.annotations,
@@ -96758,7 +96910,10 @@ function validateStatements(statements, returnType, scope, environment, uri, ran
96758
96910
  diagnostics
96759
96911
  );
96760
96912
  const inferred = declared ?? inferExpressionType(statement.init, scope, environment);
96761
- if (inferred) scope.set(statement.name, inferred);
96913
+ if (inferred) {
96914
+ scope.set(statement.name, inferred);
96915
+ environment.callScopes.delete(scope);
96916
+ }
96762
96917
  } else if (statement.kind === "assign") {
96763
96918
  const target = inferExpressionType(statement.target, scope, environment);
96764
96919
  if (statement.value)
@@ -97541,7 +97696,18 @@ function validateExpression(expression, expected, scope, environment, uri, range
97541
97696
  );
97542
97697
  return;
97543
97698
  }
97544
- const parameters = callParameters(expression.callee, scope, environment);
97699
+ const binding = sourceCallBinding(expression, scope, environment);
97700
+ if (binding?.error?.message.replace(/^\d+:\d+: /, "").startsWith("No overload of ")) {
97701
+ pushDiagnostic(
97702
+ diagnostics,
97703
+ uri,
97704
+ anchor ? anchorSpan(anchor, binding.error, 1) : range2,
97705
+ "invalid-function-call",
97706
+ binding.error.message.replace(/^\d+:\d+: /, "")
97707
+ );
97708
+ return;
97709
+ }
97710
+ const parameters = callParameters(expression, scope, environment);
97545
97711
  expression.args.forEach((argument2, index) => {
97546
97712
  const name = expression.argumentNames?.[index];
97547
97713
  const parameter4 = name === void 0 || name === null ? parameters?.[index] : parameters?.find((candidate) => candidate.name === name);
@@ -98000,6 +98166,16 @@ function semanticAst(type2, pos) {
98000
98166
  return { ...common, kind: "primitive", name: type2.name };
98001
98167
  }
98002
98168
  const args = type2.arguments ?? [];
98169
+ if (type2.name === "")
98170
+ return {
98171
+ ...common,
98172
+ kind: "tuple",
98173
+ elements: args.map((argument2, index) => ({
98174
+ pos,
98175
+ type: semanticAst(argument2, pos),
98176
+ ...type2.tupleNames?.[index] ? { name: type2.tupleNames[index] } : {}
98177
+ }))
98178
+ };
98003
98179
  if ((type2.name === "List" || type2.name === "Set") && args[0]) {
98004
98180
  return {
98005
98181
  ...common,
@@ -98385,34 +98561,192 @@ function inferExpressionType(expression, scope, environment) {
98385
98561
  const argument2 = expression.args[0];
98386
98562
  return argument2 === void 0 ? void 0 : inferExpressionType(argument2, scope, environment);
98387
98563
  }
98388
- return environment.functions.get(expression.callee.name)?.[0]?.returnType;
98564
+ }
98565
+ if (expression.kind === "call") {
98566
+ const binding = sourceCallBinding(expression, scope, environment);
98567
+ if (binding?.returnType) return binding.returnType;
98568
+ const member = sourceCallMember(expression.callee, scope, environment);
98569
+ if (member?.member.kind === "function") {
98570
+ const bindings = new Map(member.bindings);
98571
+ for (const [
98572
+ index,
98573
+ parameter4
98574
+ ] of member.member.genericParameters.entries()) {
98575
+ const argument2 = expression.typeArguments?.[index];
98576
+ if (!argument2) return void 0;
98577
+ bindings.set(parameter4.name, semanticAstType(argument2));
98578
+ }
98579
+ return substituteSemanticType(semanticType(member.member.type), bindings);
98580
+ }
98581
+ if (member === null) return void 0;
98582
+ const callee = inferExpressionType(expression.callee, scope, environment);
98583
+ return callee?.name === "NeoDelegate" ? callee.arguments?.[0] : void 0;
98389
98584
  }
98390
98585
  return void 0;
98391
98586
  }
98392
- function callParameters(callee, scope, environment) {
98393
- if (callee.kind === "ident") {
98394
- return environment.functions.get(callee.name)?.[0]?.parameters.map((type2) => ({ name: null, type: type2 }));
98587
+ function sourceCallBinding(expression, scope, environment) {
98588
+ const cached = environment.callBindings.get(expression);
98589
+ if (cached?.scope === scope) return cached.binding;
98590
+ let entry = environment.callScopes.get(scope);
98591
+ if (!entry) {
98592
+ const owner = environment.types.get(scope.get("this")?.name ?? "");
98593
+ const { context } = initializerResolver(
98594
+ environment,
98595
+ owner?.name ?? "",
98596
+ false
98597
+ );
98598
+ const names2 = new Set(scope.keys());
98599
+ names2.delete("this");
98600
+ names2.delete("root");
98601
+ for (const member of owner?.members ?? []) {
98602
+ if (member.kind === "function") names2.delete(member.name);
98603
+ }
98604
+ entry = { context, names: names2, types: /* @__PURE__ */ new Map() };
98605
+ environment.callScopes.set(scope, entry);
98395
98606
  }
98396
- if (callee.kind !== "member") return void 0;
98397
- const receiverType = inferExpressionType(callee.receiver, scope, environment);
98398
- const staticDeclaration = receiverType === void 0 && callee.receiver.kind === "ident" ? environment.types.get(callee.receiver.name) : void 0;
98399
- let owner = staticDeclaration ?? (receiverType && environment.types.get(receiverType.name));
98607
+ const parameters = [];
98608
+ const seen = /* @__PURE__ */ new Set();
98609
+ for (const { name } of collectIdentifierReads(expression, entry.names)) {
98610
+ if (seen.has(name)) continue;
98611
+ seen.add(name);
98612
+ if (!entry.types.has(name))
98613
+ entry.types.set(
98614
+ name,
98615
+ semanticTypeRef(scope.get(name), scope, environment)
98616
+ );
98617
+ const type2 = entry.types.get(name);
98618
+ if (type2) parameters.push({ name, type: type2 });
98619
+ }
98620
+ let symbol;
98621
+ const resolver = new StrictNeoScriptResolver(
98622
+ { ...entry.context, kind: "function", parameters },
98623
+ environment.projectIndex,
98624
+ void 0,
98625
+ {
98626
+ onCallResolved(pos, resolved) {
98627
+ if (pos === expression.pos) symbol = resolved;
98628
+ }
98629
+ }
98630
+ );
98631
+ let binding;
98632
+ try {
98633
+ const type2 = resolver.resolveExpressionType(expression);
98634
+ binding = {
98635
+ returnType: semanticResolvedType(type2, environment.projectIndex),
98636
+ ...symbol?.parameters ? {
98637
+ parameters: symbol.parameters.map((parameter4) => ({
98638
+ name: parameter4.name,
98639
+ type: semanticResolvedType(
98640
+ parameter4.type,
98641
+ environment.projectIndex
98642
+ )
98643
+ }))
98644
+ } : {}
98645
+ };
98646
+ } catch (error) {
98647
+ if (!(error instanceof CompileError)) throw error;
98648
+ binding = { error };
98649
+ }
98650
+ environment.callBindings.set(expression, { scope, binding });
98651
+ return binding;
98652
+ }
98653
+ function semanticResolvedType(type2, project, read = true) {
98654
+ const child2 = (type3) => semanticResolvedType(type3, project, false);
98655
+ if (read && type2.kind === "reference")
98656
+ return semanticResolvedType(
98657
+ {
98658
+ ...type2.target,
98659
+ nullable: type2.nullable === true || type2.target.nullable === true
98660
+ },
98661
+ project
98662
+ );
98663
+ if (read && type2.kind === "set" && type2.elementType.kind === "reference")
98664
+ return {
98665
+ name: "Set",
98666
+ nullable: type2.nullable === true,
98667
+ arguments: [semanticResolvedType(type2.elementType, project)]
98668
+ };
98669
+ const nullable2 = type2.nullable === true;
98670
+ switch (type2.kind) {
98671
+ case "primitive":
98672
+ return { name: type2.name, nullable: nullable2 };
98673
+ case "typeParameter":
98674
+ return { name: type2.name, nullable: nullable2 };
98675
+ case "named":
98676
+ return {
98677
+ name: project.typeById.get(type2.typeId)?.name ?? type2.typeId,
98678
+ nullable: nullable2,
98679
+ arguments: (type2.typeArguments ?? []).map(child2)
98680
+ };
98681
+ case "tuple":
98682
+ return {
98683
+ name: "",
98684
+ nullable: nullable2,
98685
+ arguments: type2.elements.map((element) => child2(element.type)),
98686
+ tupleNames: type2.elements.map((element) => element.name)
98687
+ };
98688
+ case "list":
98689
+ return { name: "List", nullable: nullable2, arguments: [child2(type2.elementType)] };
98690
+ case "set":
98691
+ return { name: "Set", nullable: nullable2, arguments: [child2(type2.elementType)] };
98692
+ case "dictionary":
98693
+ return {
98694
+ name: "Dictionary",
98695
+ nullable: nullable2,
98696
+ arguments: [child2(type2.keyType), child2(type2.valueType)]
98697
+ };
98698
+ case "reference":
98699
+ return { name: "Reference", nullable: nullable2, arguments: [child2(type2.target)] };
98700
+ case "delegate":
98701
+ return {
98702
+ name: "NeoDelegate",
98703
+ nullable: nullable2,
98704
+ arguments: [child2(type2.returnType), ...type2.parameterTypes.map(child2)]
98705
+ };
98706
+ case "action":
98707
+ return {
98708
+ name: "NeoAction",
98709
+ nullable: nullable2,
98710
+ arguments: type2.parameterTypes.map(child2)
98711
+ };
98712
+ }
98713
+ }
98714
+ function sourceCallMember(callee, scope, environment) {
98715
+ if (callee.kind !== "ident" && callee.kind !== "member") return void 0;
98716
+ const receiver = callee.kind === "ident" ? scope.get("this") : inferExpressionType(callee.receiver, scope, environment);
98717
+ const staticDeclaration = !receiver && callee.kind === "member" && callee.receiver.kind === "ident" ? environment.types.get(callee.receiver.name) : void 0;
98718
+ let owner = staticDeclaration ?? (receiver && environment.types.get(receiver.name));
98400
98719
  const visited = /* @__PURE__ */ new Set();
98401
98720
  let functionCount = 0;
98402
- while (owner !== void 0 && !visited.has(owner.name)) {
98721
+ while (owner && !visited.has(owner.name)) {
98403
98722
  visited.add(owner.name);
98404
- for (const member of owner.members) {
98405
- if (member.name === callee.name && member.kind === "function")
98723
+ for (const member2 of owner.members) {
98724
+ if (member2.name === callee.name && member2.kind === "function")
98406
98725
  functionCount++;
98407
98726
  }
98408
- if (functionCount > 1) return void 0;
98727
+ if (functionCount > 1) return null;
98409
98728
  const base = owner.baseTypes.find(
98410
98729
  (type2) => environment.types.has(type2.name)
98411
98730
  );
98412
98731
  owner = base && environment.types.get(base.name);
98413
98732
  }
98414
- const resolved = staticDeclaration === void 0 ? receiverType === void 0 ? void 0 : sourceClassMemberForType(receiverType, callee.name, environment) : sourceClassMemberByName(staticDeclaration, callee.name, environment);
98415
- if (resolved?.member.kind !== "function") return void 0;
98733
+ const member = receiver ? sourceClassMemberForType(receiver, callee.name, environment) : staticDeclaration && sourceClassMemberByName(staticDeclaration, callee.name, environment);
98734
+ return !staticDeclaration || member?.member.modifiers.includes("static") ? member : void 0;
98735
+ }
98736
+ function callParameters(expression, scope, environment) {
98737
+ const binding = sourceCallBinding(expression, scope, environment);
98738
+ if (binding?.parameters) return binding.parameters;
98739
+ const callee = expression.callee;
98740
+ if (callee.kind !== "member" && callee.kind !== "ident")
98741
+ return delegateCallParameters(
98742
+ inferExpressionType(callee, scope, environment)
98743
+ );
98744
+ const resolved = sourceCallMember(callee, scope, environment);
98745
+ if (resolved === null) return void 0;
98746
+ if (resolved?.member.kind !== "function")
98747
+ return delegateCallParameters(
98748
+ inferExpressionType(callee, scope, environment)
98749
+ );
98416
98750
  return resolved.member.parameters.map((parameter4) => ({
98417
98751
  name: parameter4.name,
98418
98752
  type: substituteSemanticType(
@@ -98421,6 +98755,9 @@ function callParameters(callee, scope, environment) {
98421
98755
  )
98422
98756
  }));
98423
98757
  }
98758
+ function delegateCallParameters(type2) {
98759
+ return type2?.name === "NeoDelegate" ? type2.arguments?.slice(1).map((type3) => ({ name: null, type: type3 })) : void 0;
98760
+ }
98424
98761
  function semanticMemberType(member, environment, bindings = /* @__PURE__ */ new Map()) {
98425
98762
  const type2 = substituteSemanticType(semanticType(member.type), bindings);
98426
98763
  if (type2.name !== "List") return type2;
@@ -98658,21 +98995,23 @@ function matchingDeclaredConstructor(declaration, argumentNames) {
98658
98995
  return neoScriptNamedCallSignature(declaration.constructors, argumentNames) ?? null;
98659
98996
  }
98660
98997
  function semanticType(type2) {
98998
+ const read = referenceReadType(type2);
98999
+ return read === type2 ? declaredSemanticType(type2) : semanticType(read);
99000
+ }
99001
+ function declaredSemanticType(type2) {
98661
99002
  if (type2.tupleElements)
98662
99003
  return {
98663
99004
  name: "",
98664
99005
  nullable: type2.nullable,
98665
99006
  arguments: type2.tupleElements.map(
98666
- (element) => semanticType(element.type)
99007
+ (element) => declaredSemanticType(element.type)
98667
99008
  ),
98668
99009
  tupleNames: type2.tupleElements.map((element) => element.name)
98669
99010
  };
98670
- const read = referenceReadType(type2);
98671
- if (read !== type2) return semanticType(read);
98672
99011
  return {
98673
99012
  name: type2.name,
98674
99013
  nullable: type2.nullable,
98675
- arguments: type2.typeArguments.map(semanticType)
99014
+ arguments: type2.typeArguments.map(declaredSemanticType)
98676
99015
  };
98677
99016
  }
98678
99017
  function semanticAstType(type2) {
@@ -98697,6 +99036,9 @@ function semanticAstType(type2) {
98697
99036
  arguments: type2.kind === "dict" ? [semanticAstType(type2.key), semanticAstType(type2.value)] : [semanticAstType(type2.element)]
98698
99037
  };
98699
99038
  }
99039
+ function formatAnnotationValueType(type2) {
99040
+ return describeType(contractType(type2));
99041
+ }
98700
99042
  function contractType(type2) {
98701
99043
  const nullable2 = type2.endsWith("?");
98702
99044
  const withoutNullable = type2.replace(/\?$/, "");
@@ -98799,7 +99141,7 @@ function validateListAnnotations(uri, member, ownerName, environment, diagnostic
98799
99141
  const domainError = indexKeyDomainError(
98800
99142
  field.member,
98801
99143
  substituteSemanticType(semanticType(field.member.type), field.bindings),
98802
- environment
99144
+ environment.enums
98803
99145
  );
98804
99146
  if (domainError !== null) {
98805
99147
  pushDiagnostic(
@@ -98838,16 +99180,16 @@ function sourceClassMemberForType(type2, name, environment) {
98838
99180
  }
98839
99181
  return sourceClassMemberByName(declaration, name, environment, bindings);
98840
99182
  }
98841
- function indexKeyDomainError(field, type2, environment) {
99183
+ function indexKeyDomainError(field, type2, enums) {
98842
99184
  if (field.kind !== "field") {
98843
99185
  return `'${field.name}' is a ${field.kind}, and index keys require a stored field`;
98844
99186
  }
98845
99187
  if (type2.name === "string") {
98846
99188
  return annotationEnumOption(field.annotations, "settings", "format") === "Plain" ? null : `'${field.name}' is localized, and String index keys must be plain`;
98847
99189
  }
98848
- if (environment.enums.has(type2.name)) return null;
99190
+ if (enums.has(type2.name)) return null;
98849
99191
  const entry = type2.arguments?.[0];
98850
- if (type2.name === "Set" && entry !== void 0 && environment.enums.has(entry.name)) {
99192
+ if (type2.name === "Set" && entry !== void 0 && enums.has(entry.name)) {
98851
99193
  return `'${field.name}' is a multi-select Enum, and index keys require a single-select Enum`;
98852
99194
  }
98853
99195
  return `'${field.name}' is a ${type2.name} field, and index keys require a plain String or a single-select Enum`;
@@ -98860,17 +99202,6 @@ function annotationEnumOption(annotations, name, field) {
98860
99202
  function isListContext(context) {
98861
99203
  return context.kind === "member" && (context.type.name === "List" || context.type.name === "Set");
98862
99204
  }
98863
- function findTypeAnnotation(type2, position) {
98864
- const own = type2.annotations.find(
98865
- (annotation2) => inAnnotationArguments(annotation2, position)
98866
- );
98867
- if (own) return { annotation: own, type: type2 };
98868
- for (const argument2 of type2.typeArguments) {
98869
- const nested = findTypeAnnotation(argument2, position);
98870
- if (nested) return nested;
98871
- }
98872
- return null;
98873
- }
98874
99205
  function describeAnnotationContext(context) {
98875
99206
  if (context.kind === "member" || context.kind === "type" || context.kind === "flowBinding" || context.kind === "flowMember")
98876
99207
  return `${context.type.name} ${context.kind}`;
@@ -98885,8 +99216,6 @@ function contains(range2, position) {
98885
99216
  }
98886
99217
  function inAnnotationArguments(annotation2, position) {
98887
99218
  if (!contains(annotation2.range, position)) return false;
98888
- const first = annotation2.arguments[0];
98889
- if (first) return compare(first.range.start, position) <= 0;
98890
99219
  return compare(annotation2.nameRange.end, position) < 0;
98891
99220
  }
98892
99221
  function compare(left, right) {
@@ -99006,7 +99335,7 @@ function classDerivesFromName(name, ancestorName, environment, seen = /* @__PURE
99006
99335
  return classDerivesFromName(base.name, ancestorName, environment, seen);
99007
99336
  });
99008
99337
  }
99009
- var NEO_VARIANT_FOLDER_SETTING, NEO_ANIMATION_CHILD_OVERRIDE_TYPE_NAME, primitiveType, LIST_COLUMN_INHERITANCE_KEY, documentContracts, previousSemanticContract, validDocuments, DECLARATION_BODY_GLOBAL_TYPES, SEMANTIC_PRIMITIVE_TYPE_NAMES, AST_PRIMITIVE_TYPE_NAMES;
99338
+ var NEO_VARIANT_FOLDER_SETTING, NEO_ANIMATION_CHILD_OVERRIDE_TYPE_NAME, primitiveType, LIST_COLUMN_INHERITANCE_KEY, documentContracts, previousSemanticContract, validDocuments, ANNOTATION_SITES, DECLARATION_BODY_GLOBAL_TYPES, SEMANTIC_PRIMITIVE_TYPE_NAMES, AST_PRIMITIVE_TYPE_NAMES;
99010
99339
  var init_project_source_semantics = __esm({
99011
99340
  "../packages/neoscript-language/src/project-source-semantics.ts"() {
99012
99341
  "use strict";
@@ -99036,6 +99365,7 @@ var init_project_source_semantics = __esm({
99036
99365
  LIST_COLUMN_INHERITANCE_KEY = "__other__";
99037
99366
  documentContracts = /* @__PURE__ */ new WeakMap();
99038
99367
  validDocuments = /* @__PURE__ */ new WeakMap();
99368
+ ANNOTATION_SITES = /* @__PURE__ */ new WeakMap();
99039
99369
  DECLARATION_BODY_GLOBAL_TYPES = /* @__PURE__ */ new Set([
99040
99370
  NEOSCRIPT_IMAGE_REGISTRY_TYPE,
99041
99371
  NEOSCRIPT_AUDIO_CLIP_REGISTRY_TYPE,
@@ -99129,6 +99459,16 @@ function projectSourceAccessors(input, containingRange) {
99129
99459
  openIndex = cursor;
99130
99460
  break;
99131
99461
  }
99462
+ if (!body) {
99463
+ const start = bodyStart + open2.end;
99464
+ const end = full.offsetAt(range2.end);
99465
+ body = {
99466
+ range: full.range(start, end),
99467
+ source: source.slice(start, end),
99468
+ form: "block"
99469
+ };
99470
+ openIndex = tokens.length - 1;
99471
+ }
99132
99472
  }
99133
99473
  accessors.push({
99134
99474
  keyword: token.text,
@@ -99155,6 +99495,7 @@ function expressionAccessor(source, full, tokens, bodyStart, firstIndex2) {
99155
99495
  const start = bodyStart + first.start;
99156
99496
  let end = bodyStart + (tokens.at(-1)?.start ?? 0);
99157
99497
  let depth = 0;
99498
+ let terminated = false;
99158
99499
  for (let cursor = firstIndex2; cursor < tokens.length; cursor++) {
99159
99500
  const token = tokens[cursor];
99160
99501
  if (token.kind !== "punctuation") continue;
@@ -99169,6 +99510,7 @@ function expressionAccessor(source, full, tokens, bodyStart, firstIndex2) {
99169
99510
  if (token.text === "}") {
99170
99511
  if (depth === 0) {
99171
99512
  end = bodyStart + token.start;
99513
+ terminated = true;
99172
99514
  break;
99173
99515
  }
99174
99516
  depth--;
@@ -99176,14 +99518,17 @@ function expressionAccessor(source, full, tokens, bodyStart, firstIndex2) {
99176
99518
  }
99177
99519
  if (depth === 0 && token.text === ";") {
99178
99520
  end = bodyStart + token.start;
99521
+ terminated = true;
99179
99522
  break;
99180
99523
  }
99181
99524
  }
99182
- const trimmed = source.slice(start, end).trimEnd();
99183
- if (trimmed.length === 0) return null;
99525
+ const authored = source.slice(start, end);
99526
+ const trimmed = authored.trimEnd();
99527
+ if (trimmed.length === 0 && terminated) return null;
99528
+ const body = terminated ? trimmed : authored;
99184
99529
  return {
99185
- range: full.range(start, start + trimmed.length),
99186
- source: trimmed,
99530
+ range: full.range(start, start + body.length),
99531
+ source: body,
99187
99532
  form: "expression"
99188
99533
  };
99189
99534
  }
@@ -99410,7 +99755,7 @@ function compileProjectSourceBodies(documents, options = {}) {
99410
99755
  `dialogue-group:${uri}:${declaration.name}:${member.name}`
99411
99756
  ),
99412
99757
  unit: "function",
99413
- range: expression?.range ?? innerBodyRange(document.syntax.source, member.body.range),
99758
+ range: expression?.range ?? innerBodyRange(document.syntax.source, member.body),
99414
99759
  ...expression ? { bodyMode: "expression" } : {},
99415
99760
  context: {
99416
99761
  project,
@@ -99474,10 +99819,7 @@ function compileProjectSourceBodies(documents, options = {}) {
99474
99819
  constructor2
99475
99820
  ),
99476
99821
  unit: "constructor",
99477
- range: innerBodyRange(
99478
- document.syntax.source,
99479
- constructor2.body.range
99480
- ),
99822
+ range: innerBodyRange(document.syntax.source, constructor2.body),
99481
99823
  context: {
99482
99824
  project,
99483
99825
  declaringType,
@@ -99513,7 +99855,7 @@ function compileProjectSourceBodies(documents, options = {}) {
99513
99855
  declarationRange: initBlock.keywordRange,
99514
99856
  memberId: initId,
99515
99857
  unit: "init",
99516
- range: innerBodyRange(document.syntax.source, initBlock.body.range),
99858
+ range: innerBodyRange(document.syntax.source, initBlock.body),
99517
99859
  context: {
99518
99860
  project,
99519
99861
  declaringType,
@@ -99572,7 +99914,7 @@ function compileProjectSourceBodies(documents, options = {}) {
99572
99914
  memberId: info.symbol.id,
99573
99915
  unit: "function",
99574
99916
  signature: sourceOverloadParameterIdentity(member),
99575
- range: expressionBody?.range ?? innerBodyRange(document.syntax.source, member.body.range),
99917
+ range: expressionBody?.range ?? innerBodyRange(document.syntax.source, member.body),
99576
99918
  ...expressionBody ? { bodyMode: "expression" } : {},
99577
99919
  context: {
99578
99920
  ...baseContext2,
@@ -100791,10 +101133,13 @@ function memberWritability(annotations) {
100791
101133
  if (/\.Session\b/.test(allowed ?? "")) return "session";
100792
101134
  return "runtime";
100793
101135
  }
100794
- function innerBodyRange(text, range2) {
100795
- const start = text.offsetAt(range2.start);
100796
- const end = text.offsetAt(range2.end);
100797
- return text.range(Math.min(end, start + 1), Math.max(start + 1, end - 1));
101136
+ function innerBodyRange(text, body) {
101137
+ const start = text.offsetAt(body.range.start);
101138
+ const end = text.offsetAt(body.range.end);
101139
+ return text.range(
101140
+ Math.min(end, start + 1),
101141
+ body.unclosed ? end : Math.max(start + 1, end - 1)
101142
+ );
100798
101143
  }
100799
101144
  function collectRegistryMembers(documents) {
100800
101145
  const byRegistryType = /* @__PURE__ */ new Map();
@@ -106881,8 +107226,10 @@ function parseIndexPathSpellingV4(expression) {
106881
107226
  key: indexed.index.value
106882
107227
  };
106883
107228
  }
106884
- function parseSlotPathSpellingV4(expression, isStaticSymbol) {
106885
- if (expression.kind !== "call") return null;
107229
+ function parseSlotPathSpellingV4(expression, isStaticSymbol, allowImplicit = false) {
107230
+ if (expression.kind !== "call") {
107231
+ return allowImplicit ? parseSlotPath(expression, isStaticSymbol) : null;
107232
+ }
106886
107233
  if (expression.callee.kind !== "ident") return null;
106887
107234
  if (expression.callee.name !== "Reference") return null;
106888
107235
  if ((expression.typeArguments?.length ?? 0) > 0) return null;
@@ -106891,8 +107238,11 @@ function parseSlotPathSpellingV4(expression, isStaticSymbol) {
106891
107238
  }
106892
107239
  const argument2 = expression.args[0];
106893
107240
  if (expression.args.length !== 1 || argument2 === void 0) return null;
107241
+ return parseSlotPath(argument2, isStaticSymbol);
107242
+ }
107243
+ function parseSlotPath(expression, isStaticSymbol) {
106894
107244
  const steps = [];
106895
- let current = argument2;
107245
+ let current = expression;
106896
107246
  for (; ; ) {
106897
107247
  const indexed = current.kind === "force" ? current.operand : current;
106898
107248
  if (indexed.kind === "index") {
@@ -106987,6 +107337,7 @@ function astTypeNameV4(type2) {
106987
107337
  if (type2.kind === "primitive" || type2.kind === "named") return type2.name;
106988
107338
  if (type2.kind === "list") return "List";
106989
107339
  if (type2.kind === "set") return "Set";
107340
+ if (type2.kind === "tuple") return "tuple";
106990
107341
  return "Dictionary";
106991
107342
  }
106992
107343
  function encodeMemberDefaultKeyReferenceV4(spelling) {
@@ -122193,90 +122544,60 @@ function constructorExpressionSlice(source) {
122193
122544
  return normalizeInitializerSource(source);
122194
122545
  }
122195
122546
  function topLevelEntrySlices(initializer, open2, close) {
122196
- const start = topLevelIndexOf(initializer, open2);
122197
- if (start < 0) return [];
122547
+ const tokens = lex(initializer).roots.filter(
122548
+ (token) => token.kind !== "comment"
122549
+ );
122550
+ const angles = [];
122551
+ const genericStarts = /* @__PURE__ */ new Set();
122552
+ for (let index = 0; index < tokens.length; index++) {
122553
+ const token = tokens[index];
122554
+ if (token.kind !== "operator") continue;
122555
+ if (token.text === "<") angles.push(index);
122556
+ else if (token.text === ">") {
122557
+ const start = angles.pop();
122558
+ const next = tokens[index + 1]?.text;
122559
+ if (start !== void 0 && (next === "(" || next === "{" || next === "."))
122560
+ genericStarts.add(start - 1);
122561
+ }
122562
+ }
122198
122563
  const slices = [];
122199
122564
  let depth = 0;
122200
122565
  let entryStart = -1;
122201
- let quote6 = null;
122202
- let escaped = false;
122203
- let index = start;
122204
- while (index < initializer.length) {
122205
- const character = initializer[index];
122206
- if (quote6 !== null) {
122207
- if (escaped) escaped = false;
122208
- else if (character === "\\") escaped = true;
122209
- else if (character === quote6) quote6 = null;
122210
- index += 1;
122211
- continue;
122212
- }
122213
- const afterComment = commentEndIndex(initializer, index);
122214
- if (afterComment !== null) {
122215
- index = afterComment;
122216
- continue;
122217
- }
122218
- if (character === '"' || character === "'") {
122219
- quote6 = character;
122220
- index += 1;
122221
- continue;
122566
+ for (let index = 0; index < tokens.length; index++) {
122567
+ const token = tokens[index];
122568
+ if (genericStarts.has(index)) {
122569
+ const end = new Parser(tokens, index).typeEnd();
122570
+ const next = tokens[end]?.text;
122571
+ if (end > index && (next === "(" || next === "{" || next === ".")) {
122572
+ index = end - 1;
122573
+ continue;
122574
+ }
122222
122575
  }
122576
+ if (token.kind !== "punctuation") continue;
122577
+ const character = token.text;
122578
+ if (depth === 0 && character !== open2) continue;
122223
122579
  if (character === "[" || character === "{" || character === "(") {
122224
- depth += 1;
122225
- if (depth === 1) entryStart = index + 1;
122226
- index += 1;
122227
- continue;
122228
- }
122229
- if (character === "]" || character === "}" || character === ")") {
122230
- depth -= 1;
122580
+ depth++;
122581
+ if (depth === 1) entryStart = token.end;
122582
+ } else if (character === "]" || character === "}" || character === ")") {
122583
+ depth--;
122231
122584
  if (depth === 0) {
122232
122585
  if (character !== close) return [];
122233
122586
  const text = normalizeInitializerSource(
122234
- initializer.slice(entryStart, index)
122587
+ initializer.slice(entryStart, token.start)
122235
122588
  );
122236
- if (text.length > 0 || slices.length > 0) slices.push(text);
122589
+ if (text.length > 0) slices.push(text);
122237
122590
  return slices.filter((entry) => entry.length > 0);
122238
122591
  }
122239
- index += 1;
122240
- continue;
122241
- }
122242
- if (character === "," && depth === 1) {
122592
+ } else if (character === "," && depth === 1) {
122243
122593
  slices.push(
122244
- normalizeInitializerSource(initializer.slice(entryStart, index))
122594
+ normalizeInitializerSource(initializer.slice(entryStart, token.start))
122245
122595
  );
122246
- entryStart = index + 1;
122596
+ entryStart = token.end;
122247
122597
  }
122248
- index += 1;
122249
122598
  }
122250
122599
  return [];
122251
122600
  }
122252
- function topLevelIndexOf(source, character) {
122253
- let quote6 = null;
122254
- let escaped = false;
122255
- let index = 0;
122256
- while (index < source.length) {
122257
- const current = source[index];
122258
- if (quote6 !== null) {
122259
- if (escaped) escaped = false;
122260
- else if (current === "\\") escaped = true;
122261
- else if (current === quote6) quote6 = null;
122262
- index += 1;
122263
- continue;
122264
- }
122265
- const afterComment = commentEndIndex(source, index);
122266
- if (afterComment !== null) {
122267
- index = afterComment;
122268
- continue;
122269
- }
122270
- if (current === '"' || current === "'") {
122271
- quote6 = current;
122272
- index += 1;
122273
- continue;
122274
- }
122275
- if (current === character) return index;
122276
- index += 1;
122277
- }
122278
- return -1;
122279
- }
122280
122601
  function matchesStoredInitializer(defaultValue, source) {
122281
122602
  if (!isObjectRecord(defaultValue) || !isObjectRecord(defaultValue.init))
122282
122603
  return false;
@@ -122290,6 +122611,7 @@ var normalizedInitializers, normalizedInitializerCharacters, MAX_NORMALIZED_INIT
122290
122611
  var init_init_source = __esm({
122291
122612
  "src/project-source/init-source.ts"() {
122292
122613
  "use strict";
122614
+ init_executable_parser();
122293
122615
  init_lexer();
122294
122616
  init_value_comparison();
122295
122617
  normalizedInitializers = /* @__PURE__ */ new Map();
@@ -124882,10 +125204,36 @@ function deferredReferenceDefault(context, expression) {
124882
125204
  function deferredReferenceValue(context, expression) {
124883
125205
  const spelling = parseIndexPathSpellingV4(expression) ?? parseSlotPathSpellingV4(
124884
125206
  expression,
124885
- (symbol) => context.staticValueIdsBySymbol.has(symbol) || context.classIdsByName.has(symbol.slice(0, symbol.indexOf(".")))
125207
+ (symbol) => context.staticValueIdsBySymbol.has(symbol) || context.classIdsByName.has(symbol.slice(0, symbol.indexOf("."))),
125208
+ isStoredValuePath(context, expression)
124886
125209
  );
124887
125210
  return spelling === null ? null : encodeMemberDefaultKeyReferenceV4(spelling);
124888
125211
  }
125212
+ function isStoredValuePath(context, expression) {
125213
+ const path = expressionMemberPath(expression);
125214
+ if (path === null) return false;
125215
+ const separator = path.lastIndexOf(".");
125216
+ if (separator < 0) return false;
125217
+ const receiver = path.slice(0, separator);
125218
+ const classId = context.rootValueTargetsByPath.get(receiver)?.classId ?? context.classIdsByName.get(receiver);
125219
+ if (classId === void 0) return false;
125220
+ const memberId = effectiveMemberIdByName(
125221
+ context,
125222
+ classId,
125223
+ path.slice(separator + 1)
125224
+ );
125225
+ if (memberId === null) return false;
125226
+ if (!receiver.startsWith("root.") && !isStaticMember2(context, memberId))
125227
+ return false;
125228
+ const source = context.sourceMembersById.get(memberId);
125229
+ if (source !== void 0) {
125230
+ return source.member.kind === "field" && source.member.type.name !== "Reference" && !(source.member.type.name === "Set" && source.member.type.arguments[0]?.name === "Reference") && !source.ownerClass.genericParameters.some(
125231
+ (parameter4) => parameter4.name === source.member.type.name
125232
+ );
125233
+ }
125234
+ const member = context.loweredMembers.get(memberId) ?? context.baseMembers.get(memberId);
125235
+ return member !== void 0 && member.kind !== "lookup" && member.kind !== "generic" && member.kind !== "function" && member.kind !== "scriptFunction";
125236
+ }
124889
125237
  function slotReferenceType(readType) {
124890
125238
  if (readType.name === "Reference") return readType;
124891
125239
  const element = readType.name === "Set" ? readType.arguments[0] : void 0;
@@ -125479,6 +125827,12 @@ function positionRequiresEvaluation(context, expression, expected, ownerClass) {
125479
125827
  ownerClass.name
125480
125828
  )
125481
125829
  );
125830
+ const selectionEntry = expected.name === "Set" ? expected.arguments[0] : void 0;
125831
+ if (selectionEntry?.name === "Reference" && expression.kind === "litList") {
125832
+ return expression.elements.some(
125833
+ (element) => positionRequiresEvaluation(context, element, selectionEntry, ownerClass)
125834
+ );
125835
+ }
125482
125836
  if (isStoredDelegateLiteral(expected, expression))
125483
125837
  return requiresEvaluation();
125484
125838
  if (isStoredActionLiteral(expected, expression)) return false;
@@ -126131,7 +126485,7 @@ function lowerGenericArgument(context, ownerClass, type2, memberId, genericParam
126131
126485
  genericParamId
126132
126486
  };
126133
126487
  const base = context.baseMembers.get(memberId);
126134
- if (base && JSON.stringify(manifestTypeForMember(context, base)) === JSON.stringify(type2)) {
126488
+ if (base && base.kind !== "tuple" && JSON.stringify(manifestTypeForMember(context, base)) === JSON.stringify(type2)) {
126135
126489
  context.loweredMembers.set(memberId, { ...base, owner });
126136
126490
  if (base.kind === "list" || base.kind === "set" || base.kind === "dictionary") {
126137
126491
  lowerCollectionEntry(
@@ -127045,7 +127399,7 @@ function renderVariantSelectionV4(context, memberName, value) {
127045
127399
  );
127046
127400
  }
127047
127401
  const rootPath = context.collectionValuePaths.get(rowValueId);
127048
- const reference2 = rootPath === void 0 ? `Reference(id: ${quoteNeoString(rowValueId)})` : `Reference(${rootPath})`;
127402
+ const reference2 = rootPath === void 0 ? `Reference(id: ${quoteNeoString(rowValueId)})` : rootPath;
127049
127403
  return `${path}.Bind(${reference2})`;
127050
127404
  }
127051
127405
  var init_variant_selection_source = __esm({
@@ -127868,7 +128222,7 @@ function memberSettings(context, member) {
127868
128222
  member.collectionValueId
127869
128223
  );
127870
128224
  settings.push(
127871
- rootPath === void 0 ? `collectionValue: Reference(id: ${quote(member.collectionValueId)})` : `collectionValue: Reference(${rootPath})`
128225
+ rootPath === void 0 ? `collectionValue: Reference(id: ${quote(member.collectionValueId)})` : `collectionValue: ${rootPath}`
127872
128226
  );
127873
128227
  }
127874
128228
  } else if (member.kind === "dialogueLookup") {
@@ -129014,7 +129368,7 @@ function emitVariantFolder(context, className, folder) {
129014
129368
  const rootPath = context.collectionValuePaths.get(
129015
129369
  folder.binding.collectionValueId
129016
129370
  );
129017
- const collectionValue = rootPath === void 0 ? `Reference(id: ${quote(folder.binding.collectionValueId)})` : `Reference(${rootPath})`;
129371
+ const collectionValue = rootPath === void 0 ? `Reference(id: ${quote(folder.binding.collectionValueId)})` : rootPath;
129018
129372
  return `${id(folder.id)}${NEO_LOOKUP_VARIANT_FOLDER_TYPE_NAME}<${className}, ${valueType}> ${variantFolderSymbol(folder)} = new(
129019
129373
  path: ${quote(folder.path)},
129020
129374
  collection: ${qualifiedMember(context, folder.binding.collectionMemberId)},
@@ -130065,7 +130419,7 @@ function emitDialogueGroup(data, recordId, name, priorityNames, dialogueNames, u
130065
130419
  const path = collectionValuePaths.get(data.collectionValueId);
130066
130420
  args.push([
130067
130421
  "collectionValue",
130068
- path === void 0 ? `Reference(id: ${quote2(data.collectionValueId)})` : `Reference(${path})`
130422
+ path === void 0 ? `Reference(id: ${quote2(data.collectionValueId)})` : path
130069
130423
  ]);
130070
130424
  }
130071
130425
  const source = collectDialogueGroupFunctions(data, recordId, uiLogicResolver);
@@ -144396,14 +144750,14 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
144396
144750
  const currentById = new Map(
144397
144751
  args.document.members.map((member) => [member.id, member])
144398
144752
  );
144399
- const sourceMembers = authoredPostDocument.members.map(
144753
+ const sourceMembers2 = authoredPostDocument.members.map(
144400
144754
  (member) => remappedMembers.get(member.id) ?? (recompileTargets.memberIds.has(member.id) || explicitlyChangedMemberIds.has(member.id) ? stripDerivedBodies(member) : member)
144401
144755
  );
144402
144756
  let currentSourceMembers;
144403
144757
  let postCompilationProject;
144404
144758
  let currentCompilationProject;
144405
144759
  const toleratedPreexistingFailures = /* @__PURE__ */ new Set();
144406
- for (const member of sourceMembers) {
144760
+ for (const member of sourceMembers2) {
144407
144761
  if (!hasAuthoredNeoScriptBody(member)) continue;
144408
144762
  if (!recompileTargets.memberIds.has(member.id) || remappedMembers.has(member.id)) {
144409
144763
  continue;
@@ -144412,11 +144766,11 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
144412
144766
  compileOneAuthoredMember({
144413
144767
  scriptSources: scriptSources.get(`member:${member.id}`),
144414
144768
  document: authoredPostDocument,
144415
- members: sourceMembers,
144769
+ members: sourceMembers2,
144416
144770
  member,
144417
144771
  compilationProject: postCompilationProject ??= cachedServerCompilationProject({
144418
144772
  ...authoredPostDocument,
144419
- members: sourceMembers
144773
+ members: sourceMembers2
144420
144774
  })
144421
144775
  });
144422
144776
  } catch (postWriteError) {
@@ -144449,7 +144803,7 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
144449
144803
  }
144450
144804
  }
144451
144805
  const compiledById = new Map(
144452
- sourceMembers.map((member) => [member.id, member])
144806
+ sourceMembers2.map((member) => [member.id, member])
144453
144807
  );
144454
144808
  const explicitMemberIds = /* @__PURE__ */ new Set();
144455
144809
  for (const change of authoredChanges) {
@@ -144470,7 +144824,7 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
144470
144824
  return { ...change, nextData: compiled };
144471
144825
  });
144472
144826
  const hashByKey = indexLiveContentHashesByRecordKey(args.contentHashHeads);
144473
- for (const compiled of sourceMembers) {
144827
+ for (const compiled of sourceMembers2) {
144474
144828
  if (!recompileTargets.memberIds.has(compiled.id)) continue;
144475
144829
  if (explicitMemberIds.has(compiled.id)) continue;
144476
144830
  if (toleratedPreexistingFailures.has(compiled.id)) continue;
@@ -144503,7 +144857,7 @@ function* prepareServerOwnedSchemaCommitPasses(args) {
144503
144857
  targetIds: recompileTargets.constructorIds,
144504
144858
  contentHashHeads: args.contentHashHeads
144505
144859
  });
144506
- const constructionTypeMembers = [...sourceMembers];
144860
+ const constructionTypeMembers = [...sourceMembers2];
144507
144861
  const appendConstructionTypes = () => {
144508
144862
  const created = compiledConstructionTypeMembers(
144509
144863
  constructionTypeMembers,
@@ -159180,7 +159534,7 @@ function folderBinding(context, global) {
159180
159534
  }
159181
159535
  if (collectionValue === void 0) {
159182
159536
  throw new Error(
159183
- `Lookup variant folder ${global.name} requires collectionValue: Reference(...).`
159537
+ `Lookup variant folder ${global.name} requires collectionValue naming a collection row.`
159184
159538
  );
159185
159539
  }
159186
159540
  const collectionValueId = lowerReferenceValue(collectionValue);
@@ -159192,11 +159546,10 @@ function folderBinding(context, global) {
159192
159546
  return { collectionMemberId, collectionValueId };
159193
159547
  }
159194
159548
  function lowerReferenceValue(expression) {
159195
- if (expression.kind !== "call" || expression.callee.kind !== "ident" || expression.callee.name !== "Reference")
159196
- return null;
159197
- const idIndex = expression.argumentNames?.findIndex((name) => name === "id") ?? -1;
159198
- const target = expression.args[idIndex >= 0 ? idIndex : 0];
159199
- if (target?.kind === "litString") return target.value;
159549
+ const isReferenceCall2 = expression.kind === "call" && expression.callee.kind === "ident" && expression.callee.name === "Reference";
159550
+ const idIndex = isReferenceCall2 ? expression.argumentNames?.findIndex((name) => name === "id") ?? -1 : -1;
159551
+ const target = isReferenceCall2 ? expression.args[idIndex >= 0 ? idIndex : 0] : expression;
159552
+ if (isReferenceCall2 && target?.kind === "litString") return target.value;
159200
159553
  const path = target === void 0 ? null : dottedPath(target);
159201
159554
  if (path === null || !path.startsWith("root.")) return null;
159202
159555
  return referenceId2(`Reference(${path})`);
@@ -162017,9 +162370,14 @@ function defaultRequiresOwnedRows(context, member, sourceExpression, source) {
162017
162370
  }
162018
162371
  function memberInitializerRequiresEvaluation(context, member, expression, source) {
162019
162372
  if (member.kind === "class" && member.partial === true) return false;
162020
- if (member.kind === "lookup" && isDeferredPathReferenceValue(context, expression)) {
162373
+ if (member.kind === "lookup" && isDeferredPathReferenceValue(context, expression, member)) {
162021
162374
  return false;
162022
162375
  }
162376
+ if (member.kind === "lookup" && expression.kind === "litList") {
162377
+ return expression.elements.some(
162378
+ (element) => memberInitializerRequiresEvaluation(context, member, element, source)
162379
+ );
162380
+ }
162023
162381
  const unorderedDefault = source.purpose === "memberDefault" && member.id === source.memberId && member.kind === "list" && member.listKind === "unordered" && expression.kind === "litList" && expression.elements.length > 0;
162024
162382
  const requiresEvaluation = unorderedDefault || source.purpose === "memberDefault" && member.id === source.memberId && constructsValue(expression) && slotForwardsTypeParameter2(context, member, source.ownerClassId) || context.localValues.readsInstance(expression) || isSchemaMemberValueRead(context, expression, source) || isUnresolvedLiteralName(context, member, expression) || initializerRequiresEvaluation(
162025
162383
  context.declaredConstructors,
@@ -162049,18 +162407,19 @@ function slotForwardsTypeParameter2(context, member, ownerClassId) {
162049
162407
  }
162050
162408
  return false;
162051
162409
  }
162052
- function deferredPathSpelling(context, expression) {
162410
+ function deferredPathSpelling(context, expression, expected) {
162053
162411
  return parseIndexPathSpellingV4(expression) ?? parseSlotPathSpellingV4(
162054
162412
  expression,
162055
- (symbol) => context.staticValueIdsBySymbol.has(symbol)
162413
+ (symbol) => context.staticValueIdsBySymbol.has(symbol),
162414
+ isStoredSlotPath(context, expression, expected)
162056
162415
  );
162057
162416
  }
162058
- function isDeferredPathReferenceValue(context, sourceExpression) {
162417
+ function isDeferredPathReferenceValue(context, sourceExpression, expected) {
162059
162418
  const expression = annotatedValue(sourceExpression).expression;
162060
162419
  const elements = expression.kind === "litList" ? expression.elements : [expression];
162061
162420
  let indexPaths = 0;
162062
162421
  for (const element of elements) {
162063
- if (deferredPathSpelling(context, element) !== null) {
162422
+ if (deferredPathSpelling(context, element, expected) !== null) {
162064
162423
  indexPaths += 1;
162065
162424
  continue;
162066
162425
  }
@@ -162070,6 +162429,35 @@ function isDeferredPathReferenceValue(context, sourceExpression) {
162070
162429
  }
162071
162430
  return indexPaths > 0;
162072
162431
  }
162432
+ function isStoredSlotPath(context, expression, expected) {
162433
+ const path = memberPath2(expression);
162434
+ if (path === null) return false;
162435
+ const separator = path.lastIndexOf(".");
162436
+ if (separator < 0) return false;
162437
+ const receiver = path.slice(0, separator);
162438
+ const staticClass = context.classesByName.get(receiver);
162439
+ const classId = context.rootValueTargetsByPath.get(receiver)?.classId ?? staticClass?.id;
162440
+ if (classId === void 0) return false;
162441
+ const memberId = classSchemaMemberId(
162442
+ context,
162443
+ classId,
162444
+ path.slice(separator + 1)
162445
+ );
162446
+ const member = memberId === null ? void 0 : context.members.get(memberId);
162447
+ if (member === void 0) return false;
162448
+ if (staticClass !== void 0 && member.modifier !== "static") return false;
162449
+ if (member.kind === "lookup") {
162450
+ if (member.declaredType === null) return false;
162451
+ if (member.multiselect) return false;
162452
+ const storedType = {
162453
+ kind: "reference",
162454
+ nullable: !member.required,
162455
+ target: member.declaredType
162456
+ };
162457
+ return canonicallyEqual(expected.declaredType, storedType);
162458
+ }
162459
+ return member.kind !== "generic" && member.kind !== "computed" && member.kind !== "function" && member.kind !== "scriptFunction";
162460
+ }
162073
162461
  function isSchemaMemberValueRead(context, expression, source) {
162074
162462
  const path = memberPath2(annotatedValue(expression).expression);
162075
162463
  if (path === null) return false;
@@ -165468,7 +165856,8 @@ function lowerRawMemberTypeName(context, memberId) {
165468
165856
  if (member.kind === 8 /* Enum */ && typeof member.enumId === "string") {
165469
165857
  return context.enumNames.get(member.enumId) ?? null;
165470
165858
  }
165471
- if (member.kind === 9 /* Lookup */) return "Reference";
165859
+ if (member.kind === 9 /* Lookup */)
165860
+ return member.selection === 1 /* Multi */ ? "Set" : "Reference";
165472
165861
  if (member.kind === 6 /* List */) return "List";
165473
165862
  if (member.kind === 28 /* Set */) return "Set";
165474
165863
  if (member.kind === 5 /* Dictionary */) return "Dictionary";
@@ -165484,7 +165873,7 @@ function lowerSchemaMemberTypeName(context, member) {
165484
165873
  case "enum":
165485
165874
  return context.enumNames.get(member.enumId) ?? null;
165486
165875
  case "lookup":
165487
- return "Reference";
165876
+ return member.multiselect ? "Set" : "Reference";
165488
165877
  case "list":
165489
165878
  return "List";
165490
165879
  case "set":
@@ -165909,7 +166298,7 @@ function lowerReferences(context, member, expression, ownerValueId, source) {
165909
166298
  }
165910
166299
  const ids = [];
165911
166300
  for (const [index, entry] of elements.entries()) {
165912
- const path = member.kind === "lookup" ? deferredPathSpelling(context, entry) : null;
166301
+ const path = member.kind === "lookup" ? deferredPathSpelling(context, entry, member) : null;
165913
166302
  if (path !== null) {
165914
166303
  ids.push(`${PENDING_ID_PREFIX}reference-index:${source.label}:${index}`);
165915
166304
  context.referenceObligations.push({
@@ -168938,9 +169327,14 @@ function schemaTypeForBindingMember(context, memberId, environment, visited = /*
168938
169327
  if (member.declaredType !== null) {
168939
169328
  if (member.collectionMemberId === null && member.multiselect) {
168940
169329
  return {
168941
- kind: "lookup",
169330
+ kind: "set",
168942
169331
  nullable: nullable2,
168943
- entryType: referenceReadType2(context, member.declaredType)
169332
+ setMemberId: member.id,
169333
+ entryType: {
169334
+ kind: "reference",
169335
+ nullable: false,
169336
+ target: member.declaredType
169337
+ }
168944
169338
  };
168945
169339
  }
168946
169340
  return { kind: "reference", nullable: nullable2, target: member.declaredType };
@@ -170107,10 +170501,10 @@ function unboundReferenceTypeName(context, member, targetId) {
170107
170501
  if (manifestMember.collectionMemberId !== null) return null;
170108
170502
  const declared = manifestMember.declaredType;
170109
170503
  if (declared === null) return null;
170110
- if (declared.kind !== "class" && declared.kind !== "interface" && declared.kind !== "generic") {
170504
+ if (declared.kind !== "interface" && declared.kind !== "generic") {
170111
170505
  return storedTypeArgumentName(context, declared, /* @__PURE__ */ new Map());
170112
170506
  }
170113
- const classId = declared.kind === "class" ? declared.classId : context.values.get(targetId)?.classId;
170507
+ const classId = context.values.get(targetId)?.classId;
170114
170508
  if (typeof classId !== "string") return null;
170115
170509
  return context.manifestClasses.get(classId)?.name ?? null;
170116
170510
  }
@@ -184756,6 +185150,43 @@ var init_export_state = __esm({
184756
185150
  }
184757
185151
  });
184758
185152
 
185153
+ // ../packages/neoscript-language/src/argument-name-completions.ts
185154
+ function argumentNameCompletions(fields, tokens, start, prefixEnd, position) {
185155
+ const edit = argumentNameCompletionEdit(tokens, start, prefixEnd, position);
185156
+ if (!edit) return [];
185157
+ const { range: range2, hasColon } = edit;
185158
+ const items = [];
185159
+ for (const field of fields) {
185160
+ const insertText = hasColon ? field.name : `${field.name}: `;
185161
+ items.push({
185162
+ label: field.name,
185163
+ kind: "property",
185164
+ detail: field.defaultText === void 0 ? field.type : `[${field.type} = ${field.defaultText}]`,
185165
+ insertText,
185166
+ textEdit: { range: range2, newText: insertText }
185167
+ });
185168
+ }
185169
+ return items;
185170
+ }
185171
+ function argumentNameCompletionEdit(tokens, start, prefixEnd, position) {
185172
+ const first = tokens[start];
185173
+ if (prefixEnd > start + 1) return null;
185174
+ if (prefixEnd > start && (!first || !isCallArgumentLabelToken(first)))
185175
+ return null;
185176
+ const editingName = first !== void 0 && isCallArgumentLabelToken(first) && positionCompare(first.range.start, position) <= 0 && positionCompare(position, first.range.end) <= 0;
185177
+ if (first && isCallArgumentLabelToken(first) && !editingName) return null;
185178
+ const hasColon = editingName && tokens[start + 1]?.text === ":";
185179
+ const range2 = editingName ? first.range : { start: position, end: position };
185180
+ return { range: range2, hasColon };
185181
+ }
185182
+ var init_argument_name_completions = __esm({
185183
+ "../packages/neoscript-language/src/argument-name-completions.ts"() {
185184
+ "use strict";
185185
+ init_executable_parser();
185186
+ init_project_source_tokens();
185187
+ }
185188
+ });
185189
+
184759
185190
  // ../packages/neoscript-language/src/tuple-symbols.ts
184760
185191
  function tupleElementSymbol(element, index, alias = false) {
184761
185192
  const location3 = alias ? void 0 : element.labelLocation;
@@ -185169,6 +185600,85 @@ function complete(snapshot, position) {
185169
185600
  items: rankAndDeduplicate(candidates, prefix)
185170
185601
  };
185171
185602
  }
185603
+ function completeFunctionArgument(snapshot, position) {
185604
+ const argument2 = callArgumentAt(snapshot, snapshot.source.offsetAt(position));
185605
+ if (!argument2 || argument2.call.kind === "constructor" || !callSymbol(snapshot, argument2.call))
185606
+ return null;
185607
+ const features = scriptFeatureIndex(snapshot);
185608
+ for (let opener = innermostOpener(features, snapshot.source.offsetAt(position)); opener >= 0 && features.tokens[opener].start > argument2.call.openParenOffset; opener = features.enclosingOpener[opener]) {
185609
+ if (features.tokens[opener].text === "{") return null;
185610
+ }
185611
+ const values = complete(snapshot, position);
185612
+ const names2 = functionArgumentNames(snapshot, position);
185613
+ if (!names2) return values;
185614
+ const offset = snapshot.source.offsetAt(position);
185615
+ const word = wordRangeAt(snapshot.source.text, offset);
185616
+ return {
185617
+ ...values,
185618
+ items: rankAndDeduplicate(
185619
+ names2.onlyNames ? names2.items : [...names2.items, ...values.items],
185620
+ snapshot.source.text.slice(word.start, offset)
185621
+ )
185622
+ };
185623
+ }
185624
+ function functionArgumentNames(snapshot, position) {
185625
+ const offset = snapshot.source.offsetAt(position);
185626
+ if (lambdaBodyAt(snapshot, offset)) return null;
185627
+ const argument2 = callArgumentAt(snapshot, offset);
185628
+ if (argument2?.call.kind !== "function") return null;
185629
+ const { call, index } = argument2;
185630
+ const { tokens } = scriptFeatureIndex(snapshot);
185631
+ const startOffset = call.argumentRanges[index] ? snapshot.source.offsetAt(call.argumentRanges[index].start) : offset;
185632
+ const start = firstIndex(tokens, (token) => token.start >= startOffset);
185633
+ const prefixEnd = firstIndex(tokens, (token) => token.start >= offset);
185634
+ const edit = argumentNameCompletionEdit(tokens, start, prefixEnd, position);
185635
+ if (!edit) return null;
185636
+ const symbol = callSymbol(snapshot, call);
185637
+ if (!symbol?.parameters) return null;
185638
+ const labels = [...call.argumentNames];
185639
+ labels[index] = null;
185640
+ const bound = boundOverloadId(
185641
+ snapshot,
185642
+ snapshot.source.offsetAt(call.nameRange.start),
185643
+ call.name
185644
+ );
185645
+ const overloads = callOverloads(snapshot, call, symbol, bound).map(
185646
+ (overload) => ({ parameters: overload.parameters ?? [] })
185647
+ );
185648
+ const reachable = neoScriptApplicableSignatures(overloads, labels);
185649
+ const fields = /* @__PURE__ */ new Map();
185650
+ for (const { parameters } of reachable) {
185651
+ const used = /* @__PURE__ */ new Set();
185652
+ call.argumentNames.forEach((name, argumentIndex) => {
185653
+ if (argumentIndex === index) return;
185654
+ const parameter4 = neoScriptArgumentParameter(
185655
+ parameters,
185656
+ name,
185657
+ argumentIndex
185658
+ );
185659
+ if (parameter4) used.add(parameter4.name.toLowerCase());
185660
+ });
185661
+ for (const parameter4 of parameters) {
185662
+ const key = parameter4.name.toLowerCase();
185663
+ if (used.has(key) || fields.has(key)) continue;
185664
+ fields.set(key, {
185665
+ name: parameter4.name,
185666
+ type: formatType(parameter4.type, snapshot.project),
185667
+ ...parameter4.defaultValue ? { defaultText: parameter4.defaultValue.displayText } : {}
185668
+ });
185669
+ }
185670
+ }
185671
+ return {
185672
+ items: argumentNameCompletions(
185673
+ [...fields.values()],
185674
+ tokens,
185675
+ start,
185676
+ prefixEnd,
185677
+ position
185678
+ ),
185679
+ onlyNames: edit.hasColon
185680
+ };
185681
+ }
185172
185682
  function hover(snapshot, position) {
185173
185683
  const offset = snapshot.source.offsetAt(position);
185174
185684
  const reference2 = referenceAt(snapshot.parsed.references, offset);
@@ -185274,6 +185784,10 @@ function definition(snapshot, position) {
185274
185784
  ) === index
185275
185785
  );
185276
185786
  }
185787
+ function constructorTypeAt(snapshot, position) {
185788
+ const argument2 = callArgumentAt(snapshot, snapshot.source.offsetAt(position));
185789
+ return argument2?.call.kind === "constructor" ? constructionType(snapshot, argument2.call)?.declaration.name ?? null : null;
185790
+ }
185277
185791
  function signatureHelp(snapshot, position) {
185278
185792
  const argument2 = callArgumentAt(snapshot, snapshot.source.offsetAt(position));
185279
185793
  if (!argument2) return null;
@@ -185670,6 +186184,12 @@ function typeArgumentCount(tokens) {
185670
186184
  }
185671
186185
  return count;
185672
186186
  }
186187
+ function callParametersAt(snapshot, position) {
186188
+ const call = scriptFeatureIndex(snapshot).calls.get(
186189
+ snapshot.source.offsetAt(position)
186190
+ );
186191
+ return call?.kind === "function" ? callSymbol(snapshot, call)?.parameters ?? null : null;
186192
+ }
185673
186193
  function inlayHints(snapshot, range2) {
185674
186194
  const hints = [];
185675
186195
  for (const call of snapshot.parsed.calls) {
@@ -185689,11 +186209,9 @@ function inlayHints(snapshot, range2) {
185689
186209
  if (!argumentRange || !parameterName || call.argumentNames[index]) {
185690
186210
  continue;
185691
186211
  }
185692
- if (obviousParameterName(snapshot, argumentRange, parameterName)) {
185693
- continue;
185694
- }
185695
- const position = firstNonWhitespacePosition(snapshot, argumentRange);
185696
- if (comparePositions(position, argumentRange.end) >= 0) continue;
186212
+ const argument2 = argumentTokenBounds(snapshot, argumentRange);
186213
+ if (!argument2 || obviousParameterName(argument2, parameterName)) continue;
186214
+ const position = argument2.first.range.start;
185697
186215
  if (range2 && !positionInRange(position, range2)) continue;
185698
186216
  hints.push({
185699
186217
  position,
@@ -185718,11 +186236,8 @@ function inlayHints(snapshot, range2) {
185718
186236
  }
185719
186237
  return hints;
185720
186238
  }
185721
- function obviousParameterName(snapshot, argumentRange, parameterName) {
185722
- const start = snapshot.source.offsetAt(argumentRange.start);
185723
- const end = snapshot.source.offsetAt(argumentRange.end);
185724
- const argument2 = snapshot.source.text.slice(start, end).trim();
185725
- return /^[A-Za-z_][A-Za-z0-9_]*$/.test(argument2) && normalizeHintName(argument2) === normalizeHintName(parameterName);
186239
+ function obviousParameterName(argument2, parameterName) {
186240
+ return argument2.first === argument2.last && argument2.first.kind === "identifier" && normalizeHintName(argument2.first.text) === normalizeHintName(parameterName);
185726
186241
  }
185727
186242
  function normalizeHintName(name) {
185728
186243
  return name.replaceAll("_", "").toLocaleLowerCase();
@@ -185758,18 +186273,7 @@ function positionCompare2(left, right) {
185758
186273
  }
185759
186274
  function constructorParameterNames(type2) {
185760
186275
  const declared = type2?.declaredConstructors ?? [];
185761
- if (declared.length > 0) {
185762
- const arity = Math.max(
185763
- ...declared.map((constructor2) => constructor2.parameters.length)
185764
- );
185765
- return Array.from({ length: arity }, (_, index) => {
185766
- const names2 = new Set(
185767
- declared.map((constructor2) => constructor2.parameters[index]?.name)
185768
- );
185769
- const [name] = names2;
185770
- return names2.size === 1 && name ? name : null;
185771
- });
185772
- }
186276
+ if (declared.length > 0) return neoScriptCommonParameterNames(declared);
185773
186277
  return type2?.constructorSignature?.parameters.map((parameter4) => parameter4.name) ?? null;
185774
186278
  }
185775
186279
  function documentSymbols2(snapshot) {
@@ -186731,6 +187235,22 @@ function innermostOpener(features, offset) {
186731
187235
  return token.kind === "punctuation" && (token.text === "(" || token.text === "[" || token.text === "{") ? last : enclosingOpener[last];
186732
187236
  }
186733
187237
  function callSymbol(snapshot, call) {
187238
+ if (call.kind === "expression") {
187239
+ const features = scriptFeatureIndex(snapshot);
187240
+ const open2 = features.tokenIndexes.get(call.openParenOffset);
187241
+ if (open2 === void 0) return void 0;
187242
+ const type2 = inferExpressionType2(
187243
+ expressionTokensBefore(features.tokens, open2),
187244
+ snapshot,
187245
+ call.openParenOffset
187246
+ );
187247
+ return type2.kind === "delegate" ? {
187248
+ id: `delegate:${call.openParenOffset}`,
187249
+ name: "delegate",
187250
+ kind: "local",
187251
+ type: type2
187252
+ } : void 0;
187253
+ }
186734
187254
  const reference2 = scriptFeatureIndex(snapshot).references.get(
186735
187255
  snapshot.source.offsetAt(call.nameRange.start)
186736
187256
  );
@@ -187292,7 +187812,7 @@ function isKnownMemberReceiver(snapshot, receiver) {
187292
187812
  function specializeGenericCall(snapshot, resolved, typeArguments, openParenOffset) {
187293
187813
  if (resolved === null) return null;
187294
187814
  const inferred = openParenOffset === void 0 ? void 0 : flowProbe(snapshot).calls.get(openParenOffset);
187295
- if (inferred !== void 0 && inferred.id === resolved.symbol?.id)
187815
+ if (inferred !== void 0)
187296
187816
  return { type: inferred.returnType ?? inferred.type, symbol: inferred };
187297
187817
  const { symbol } = resolved;
187298
187818
  const parameters = symbol?.typeParameters;
@@ -187743,9 +188263,10 @@ function flowProbe(snapshot) {
187743
188263
  return result;
187744
188264
  const text = snapshot.source.text;
187745
188265
  const source = snapshot.source;
188266
+ const context = snapshot.expressionRange && snapshot.context.kind === "initializerExpression" ? { ...snapshot.context, kind: "function" } : snapshot.context;
187746
188267
  compileNeoScriptStrict(
187747
188268
  { uri: snapshot.uri, languageId: "neoscript", version: 1, text },
187748
- snapshot.context,
188269
+ context,
187749
188270
  {
187750
188271
  emit: false,
187751
188272
  projectIndex: snapshot.project,
@@ -189045,15 +189566,22 @@ function significantTokensBefore(tokens, offset, start = 0) {
189045
189566
  }
189046
189567
  function expressionTokensBefore(tokens, endExclusive) {
189047
189568
  let depth = 0;
189569
+ let groupEnd = -1;
189048
189570
  let start = endExclusive - 1;
189049
189571
  for (; start >= 0; start--) {
189050
189572
  const token = tokens[start];
189051
189573
  if (!token) continue;
189052
- if (token.kind === "punctuation" && [")", "]"].includes(token.text))
189574
+ if (token.kind === "punctuation" && [")", "]"].includes(token.text)) {
189575
+ if (depth === 0) groupEnd = start;
189053
189576
  depth++;
189577
+ }
189054
189578
  if (token.kind === "punctuation" && ["(", "["].includes(token.text)) {
189055
189579
  if (depth > 0) depth--;
189056
189580
  else break;
189581
+ if (depth === 0 && ["if", "while", "for", "foreach"].includes(
189582
+ tokens[start - 1]?.text ?? ""
189583
+ ))
189584
+ return tokens.slice(groupEnd + 1, endExclusive);
189057
189585
  }
189058
189586
  if (depth === 0 && token.kind === "operator" && token.text === ">") {
189059
189587
  const name = genericCallNameIndex(tokens, start);
@@ -189207,14 +189735,16 @@ function boundParameter(parameters, call, index) {
189207
189735
  index
189208
189736
  );
189209
189737
  }
189210
- function firstNonWhitespacePosition(snapshot, range2) {
189738
+ function argumentTokenBounds(snapshot, range2) {
189211
189739
  const start = snapshot.source.offsetAt(range2.start);
189212
189740
  const end = snapshot.source.offsetAt(range2.end);
189213
- let offset = start;
189214
- while (offset < end && /\s/.test(snapshot.source.text[offset] ?? "")) {
189215
- offset++;
189216
- }
189217
- return snapshot.source.positionAt(offset);
189741
+ const tokens = snapshot.lexed.tokens;
189742
+ let first = firstIndex(tokens, (token) => token.start >= start);
189743
+ let last = firstIndex(tokens, (token) => token.start >= end) - 1;
189744
+ while (first <= last && tokens[first].kind === "comment") first++;
189745
+ while (last >= first && tokens[last].kind === "comment") last--;
189746
+ if (first > last || tokens[first]?.kind === "eof") return null;
189747
+ return { first: tokens[first], last: tokens[last] };
189218
189748
  }
189219
189749
  function positionInRange(position, range2) {
189220
189750
  return comparePositions(position, range2.start) >= 0 && comparePositions(position, range2.end) <= 0;
@@ -189232,6 +189762,7 @@ var SCRIPT_FEATURE_INDEX, assumedLambdaInputs, LIST_OPENERS, LIST_CLOSERS, TUPLE
189232
189762
  var init_analyzer = __esm({
189233
189763
  "../packages/neoscript-language/src/analyzer.ts"() {
189234
189764
  "use strict";
189765
+ init_argument_name_completions();
189235
189766
  init_extension_members();
189236
189767
  init_random_contract();
189237
189768
  init_error_contract();
@@ -189336,10 +189867,25 @@ function createContext2(analysis, source) {
189336
189867
  } : {}
189337
189868
  };
189338
189869
  const resolver = new StrictNeoScriptResolver(context, project);
189870
+ const parameterContexts = /* @__PURE__ */ new Map();
189339
189871
  const parameterResolvers = /* @__PURE__ */ new Map();
189872
+ function parameterContext(constructorIndex) {
189873
+ const key = constructorIndex ?? -1;
189874
+ const cached = parameterContexts.get(key);
189875
+ if (cached) return cached;
189876
+ const declared = constructorIndex === void 0 ? source?.headerParameters : source?.constructors[constructorIndex]?.parameters;
189877
+ const parameters = declared?.flatMap((parameter4) => {
189878
+ const type2 = resolveSourceType(parameter4.type, context, project);
189879
+ return type2 ? [{ name: parameter4.name, type: type2 }] : [];
189880
+ });
189881
+ const created = parameters?.length ? { ...context, parameters } : context;
189882
+ parameterContexts.set(key, created);
189883
+ return created;
189884
+ }
189340
189885
  return {
189341
189886
  context,
189342
189887
  project,
189888
+ parameterContext,
189343
189889
  provide: createListenerAnnotationProvider(project, context),
189344
189890
  resolver,
189345
189891
  /**
@@ -189352,14 +189898,8 @@ function createContext2(analysis, source) {
189352
189898
  const key = constructorIndex ?? -1;
189353
189899
  const cached = parameterResolvers.get(key);
189354
189900
  if (cached) return cached;
189355
- const declared = constructorIndex === void 0 ? source?.headerParameters : source?.constructors[constructorIndex]?.parameters;
189356
- const parameters = declared?.flatMap(
189357
- (parameter4) => {
189358
- const type2 = resolveSourceType(parameter4.type, context, project);
189359
- return type2 ? [{ name: parameter4.name, type: type2 }] : [];
189360
- }
189361
- );
189362
- const created = parameters?.length ? new StrictNeoScriptResolver({ ...context, parameters }, project) : resolver;
189901
+ const scoped = parameterContext(constructorIndex);
189902
+ const created = scoped !== context ? new StrictNeoScriptResolver(scoped, project) : resolver;
189363
189903
  parameterResolvers.set(key, created);
189364
189904
  return created;
189365
189905
  }
@@ -189367,9 +189907,17 @@ function createContext2(analysis, source) {
189367
189907
  }
189368
189908
  function listenerSourceContext(analysis, document, position) {
189369
189909
  const source = analysis.documents.get(document.uri);
189370
- const declaring = source?.declarations.find(
189371
- (declaration) => declaration.kind === "class" && rangeContains(declaration.range, position)
189372
- );
189910
+ const declarations = source?.declarations ?? [];
189911
+ let low = 0;
189912
+ let high = declarations.length;
189913
+ while (low < high) {
189914
+ const middle = low + high >>> 1;
189915
+ if (positionCompare(declarations[middle].range.end, position) < 0)
189916
+ low = middle + 1;
189917
+ else high = middle;
189918
+ }
189919
+ const candidate = declarations[low];
189920
+ const declaring = candidate?.kind === "class" && rangeContains(candidate.range, position) ? candidate : void 0;
189373
189921
  const name = declaring?.name;
189374
189922
  let contexts = CONTEXTS.get(analysis);
189375
189923
  if (!contexts) {
@@ -189600,6 +190148,224 @@ var init_project_listener_annotations = __esm({
189600
190148
  }
189601
190149
  });
189602
190150
 
190151
+ // ../packages/neoscript-language/src/project-annotation-path-completions.ts
190152
+ function annotationSchemaPathCompletions(analysis, document, position, site, field, tokens, next) {
190153
+ const kind = annotationSchemaPathKind(site.annotation.name, field);
190154
+ if (!kind) return null;
190155
+ const entryMember = kind === "member";
190156
+ const collection = kind === "collection";
190157
+ const atCursor = projectTokenAt(document, position);
190158
+ if (atCursor?.kind === "comment" || atCursor?.kind === "string") return [];
190159
+ if (next && positionCompare(position, next.range.start) < 0 && ![",", ")"].includes(next.text))
190160
+ return [];
190161
+ const { context, project } = listenerSourceContext(
190162
+ analysis,
190163
+ document,
190164
+ position
190165
+ );
190166
+ const targetType = annotationTargetType(site, context, project);
190167
+ let receiver;
190168
+ let word;
190169
+ if (entryMember) {
190170
+ if (tokens.length > 1) return [];
190171
+ receiver = targetType ? neoScriptMemberLookupType(targetType) : void 0;
190172
+ word = tokens[0];
190173
+ } else {
190174
+ if (tokens.length > 3) return [];
190175
+ if (tokens.length >= 2) {
190176
+ if (tokens[1]?.text !== ".") return [];
190177
+ const owner = project.typeByName.get(tokens[0].text);
190178
+ if (!owner || owner.kind !== "class") return [];
190179
+ receiver = { kind: "named", typeId: owner.id };
190180
+ word = tokens[2];
190181
+ } else {
190182
+ word = tokens[0];
190183
+ }
190184
+ }
190185
+ if (word && word.kind !== "identifier" && word.kind !== "type") return [];
190186
+ if (word && positionCompare(word.range.end, position) < 0) return [];
190187
+ const editingWord = word ?? (atCursor?.kind === "identifier" || atCursor?.kind === "type" ? atCursor : void 0);
190188
+ const range2 = editingWord?.range ?? { start: position, end: position };
190189
+ const sources2 = entryMember && site.annotation.name === "index" ? sourceMembers(analysis) : null;
190190
+ const enums = {
190191
+ has: (name) => project.typeByName.get(name)?.kind === "enum"
190192
+ };
190193
+ const isClass = (value) => {
190194
+ const bound = neoScriptMemberLookupType(value);
190195
+ return bound.kind === "named" && project.typeById.get(bound.typeId)?.kind === "class";
190196
+ };
190197
+ const eligible = (symbol, type2) => {
190198
+ if (symbol.static || symbol.kind !== "field" && symbol.kind !== "property")
190199
+ return false;
190200
+ if (entryMember && site.annotation.name === "index") {
190201
+ const source = symbol.selectionLocation;
190202
+ const member = source ? sources2?.get(locationKey2(source.uri, source.range.start)) : void 0;
190203
+ if (!member) return false;
190204
+ let name = type2.kind;
190205
+ if (type2.kind === "primitive") name = type2.name;
190206
+ else if (type2.kind === "named")
190207
+ name = project.typeById.get(type2.typeId)?.name ?? type2.typeId;
190208
+ return indexKeyDomainError(member, { name }, enums) === null;
190209
+ }
190210
+ if (!collection) return true;
190211
+ const entry = collectionElement(type2);
190212
+ if (!entry) return false;
190213
+ if (!targetType) return true;
190214
+ const classes = isClass(targetType) && isClass(entry);
190215
+ return isNeoScriptTypeAssignable(
190216
+ { ...classes ? targetType : entry, nullable: false },
190217
+ { ...classes ? entry : targetType, nullable: false },
190218
+ project
190219
+ );
190220
+ };
190221
+ const items = [];
190222
+ if (receiver?.kind === "named") {
190223
+ const owner = project.typeById.get(receiver.typeId);
190224
+ if (!owner) return [];
190225
+ for (const symbol of owner.members) {
190226
+ const type2 = substituteTypeParameters(
190227
+ symbol.type,
190228
+ receiver,
190229
+ owner,
190230
+ project
190231
+ );
190232
+ if (!eligible(symbol, type2)) continue;
190233
+ items.push({
190234
+ label: symbol.name,
190235
+ kind: "property",
190236
+ detail: formatType(type2, project),
190237
+ symbolId: symbol.id,
190238
+ insertText: symbol.name,
190239
+ textEdit: { range: range2, newText: symbol.name }
190240
+ });
190241
+ }
190242
+ } else if (!entryMember) {
190243
+ for (const owner of project.typeById.values()) {
190244
+ if (owner.kind !== "class" || !owner.location) continue;
190245
+ if (!owner.members.some((member) => eligible(member, member.type)))
190246
+ continue;
190247
+ items.push({
190248
+ label: owner.name,
190249
+ kind: "class",
190250
+ insertText: owner.name,
190251
+ textEdit: { range: range2, newText: owner.name }
190252
+ });
190253
+ }
190254
+ }
190255
+ if (entryMember && site.annotation.name === "column") {
190256
+ items.push({
190257
+ label: "__other__",
190258
+ kind: "property",
190259
+ detail: "Inherited columns",
190260
+ insertText: "__other__",
190261
+ textEdit: { range: range2, newText: "__other__" }
190262
+ });
190263
+ }
190264
+ return items;
190265
+ }
190266
+ function annotationSchemaPathKind(annotation2, field) {
190267
+ if (field === "member" && (annotation2 === "index" || annotation2 === "column"))
190268
+ return "member";
190269
+ if (annotation2 === "settings" && (field === "collection" || field === "target"))
190270
+ return field;
190271
+ return null;
190272
+ }
190273
+ function annotationTargetType(site, context, project) {
190274
+ const declared = site.type ? resolveSourceType(site.type, context, project) : null;
190275
+ const resolved = declared?.kind === "reference" ? declared.target : declared;
190276
+ return resolved ? collectionElement(resolved) ?? resolved : null;
190277
+ }
190278
+ function annotationSchemaPathTarget(analysis, document, token, site) {
190279
+ const argumentIndex = site.annotation.arguments.findIndex(
190280
+ (argument3) => rangeContains(argument3.range, token.range.start)
190281
+ );
190282
+ const argument2 = site.annotation.arguments[argumentIndex];
190283
+ if (!argument2) return void 0;
190284
+ const field = argument2.name ?? site.fields[argumentIndex]?.name;
190285
+ const kind = field && annotationSchemaPathKind(site.annotation.name, field);
190286
+ if (!kind) return void 0;
190287
+ const allTokens = projectTokens(document);
190288
+ const tokens = [];
190289
+ for (let index = projectTokenIndexAt(document, argument2.range.start); index < allTokens.length; index++) {
190290
+ const current = allTokens[index];
190291
+ if (positionCompare(current.range.start, argument2.range.end) >= 0) break;
190292
+ if (current.kind !== "comment") tokens.push(current);
190293
+ }
190294
+ if (tokens[1]?.text === ":") tokens.splice(0, 2);
190295
+ const { context, project } = listenerSourceContext(
190296
+ analysis,
190297
+ document,
190298
+ token.range.start
190299
+ );
190300
+ let receiver;
190301
+ if (kind === "member") {
190302
+ if (tokens.length !== 1 || tokens[0] !== token || site.annotation.name === "column" && token.text === "__other__")
190303
+ return null;
190304
+ receiver = annotationTargetType(site, context, project);
190305
+ } else {
190306
+ const owner2 = project.typeByName.get(tokens[0]?.text ?? "");
190307
+ if (!owner2 || owner2.kind !== "class") return null;
190308
+ if (tokens[0] === token) return owner2;
190309
+ if (tokens.length !== 3 || tokens[1]?.text !== "." || tokens[2] !== token)
190310
+ return null;
190311
+ receiver = { kind: "named", typeId: owner2.id };
190312
+ }
190313
+ if (!receiver) return null;
190314
+ const bound = neoScriptMemberLookupType(receiver);
190315
+ const owner = bound.kind === "named" ? project.typeById.get(bound.typeId) : void 0;
190316
+ return owner ? schemaMembers(owner).get(token.text) ?? null : null;
190317
+ }
190318
+ function schemaMembers(owner) {
190319
+ const cached = SCHEMA_MEMBERS.get(owner);
190320
+ if (cached) return cached;
190321
+ const members2 = /* @__PURE__ */ new Map();
190322
+ for (const member of owner.members) {
190323
+ if (member.static || member.kind !== "field" && member.kind !== "property")
190324
+ continue;
190325
+ if (!members2.has(member.name)) members2.set(member.name, member);
190326
+ }
190327
+ SCHEMA_MEMBERS.set(owner, members2);
190328
+ return members2;
190329
+ }
190330
+ function collectionElement(type2) {
190331
+ if (type2.kind === "list" || type2.kind === "set") return type2.elementType;
190332
+ if (type2.kind === "dictionary") return type2.valueType;
190333
+ return null;
190334
+ }
190335
+ function sourceMembers(analysis) {
190336
+ let members2 = SOURCE_MEMBERS.get(analysis);
190337
+ if (!members2) {
190338
+ const result = /* @__PURE__ */ new Map();
190339
+ for (const [uri, document] of analysis.documents) {
190340
+ for (const declaration of document.declarations) {
190341
+ if (declaration.kind === "global" || declaration.kind === "enum")
190342
+ continue;
190343
+ for (const member of declaration.members)
190344
+ result.set(locationKey2(uri, member.nameRange.start), member);
190345
+ }
190346
+ }
190347
+ members2 = result;
190348
+ SOURCE_MEMBERS.set(analysis, members2);
190349
+ }
190350
+ return members2;
190351
+ }
190352
+ function locationKey2(uri, position) {
190353
+ return `${uri}:${position.line}:${position.character}`;
190354
+ }
190355
+ var SCHEMA_MEMBERS, SOURCE_MEMBERS;
190356
+ var init_project_annotation_path_completions = __esm({
190357
+ "../packages/neoscript-language/src/project-annotation-path-completions.ts"() {
190358
+ "use strict";
190359
+ init_project_source_semantics();
190360
+ init_project_listener_annotations();
190361
+ init_project_source_tokens();
190362
+ init_project2();
190363
+ init_type_substitution();
190364
+ SCHEMA_MEMBERS = /* @__PURE__ */ new WeakMap();
190365
+ SOURCE_MEMBERS = /* @__PURE__ */ new WeakMap();
190366
+ }
190367
+ });
190368
+
189603
190369
  // ../packages/neoscript-language/src/project-source-lifecycle-editor.ts
189604
190370
  function projectLifecycleHooks(analysis) {
189605
190371
  let hooks = PROJECT_LIFECYCLE_HOOKS.get(analysis);
@@ -190062,6 +190828,9 @@ function projectDiagnostics(analysis, uri) {
190062
190828
  }));
190063
190829
  }
190064
190830
  function projectCompletions(analysis, document, position) {
190831
+ if (projectTokenAt(document, position)?.kind === "comment") {
190832
+ return { isIncomplete: false, items: [] };
190833
+ }
190065
190834
  const variantPathInBody = projectVariantPathCompletions(
190066
190835
  analysis,
190067
190836
  document,
@@ -190078,9 +190847,16 @@ function projectCompletions(analysis, document, position) {
190078
190847
  const body = projectBodySnapshotAt(analysis, document, position);
190079
190848
  if (body) {
190080
190849
  const script = complete(body, position);
190081
- return variantScopeInBody === null ? script : {
190850
+ const names2 = projectConstructorArgumentCompletions(
190851
+ analysis,
190852
+ document,
190853
+ position,
190854
+ body
190855
+ );
190856
+ const items = names2?.length ? [...names2, ...script.items] : script.items;
190857
+ return variantScopeInBody === null ? { ...script, items } : {
190082
190858
  ...script,
190083
- items: [...script.items, variantScopeInBody]
190859
+ items: [...items, variantScopeInBody]
190084
190860
  };
190085
190861
  }
190086
190862
  const groupMembers = dialogueGroupCompletions(analysis, document, position);
@@ -190109,6 +190885,25 @@ function projectCompletions(analysis, document, position) {
190109
190885
  const targets = listenerHandlerCompletions(listener, document);
190110
190886
  if (targets) return { isIncomplete: false, items: targets };
190111
190887
  }
190888
+ const source = analysis.documents.get(document.uri);
190889
+ const annotationSite = source ? contextualAnnotationSite(source, position) : null;
190890
+ if (annotationSite) {
190891
+ const schemaPath = projectAnnotationSchemaCompletions(
190892
+ analysis,
190893
+ document,
190894
+ position,
190895
+ annotationSite
190896
+ );
190897
+ if (schemaPath !== null) return { isIncomplete: false, items: schemaPath };
190898
+ }
190899
+ const expression = projectExpressionSnapshotAt(
190900
+ analysis,
190901
+ document,
190902
+ position,
190903
+ annotationSite
190904
+ );
190905
+ const argument2 = expression && completeFunctionArgument(expression.snapshot, position);
190906
+ if (argument2) return argument2;
190112
190907
  const builtinMembers = projectBuiltinStaticMemberCompletions(
190113
190908
  document,
190114
190909
  position
@@ -190119,6 +190914,18 @@ function projectCompletions(analysis, document, position) {
190119
190914
  items: builtinMembers.map(projectBuiltinCompletionItem)
190120
190915
  };
190121
190916
  }
190917
+ const expressionMembers = projectExpressionMemberCompletions(
190918
+ analysis,
190919
+ document,
190920
+ position,
190921
+ annotationSite
190922
+ );
190923
+ if (expressionMembers) {
190924
+ return variantScopeInBody === null ? expressionMembers : {
190925
+ ...expressionMembers,
190926
+ items: [...expressionMembers.items, variantScopeInBody]
190927
+ };
190928
+ }
190122
190929
  const members2 = projectMemberCompletions(analysis, document, position);
190123
190930
  const variantScope = variantScopeInBody;
190124
190931
  if (members2 || variantScope) {
@@ -190153,43 +190960,16 @@ function projectCompletions(analysis, document, position) {
190153
190960
  }))
190154
190961
  };
190155
190962
  }
190156
- const source = analysis.documents.get(document.uri);
190157
- const annotationFields = source ? contextualAnnotationFields(source, position) : null;
190963
+ const annotationFields = annotationSite?.fields;
190158
190964
  if (annotationFields) {
190159
- const activeOption = activeNamedArgument(document.text, position);
190160
- const activeField = activeOption ? annotationFields.find((field) => field.name === activeOption) : void 0;
190161
- const activeArgument = activeOption ?? activeAnnotationArgumentName(document.text, position);
190162
- if (activeArgument === NEO_VARIANT_FOLDER_SETTING && source) {
190163
- const folders = projectVariantFolderCompletions(
190164
- analysis,
190165
- source,
190166
- position
190167
- );
190168
- if (folders) return { isIncomplete: false, items: folders };
190169
- }
190170
- const enumCases = activeField ? generatedContractEnumCases(activeField.type) : null;
190171
- if (enumCases) {
190172
- return {
190173
- isIncomplete: false,
190174
- items: enumCases.map((name) => ({
190175
- label: `.${name}`,
190176
- kind: "enumMember",
190177
- ...activeField ? { detail: activeField.type } : {},
190178
- // The active-option matcher requires the contextual dot to have
190179
- // already been authored. VS Code replaces only the identifier word,
190180
- // so inserting another dot would produce `..Option`.
190181
- insertText: name
190182
- }))
190183
- };
190184
- }
190185
190965
  return {
190186
190966
  isIncomplete: false,
190187
- items: annotationFields.map((field) => ({
190188
- label: field.name,
190189
- kind: "property",
190190
- detail: field.type,
190191
- insertText: `${field.name}: `
190192
- }))
190967
+ items: projectAnnotationArgumentCompletions(
190968
+ analysis,
190969
+ document,
190970
+ position,
190971
+ annotationFields
190972
+ )
190193
190973
  };
190194
190974
  }
190195
190975
  const contextualEnum = projectContextualEnumCompletions(
@@ -190200,22 +190980,15 @@ function projectCompletions(analysis, document, position) {
190200
190980
  if (contextualEnum) {
190201
190981
  return { isIncomplete: false, items: contextualEnum };
190202
190982
  }
190203
- const constructorFields = projectConstructorArgumentCompletions(
190983
+ const constructorNames = projectConstructorArgumentCompletions(
190204
190984
  analysis,
190205
190985
  document,
190206
190986
  position
190207
190987
  );
190208
- if (constructorFields) {
190988
+ if (constructorNames) {
190209
190989
  return {
190210
190990
  isIncomplete: false,
190211
- items: constructorFields.map((field) => ({
190212
- label: field.name,
190213
- kind: "property",
190214
- // P65 §6. C#-style square brackets mark a defaulted parameter as
190215
- // omittable at the call site.
190216
- detail: field.defaultText === void 0 ? field.type : `[${field.type} = ${field.defaultText}]`,
190217
- insertText: `${field.name}: `
190218
- }))
190991
+ items: constructorNames
190219
190992
  };
190220
190993
  }
190221
190994
  const initializerMembers = projectInitializerMemberCompletions(
@@ -190278,7 +191051,12 @@ function projectAnnotationCompletions(analysis, document, position) {
190278
191051
  return ["id", "listeners"].map((name) => ({
190279
191052
  label: `@${name}`,
190280
191053
  kind: "snippet",
190281
- insertText: name
191054
+ insertText: name,
191055
+ filterText: name,
191056
+ textEdit: {
191057
+ range: source.range(word.start, word.end),
191058
+ newText: name
191059
+ }
190282
191060
  }));
190283
191061
  }
190284
191062
  const names2 = projectAnnotationNamesAt(analysis, document, position);
@@ -190286,6 +191064,7 @@ function projectAnnotationCompletions(analysis, document, position) {
190286
191064
  label: `@${name}`,
190287
191065
  kind: "snippet",
190288
191066
  insertText: name,
191067
+ filterText: name,
190289
191068
  textEdit: {
190290
191069
  range: source.range(word.start, word.end),
190291
191070
  newText: name
@@ -190347,7 +191126,8 @@ function projectDeclarationAnnotationNames(declaration) {
190347
191126
  function projectMemberAnnotationNames(member) {
190348
191127
  const names2 = ["id", "settings", "storage", "distribution"];
190349
191128
  if (member?.kind === "function") names2.push("effect");
190350
- if (member?.type.name === "List") names2.push("index", "column");
191129
+ if (member?.type.name === "List" || member?.type.name === "Set")
191130
+ names2.push("index", "column");
190351
191131
  return names2;
190352
191132
  }
190353
191133
  function projectContextualEnumCompletions(analysis, document, position) {
@@ -190639,6 +191419,85 @@ function projectBodyIndex(analysis, context) {
190639
191419
  }
190640
191420
  return index;
190641
191421
  }
191422
+ function projectExpressionMemberCompletions(analysis, document, position, annotationSite) {
191423
+ const source = projectSourceText(document);
191424
+ const offset = source.offsetAt(position);
191425
+ const word = projectWordRange(document.text, offset);
191426
+ const before = tokensBeforePosition(
191427
+ projectSignificantTokens(analysis, document),
191428
+ source.positionAt(word.start)
191429
+ );
191430
+ const dot = before.at(-1);
191431
+ if (dot?.text !== "." && dot?.text !== "?.") return null;
191432
+ const receiver = before.at(-2);
191433
+ if (!receiver || !(receiver.kind === "identifier" || receiver.kind === "type" || [")", "]", ">", "!", "this", "base", "root"].includes(receiver.text)))
191434
+ return null;
191435
+ const expression = projectExpressionSnapshotAt(
191436
+ analysis,
191437
+ document,
191438
+ dot.range.start,
191439
+ annotationSite,
191440
+ true
191441
+ );
191442
+ if (!expression) return null;
191443
+ const result = complete(expression.snapshot, position);
191444
+ return expression.bounded || result.items.length > 0 ? result : null;
191445
+ }
191446
+ function projectExpressionSnapshotAt(analysis, document, position, annotationSite = null, recover = false) {
191447
+ const source = projectSourceText(document);
191448
+ const root = initializerRootAt(analysis, document, position);
191449
+ const argument2 = annotationSite?.annotation.arguments.find(
191450
+ (argument3) => rangeContains(argument3.range, position)
191451
+ );
191452
+ const range2 = argument2?.range ?? root?.range;
191453
+ if (!range2 && !recover) return null;
191454
+ const cached = range2 && PROJECT_EXPRESSION_SNAPSHOT_CACHE.get(analysis)?.get(document)?.get(range2);
191455
+ if (cached) return { snapshot: cached, bounded: true };
191456
+ const language = listenerSourceContext(analysis, document, position);
191457
+ const staticField = root?.slot.kind === "declared" && root.slot.field?.static;
191458
+ let context = argument2 ? language.context : language.parameterContext(root?.constructorIndex);
191459
+ if (staticField) {
191460
+ const { thisClass: _thisClass, ...staticContext } = language.context;
191461
+ context = { ...staticContext, staticMember: true };
191462
+ }
191463
+ const key = range2 ?? context;
191464
+ let documents = PROJECT_EXPRESSION_SNAPSHOT_CACHE.get(analysis);
191465
+ if (!documents) {
191466
+ documents = /* @__PURE__ */ new WeakMap();
191467
+ PROJECT_EXPRESSION_SNAPSHOT_CACHE.set(analysis, documents);
191468
+ }
191469
+ let snapshots = documents.get(document);
191470
+ if (!snapshots) {
191471
+ snapshots = /* @__PURE__ */ new WeakMap();
191472
+ documents.set(document, snapshots);
191473
+ }
191474
+ let snapshot = snapshots.get(key);
191475
+ if (!snapshot) {
191476
+ const initialStart = range2 ? source.offsetAt(range2.start) : 0;
191477
+ let start = initialStart;
191478
+ const end = range2 ? source.offsetAt(range2.end) : document.text.length;
191479
+ const lexed = analysis.documents.get(document.uri)?.syntax ?? lex(document.text);
191480
+ let sliced = sliceLexResult(lexed, start, end);
191481
+ const tokens = sliced.tokens.filter((token) => token.kind !== "comment");
191482
+ if (tokens[1]?.text === ":" || tokens[1]?.text === "=")
191483
+ start = tokens[1].end;
191484
+ else if (tokens[0]?.text === ":" || tokens[0]?.text === "=")
191485
+ start = tokens[0].end;
191486
+ if (start !== initialStart) sliced = sliceLexResult(lexed, start, end);
191487
+ const syntax = analyzeNeoScriptSyntax(document.text, context.kind, sliced);
191488
+ snapshot = {
191489
+ uri: document.uri,
191490
+ expressionRange: source.range(start, end),
191491
+ source: syntax.lexed.source,
191492
+ lexed: syntax.lexed,
191493
+ parsed: syntax.parsed,
191494
+ context,
191495
+ project: projectBodyIndex(analysis, context)
191496
+ };
191497
+ snapshots.set(key, snapshot);
191498
+ }
191499
+ return { snapshot, bounded: range2 !== void 0 };
191500
+ }
190642
191501
  function projectWordRange(text, offset) {
190643
191502
  let start = offset;
190644
191503
  while (start > 0 && /[A-Za-z0-9_]/.test(text[start - 1] ?? "")) start--;
@@ -190851,37 +191710,202 @@ function projectBuiltinSymbolSignature(symbol) {
190851
191710
  }
190852
191711
  return `${formatType(symbol.type)} ${symbol.name}`;
190853
191712
  }
190854
- function projectConstructorArgumentCompletions(analysis, document, position) {
191713
+ function projectAnnotationSchemaCompletions(analysis, document, position, site) {
191714
+ const documentTokens = projectSignificantTokens(analysis, document);
191715
+ const tokens = tokensBeforePosition(documentTokens, position);
191716
+ const openIndex = activeCallOpenIndex(tokens, position);
191717
+ if (openIndex < 0 || tokens[openIndex - 2]?.text !== "@") return null;
191718
+ const active = activeCallArgument(tokens, openIndex, position);
191719
+ if (active.label === null && callArgumentLabel(documentTokens, active.start, documentTokens.length) !== null)
191720
+ return null;
191721
+ const field = active.label === null ? site.fields[active.index] : site.fields.find((field2) => field2.name === active.label);
191722
+ if (!field) return null;
191723
+ const start = active.start + (active.label === null ? 0 : 2);
191724
+ if (active.label === null && start === tokens.length) return null;
191725
+ const items = annotationSchemaPathCompletions(
191726
+ analysis,
191727
+ document,
191728
+ position,
191729
+ site,
191730
+ field.name,
191731
+ documentTokens.slice(start, tokens.length),
191732
+ documentTokens[tokens.length]
191733
+ );
191734
+ if (items === null || active.label !== null) return items;
191735
+ return [
191736
+ ...items,
191737
+ ...projectAnnotationArgumentCompletions(
191738
+ analysis,
191739
+ document,
191740
+ position,
191741
+ site.fields
191742
+ )
191743
+ ];
191744
+ }
191745
+ function projectAnnotationArgumentCompletions(analysis, document, position, fields) {
191746
+ const documentTokens = projectSignificantTokens(analysis, document);
191747
+ const tokens = tokensBeforePosition(documentTokens, position);
191748
+ const openIndex = activeCallOpenIndex(tokens, position);
191749
+ if (openIndex < 0 || tokens[openIndex - 2]?.text !== "@") return [];
191750
+ const active = activeCallArgument(tokens, openIndex, position);
191751
+ let valueItems = [];
191752
+ const named = callArgumentLabel(
191753
+ documentTokens,
191754
+ active.start,
191755
+ documentTokens.length
191756
+ );
191757
+ if (active.label !== null || named === null) {
191758
+ const field = active.label === null ? fields[active.index] : fields.find((field2) => field2.name === active.label);
191759
+ const start = active.start + (active.label === null ? 0 : 2);
191760
+ if (field && (active.label !== null || start < tokens.length)) {
191761
+ const values = projectAnnotationValueCompletions(
191762
+ analysis,
191763
+ document,
191764
+ position,
191765
+ documentTokens,
191766
+ tokens,
191767
+ start,
191768
+ field
191769
+ );
191770
+ if (values !== null) {
191771
+ if (active.label !== null || tokens[start]?.text === ".") return values;
191772
+ valueItems = values;
191773
+ }
191774
+ }
191775
+ }
191776
+ if (active.label !== null) return valueItems;
191777
+ const first = documentTokens[active.start];
191778
+ if (tokens.length > active.start + 1) return valueItems;
191779
+ if (tokens.length > active.start && (!first || !isCallArgumentLabelToken(first)))
191780
+ return valueItems;
191781
+ const used = /* @__PURE__ */ new Set();
191782
+ const args = projectCallArguments(documentTokens, openIndex);
191783
+ for (let index = 0; index < args.length; index++) {
191784
+ const argument2 = args[index];
191785
+ if (first && positionCompare(argument2.start, first.range.start) === 0) {
191786
+ continue;
191787
+ }
191788
+ const name = argument2.name ?? fields[index]?.name;
191789
+ if (name !== void 0) used.add(name);
191790
+ }
191791
+ return [
191792
+ ...argumentNameCompletions(
191793
+ fields.filter((field) => !used.has(field.name)).map((field) => ({
191794
+ ...field,
191795
+ type: formatAnnotationValueType(field.type)
191796
+ })),
191797
+ documentTokens,
191798
+ active.start,
191799
+ tokens.length,
191800
+ position
191801
+ ),
191802
+ ...valueItems
191803
+ ];
191804
+ }
191805
+ function projectAnnotationValueCompletions(analysis, document, position, documentTokens, tokens, start, field) {
191806
+ const dot = tokens[start]?.text === ".";
191807
+ const wordIndex = start + (dot ? 1 : 0);
191808
+ if (tokens.length > wordIndex + 1) return [];
191809
+ const word = documentTokens[wordIndex];
191810
+ const isWord = word?.kind === "identifier" || word?.text === "true" || word?.text === "false";
191811
+ const editingWord = isWord && positionCompare(word.range.start, position) <= 0 && positionCompare(position, word.range.end) <= 0;
191812
+ if (tokens.length > wordIndex && !editingWord) return [];
191813
+ if (word && !editingWord && ![",", ")"].includes(word.text)) return [];
191814
+ const atCursor = projectTokenAt(document, position);
191815
+ if (atCursor?.kind === "comment" || atCursor?.kind === "string") return [];
191816
+ const range2 = editingWord ? word.range : { start: position, end: position };
191817
+ const enumCases = generatedContractEnumCases(field.type);
191818
+ if (enumCases) {
191819
+ return enumCases.map((name) => {
191820
+ const insertText = dot ? name : `.${name}`;
191821
+ return {
191822
+ label: `.${name}`,
191823
+ kind: "enumMember",
191824
+ detail: field.type,
191825
+ filterText: name,
191826
+ insertText,
191827
+ textEdit: { range: range2, newText: insertText }
191828
+ };
191829
+ });
191830
+ }
191831
+ if (dot) return [];
191832
+ if (field.type === "bool" || field.type === "bool?") {
191833
+ return ["true", "false"].map((name) => ({
191834
+ label: name,
191835
+ kind: "keyword",
191836
+ detail: field.type,
191837
+ insertText: name,
191838
+ textEdit: { range: range2, newText: name }
191839
+ }));
191840
+ }
191841
+ if (field.name === NEO_VARIANT_FOLDER_SETTING) {
191842
+ const source = analysis.documents.get(document.uri);
191843
+ const folders = source ? projectVariantFolderCompletions(analysis, source, position) : null;
191844
+ if (folders)
191845
+ return folders.map((item) => ({
191846
+ ...item,
191847
+ textEdit: { range: range2, newText: item.insertText ?? item.label }
191848
+ }));
191849
+ }
191850
+ return null;
191851
+ }
191852
+ function projectConstructorArgumentCompletions(analysis, document, position, body) {
190855
191853
  const documentTokens = projectSignificantTokens(analysis, document);
190856
191854
  const tokens = tokensBeforePosition(documentTokens, position);
190857
191855
  const openIndex = activeCallOpenIndex(tokens, position);
190858
191856
  if (openIndex < 0) return null;
190859
- const callee = tokens[openIndex - 1];
191857
+ const calleeIndex = projectCallCalleeIndex(tokens, openIndex);
191858
+ const callee = tokens[calleeIndex];
190860
191859
  if (!callee) return null;
190861
- const beforeCallee = tokens[openIndex - 2];
190862
- const typeName = callee.text === "Pause" ? "Pause" : beforeCallee?.text === "new" ? callee.text : callee.text === "new" ? contextualConstructorType(analysis, document, callee.range.start) : null;
191860
+ const beforeCallee = tokens[calleeIndex - 1];
191861
+ const constructorType = body ? constructorTypeAt(body, position) : projectConstructorTypeName(analysis, document, callee, beforeCallee);
191862
+ const typeName = callee.text === "Pause" ? "Pause" : constructorType;
190863
191863
  if (!typeName) return null;
190864
191864
  const active = activeCallArgument(tokens, openIndex, position);
190865
191865
  if (active.label !== null) return null;
190866
- const activeStart = documentTokens[active.start]?.range.start;
190867
- const used = /* @__PURE__ */ new Set();
190868
- for (const { name, start } of projectCallArguments(
191866
+ const args = projectCallArguments(documentTokens, openIndex);
191867
+ const builtin = lookupVariantFolderArgumentFields(typeName) ?? graphConstructorNamedArguments(typeName);
191868
+ const fields = builtin ? unusedConstructorArguments(builtin, args, active.index) : declaredConstructorNamedArguments(analysis, typeName, args, active.index);
191869
+ if (!fields) return null;
191870
+ return argumentNameCompletions(
191871
+ fields,
190869
191872
  documentTokens,
190870
- openIndex
190871
- )) {
190872
- if (name !== null && !(activeStart && positionCompare(start, activeStart) === 0)) {
190873
- used.add(name);
190874
- }
191873
+ active.start,
191874
+ tokens.length,
191875
+ position
191876
+ );
191877
+ }
191878
+ function projectCallCalleeIndex(tokens, openIndex) {
191879
+ if (!/^>+$/.test(tokens[openIndex - 1]?.text ?? "")) return openIndex - 1;
191880
+ let depth = 0;
191881
+ for (let index = openIndex - 1; index >= 0; index--) {
191882
+ const token = tokens[index];
191883
+ if (/^>+$/.test(token.text)) depth += token.text.length;
191884
+ else if (token.text === "<") {
191885
+ if (--depth === 0)
191886
+ return callOpenParenIndex(tokens, index - 1) === openIndex ? index - 1 : -1;
191887
+ } else if (!isCallTypeArgumentToken(token)) return -1;
190875
191888
  }
190876
- const fields = lookupVariantFolderArgumentFields(typeName) ?? graphConstructorNamedArguments(typeName) ?? declaredConstructorNamedArguments(analysis, typeName, used);
190877
- if (!fields) return null;
190878
- return fields.filter((field) => !used.has(field.name));
191889
+ return -1;
191890
+ }
191891
+ function unusedConstructorArguments(fields, args, activeIndex) {
191892
+ const used = /* @__PURE__ */ new Set();
191893
+ for (const argument2 of args) {
191894
+ if (argument2.index === activeIndex) continue;
191895
+ const parameter4 = neoScriptArgumentParameter(
191896
+ fields,
191897
+ argument2.name,
191898
+ argument2.index
191899
+ );
191900
+ if (parameter4) used.add(parameter4.name.toLowerCase());
191901
+ }
191902
+ return fields.filter((field) => !used.has(field.name.toLowerCase()));
190879
191903
  }
190880
191904
  function lookupVariantFolderArgumentFields(typeName) {
190881
191905
  if (typeName !== NEO_LOOKUP_VARIANT_FOLDER_TYPE_NAME) return null;
190882
191906
  return NEO_LOOKUP_VARIANT_FOLDER_CONSTRUCTOR_ARGUMENTS;
190883
191907
  }
190884
- function declaredConstructorNamedArguments(analysis, typeName, used) {
191908
+ function declaredConstructorNamedArguments(analysis, typeName, args, activeIndex) {
190885
191909
  const contract = classConstructionContract(
190886
191910
  projectConstructionIndex(analysis),
190887
191911
  typeName
@@ -190889,17 +191913,28 @@ function declaredConstructorNamedArguments(analysis, typeName, used) {
190889
191913
  if (!contract) return null;
190890
191914
  if (contract.kind === "implicit") return null;
190891
191915
  if (contract.kind === "required") {
190892
- return contract.parameters.map(parameterArgumentField);
191916
+ return unusedConstructorArguments(
191917
+ contract.parameters.map(parameterArgumentField),
191918
+ args,
191919
+ activeIndex
191920
+ );
190893
191921
  }
190894
- const reachable = neoScriptApplicableSignatures(contract.constructors, [
190895
- ...used
190896
- ]);
191922
+ const labels = projectCallArgumentLabels(args, activeIndex);
191923
+ labels[activeIndex] = null;
191924
+ const reachable = neoScriptApplicableSignatures(
191925
+ contract.constructors,
191926
+ labels
191927
+ );
190897
191928
  const selected = reachable.length > 0 ? reachable : contract.constructors;
190898
191929
  const fields = /* @__PURE__ */ new Map();
190899
191930
  for (const constructor2 of selected) {
190900
- for (const parameter4 of constructor2.parameters) {
190901
- if (fields.has(parameter4.name)) continue;
190902
- fields.set(parameter4.name, parameterArgumentField(parameter4));
191931
+ for (const field of unusedConstructorArguments(
191932
+ constructor2.parameters.map(parameterArgumentField),
191933
+ args,
191934
+ activeIndex
191935
+ )) {
191936
+ const key = field.name.toLowerCase();
191937
+ if (!fields.has(key)) fields.set(key, field);
190903
191938
  }
190904
191939
  }
190905
191940
  return [...fields.values()];
@@ -190972,10 +192007,6 @@ function constructibleMembers(analysis, typeName) {
190972
192007
  function sourceParameterSignatureText(parameter4) {
190973
192008
  return constructorParameterLabel(sourceParameterProjection(parameter4));
190974
192009
  }
190975
- function functionParameterLabel(parameter4) {
190976
- const suffix = parameter4.defaultValue === void 0 ? "" : ` = ${parameter4.defaultValue.text}`;
190977
- return `${parameter4.type.name} ${parameter4.name}${suffix}`;
190978
- }
190979
192010
  function projectConstructionIndex(analysis) {
190980
192011
  const cached = CONSTRUCTION_INDEX_CACHE.get(analysis);
190981
192012
  if (cached) return cached;
@@ -191188,22 +192219,6 @@ function graphConstructorNamedArguments(typeName) {
191188
192219
  return null;
191189
192220
  }
191190
192221
  }
191191
- function activeAnnotationArgumentName(text, position) {
191192
- const lines = text.split("\n");
191193
- const prefix = [
191194
- ...lines.slice(0, position.line),
191195
- (lines[position.line] ?? "").slice(0, position.character)
191196
- ].join("\n");
191197
- return /([A-Za-z_][A-Za-z0-9_]*)\s*:\s*[A-Za-z0-9_]*$/.exec(prefix)?.[1] ?? null;
191198
- }
191199
- function activeNamedArgument(text, position) {
191200
- const lines = text.split("\n");
191201
- const prefix = [
191202
- ...lines.slice(0, position.line),
191203
- (lines[position.line] ?? "").slice(0, position.character)
191204
- ].join("\n");
191205
- return /([A-Za-z_][A-Za-z0-9_]*)\s*:\s*\.[A-Za-z0-9_]*$/.exec(prefix)?.[1] ?? null;
191206
- }
191207
192222
  function referenceHoverText(analysis, symbol, reference2) {
191208
192223
  const storage = `\`${reference2.storage}\``;
191209
192224
  const member = symbol.ownerName === void 0 ? void 0 : cachedProjectIndex(analysis.project).typeByName.get(symbol.ownerName)?.members.find(({ name }) => name === symbol.name);
@@ -191250,7 +192265,20 @@ Requires a list of \`void(${type2})\` method targets. The member name is require
191250
192265
  }
191251
192266
  const body = projectBodySnapshotAt(analysis, document, position);
191252
192267
  if (body) return hover(body, position);
191253
- const builtin = projectBuiltinSymbolAt(document, position);
192268
+ const sourceDocument = analysis.documents.get(document.uri);
192269
+ const annotationSite = sourceDocument ? contextualAnnotationSite(sourceDocument, position) : null;
192270
+ const token = projectTokenAt(document, position);
192271
+ const parameter4 = annotationSite ? annotationParameterHover(document, position, annotationSite) : null;
192272
+ if (parameter4) return parameter4;
192273
+ const schemaPath = annotationSite && token ? annotationSchemaPathTarget(analysis, document, token, annotationSite) : void 0;
192274
+ const expression = schemaPath === void 0 ? projectExpressionSnapshotAt(
192275
+ analysis,
192276
+ document,
192277
+ position,
192278
+ annotationSite
192279
+ ) : null;
192280
+ const inferred = expression ? hover(expression.snapshot, position) : null;
192281
+ const builtin = inferred ? null : projectBuiltinSymbolAt(document, position);
191254
192282
  if (builtin) {
191255
192283
  if (builtin.symbol) {
191256
192284
  const documentation3 = builtin.symbol.documentation ? `
@@ -191276,7 +192304,7 @@ Schema id: \`${builtin.type.id}\``
191276
192304
  };
191277
192305
  }
191278
192306
  const resolved = projectSymbolAt(analysis, document, position);
191279
- if (!resolved) return null;
192307
+ if (!resolved) return inferred;
191280
192308
  const owner = resolved.symbol.ownerName ? ` on \`${resolved.symbol.ownerName}\`` : "";
191281
192309
  const documentation = resolved.symbol.documentation ? `
191282
192310
 
@@ -191291,11 +192319,57 @@ ${referenceHoverText(analysis, resolved.symbol, resolved.symbol.reference)}` : "
191291
192319
  const setStorage = setStorageHoverMarkdown(analysis, resolved.symbol);
191292
192320
  const contract = resolved.symbol.kind === "class" ? projectConstructionContractMarkdown(analysis, resolved.symbol.name) : "";
191293
192321
  const lifecycle = resolved.symbol.kind === "member" && resolved.symbol.callable === true && resolved.symbol.static !== true && analysis.documents.get(resolved.symbol.location.uri)?.kind !== "flow" ? lifecycleHoverMarkdown(analysis, resolved.symbol.name) : "";
192322
+ if (inferred) {
192323
+ return {
192324
+ ...inferred,
192325
+ markdown: `${inferred.markdown}${reference2}${setStorage}${lifecycle}${contract}`
192326
+ };
192327
+ }
191294
192328
  return {
191295
192329
  range: resolved.token.range,
191296
192330
  markdown: `**${resolved.symbol.kind}** \`${resolved.symbol.name}\`${detail}${owner}${reference2}${setStorage}${documentation}${lifecycle}${contract}${id2}`
191297
192331
  };
191298
192332
  }
192333
+ function annotationParameterHover(document, position, site) {
192334
+ const tokens = projectTokens(document);
192335
+ const index = projectTokenIndexAt(document, position);
192336
+ const token = tokens[index];
192337
+ if (!token || !isCallArgumentLabelToken(token)) return null;
192338
+ if (tokens[significantTokenIndex(tokens, index, 1)]?.text !== ":")
192339
+ return null;
192340
+ const previous = significantTokenIndex(tokens, index, -1);
192341
+ if (tokens[previous]?.text !== "(" && tokens[previous]?.text !== ",")
192342
+ return null;
192343
+ const open2 = enclosingOpeners(tokens)[index];
192344
+ const callee = tokens[significantTokenIndex(tokens, open2, -1)];
192345
+ if (!callee || positionCompare(callee.range.start, site.annotation.nameRange.start) !== 0)
192346
+ return null;
192347
+ const field = site.fields.find((field2) => field2.name === token.text);
192348
+ if (!field) return null;
192349
+ const path = annotationSchemaPathKind(site.annotation.name, field.name);
192350
+ let type2 = formatAnnotationValueType(field.type);
192351
+ let description = "";
192352
+ if (path === "member") {
192353
+ type2 = "entry member";
192354
+ description = "Names a member of the collection entry, such as `Slug`.";
192355
+ } else if (path) {
192356
+ type2 = path === "collection" ? "collection path" : "member path";
192357
+ description = "Names a schema member using `Class.Member`.";
192358
+ } else if (site.annotation.name === "settings" && field.name === "collectionValue") {
192359
+ type2 = "collection reference";
192360
+ description = "Selects a collection instance, such as `root.Assets.Items`. The `Reference(...)` wrapper is optional.";
192361
+ }
192362
+ const options = generatedContractEnumCases(field.type);
192363
+ const choices = options?.length ? `
192364
+
192365
+ Values: ${options.map((option) => `\`.${option}\``).join(", ")}.` : "";
192366
+ return {
192367
+ range: token.range,
192368
+ markdown: `\`@${site.annotation.name}(${field.name}: ${type2})\`${description ? `
192369
+
192370
+ ${description}` : ""}${choices}`
192371
+ };
192372
+ }
191299
192373
  function setStorageHoverMarkdown(analysis, symbol) {
191300
192374
  if (symbol.kind !== "member" || symbol.ownerName === void 0) return "";
191301
192375
  const owner = findTypeDeclaration(analysis, symbol.ownerName);
@@ -191467,7 +192541,8 @@ function projectSignatureHelp(analysis, document, position) {
191467
192541
  const openIndex = activeCallOpenIndex(tokens, position);
191468
192542
  if (openIndex < 0) return null;
191469
192543
  const open2 = tokens[openIndex];
191470
- const callee = tokens[openIndex - 1];
192544
+ const calleeIndex = projectCallCalleeIndex(tokens, openIndex);
192545
+ const callee = tokens[calleeIndex];
191471
192546
  if (!open2 || !callee) return null;
191472
192547
  const active = activeCallArgument(tokens, openIndex, position);
191473
192548
  const activeParameter = active.index;
@@ -191476,16 +192551,19 @@ function projectSignatureHelp(analysis, document, position) {
191476
192551
  active.start,
191477
192552
  documentTokens.length
191478
192553
  );
191479
- const beforeCallee = tokens[openIndex - 2];
192554
+ const beforeCallee = tokens[calleeIndex - 1];
191480
192555
  if (beforeCallee?.text === "@") {
191481
- const source = analysis.documents.get(document.uri);
191482
- const contextual = source ? contextualAnnotationFields(source, position) : null;
191483
- const parameters = contextual?.map((field) => `${field.type} ${field.name}`) ?? annotationSignatureParameters(callee.text);
192556
+ const source2 = analysis.documents.get(document.uri);
192557
+ const contextual = source2 ? contextualAnnotationFields(source2, position) : null;
192558
+ const parameters = contextual?.map((field) => ({
192559
+ name: field.name,
192560
+ label: `${formatAnnotationValueType(field.type)} ${field.name}`
192561
+ })) ?? annotationSignatureParameters(callee.text);
191484
192562
  if (!parameters) return null;
191485
192563
  return signatureResult(
191486
192564
  `@${callee.text}`,
191487
- parameters,
191488
- neoScriptClampActiveParameter(activeParameter, parameters.length)
192565
+ parameters.map((parameter4) => parameter4.label),
192566
+ neoScriptActiveParameter(parameters, label, activeParameter)
191489
192567
  );
191490
192568
  }
191491
192569
  if (callee.text === "Reference") {
@@ -191493,7 +192571,11 @@ function projectSignatureHelp(analysis, document, position) {
191493
192571
  return signatureResult(
191494
192572
  "Reference",
191495
192573
  parameters,
191496
- neoScriptClampActiveParameter(activeParameter, parameters.length)
192574
+ neoScriptActiveParameter(
192575
+ [{ name: "id" }, { name: "withProvenance" }],
192576
+ label,
192577
+ activeParameter
192578
+ )
191497
192579
  );
191498
192580
  }
191499
192581
  if (callee.text === "Pause") {
@@ -191513,8 +192595,9 @@ function projectSignatureHelp(analysis, document, position) {
191513
192595
  if (constructorType) {
191514
192596
  const overloads = declaredConstructorOverloads(analysis, constructorType);
191515
192597
  if (overloads) {
191516
- const labels = projectCallArguments(documentTokens, openIndex).map(
191517
- ({ name }) => name
192598
+ const labels = projectCallArgumentLabels(
192599
+ projectCallArguments(documentTokens, openIndex),
192600
+ activeParameter
191518
192601
  );
191519
192602
  return constructorOverloadSignatures(
191520
192603
  constructorType,
@@ -191531,25 +192614,15 @@ function projectSignatureHelp(analysis, document, position) {
191531
192614
  neoScriptActiveParameter(parameters, label, activeParameter)
191532
192615
  );
191533
192616
  }
191534
- const functions = projectFunctionsNamed(analysis, callee.text);
191535
- if (functions.length === 0) return null;
191536
- return {
191537
- signatures: functions.map(({ owner, member }) => {
191538
- const parameters = member.parameters.map(functionParameterLabel);
191539
- return {
191540
- label: `${member.type.name} ${owner}.${member.name}(${parameters.join(", ")})`,
191541
- parameters: member.parameters.map((parameter4) => ({
191542
- label: functionParameterLabel(parameter4)
191543
- }))
191544
- };
191545
- }),
191546
- activeSignature: 0,
191547
- activeParameter: neoScriptActiveParameter(
191548
- functions[0].member.parameters,
191549
- label,
191550
- activeParameter
191551
- )
191552
- };
192617
+ const source = analysis.documents.get(document.uri);
192618
+ const expression = projectExpressionSnapshotAt(
192619
+ analysis,
192620
+ document,
192621
+ callee.range.start,
192622
+ source ? contextualAnnotationSite(source, callee.range.start) : null,
192623
+ true
192624
+ );
192625
+ return expression ? signatureHelp(expression.snapshot, position) : null;
191553
192626
  }
191554
192627
  function declaredConstructorOverloads(analysis, typeName) {
191555
192628
  if (lookupVariantFolderArgumentFields(typeName) !== null) return null;
@@ -191581,25 +192654,21 @@ function projectInlayHints(analysis, document, range2) {
191581
192654
  );
191582
192655
  const delimiterEnds = projectDelimiterEnds(tokens);
191583
192656
  const hints = [];
191584
- for (let index = 0; index < tokens.length - 1; index++) {
191585
- const callee = tokens[index];
191586
- const open2 = tokens[index + 1];
192657
+ for (let index = 0; index < tokens.length; index++) {
192658
+ if (tokens[index]?.text !== "(") continue;
192659
+ const calleeIndex = projectCallCalleeIndex(tokens, index);
192660
+ const callee = tokens[calleeIndex];
191587
192661
  if (!callee || callee.kind !== "identifier" && callee.kind !== "type") {
191588
192662
  continue;
191589
192663
  }
191590
192664
  if (rangeItemAt(bodyContexts, callee.range.start)) {
191591
192665
  continue;
191592
192666
  }
191593
- if (!open2 || open2.text !== "(") continue;
191594
- const beforeCallee = tokens[index - 1];
192667
+ const beforeCallee = tokens[calleeIndex - 1];
191595
192668
  if (beforeCallee?.text === "@") continue;
191596
192669
  if (declarationNames.has(positionKey(callee.range.start))) continue;
191597
192670
  if (range2 && positionCompare(callee.range.start, range2.end) > 0) break;
191598
- const callArguments2 = projectCallArguments(
191599
- tokens,
191600
- index + 1,
191601
- delimiterEnds
191602
- );
192671
+ const callArguments2 = projectCallArguments(tokens, index, delimiterEnds);
191603
192672
  if (range2 && !callArguments2.some((argument2) => rangeContains(range2, argument2.start)))
191604
192673
  continue;
191605
192674
  const parameterNames = projectCallParameterNames(
@@ -191612,7 +192681,7 @@ function projectInlayHints(analysis, document, range2) {
191612
192681
  for (let argument2 = 0; argument2 < callArguments2.length; argument2++) {
191613
192682
  const argumentToken = callArguments2[argument2];
191614
192683
  if (!argumentToken || argumentToken.name !== null) continue;
191615
- const name = parameterNames[argument2];
192684
+ const name = parameterNames[argumentToken.index];
191616
192685
  if (!name) continue;
191617
192686
  if (argumentToken.identifier && normalizeProjectHintName(argumentToken.identifier) === normalizeProjectHintName(name)) {
191618
192687
  continue;
@@ -191656,22 +192725,34 @@ function projectCallParameterNames(analysis, document, callee, beforeCallee) {
191656
192725
  beforeCallee
191657
192726
  );
191658
192727
  if (constructorType) {
192728
+ const overloads = declaredConstructorOverloads(analysis, constructorType);
192729
+ if (overloads) return neoScriptCommonParameterNames(overloads);
191659
192730
  const parameters = projectConstructorParameters(analysis, constructorType);
191660
192731
  if (parameters.length === 0) return null;
191661
192732
  return parameters.map((parameter4) => parameter4.name);
191662
192733
  }
191663
- const functions = projectFunctionsNamed(analysis, callee.text);
191664
- if (functions.length === 0) return null;
191665
- const arity = Math.max(
191666
- ...functions.map(({ member }) => member.parameters.length)
192734
+ const source = analysis.documents.get(document.uri);
192735
+ const expression = projectExpressionSnapshotAt(
192736
+ analysis,
192737
+ document,
192738
+ callee.range.start,
192739
+ source ? contextualAnnotationSite(source, callee.range.start) : null,
192740
+ true
191667
192741
  );
191668
- return Array.from({ length: arity }, (_, parameterIndex) => {
191669
- const names2 = new Set(
191670
- functions.map(({ member }) => member.parameters[parameterIndex]?.name)
191671
- );
191672
- const [name] = names2;
191673
- return names2.size === 1 && name ? name : null;
191674
- });
192742
+ if (expression) {
192743
+ return callParametersAt(expression.snapshot, callee.range.start)?.map(
192744
+ (parameter4) => parameter4.name
192745
+ ) ?? null;
192746
+ }
192747
+ return null;
192748
+ }
192749
+ function projectCallArgumentLabels(args, activeIndex) {
192750
+ const labels = Array.from(
192751
+ { length: Math.max(activeIndex + 1, (args.at(-1)?.index ?? -1) + 1) },
192752
+ () => null
192753
+ );
192754
+ for (const argument2 of args) labels[argument2.index] = argument2.name;
192755
+ return labels;
191675
192756
  }
191676
192757
  function projectDelimiterEnds(tokens) {
191677
192758
  const ends = /* @__PURE__ */ new Map();
@@ -191689,6 +192770,7 @@ function projectDelimiterEnds(tokens) {
191689
192770
  function projectCallArguments(tokens, openIndex, delimiterEnds) {
191690
192771
  const result = [];
191691
192772
  let atArgumentStart = true;
192773
+ let argumentIndex = 0;
191692
192774
  let depth = 0;
191693
192775
  for (let index = openIndex + 1; index < tokens.length; index++) {
191694
192776
  const token = tokens[index];
@@ -191704,11 +192786,13 @@ function projectCallArguments(tokens, openIndex, delimiterEnds) {
191704
192786
  break;
191705
192787
  } else if (depth === 0 && text === ",") {
191706
192788
  atArgumentStart = true;
192789
+ argumentIndex++;
191707
192790
  continue;
191708
192791
  }
191709
192792
  if (atArgumentStart) {
191710
192793
  const name = callArgumentLabel(tokens, index, tokens.length);
191711
192794
  result.push({
192795
+ index: argumentIndex,
191712
192796
  start: token.range.start,
191713
192797
  name,
191714
192798
  ...token.kind === "identifier" && (tokens[index + 1]?.text === "," || tokens[index + 1]?.text === ")") ? { identifier: token.text } : {}
@@ -191717,13 +192801,9 @@ function projectCallArguments(tokens, openIndex, delimiterEnds) {
191717
192801
  }
191718
192802
  if (opens && delimiterEnds) {
191719
192803
  index = delimiterEnds.get(index) ?? tokens.length;
191720
- } else if (text === "new" && tokens[index + 2]?.text === "<") {
191721
- let angles = 0;
191722
- index += 2;
191723
- for (; index < tokens.length; index++) {
191724
- if (tokens[index].text === "<") angles++;
191725
- else if (tokens[index].text === ">" && --angles === 0) break;
191726
- }
192804
+ } else if (tokens[index + 1]?.text === "<") {
192805
+ const open2 = callOpenParenIndex(tokens, index);
192806
+ if (open2 >= 0) index = open2 - 1;
191727
192807
  }
191728
192808
  }
191729
192809
  return result;
@@ -191965,10 +193045,28 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
191965
193045
  const tokenIndex = projectTokenIndexAt(document, position);
191966
193046
  const sourceTokens = projectTokens(document);
191967
193047
  const token = sourceTokens[tokenIndex];
193048
+ const previousIndex = significantTokenIndex(sourceTokens, tokenIndex, -1);
193049
+ const previous = sourceTokens[previousIndex];
191968
193050
  if (!isProjectNameToken(token)) return null;
191969
193051
  if (isAnnotationName(sourceTokens, tokenIndex)) return null;
191970
193052
  const body = projectBodySnapshotAt(analysis, document, position);
191971
- const tupleLabel = body ? tupleLabelSymbolAtPosition(body, position) : null;
193053
+ const sourceDocument = analysis.documents.get(document.uri);
193054
+ const annotationSite = !body && sourceDocument ? contextualAnnotationSite(sourceDocument, position) : null;
193055
+ if (annotationSite) {
193056
+ const target = annotationSchemaPathTarget(
193057
+ analysis,
193058
+ document,
193059
+ token,
193060
+ annotationSite
193061
+ );
193062
+ if (target !== void 0) {
193063
+ const location3 = target?.selectionLocation ?? target?.location;
193064
+ const symbol = location3 && symbolsDeclaredAt(index, location3.uri, location3.range)[0];
193065
+ return symbol ? { token, symbol } : null;
193066
+ }
193067
+ }
193068
+ const executable = body ?? projectExpressionSnapshotAt(analysis, document, position, annotationSite)?.snapshot;
193069
+ const tupleLabel = executable ? tupleLabelSymbolAtPosition(executable, position) : null;
191972
193070
  if (tupleLabel?.location)
191973
193071
  return {
191974
193072
  token,
@@ -191984,8 +193082,8 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
191984
193082
  const symbol = location3 && symbolsDeclaredAt(index, location3.uri, location3.range)[0];
191985
193083
  return symbol ? { token, symbol } : null;
191986
193084
  }
191987
- if (body) {
191988
- const local = localSymbolAtPosition(body, position);
193085
+ if (executable) {
193086
+ const local = localSymbolAtPosition(executable, position);
191989
193087
  if (local?.location) {
191990
193088
  return {
191991
193089
  token,
@@ -191997,10 +193095,10 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
191997
193095
  }
191998
193096
  };
191999
193097
  }
192000
- const reference2 = referenceAtPosition(body, position);
192001
- const symbolId = reference2 ? resolveReferenceSymbolId(body, reference2) : null;
192002
- const executable = symbolId ? body.project.symbolById.get(symbolId) : void 0;
192003
- const location3 = executable?.selectionLocation ?? executable?.location;
193098
+ const reference2 = referenceAtPosition(executable, position);
193099
+ const symbolId = reference2 ? resolveReferenceSymbolId(executable, reference2) : null;
193100
+ const target = symbolId ? executable.project.symbolById.get(symbolId) : void 0;
193101
+ const location3 = target?.selectionLocation ?? target?.location;
192004
193102
  const located = location3 ? symbolsDeclaredAt(index, location3.uri, location3.range)[0] : void 0;
192005
193103
  const symbol = located ?? (symbolId ? index.byId.get(symbolId) : void 0);
192006
193104
  if (symbol) return { token, symbol };
@@ -192021,7 +193119,7 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
192021
193119
  const source = analysis.documents.get(document.uri);
192022
193120
  const typePosition = source && sourceTypeAt(source, token.range.start);
192023
193121
  const inScope = (symbol) => !symbol.scopeRange || symbol.location.uri === document.uri && rangeContains(symbol.scopeRange, token.range.start);
192024
- if (typePosition || sourceTokens[tokenIndex - 1]?.text === "new") {
193122
+ if (typePosition || previous?.text === "new") {
192025
193123
  const types = candidates.filter((symbol) => isProjectTypeSymbol(symbol) && inScope(symbol)).sort(compareScopeSize);
192026
193124
  const innermost = types[0];
192027
193125
  if (innermost?.scopeRange) return { token, symbol: innermost };
@@ -192052,13 +193150,13 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
192052
193150
  if (constructed) return { token, symbol: constructed };
192053
193151
  }
192054
193152
  const owner = source ? declarationContaining(source, token.range.start)?.name : void 0;
192055
- if (owner && sourceTokens[tokenIndex - 1]?.text !== ".") {
193153
+ if (owner && previous?.text !== "." && previous?.text !== "?.") {
192056
193154
  const owned = visibleCandidates.filter(
192057
193155
  (symbol) => symbol.ownerName === owner
192058
193156
  );
192059
193157
  if (owned.length === 1) return { token, symbol: owned[0] };
192060
193158
  }
192061
- const dotOwner = sourceTokens[tokenIndex - 1]?.text === "." ? sourceTokens[tokenIndex - 2] : void 0;
193159
+ const dotOwner = previous?.text === "." || previous?.text === "?." ? sourceTokens[significantTokenIndex(sourceTokens, previousIndex, -1)] : void 0;
192062
193160
  if (dotOwner) {
192063
193161
  const resolvedOwner = indexedProjectSymbolAt(
192064
193162
  analysis,
@@ -192360,6 +193458,10 @@ function activeCallArgument(tokens, openIndex, position) {
192360
193458
  parameter4++;
192361
193459
  start = end + 1;
192362
193460
  }
193461
+ if (tokens[end + 1]?.text === "<") {
193462
+ const open2 = callOpenParenIndex(tokens, end);
193463
+ if (open2 >= 0) end = open2 - 1;
193464
+ }
192363
193465
  }
192364
193466
  return {
192365
193467
  index: parameter4,
@@ -192370,28 +193472,31 @@ function activeCallArgument(tokens, openIndex, position) {
192370
193472
  function annotationSignatureParameters(name) {
192371
193473
  switch (name) {
192372
193474
  case "id":
192373
- return ["string id"];
193475
+ return [{ name: "id", label: "string id" }];
192374
193476
  case "settings":
192375
- return ["named settings"];
193477
+ return [{ name: "", label: "named settings" }];
192376
193478
  case "storage":
192377
- return ["StorageKind allowed"];
193479
+ return [{ name: "allowed", label: "StorageKind allowed" }];
192378
193480
  case "distribution":
192379
- return ["NeoSubtreeDistribution kind"];
193481
+ return [{ name: "kind", label: "NeoSubtreeDistribution kind" }];
192380
193482
  case "effect":
192381
- return ["NeoEffectKind kind"];
193483
+ return [{ name: "kind", label: "NeoEffectKind kind" }];
192382
193484
  case "relations":
192383
- return ["relation descriptors"];
193485
+ return [{ name: "", label: "relation descriptors" }];
192384
193486
  case "incomplete":
192385
- return ["string reason"];
193487
+ return [{ name: "reason", label: "string reason" }];
192386
193488
  case "index":
192387
- return ["entry member", "ListIndexKind kind"];
193489
+ return [
193490
+ { name: "member", label: "entry member" },
193491
+ { name: "kind", label: "ListIndexKind kind" }
193492
+ ];
192388
193493
  case "column":
192389
193494
  return [
192390
- "entry member",
192391
- "int width",
192392
- "ColumnVisibilityKind visibility",
192393
- "ColumnPinKind pin",
192394
- "ColumnOverflowKind overflow"
193495
+ { name: "member", label: "entry member" },
193496
+ { name: "width", label: "int width" },
193497
+ { name: "visibility", label: "ColumnVisibilityKind visibility" },
193498
+ { name: "pin", label: "ColumnPinKind pin" },
193499
+ { name: "overflow", label: "ColumnOverflowKind overflow" }
192395
193500
  ];
192396
193501
  default:
192397
193502
  return null;
@@ -192460,7 +193565,11 @@ function initializerRoots(source) {
192460
193565
  slot: {
192461
193566
  kind: "declared",
192462
193567
  type: member.type,
192463
- field: { owner: declaration.name, name: member.name }
193568
+ field: {
193569
+ owner: declaration.name,
193570
+ name: member.name,
193571
+ static: member.modifiers.includes("static")
193572
+ }
192464
193573
  },
192465
193574
  range: member.initializer.range
192466
193575
  });
@@ -193106,27 +194215,6 @@ function graphConstructorParameters(typeName) {
193106
194215
  return [];
193107
194216
  }
193108
194217
  }
193109
- function projectFunctionsNamed(analysis, name) {
193110
- let byName = PROJECT_FUNCTIONS.get(analysis);
193111
- if (!byName) {
193112
- byName = /* @__PURE__ */ new Map();
193113
- for (const document of analysis.documents.values()) {
193114
- for (const declaration of document.declarations) {
193115
- if (declaration.kind === "global" || declaration.kind === "enum")
193116
- continue;
193117
- for (const member of declaration.members) {
193118
- if (member.kind !== "function") continue;
193119
- const entry = { owner: declaration.name, member };
193120
- const named = byName.get(member.name);
193121
- if (named) named.push(entry);
193122
- else byName.set(member.name, [entry]);
193123
- }
193124
- }
193125
- }
193126
- PROJECT_FUNCTIONS.set(analysis, byName);
193127
- }
193128
- return byName.get(name) ?? [];
193129
- }
193130
194218
  function dialoguePathTokens(tokens, end) {
193131
194219
  const path = [];
193132
194220
  for (let i2 = end; i2 >= 0 && isProjectNameToken(tokens[i2]); i2 -= 2) {
@@ -193177,10 +194265,12 @@ function dialogueGroupCompletions(analysis, document, position) {
193177
194265
  function isDialogueGroupArgument(tokens, pathStart) {
193178
194266
  return tokens[pathStart - 1]?.text === ":" && tokens[pathStart - 2]?.text === "group";
193179
194267
  }
193180
- var PROJECT_BODIES, PROJECT_BODY_INDEX_CACHE, PROJECT_BODY_SNAPSHOT_CACHE, SOURCE_TYPES, CONSTRUCTION_INDEX_CACHE, VARIANT_SCOPE_INDEX_CACHE, PROJECT_SYMBOL_INDEX_CACHE, ENCLOSING_OPENERS, significantTokens2, INITIALIZER_ROOTS, CONSTRUCTION_SITE_CACHE, DECLARATION_FIELDS, PROJECT_TYPE_DECLARATIONS, PROJECT_FUNCTIONS;
194268
+ var PROJECT_BODIES, PROJECT_EXPRESSION_SNAPSHOT_CACHE, PROJECT_BODY_INDEX_CACHE, PROJECT_BODY_SNAPSHOT_CACHE, SOURCE_TYPES, CONSTRUCTION_INDEX_CACHE, VARIANT_SCOPE_INDEX_CACHE, PROJECT_SYMBOL_INDEX_CACHE, ENCLOSING_OPENERS, significantTokens2, INITIALIZER_ROOTS, CONSTRUCTION_SITE_CACHE, DECLARATION_FIELDS, PROJECT_TYPE_DECLARATIONS;
193181
194269
  var init_project_source_language_features = __esm({
193182
194270
  "../packages/neoscript-language/src/project-source-language-features.ts"() {
193183
194271
  "use strict";
194272
+ init_argument_name_completions();
194273
+ init_project_annotation_path_completions();
193184
194274
  init_random_contract();
193185
194275
  init_analyzer();
193186
194276
  init_project_source_dialogue_groups();
@@ -193209,6 +194299,7 @@ var init_project_source_language_features = __esm({
193209
194299
  init_quick_fixes();
193210
194300
  init_syntax();
193211
194301
  PROJECT_BODIES = /* @__PURE__ */ new WeakMap();
194302
+ PROJECT_EXPRESSION_SNAPSHOT_CACHE = /* @__PURE__ */ new WeakMap();
193212
194303
  PROJECT_BODY_INDEX_CACHE = /* @__PURE__ */ new WeakMap();
193213
194304
  PROJECT_BODY_SNAPSHOT_CACHE = /* @__PURE__ */ new WeakMap();
193214
194305
  SOURCE_TYPES = /* @__PURE__ */ new WeakMap();
@@ -193221,7 +194312,6 @@ var init_project_source_language_features = __esm({
193221
194312
  CONSTRUCTION_SITE_CACHE = /* @__PURE__ */ new WeakMap();
193222
194313
  DECLARATION_FIELDS = /* @__PURE__ */ new WeakMap();
193223
194314
  PROJECT_TYPE_DECLARATIONS = /* @__PURE__ */ new WeakMap();
193224
- PROJECT_FUNCTIONS = /* @__PURE__ */ new WeakMap();
193225
194315
  }
193226
194316
  });
193227
194317
 
@@ -194341,7 +195431,7 @@ function sameLocationInList(target, locations) {
194341
195431
  (location3) => location3.uri === target.uri && location3.range.start.line === target.range.start.line && location3.range.start.character === target.range.start.character
194342
195432
  );
194343
195433
  }
194344
- function locationKey2(location3) {
195434
+ function locationKey3(location3) {
194345
195435
  const { start, end } = location3.range;
194346
195436
  return JSON.stringify([
194347
195437
  location3.uri,
@@ -194909,7 +195999,7 @@ var init_service = __esm({
194909
195999
  const declaration = resolved.symbol;
194910
196000
  const family = projectReferenceFamily(analysis, declaration, index);
194911
196001
  const familyLocations = new Set(
194912
- family.map((member) => locationKey2(member.location))
196002
+ family.map((member) => locationKey3(member.location))
194913
196003
  );
194914
196004
  const familyIds = new Set(
194915
196005
  family.flatMap((member) => member.id === null ? [] : [member.id])
@@ -194932,11 +196022,11 @@ var init_service = __esm({
194932
196022
  candidate.range.start,
194933
196023
  index
194934
196024
  )?.symbol;
194935
- if (!candidateSymbol || !familyLocations.has(locationKey2(candidateSymbol.location))) {
196025
+ if (!candidateSymbol || !familyLocations.has(locationKey3(candidateSymbol.location))) {
194936
196026
  continue;
194937
196027
  }
194938
196028
  const location3 = { uri: state.document.uri, range: candidate.range };
194939
- if (!includeDeclaration && familyLocations.has(locationKey2(location3))) {
196029
+ if (!includeDeclaration && familyLocations.has(locationKey3(location3))) {
194940
196030
  continue;
194941
196031
  }
194942
196032
  locations.push(location3);
@@ -194951,7 +196041,7 @@ var init_service = __esm({
194951
196041
  const symbolId = resolveReferenceSymbolId(snapshot, candidate);
194952
196042
  if (symbolId === null) continue;
194953
196043
  const matches = familyIds.has(symbolId) || definition(snapshot, candidate.range.start).some(
194954
- (location3) => familyLocations.has(locationKey2(location3))
196044
+ (location3) => familyLocations.has(locationKey3(location3))
194955
196045
  );
194956
196046
  if (!matches) continue;
194957
196047
  locations.push({ uri: state.document.uri, range: candidate.range });
@@ -194959,7 +196049,7 @@ var init_service = __esm({
194959
196049
  if (declaration.kind !== "parameter") continue;
194960
196050
  for (const label of namedArgumentLabels(snapshot)) {
194961
196051
  const parameter4 = label.parameter.selectionLocation;
194962
- if (parameter4 && familyLocations.has(locationKey2(parameter4)))
196052
+ if (parameter4 && familyLocations.has(locationKey3(parameter4)))
194963
196053
  locations.push({ uri: state.document.uri, range: label.range });
194964
196054
  }
194965
196055
  }
@@ -237078,7 +238168,7 @@ var releaseWorkspaceLock = () => void 0;
237078
238168
  async function main() {
237079
238169
  const args = parseArgs(process.argv.slice(2));
237080
238170
  if (args.command === "--version") {
237081
- console.log("0.89.0");
238171
+ console.log("0.89.1");
237082
238172
  return;
237083
238173
  }
237084
238174
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {