@neocompose/cli 0.89.0 → 0.89.2

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.
@@ -22918,8 +22918,12 @@ var FunctionTypeInference = class {
22918
22918
  const value = actual.parameterTypes[index];
22919
22919
  if (value !== void 0) this.add(value, expected, "exact");
22920
22920
  });
22921
- } else if (pattern.kind === "reference" && actual.kind === "reference") {
22922
- this.add(actual.target, pattern.target, "exact");
22921
+ } else if (pattern.kind === "reference") {
22922
+ this.add(
22923
+ actual.kind === "reference" ? actual.target : actual,
22924
+ pattern.target,
22925
+ "exact"
22926
+ );
22923
22927
  }
22924
22928
  }
22925
22929
  fix(index) {
@@ -33327,11 +33331,14 @@ function resolveMemberForValueRow(row, ctx, visited) {
33327
33331
  ctx.__valueOverlay
33328
33332
  );
33329
33333
  if (parent === null) continue;
33330
- const parentMember = resolveMemberForValueRow(
33331
- parent,
33332
- ctx,
33333
- new Set(visited)
33334
- );
33334
+ let parentMember = resolveMemberForValueRow(parent, ctx, new Set(visited));
33335
+ if (parentMember?.kind === 21 /* Generic */) {
33336
+ parentMember = substituteMember(
33337
+ parentMember,
33338
+ runtimeParentGenericEnv(parent, ctx, /* @__PURE__ */ new Set()),
33339
+ ctx.vm.members
33340
+ );
33341
+ }
33335
33342
  if (parentMember !== null && isMemberTupleBase(parentMember)) {
33336
33343
  const memberId = parentMember.elementMemberIds[Number(link.key)];
33337
33344
  return memberId === void 0 ? null : evalMemberById(ctx.vm, memberId);
@@ -49942,18 +49949,19 @@ function buildNeoScriptEditorIndex(lexed, kind) {
49942
49949
  lexed,
49943
49950
  diagnostics
49944
49951
  );
49952
+ const regionCalls = indexCalls(executable, executablePairs, lexed);
49945
49953
  const regionLocals = applySwitchSectionScopes(
49946
49954
  indexLocals(
49947
49955
  executable,
49948
49956
  executablePairs,
49949
49957
  lexed,
49950
49958
  diagnostics,
49951
- lambdaBodies
49959
+ lambdaBodies,
49960
+ regionCalls
49952
49961
  ),
49953
49962
  regionSwitches,
49954
49963
  lexed
49955
49964
  );
49956
- const regionCalls = indexCalls(executable, executablePairs, lexed);
49957
49965
  const declarations = new Set(
49958
49966
  regionLocals.map(
49959
49967
  (local) => `${local.nameRange.start.line}:${local.nameRange.start.character}`
@@ -50406,9 +50414,10 @@ function duplicateUnitDiagnostic(label, units, diagnostics) {
50406
50414
  ]
50407
50415
  });
50408
50416
  }
50409
- function indexLocals(tokens, pairs, lexed, diagnostics, lambdaBodies) {
50417
+ function indexLocals(tokens, pairs, lexed, diagnostics, lambdaBodies, calls) {
50410
50418
  const locals = [];
50411
50419
  const braceScope = braceScopeIndex(tokens, lexed.end);
50420
+ const switchArrows = switchExpressionArrowIndexes(tokens, calls);
50412
50421
  for (let index = 0; index < tokens.length; index++) {
50413
50422
  const caught = tryParseCatchParameter(tokens, index, pairs, lexed);
50414
50423
  if (caught) {
@@ -50429,7 +50438,13 @@ function indexLocals(tokens, pairs, lexed, diagnostics, lambdaBodies) {
50429
50438
  index = loop.resumeTokenIndex;
50430
50439
  continue;
50431
50440
  }
50432
- const lambda = tryParseLambdaParameters(tokens, index, pairs, lexed);
50441
+ const lambda = tryParseLambdaParameters(
50442
+ tokens,
50443
+ index,
50444
+ pairs,
50445
+ lexed,
50446
+ switchArrows
50447
+ );
50433
50448
  if (lambda) {
50434
50449
  locals.push(...lambda.locals);
50435
50450
  lambdaBodies.push(lambda.body);
@@ -50597,7 +50612,35 @@ function statementEndTokenIndex(tokens, start) {
50597
50612
  }
50598
50613
  return tokens.length;
50599
50614
  }
50600
- function tryParseLambdaParameters(tokens, start, pairs, lexed) {
50615
+ function switchExpressionArrowIndexes(tokens, calls) {
50616
+ const enclosing = enclosingOpenerIndex(tokens);
50617
+ const inResult = /* @__PURE__ */ new Set();
50618
+ const arrows = /* @__PURE__ */ new Set();
50619
+ const genericEnds = /* @__PURE__ */ new Map();
50620
+ for (const call of calls) {
50621
+ const first = call.typeArgumentTokens?.[0];
50622
+ if (first) genericEnds.set(first.start, call.openParenOffset);
50623
+ }
50624
+ for (let index = 0; index < tokens.length; index++) {
50625
+ const token = tokens[index];
50626
+ const genericEnd = genericEnds.get(token.start);
50627
+ if (genericEnd !== void 0) {
50628
+ while (tokens[index + 1] && tokens[index + 1].start < genericEnd)
50629
+ index++;
50630
+ continue;
50631
+ }
50632
+ const opener = enclosing[index];
50633
+ if (tokens[opener]?.text !== "{" || tokens[opener - 1]?.text !== "switch")
50634
+ continue;
50635
+ if (token.text === ",") inResult.delete(opener);
50636
+ else if (token.text === "=>" && !inResult.has(opener)) {
50637
+ arrows.add(index);
50638
+ inResult.add(opener);
50639
+ }
50640
+ }
50641
+ return arrows;
50642
+ }
50643
+ function tryParseLambdaParameters(tokens, start, pairs, lexed, switchArrows) {
50601
50644
  const open = tokens[start];
50602
50645
  if (!open) return null;
50603
50646
  if (open.kind === "identifier") {
@@ -50605,6 +50648,7 @@ function tryParseLambdaParameters(tokens, start, pairs, lexed) {
50605
50648
  if (!arrow2 || arrow2.kind !== "operator" || arrow2.text !== "=>") {
50606
50649
  return null;
50607
50650
  }
50651
+ if (switchArrows.has(start + 1)) return null;
50608
50652
  const body2 = lambdaBodySpan(tokens, start + 1, pairs, lexed);
50609
50653
  return {
50610
50654
  locals: [
@@ -50629,6 +50673,7 @@ function tryParseLambdaParameters(tokens, start, pairs, lexed) {
50629
50673
  if (closeIndex === void 0) return null;
50630
50674
  const arrow = tokens[closeIndex + 1];
50631
50675
  if (!arrow || arrow.kind !== "operator" || arrow.text !== "=>") return null;
50676
+ if (switchArrows.has(closeIndex + 1)) return null;
50632
50677
  const body = lambdaBodySpan(tokens, closeIndex + 1, pairs, lexed);
50633
50678
  const locals = [];
50634
50679
  for (const [parameterIndex, [from, to]] of patternSegments(
@@ -50834,7 +50879,9 @@ function indexCalls(tokens, pairs, lexed) {
50834
50879
  const name = tokens[index];
50835
50880
  const openIndex = callOpenParenIndex(tokens, index);
50836
50881
  const open = tokens[openIndex];
50837
- if (!name || name.kind !== "identifier") continue;
50882
+ if (!name) continue;
50883
+ const expression = [")", "]", "!"].includes(name.text) && openIndex === index + 1;
50884
+ if (name.kind !== "identifier" && !expression) continue;
50838
50885
  if (!open || open.kind !== "punctuation" || open.text !== "(") continue;
50839
50886
  const previous = tokens[index - 1];
50840
50887
  const targetTyped = isContextualNew(name, previous, open);
@@ -50863,14 +50910,19 @@ function indexCalls(tokens, pairs, lexed) {
50863
50910
  segmentStart = token.end;
50864
50911
  segmentStartIndex = cursor + 1;
50865
50912
  }
50913
+ if (tokens[cursor + 1]?.text === "<") {
50914
+ const genericOpen = callOpenParenIndex(tokens, cursor);
50915
+ if (genericOpen >= 0) cursor = genericOpen - 1;
50916
+ }
50866
50917
  }
50867
50918
  if (segmentStart < (close?.start ?? lexed.end)) {
50868
50919
  ranges.push(lexed.source.range(segmentStart, close?.start ?? lexed.end));
50869
50920
  names2.push(callArgumentLabel(tokens, segmentStartIndex, limit));
50870
50921
  }
50922
+ const namedKind = contextualKeyword ? "constructor" : "function";
50871
50923
  calls.push({
50872
- kind: contextualKeyword ? "constructor" : "function",
50873
- name: name.text,
50924
+ kind: expression ? "expression" : namedKind,
50925
+ name: expression ? "delegate" : name.text,
50874
50926
  nameRange: name.range,
50875
50927
  ...contextualKeyword ? { contextualKeywordRange: contextualKeyword.range } : {},
50876
50928
  ...targetTyped ? { targetTyped: true } : {},
@@ -52690,6 +52742,10 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
52690
52742
  if (expected === void 0) return;
52691
52743
  this.requireAssignable(resolved.type, expected, expression.pos, "value");
52692
52744
  }
52745
+ /** Type a source expression with the same call binding rules as executable code. */
52746
+ resolveExpressionType(expression) {
52747
+ return this.resolveExpression(expression, this.initialScope()).type;
52748
+ }
52693
52749
  persistedListenerCompletions(receiver, expected) {
52694
52750
  const scope = this.initialScope();
52695
52751
  let receiverType = this.context.thisClass;
@@ -54956,8 +55012,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
54956
55012
  );
54957
55013
  }
54958
55014
  }
54959
- resolveMemberRowOf(place, scope) {
54960
- const optional2 = place.optional === true;
55015
+ resolveMemberRowOf(place, scope, resolved) {
54961
55016
  if ((this.context.kind === "initializer" || this.context.kind === "initializerExpression") && this.delegateCaptureContexts.length === 0 && referencePlaceRoot(place) === "this") {
54962
55017
  const text = referencePlaceText(place) ?? "this";
54963
55018
  throw new CompileError(
@@ -54965,12 +55020,12 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
54965
55020
  place.pos
54966
55021
  );
54967
55022
  }
54968
- const slot = this.resolveMemberNatural(
55023
+ const slot = resolved ?? this.resolveMemberNatural(
54969
55024
  place.receiver,
54970
55025
  place.name,
54971
55026
  scope,
54972
55027
  place.pos,
54973
- optional2
55028
+ place.optional === true
54974
55029
  );
54975
55030
  const member = slot.symbol;
54976
55031
  if (member === void 0) {
@@ -54988,19 +55043,55 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
54988
55043
  place.pos
54989
55044
  );
54990
55045
  }
54991
- const read = slot.optionalChainType ?? slot.type;
54992
- const stored = member.lookup !== void 0 && member.lookup.multiselect !== true && read.kind !== "reference" ? {
54993
- kind: "reference",
54994
- target: { ...read, nullable: false },
54995
- ...isNullable(read) ? { nullable: true } : {}
54996
- } : read;
54997
- const type2 = this.referenceType(stored, optional2);
55046
+ const type2 = this.memberReferenceType(slot, place.optional === true);
54998
55047
  if (type2.kind !== "reference") return slot;
54999
55048
  return {
55000
55049
  pointer: { type: "rowOf" /* RowOf */, place: slot.pointer },
55001
55050
  type: type2
55002
55051
  };
55003
55052
  }
55053
+ memberReferenceType(slot, optional2) {
55054
+ const read = slot.storedType ?? slot.optionalChainType ?? slot.type;
55055
+ const stored = slot.symbol?.lookup !== void 0 && slot.symbol.lookup.multiselect !== true && read.kind !== "reference" ? {
55056
+ kind: "reference",
55057
+ target: { ...read, nullable: false },
55058
+ ...isNullable(read) ? { nullable: true } : {}
55059
+ } : read;
55060
+ return this.referenceType(
55061
+ stored,
55062
+ optional2 || slot.optionalChainType !== void 0
55063
+ );
55064
+ }
55065
+ /** Only stored member slots can acquire a reference from an expected type. */
55066
+ implicitReferenceType(expression, value) {
55067
+ if (expression.kind !== "member") return void 0;
55068
+ if (value.symbol === void 0 || value.symbol.computed === true)
55069
+ return void 0;
55070
+ return this.memberReferenceType(value, expression.optional === true);
55071
+ }
55072
+ referenceInferenceType(expression, value, pattern) {
55073
+ const read = this.readReferences(value, pattern).type;
55074
+ if (pattern.kind !== "reference" || read.kind === "reference") return read;
55075
+ return this.implicitReferenceType(expression, value) ?? read;
55076
+ }
55077
+ contextualReferenceType(expression, value, expected) {
55078
+ const read = this.readReferences(value, expected).type;
55079
+ if (expected.kind !== "reference" || isNeoScriptTypeAssignable(read, expected, this.project))
55080
+ return read;
55081
+ const reference = this.implicitReferenceType(expression, value);
55082
+ return reference !== void 0 && isNeoScriptTypeAssignable(reference, expected, this.project) ? reference : read;
55083
+ }
55084
+ /** Use the same slot identity for explicit and expected-type references. */
55085
+ contextualReference(expression, value, scope, expected) {
55086
+ const read = this.readReferences(value, expected);
55087
+ if (expected?.kind !== "reference" || isNeoScriptTypeAssignable(read.type, expected, this.project))
55088
+ return read;
55089
+ const reference = this.implicitReferenceType(expression, value);
55090
+ if (expression.kind === "member" && reference !== void 0 && isNeoScriptTypeAssignable(reference, expected, this.project)) {
55091
+ return this.resolveMemberRowOf(expression, scope, value);
55092
+ }
55093
+ return read;
55094
+ }
55004
55095
  /** Whether assigning `target` rebinds a reference to a handle. */
55005
55096
  holdsHandleReference(target) {
55006
55097
  if (target.type.kind === "reference") {
@@ -55609,13 +55700,15 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
55609
55700
  });
55610
55701
  }
55611
55702
  resolveExpression(expression, scope, expected, convertSequence = true) {
55612
- const value = this.readReferences(
55703
+ const value = this.contextualReference(
55704
+ expression,
55613
55705
  this.resolveReferenceExpression(
55614
55706
  expression,
55615
55707
  scope,
55616
55708
  expected,
55617
55709
  convertSequence
55618
55710
  ),
55711
+ scope,
55619
55712
  expected
55620
55713
  );
55621
55714
  return convertSequence ? this.convertSequence(value, expected) : value;
@@ -57137,7 +57230,8 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
57137
57230
  }
57138
57231
  entryType = common;
57139
57232
  }
57140
- if (expected?.kind === "set" && this.context.kind === "initializer") {
57233
+ const referenceSelection = expected?.kind === "set" && this.context.kind === "initializer" && (expected.elementType.kind === "reference" || hasReferenceEquality(expected.elementType, this.project));
57234
+ if (expected?.kind === "set" && this.context.kind === "initializer" && !referenceSelection) {
57141
57235
  const element = expected.elementType;
57142
57236
  const spelling = element.kind === "named" && this.project.typeById.get(element.typeId)?.kind === "enum" ? `.Option or ${this.describe({ ...element, nullable: false })}.Option values` : "literal values";
57143
57237
  throw new CompileError(
@@ -57155,7 +57249,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
57155
57249
  "NeoScript strict compiler produced a non-list wire type for a list literal."
57156
57250
  );
57157
57251
  }
57158
- return {
57252
+ const list = {
57159
57253
  pointer: {
57160
57254
  type: "listLiteral" /* ListLiteral */,
57161
57255
  typeInfo: wire,
@@ -57164,6 +57258,18 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
57164
57258
  type: type2,
57165
57259
  entries: resolved
57166
57260
  };
57261
+ return referenceSelection ? this.resolveCollectionQuery(
57262
+ list,
57263
+ {
57264
+ kind: "list",
57265
+ keyType: { kind: "primitive", name: "int" },
57266
+ valueType: entryType
57267
+ },
57268
+ "ToSet",
57269
+ [],
57270
+ scope,
57271
+ pos
57272
+ ) : list;
57167
57273
  }
57168
57274
  resolveDictionaryLiteral(entries, scope, expected, pos) {
57169
57275
  const expectedDictionary = expected?.kind === "dictionary" ? expected : void 0;
@@ -57874,7 +57980,12 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
57874
57980
  const rootEntry = scope.lookupFlowRoot(pathRoot(path));
57875
57981
  if (rootEntry) {
57876
57982
  const narrowed = scope.lookupNarrowedType(path, rootEntry);
57877
- if (narrowed) resolved = { ...resolved, type: narrowed };
57983
+ if (narrowed)
57984
+ resolved = {
57985
+ ...resolved,
57986
+ storedType: resolved.type,
57987
+ type: narrowed
57988
+ };
57878
57989
  }
57879
57990
  }
57880
57991
  }
@@ -60593,17 +60704,28 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
60593
60704
  args,
60594
60705
  scope
60595
60706
  );
60596
- return resolveNeoScriptDeclaredConstructorOverload(
60707
+ const resolve = (implicit) => resolveNeoScriptDeclaredConstructorOverload(
60597
60708
  declared,
60598
60709
  named.map((name, index) => {
60599
60710
  const inferred = inferredTypes?.[index];
60600
- if (!inferred) return { name };
60711
+ const argument2 = args[index];
60712
+ if (!inferred || !argument2) return { name };
60601
60713
  return {
60602
60714
  name,
60603
- matchesParameter: (parameter3) => isNeoScriptTypeAssignable(inferred, parameter3.type, this.project)
60715
+ matchesParameter: (parameter3) => implicit && parameter3.type.kind === "reference" && isContextualReferenceExpression(argument2) ? this.targetTypedArgumentFits(argument2, parameter3.type, scope) : isNeoScriptTypeAssignable(
60716
+ implicit ? this.contextualReferenceType(
60717
+ argument2,
60718
+ inferred,
60719
+ parameter3.type
60720
+ ) : inferred.type,
60721
+ parameter3.type,
60722
+ this.project
60723
+ )
60604
60724
  };
60605
60725
  })
60606
60726
  );
60727
+ const direct = resolve(false);
60728
+ return direct.kind === "ambiguous" ? resolve(true) : direct;
60607
60729
  }
60608
60730
  /**
60609
60731
  * Types for the §6.1.1 step-2 tie-break, computed only when several
@@ -60624,7 +60746,9 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
60624
60746
  const argument2 = args[index];
60625
60747
  if (!argument2) return null;
60626
60748
  try {
60627
- return this.resolveExpression(argument2, scope).type;
60749
+ if (isContextualReferenceExpression(argument2))
60750
+ this.typeOverloadEntries(argument2, scope);
60751
+ return this.resolveReferenceExpression(argument2, scope);
60628
60752
  } catch (error) {
60629
60753
  if (error instanceof CompileError) return null;
60630
60754
  throw error;
@@ -60994,7 +61118,8 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
60994
61118
  (argument2) => this.overloadArgumentKind(argument2, scope)
60995
61119
  );
60996
61120
  argumentsList2.forEach((argument2, index) => {
60997
- if (kinds[index] !== "typed") this.typeOverloadEntries(argument2, scope);
61121
+ if (kinds[index] !== "typed" || isContextualReferenceExpression(argument2))
61122
+ this.typeOverloadEntries(argument2, scope);
60998
61123
  });
60999
61124
  const typed = argumentsList2.map(
61000
61125
  (argument2, index) => kinds[index] === "targetTyped" ? void 0 : this.resolveReferenceExpression(argument2, scope)
@@ -61042,11 +61167,11 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
61042
61167
  const fits = argumentsList2.every((argument2, index) => {
61043
61168
  const parameter3 = requiredAt(parameters, index).type;
61044
61169
  const resolved = typed[index];
61045
- if (resolved === void 0 || argument2.kind === "tuple" || kinds[index] === "numeric" && parameter3.kind === "tuple") {
61170
+ if (resolved === void 0 || parameter3.kind === "reference" && isContextualReferenceExpression(argument2) || argument2.kind === "tuple" || kinds[index] === "numeric" && parameter3.kind === "tuple") {
61046
61171
  return this.targetTypedArgumentFits(argument2, parameter3, scope);
61047
61172
  }
61048
61173
  return this.typedArgumentFits(
61049
- this.readReferences(resolved, parameter3).type,
61174
+ this.contextualReferenceType(argument2, resolved, parameter3),
61050
61175
  requiredAt(kinds, index),
61051
61176
  parameter3
61052
61177
  );
@@ -61218,6 +61343,12 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
61218
61343
  }
61219
61344
  case "annotated":
61220
61345
  return this.entryFits(argument2.expression, parameter3, scope);
61346
+ case "coalesce":
61347
+ return this.entryFits(
61348
+ argument2.left,
61349
+ { ...parameter3, nullable: true },
61350
+ scope
61351
+ ) && this.entryFits(argument2.right, parameter3, scope);
61221
61352
  case "conditional": {
61222
61353
  const { trueScope, falseScope } = this.conditionalBranchScopes(
61223
61354
  argument2,
@@ -61297,12 +61428,12 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
61297
61428
  */
61298
61429
  entryFits(argument2, parameter3, scope) {
61299
61430
  const kind = this.overloadArgumentKind(argument2, scope);
61300
- if (kind === "targetTyped" || argument2.kind === "tuple" || kind === "numeric" && parameter3.kind === "tuple") {
61431
+ if (kind === "targetTyped" || parameter3.kind === "reference" && isContextualReferenceExpression(argument2) || argument2.kind === "tuple" || kind === "numeric" && parameter3.kind === "tuple") {
61301
61432
  return this.targetTypedArgumentFits(argument2, parameter3, scope);
61302
61433
  }
61303
- const resolved = isPureArgument(argument2) ? this.resolveExpression(argument2, scope) : this.overloadEntries.get(argument2) ?? this.resolveReferenceExpression(argument2, scope);
61434
+ const resolved = isPureArgument(argument2) ? this.resolveReferenceExpression(argument2, scope) : this.overloadEntries.get(argument2) ?? this.resolveReferenceExpression(argument2, scope);
61304
61435
  return this.typedArgumentFits(
61305
- this.readReferences(resolved, parameter3).type,
61436
+ this.contextualReferenceType(argument2, resolved, parameter3),
61306
61437
  kind,
61307
61438
  parameter3
61308
61439
  );
@@ -61345,6 +61476,10 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
61345
61476
  case "annotated":
61346
61477
  visit(argument2.expression, scope);
61347
61478
  return;
61479
+ case "coalesce":
61480
+ visit(argument2.left, scope);
61481
+ visit(argument2.right, scope);
61482
+ return;
61348
61483
  case "conditional": {
61349
61484
  visit(argument2.condition, scope);
61350
61485
  const { trueScope, falseScope } = this.conditionalBranchScopes(
@@ -61529,19 +61664,16 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
61529
61664
  pos,
61530
61665
  inferred?.typeArguments
61531
61666
  );
61532
- if (signature.typeArguments.length > 0)
61533
- this.options.onCallResolved?.(pos, {
61534
- ...symbol,
61535
- type: signature.returnType,
61536
- returnType: signature.returnType,
61537
- parameters: signature.parameters,
61538
- typeParameters: (symbol.typeParameters ?? []).map(
61539
- (parameter3, index) => ({
61540
- ...parameter3,
61541
- type: requiredAt(signature.typeArguments, index)
61542
- })
61543
- )
61544
- });
61667
+ this.options.onCallResolved?.(pos, {
61668
+ ...symbol,
61669
+ type: signature.returnType,
61670
+ returnType: signature.returnType,
61671
+ parameters: signature.parameters,
61672
+ typeParameters: (symbol.typeParameters ?? []).map((parameter3, index) => ({
61673
+ ...parameter3,
61674
+ type: requiredAt(signature.typeArguments, index)
61675
+ }))
61676
+ });
61545
61677
  const wireTypeArguments = signature.typeArguments.length ? {
61546
61678
  typeArguments: signature.typeArguments.map(
61547
61679
  (argument2) => toWireType(argument2, this.project)
@@ -61716,7 +61848,12 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
61716
61848
  const prior = choice?.preResolved[index];
61717
61849
  const cached = inferred?.resolved.get(argument2);
61718
61850
  let resolved;
61719
- if (prior !== void 0) resolved = this.readReferences(prior, target);
61851
+ if (prior !== void 0 && !(target?.kind === "reference" && isContextualReferenceExpression(argument2) && !isNeoScriptTypeAssignable(
61852
+ this.readReferences(prior, target).type,
61853
+ target,
61854
+ this.project
61855
+ )))
61856
+ resolved = this.readReferences(prior, target);
61720
61857
  else if (cached && (sameCompilationType(cached.type, expected) || cached.pointer.type === "callFunction" /* CallFunction */)) {
61721
61858
  resolved = cached;
61722
61859
  } else {
@@ -61725,6 +61862,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
61725
61862
  const compile = () => this.resolveExpression(argument2, scope, target);
61726
61863
  resolved = weighed ?? (argument2.kind === "lambda" && lambdas ? this.inLambdaFrame(lambdas, argument2, compile) : compile());
61727
61864
  }
61865
+ resolved = this.contextualReference(argument2, resolved, scope, target);
61728
61866
  resolved = this.convertSequence(resolved, target);
61729
61867
  if (!isUnknown(expected)) {
61730
61868
  this.requireReferenceArgument(
@@ -61799,7 +61937,10 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
61799
61937
  if (!hasIndependentTypeEvidence(argument2)) return;
61800
61938
  const prior = weighed?.typed[index];
61801
61939
  if (prior !== void 0) {
61802
- inference.add(this.readReferences(prior, void 0).type, pattern);
61940
+ inference.add(
61941
+ this.referenceInferenceType(argument2, prior, pattern),
61942
+ pattern
61943
+ );
61803
61944
  return;
61804
61945
  }
61805
61946
  const group = pattern.kind === "delegate" ? this.inferredMethodGroupTarget(argument2, probe) : null;
@@ -61810,10 +61951,13 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
61810
61951
  pattern
61811
61952
  );
61812
61953
  } else {
61813
- const resolved = weighed?.contextless.get(argument2) ?? this.resolveExpression(argument2, probe);
61954
+ const resolved = weighed?.contextless.get(argument2) ?? this.resolveReferenceExpression(argument2, probe);
61814
61955
  weighed?.contextless.set(argument2, resolved);
61815
61956
  resolvedArguments.set(argument2, resolved);
61816
- inference.add(resolved.type, pattern);
61957
+ inference.add(
61958
+ this.referenceInferenceType(argument2, resolved, pattern),
61959
+ pattern
61960
+ );
61817
61961
  }
61818
61962
  });
61819
61963
  const error = inference.solve(callbacks, (callback, inputs) => {
@@ -64883,7 +65027,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
64883
65027
  }
64884
65028
  return canonicalPath(target) ?? "the slot";
64885
65029
  }
64886
- /** P112 §3.1. A value never converts to a reference, since it has no row. */
65030
+ /** A transient value has no stored slot to pass by reference. */
64887
65031
  requireReferenceArgument(source, target, parameter3, pos) {
64888
65032
  if (target.kind !== "reference") return;
64889
65033
  if (source.kind === "reference") return;
@@ -64892,7 +65036,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
64892
65036
  const value = this.describe(source);
64893
65037
  const article = /^[aeiou]/i.test(value) ? "an" : "a";
64894
65038
  throw new CompileError(
64895
- `Argument \`${parameter3}\` needs a ${this.describe(target)}, not ${article} ${value}. Wrap a member path in Reference() to pass a stored ${this.describe(read)}.`,
65039
+ `Argument \`${parameter3}\` needs a ${this.describe(target)}, not ${article} ${value}. Pass a stored ${this.describe(read)} member instead.`,
64896
65040
  pos
64897
65041
  );
64898
65042
  }
@@ -67165,6 +67309,7 @@ function weighedLambda(probes, expected) {
67165
67309
  if (probe === void 0 || probe.type.kind !== "delegate") return void 0;
67166
67310
  if (probe.needsReturnContext !== true && sameCompilationType(probe.type.returnType, expected.returnType))
67167
67311
  return probe;
67312
+ if (expected.returnType.kind === "reference") return void 0;
67168
67313
  return probe.retype?.(expected.returnType);
67169
67314
  }
67170
67315
  function replaceReturns(instructions, replaced) {
@@ -67287,6 +67432,9 @@ function andList(texts) {
67287
67432
  if (texts.length <= 2) return texts.join(" and ");
67288
67433
  return `${texts.slice(0, -1).join(", ")}, and ${texts[texts.length - 1]}`;
67289
67434
  }
67435
+ function isContextualReferenceExpression(expression) {
67436
+ return expression.kind === "conditional" || expression.kind === "switchExpression" || expression.kind === "coalesce" || expression.kind === "annotated";
67437
+ }
67290
67438
  function isPureArgument(expression) {
67291
67439
  switch (expression.kind) {
67292
67440
  case "litInt":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neocompose/cli",
3
- "version": "0.89.0",
3
+ "version": "0.89.2",
4
4
  "description": "Neo Compose native project-source CLI with bidirectional sync.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -9,7 +9,7 @@ description: >-
9
9
  `@neocompose/cli` or `node cli/bin/neo.mjs` in the neo-compose repository.
10
10
  ---
11
11
 
12
- <!-- reviewed-through-cli: 0.89.0 -->
12
+ <!-- reviewed-through-cli: 0.89.2 -->
13
13
 
14
14
  # Neo Compose CLI
15
15
 
@@ -109,7 +109,7 @@ The marker near the top of `SKILL.md` must exactly match the package version,
109
109
  and this quoted copy is checked too:
110
110
 
111
111
  ```html
112
- <!-- reviewed-through-cli: 0.89.0 -->
112
+ <!-- reviewed-through-cli: 0.89.2 -->
113
113
  ```
114
114
 
115
115
  Keep this skill on current behavior. Upgrade steps, rollout prerequisites,