feat(shared): add scope-resolution types + constants (#910, RFC #909 Ring 1) (#949)

Lands the authoritative data model and constants for the pure scope-based
resolution RFC (#909) as Ring 1, part 1. No runtime behavior changes —
types + constants only.

New in gitnexus-shared/src/scope-resolution/:
  - types.ts — Scope, ScopeKind, ScopeId, DefId, Range, Capture,
    BindingRef, ImportEdge, TypeRef, Resolution, ResolutionEvidence,
    Reference, ReferenceIndex, LookupParams, RegistryContributor
  - evidence-weights.ts — EvidenceWeights constant map + typeBindingWeightAtDepth
    (RFC Appendix A)
  - origin-priority.ts — ORIGIN_PRIORITY constant map for deterministic
    tie-breaks (RFC Appendix B)
  - language-classification.ts — LanguageClassification type +
    LanguageClassifications map (production × 14, experimental × 2
    for vue/cobol; governs Ring 4 DAG-retirement gate)
  - symbol-definition.ts — SymbolDefinition moved from
    gitnexus/src/core/ingestion/model/symbol-table.ts so scope-resolution
    types can reference it from the shared package

Consumer updates:
  - symbol-table.ts: removes local SymbolDefinition declaration; imports
    from gitnexus-shared
  - model/index.ts: drops SymbolDefinition from barrel re-export per
    "direct imports from gitnexus-shared" convention (see
    gitnexus-shared feedback in project memory)
  - 9 source files + 5 test files: import SymbolDefinition directly
    from 'gitnexus-shared'

Verification:
  - gitnexus-shared builds clean (tsc)
  - gitnexus builds clean (scripts/build.js)
  - 131/132 unit test files pass; 3767 tests green
  - Zero behavior changes; SymbolDefinition shape unchanged

Blocks: #911 (LanguageProvider hook interface extensions) and all of
Ring 2 (#912-#925). Closes part of #909.
This commit is contained in:
Gergő Magyar 2026-04-18 12:55:09 +01:00 committed by GitHub
parent d9da7d6692
commit afc0a8b6c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 525 additions and 48 deletions

View file

@ -23,3 +23,36 @@ export type { MroStrategy } from './mro-strategy.js';
// Pipeline progress
export type { PipelinePhase, PipelineProgress } from './pipeline.js';
// ─── Scope-based resolution — RFC #909 (Ring 1 #910) ────────────────────────
// Data model (RFC §2)
export type { SymbolDefinition } from './scope-resolution/symbol-definition.js';
export type {
ScopeId,
DefId,
ScopeKind,
Range,
Capture,
BindingRef,
ImportEdge,
TypeRef,
Scope,
ResolutionEvidence,
Resolution,
Reference,
ReferenceIndex,
LookupParams,
RegistryContributor,
} from './scope-resolution/types.js';
// Evidence + tie-break constants (RFC Appendix A, Appendix B)
export { EvidenceWeights, typeBindingWeightAtDepth } from './scope-resolution/evidence-weights.js';
export { ORIGIN_PRIORITY } from './scope-resolution/origin-priority.js';
export type { OriginForTieBreak } from './scope-resolution/origin-priority.js';
// Language classification (RFC §6.1 Ring 3/4 governance)
export {
LanguageClassifications,
isProductionLanguage,
} from './scope-resolution/language-classification.js';
export type { LanguageClassification } from './scope-resolution/language-classification.js';

View file

@ -0,0 +1,90 @@
/**
* `EvidenceWeights` RFC Appendix A (authoritative values).
*
* Starting calibration for scope-based resolution. Shadow-first rollout
* tunes these against legacy DAG parity. Every `ResolutionEvidence.weight`
* value in the codebase MUST reference this map; inline magic numbers are a
* lint violation. Extends issue #429 (centralize hardcoded confidence values).
*
* Evidence composes additively inside `composeEvidence`; the sum is capped
* at 1.0 in `Resolution.confidence`.
*/
/**
* Authoritative weight map. Keys are a mix of `ResolutionEvidence.kind`
* values and special modifiers (scope-chain depth, MRO depth decay,
* unlinked-import multiplicative cap).
*/
export const EvidenceWeights = {
// ─── Where-found signals (visibility) ─────────────────────────────────────
/** `BindingRef.origin === 'local'` */
local: 0.55,
/** `BindingRef.origin === 'import'` */
import: 0.45,
/** `BindingRef.origin === 'reexport'` */
reexport: 0.4,
/** `BindingRef.origin === 'namespace'` */
namespace: 0.4,
/** `BindingRef.origin === 'wildcard'` */
wildcard: 0.3,
// ─── Scope-chain deduction (per-hop) ──────────────────────────────────────
/** Deducted per parent-hop taken (depth-0 = 0, depth-1 = 0.02, …). */
scopeChainPerDepth: -0.02,
// ─── Receiver-type-binding signal (decays by MRO depth) ───────────────────
/**
* Weight applied when the receiver's type binding resolves to a class that
* declares the candidate as a method/field. Decays by MRO depth: direct
* class = index 0; 1 parent hop = index 1; etc. Falls back to the last
* value for depths beyond the table.
*/
typeBindingByMroDepth: [0.5, 0.42, 0.36, 0.32, 0.3] as const,
// ─── Corroborating signals ────────────────────────────────────────────────
/** `def.ownerId === resolvedReceiver.def.id` (exact owner match). */
ownerMatch: 0.2,
/** Explanatory only retained for debuggability. Never discriminates
* because surviving candidates already passed `acceptedKinds`. */
kindMatch: 0.0,
// ─── Arity compatibility (from `provider.arityCompatibility`) ─────────────
/** `provider.arityCompatibility(...) === 'compatible'` */
arityMatchCompatible: 0.1,
/** `provider.arityCompatibility(...) === 'unknown'` */
arityMatchUnknown: 0.0,
/** `provider.arityCompatibility(...) === 'incompatible'` penalizes;
* candidates filtered only when a compatible candidate exists. */
arityMatchIncompatible: -0.15,
// ─── Global fallback (only when nothing lexically visible) ────────────────
/** Hit via `QualifiedNameIndex.byQualifiedName`. */
globalQualified: 0.35,
/** Fallback hit in a `byName` index (and nothing was lexically visible). */
globalName: 0.1,
// ─── Degraded signals ─────────────────────────────────────────────────────
/** Call/reference flowing through a `dynamic-unresolved` edge. */
dynamicImportUnresolved: 0.02,
// ─── Unresolved-import cap (multiplicative, applied per-signal) ───────────
/**
* Multiplicative cap on the edge-derived evidence signal
* (`import`/`wildcard`/`reexport`/`namespace`) when
* `ImportEdge.linkStatus === 'unresolved'`. Independent corroborating
* signals on the same candidate (`owner-match`, `arity-match`,
* `type-binding`) are NOT penalized.
*/
unlinkedImportMultiplier: 0.5,
} as const;
/**
* Look up the `type-binding` signal weight for a given MRO depth, falling
* back to the last tabulated value for depths beyond the table.
*/
export function typeBindingWeightAtDepth(mroDepth: number): number {
const table = EvidenceWeights.typeBindingByMroDepth;
if (mroDepth < 0) return table[0];
if (mroDepth >= table.length) return table[table.length - 1];
return table[mroDepth];
}

View file

@ -0,0 +1,49 @@
/**
* `LanguageClassification` RFC §6.1 Ring 3 / Ring 4 governance.
*
* Classifies each `SupportedLanguages` member for the rollout. Ring 4 (DAG
* retirement) is gated on *all production languages* being registry-primary
* and stable for one release cycle; `experimental` and `quarantined`
* languages do not block.
*
* Initial classification (locked in Ring 1 #910):
* - production: javascript, typescript, python, java, c, cpp, csharp, go,
* ruby, rust, php, kotlin, swift, dart
* - experimental: vue (embedded-language / SFC complexity),
* cobol (regex-provider path)
* - quarantined: (none)
*/
import { SupportedLanguages } from '../languages.js';
export type LanguageClassification = 'production' | 'experimental' | 'quarantined';
/**
* The canonical classification for each supported language. Governance
* changes (promote `experimental` `production`, quarantine a language, )
* update this map in a dedicated PR.
*/
export const LanguageClassifications: Readonly<Record<SupportedLanguages, LanguageClassification>> =
{
[SupportedLanguages.JavaScript]: 'production',
[SupportedLanguages.TypeScript]: 'production',
[SupportedLanguages.Python]: 'production',
[SupportedLanguages.Java]: 'production',
[SupportedLanguages.C]: 'production',
[SupportedLanguages.CPlusPlus]: 'production',
[SupportedLanguages.CSharp]: 'production',
[SupportedLanguages.Go]: 'production',
[SupportedLanguages.Ruby]: 'production',
[SupportedLanguages.Rust]: 'production',
[SupportedLanguages.PHP]: 'production',
[SupportedLanguages.Kotlin]: 'production',
[SupportedLanguages.Swift]: 'production',
[SupportedLanguages.Dart]: 'production',
[SupportedLanguages.Vue]: 'experimental',
[SupportedLanguages.Cobol]: 'experimental',
};
/** Convenience predicate: is this language gating Ring 4 retirement? */
export function isProductionLanguage(lang: SupportedLanguages): boolean {
return LanguageClassifications[lang] === 'production';
}

View file

@ -0,0 +1,30 @@
/**
* `ORIGIN_PRIORITY` RFC Appendix B (authoritative values).
*
* Tie-break ordering applied inside `Registry.lookup` Step 7 when
* `|Δconfidence| < 0.001` between two `Resolution` candidates. Lower number
* = stronger (wins the tie).
*
* Full tie-break order (§4.2 Step 7):
* confidence DESC scope depth ASC MRO depth ASC ORIGIN_PRIORITY ASC
* DefId.localeCompare
*/
export type OriginForTieBreak =
| 'local'
| 'import'
| 'reexport'
| 'namespace'
| 'wildcard'
| 'global-qualified'
| 'global-name';
export const ORIGIN_PRIORITY: Readonly<Record<OriginForTieBreak, number>> = {
local: 0,
import: 1,
reexport: 2,
namespace: 3,
wildcard: 4,
'global-qualified': 5,
'global-name': 6,
};

View file

@ -0,0 +1,35 @@
/**
* `SymbolDefinition` the canonical shape of an indexed symbol record.
*
* Historically defined in `gitnexus/src/core/ingestion/model/symbol-table.ts`;
* moved into `gitnexus-shared` as part of RFC #909 Ring 1 (#910) so the
* scope-resolution types that reference it can live in the shared package
* alongside their consumers (`gitnexus/` and `gitnexus-web/`).
*
* Shape is unchanged from the prior local definition.
*/
import type { NodeLabel } from '../graph/types.js';
export interface SymbolDefinition {
nodeId: string;
filePath: string;
type: NodeLabel;
/** Canonical dot-separated qualified type name for class-like symbols
* (e.g. `App.Models.User`). Falls back to the simple symbol name when no
* package/namespace/module scope exists or no explicit qualified metadata is provided. */
qualifiedName?: string;
parameterCount?: number;
/** Number of required (non-optional, non-default) parameters.
* Enables range-based arity filtering: argCount >= requiredParameterCount && argCount <= parameterCount. */
requiredParameterCount?: number;
/** Per-parameter type names for overload disambiguation (e.g. ['int', 'String']).
* Populated when parameter types are resolvable from AST (any typed language). */
parameterTypes?: string[];
/** Raw return type text extracted from AST (e.g. 'User', 'Promise<User>') */
returnType?: string;
/** Declared type for non-callable symbols — fields/properties (e.g. 'Address', 'List<User>') */
declaredType?: string;
/** Links Method/Constructor/Property to owning Class/Struct/Trait nodeId */
ownerId?: string;
}

View file

@ -0,0 +1,264 @@
/**
* Scope-resolution type definitions RFC §2 data model (authoritative source).
*
* See: https://www.notion.so/346dc50b6ed281cfaacbe480bf231d50
*
* Anti-drift rule: every type, interface, and enum defined here is the single
* source of truth. Later code that references these names must import them
* from `gitnexus-shared`; it must not re-define them locally.
*
* Lifecycle contract (RFC §2.8): scopes are **constructed during extraction,
* linked during finalize, immutable after finalize**. All fields are
* `readonly` at the type level; `Object.freeze` is applied at runtime in dev
* builds. `ReferenceIndex` is the sole structure populated after freeze by
* resolution, before emission.
*/
import type { NodeLabel } from '../graph/types.js';
import type { SymbolDefinition } from './symbol-definition.js';
// ─── §2.1 Type aliases ──────────────────────────────────────────────────────
/** Stable per-(file, range, kind) scope identifier; interned for identity-fast equality. */
export type ScopeId = string;
/** Stable symbol-definition identifier (graph nodeId). */
export type DefId = string;
/** Kinds of lexical scope a `Scope` node can represent. */
export type ScopeKind =
| 'Module' // file root
| 'Namespace' // C++ namespace, C# namespace, Kotlin package-object, Rust mod
| 'Class' // class/struct/trait/interface body
| 'Function' // function/method/closure/lambda body
| 'Block' // { ... }, if-body, for-body, with-body, match arms
| 'Expression'; // comprehensions, for-init, pattern bindings, lambda param lists
// ─── Range + Capture (parser-agnostic) ──────────────────────────────────────
/** Source-text range. 1-based `startLine`/`endLine`; 0-based `startCol`/`endCol`. */
export interface Range {
readonly startLine: number;
readonly startCol: number;
readonly endLine: number;
readonly endCol: number;
}
/**
* Tagged capture emitted by a LanguageProvider's `emitScopeCaptures` hook.
*
* Parser-agnostic: tree-sitter queries and COBOL's regex tagger both produce
* `Capture[]`. The central `ScopeExtractor` consumes captures without
* knowing which parser produced them.
*/
export interface Capture {
/** Capture name, including leading `@` (e.g., `'@scope.module'`, `'@declaration.class'`). */
readonly name: string;
readonly range: Range;
/** The captured source text. */
readonly text: string;
}
// ─── §2.4 ImportEdge ────────────────────────────────────────────────────────
/**
* A cross-file import edge attached to a module/namespace scope.
*
* Raw (unlinked) edges are emitted during parse (Phase 1); `targetModuleScope`
* and `targetDefId` are filled in during finalize (Phase 2) via SCC-aware
* bounded-fixpoint linking (RFC §3.2).
*/
export interface ImportEdge {
/** How this scope sees the imported name (after alias). */
readonly localName: string;
/** Exporting file; `null` only when `kind === 'dynamic-unresolved'`. */
readonly targetFile: string | null;
/** The name under which the target exports this symbol. */
readonly targetExportedName: string;
/** Pre-resolved at finalize: the module scope of the exporting file. */
readonly targetModuleScope?: ScopeId;
/** Pre-resolved at finalize: the exported symbol's `DefId`. */
readonly targetDefId?: DefId;
readonly kind:
| 'named'
| 'alias'
| 'namespace'
| 'wildcard-expanded'
| 'reexport'
| 'dynamic-unresolved';
/** Re-export chain, for provenance (e.g., `['./y']` when re-exported via `./y`). */
readonly transitiveVia?: readonly string[];
/** Set to `'unresolved'` when the SCC fixpoint could not link this edge. */
readonly linkStatus?: 'unresolved';
}
// ─── §2.3 BindingRef ────────────────────────────────────────────────────────
/**
* A name binding visible at a scope, with provenance.
*
* Provenance stays at the visibility layer a name being visible because it
* is local vs imported vs wildcard-expanded vs re-exported is a property of
* the binding itself. This keeps evidence emission and `import-use` reference
* stamping first-class instead of reconstructing provenance from a side table.
*/
export interface BindingRef {
readonly def: SymbolDefinition;
readonly origin: 'local' | 'import' | 'namespace' | 'wildcard' | 'reexport';
/** Non-null for non-local origins; carries the `ImportEdge` that brought the name into this scope. */
readonly via?: ImportEdge;
}
// ─── §2.5 TypeRef ───────────────────────────────────────────────────────────
/**
* A reference to a named type, anchored at its declaration site.
*
* Design choice: raw name + declaration-site scope, resolved at lookup time.
* Pre-resolution would invert the extraction/resolution wall. Deferred thunks
* add no capability. Structured type systems are months of work per language.
* This shape keeps V1 tractable while preserving correctness for aliases,
* re-exports, and nested modules. Generics deferred to V2 via `typeArgs`.
*/
export interface TypeRef {
/** The name as written in source (e.g., `'User'`, `'models.User'`, `'List'`). */
readonly rawName: string;
/** Anchor for resolving `rawName` — the scope where the annotation/inference was written. */
readonly declaredAtScope: ScopeId;
readonly source:
| 'annotation'
| 'parameter-annotation'
| 'return-annotation'
| 'self'
| 'assignment-inferred'
| 'constructor-inferred'
| 'receiver-propagated';
/** Reserved for V2+: generic type arguments (`List<User>` → `[TypeRef('User')]`). V1 ignores. */
readonly typeArgs?: readonly TypeRef[];
}
// ─── §2.2 Scope ─────────────────────────────────────────────────────────────
/**
* The canonical lexical-scope node. Forms the spine of the SemanticModel.
*
* ScopeId shape (RFC §2.2): `scope:{filePath}#{startLine}:{startCol}-{endLine}:{endCol}:{kind}`
* deterministic, stable across reparses of the same source, interned.
*/
export interface Scope {
readonly id: ScopeId;
readonly parent: ScopeId | null;
readonly kind: ScopeKind;
readonly range: Range;
readonly filePath: string;
/** Names visible from this scope. Provenance preserved via `BindingRef.origin`. */
readonly bindings: ReadonlyMap<string, readonly BindingRef[]>;
/** Defs structurally owned by this scope (e.g., methods owned by a class body scope). */
readonly ownedDefs: readonly SymbolDefinition[];
/** Import edges attached to this scope. Mostly module/namespace scopes, but some
* languages allow local imports (Python `def f(): from x import Y`, Rust
* fn-local `use`, TS dynamic `import()`). */
readonly imports: readonly ImportEdge[];
/** Local type facts visible from this scope (parameter annotations, `self` binding, etc.). */
readonly typeBindings: ReadonlyMap<string, TypeRef>;
}
// ─── §2.6 Resolution + ResolutionEvidence ───────────────────────────────────
/**
* One piece of evidence for a `Resolution`. Multiple signals corroborate a
* single match; their weights compose additively to produce `confidence`.
*
* Weights come from `EvidenceWeights` (see `./evidence-weights.ts`).
*/
export interface ResolutionEvidence {
readonly kind:
| 'local'
| 'scope-chain'
| 'import'
| 'type-binding'
| 'owner-match'
| 'kind-match'
| 'arity-match'
| 'global-name'
| 'global-qualified'
| 'dynamic-import-unresolved';
/** Signal weight, sourced from `EvidenceWeights`. Additive; sum capped at 1.0. */
readonly weight: number;
/** Optional debug annotation (e.g., `'matched via self: User'`). */
readonly note?: string;
}
/**
* A ranked resolution candidate returned by `ClassRegistry.lookup` /
* `MethodRegistry.lookup` / `FieldRegistry.lookup`. Evidence composes
* additively; callers read `[0]` for the one-shot answer or inspect the
* evidence trace for debugging.
*/
export interface Resolution {
readonly def: SymbolDefinition;
/** Σ of `evidence[].weight`, capped at 1.0. */
readonly confidence: number;
readonly evidence: readonly ResolutionEvidence[];
/** Optional debug trace: scopes walked to reach `def`. */
readonly path?: readonly ScopeId[];
}
// ─── §2.7 Reference + ReferenceIndex ────────────────────────────────────────
/**
* A post-resolution usage fact: some code at `atRange` inside `fromScope`
* references `toDef` with the given confidence/evidence. Materialized by the
* resolution phase; emitted as graph edges (`CALLS`/`READS`/`WRITES`/etc.)
* during the emit phase.
*/
export interface Reference {
/** Innermost lexical scope containing `atRange`. */
readonly fromScope: ScopeId;
readonly toDef: DefId;
/** Location of the reference in source. */
readonly atRange: Range;
readonly kind: 'call' | 'read' | 'write' | 'type-reference' | 'inherits' | 'import-use';
readonly confidence: number;
readonly evidence: readonly ResolutionEvidence[];
}
/**
* Two-way index over `Reference` records, populated during the resolution
* phase. Scopes stay immutable after finalize; references accumulate here.
*/
export interface ReferenceIndex {
readonly bySourceScope: ReadonlyMap<ScopeId, readonly Reference[]>;
readonly byTargetDef: ReadonlyMap<DefId, readonly Reference[]>;
}
// ─── §4.1 LookupParams ──────────────────────────────────────────────────────
/**
* Opaque placeholder for the per-kind registry passed as the owner-scoped
* contributor. Typed concretely in Ring 2 SHARED (#917); kept as `unknown`
* here so Ring 1 can ship without pulling in the registry implementation.
*/
export type RegistryContributor = unknown;
/**
* Parameters accepted by `Registry.lookup`. Three registries (Class/Method/
* Field) run the same 7-step algorithm with different parameter tuples; see
* RFC §4.4 for per-registry specializations.
*/
export interface LookupParams {
readonly acceptedKinds: readonly NodeLabel[];
/** Class lookups: false. Method/Field lookups: true. */
readonly useReceiverTypeBinding: boolean;
readonly ownerScopedContributor: RegistryContributor | null;
/** Optional arity hint fed to `provider.arityCompatibility`. */
readonly arityHint?: number;
/** Explicit receiver name (e.g., `'user'` in `user.save()`). When present,
* the receiver's type binding at the callsite scope is used; otherwise
* the enclosing method's implicit `self`/`this` is consulted. See §4.1. */
readonly explicitReceiver?: { readonly name: string };
}

View file

@ -1,11 +1,7 @@
import { KnowledgeGraph } from '../graph/types.js';
import { ASTCache } from './ast-cache.js';
import type {
SymbolDefinition,
SymbolTableReader,
HeritageMap,
ExtractedHeritage,
} from './model/index.js';
import type { SymbolDefinition } from 'gitnexus-shared';
import type { SymbolTableReader, HeritageMap, ExtractedHeritage } from './model/index.js';
import { CLASS_TYPES, CALL_TARGET_TYPES, lookupMethodByOwnerWithMRO } from './model/index.js';
import type { DispatchDecision, ReceiverEnriched } from './call-types.js';

View file

@ -5,7 +5,7 @@
* Stores Property symbols keyed by `ownerNodeId\0fieldName` for O(1) lookup.
*/
import type { SymbolDefinition } from './symbol-table.js';
import type { SymbolDefinition } from 'gitnexus-shared';
// ---------------------------------------------------------------------------
// Public read-only interface

View file

@ -26,7 +26,6 @@ export {
type SymbolTableReader,
type SymbolTableWriter,
createSymbolTable,
type SymbolDefinition,
type AddMetadata,
CLASS_TYPES,
CLASS_TYPES_TUPLE,
@ -36,6 +35,8 @@ export {
type FreeCallableLabel,
CALL_TARGET_TYPES,
} from './symbol-table.js';
// `SymbolDefinition` moved to `gitnexus-shared` (RFC #909 Ring 1 #910).
// Consumers should import it directly from `gitnexus-shared`, not via this barrel.
// Type registry (classes, structs, interfaces, enums, records, impls)
export {

View file

@ -7,7 +7,7 @@
* (array values) and arity-based filtering.
*/
import type { SymbolDefinition } from './symbol-table.js';
import type { SymbolDefinition } from 'gitnexus-shared';
// ---------------------------------------------------------------------------
// Public read-only interface

View file

@ -49,8 +49,8 @@
* `NodeLabel` is missing from all three sets.
*/
import type { NodeLabel } from 'gitnexus-shared';
import type { SymbolDefinition, ClassLikeLabel, FreeCallableLabel } from './symbol-table.js';
import type { NodeLabel, SymbolDefinition } from 'gitnexus-shared';
import type { ClassLikeLabel, FreeCallableLabel } from './symbol-table.js';
import { FREE_CALLABLE_TYPES } from './symbol-table.js';
import type { MutableTypeRegistry } from './type-registry.js';
import type { MutableMethodRegistry } from './method-registry.js';

View file

@ -18,7 +18,8 @@
* (three O(1) index lookups with a narrow, type-specific result set).
*/
import type { SymbolDefinition, SymbolTableReader } from './symbol-table.js';
import type { SymbolDefinition } from 'gitnexus-shared';
import type { SymbolTableReader } from './symbol-table.js';
import type { MutableSemanticModel } from './semantic-model.js';
import { createSemanticModel } from './semantic-model.js';

View file

@ -6,7 +6,7 @@
* on resolution-context.ts (circular dependency risk).
*/
import type { SymbolDefinition } from './symbol-table.js';
import type { SymbolDefinition } from 'gitnexus-shared';
import type { SemanticModel } from './semantic-model.js';
import type { HeritageMap } from './heritage-map.js';
import type { MroStrategy } from 'gitnexus-shared';

View file

@ -53,12 +53,8 @@ import type { FieldRegistry, MutableFieldRegistry } from './field-registry.js';
import { createTypeRegistry } from './type-registry.js';
import { createMethodRegistry } from './method-registry.js';
import { createFieldRegistry } from './field-registry.js';
import type {
SymbolTableReader,
SymbolTableWriter,
SymbolDefinition,
AddMetadata,
} from './symbol-table.js';
import type { SymbolDefinition } from 'gitnexus-shared';
import type { SymbolTableReader, SymbolTableWriter, AddMetadata } from './symbol-table.js';
import { createSymbolTable } from './symbol-table.js';
import { createRegistrationTable } from './registration-table.js';

View file

@ -34,7 +34,7 @@
* logic up the dependency chain instead.
*/
import type { NodeLabel } from 'gitnexus-shared';
import type { NodeLabel, SymbolDefinition } from 'gitnexus-shared';
/**
* Class-like NodeLabels used for qualifiedName fallback inside
@ -113,28 +113,10 @@ export const CALL_TARGET_TYPES: ReadonlySet<NodeLabel> = new Set<NodeLabel>([
'Constructor',
]);
export interface SymbolDefinition {
nodeId: string;
filePath: string;
type: NodeLabel;
/** Canonical dot-separated qualified type name for class-like symbols
* (e.g. `App.Models.User`). Falls back to the simple symbol name when no
* package/namespace/module scope exists or no explicit qualified metadata is provided. */
qualifiedName?: string;
parameterCount?: number;
/** Number of required (non-optional, non-default) parameters.
* Enables range-based arity filtering: argCount >= requiredParameterCount && argCount <= parameterCount. */
requiredParameterCount?: number;
/** Per-parameter type names for overload disambiguation (e.g. ['int', 'String']).
* Populated when parameter types are resolvable from AST (any typed language). */
parameterTypes?: string[];
/** Raw return type text extracted from AST (e.g. 'User', 'Promise<User>') */
returnType?: string;
/** Declared type for non-callable symbols — fields/properties (e.g. 'Address', 'List<User>') */
declaredType?: string;
/** Links Method/Constructor/Property to owning Class/Struct/Trait nodeId */
ownerId?: string;
}
// `SymbolDefinition` moved to `gitnexus-shared` as part of RFC #909 Ring 1
// (see #910). It is imported at the top of this file from `gitnexus-shared`
// and re-used unchanged throughout. Consumers should import
// `SymbolDefinition` directly from `gitnexus-shared`, not via this file.
/**
* Optional metadata accepted by {@link SymbolTable.add}. Kept as a separate

View file

@ -6,7 +6,7 @@
* Also includes a separate index for Rust Impl blocks.
*/
import type { SymbolDefinition } from './symbol-table.js';
import type { SymbolDefinition } from 'gitnexus-shared';
// ---------------------------------------------------------------------------
// Public read-only interface

View file

@ -8,7 +8,7 @@
import { describe, it, expect } from 'vitest';
import { createFieldRegistry } from '../../../src/core/ingestion/model/field-registry.js';
import type { SymbolDefinition } from '../../../src/core/ingestion/model/symbol-table.js';
import type { SymbolDefinition } from 'gitnexus-shared';
import { makeDef as makeBaseDef } from './helpers.js';
const makeDef = (overrides: Partial<SymbolDefinition> = {}): SymbolDefinition =>

View file

@ -6,7 +6,7 @@
* test file that uses it.
*/
import type { SymbolDefinition } from '../../../src/core/ingestion/model/symbol-table.js';
import type { SymbolDefinition } from 'gitnexus-shared';
/**
* Build a {@link SymbolDefinition} with sensible defaults. Every field

View file

@ -9,7 +9,7 @@ import { createTypeRegistry } from '../../../src/core/ingestion/model/type-regis
import { createMethodRegistry } from '../../../src/core/ingestion/model/method-registry.js';
import { createFieldRegistry } from '../../../src/core/ingestion/model/field-registry.js';
import { ALL_NODE_LABELS } from '../../../src/core/ingestion/model/index.js';
import type { SymbolDefinition } from '../../../src/core/ingestion/model/symbol-table.js';
import type { SymbolDefinition } from 'gitnexus-shared';
import { makeDef as makeBaseDef } from './helpers.js';
// ---------------------------------------------------------------------------

View file

@ -10,7 +10,7 @@
import { describe, it, expect } from 'vitest';
import { createTypeRegistry } from '../../../src/core/ingestion/model/type-registry.js';
import type { SymbolDefinition } from '../../../src/core/ingestion/model/symbol-table.js';
import type { SymbolDefinition } from 'gitnexus-shared';
import { makeDef as makeBaseDef } from './helpers.js';
const makeDef = (overrides: Partial<SymbolDefinition> = {}): SymbolDefinition =>

View file

@ -1,7 +1,7 @@
import { describe, it, expect, vi } from 'vitest';
import { buildTypeEnv, type TypeEnvironment } from '../../src/core/ingestion/type-env.js';
import { BindingAccumulator } from '../../src/core/ingestion/binding-accumulator.js';
import { type SymbolDefinition } from '../../src/core/ingestion/model/symbol-table.js';
import { type SymbolDefinition } from 'gitnexus-shared';
import {
createSemanticModel,
type SemanticModel,