diff --git a/gitnexus-shared/src/index.ts b/gitnexus-shared/src/index.ts index 860558016a..0ac74b1ed3 100644 --- a/gitnexus-shared/src/index.ts +++ b/gitnexus-shared/src/index.ts @@ -83,7 +83,12 @@ export type { ResolveTypeRefContext } from './scope-resolution/resolve-type-ref. // ScopeExtractor output contracts (RFC §3.2 Phase 1; Ring 2 PKG #919) export type { ParsedFile } from './scope-resolution/parsed-file.js'; -export type { ReferenceSite, ReferenceKind, CallForm } from './scope-resolution/reference-site.js'; +export type { + ReferenceSite, + ReferenceKind, + CallForm, + MixedChainStep, +} from './scope-resolution/reference-site.js'; export type { CallableFlowOperand, CallableFlowExpectedSignature, diff --git a/gitnexus-shared/src/scope-resolution/reference-site.ts b/gitnexus-shared/src/scope-resolution/reference-site.ts index 5ced6e1762..1632bfd20b 100644 --- a/gitnexus-shared/src/scope-resolution/reference-site.ts +++ b/gitnexus-shared/src/scope-resolution/reference-site.ts @@ -124,3 +124,18 @@ export interface ReferenceSite { */ readonly argumentTypeClasses?: readonly ParameterTypeClass[]; } + +/** + * One step in a mixed receiver chain — the decoded form of a receiver that is + * itself an expression rather than a bare name. + * + * For `svc.getUser().address.save()`, the receiver of `save` decodes to + * `[{ kind: 'call', name: 'getUser' }, { kind: 'field', name: 'address' }]` + * over a base receiver of `svc`. + * + * Lives here rather than beside its producer because it is part of the + * ScopeExtractor output contract that this package owns: the producer + * (`extractMixedChain`) walks a tree-sitter AST and so must stay in the + * analyzer, but the shape it yields crosses into resolution. + */ +export type MixedChainStep = { kind: 'field' | 'call'; name: string }; diff --git a/gitnexus/src/core/ingestion/utils/call-analysis.ts b/gitnexus/src/core/ingestion/utils/call-analysis.ts index c7eb8e45fd..831045b0c1 100644 --- a/gitnexus/src/core/ingestion/utils/call-analysis.ts +++ b/gitnexus/src/core/ingestion/utils/call-analysis.ts @@ -1,3 +1,5 @@ +import type { MixedChainStep } from 'gitnexus-shared'; + import type { SyntaxNode } from './ast-helpers.js'; import { CALL_ARGUMENT_LIST_TYPES } from './ast-helpers.js'; @@ -362,8 +364,14 @@ const FIELD_ACCESS_NODE_TYPES = new Set([ 'member_binding_expression', // C# null-conditional (user?.Address) ]); -/** One step in a mixed receiver chain. */ -export type MixedChainStep = { kind: 'field' | 'call'; name: string }; +/** + * One step in a mixed receiver chain. + * + * Owned by `gitnexus-shared` — it is part of the ScopeExtractor output + * contract, and resolution consumes it. Re-exported here so the producer's + * existing importers keep a single import site. + */ +export type { MixedChainStep }; /** * Walk a receiver AST node that is itself a call expression, accumulating the