Skip to main content

fallow_graph/graph/
types.rs

1//! Shared graph types: module nodes, re-export edges, export symbols, and references.
2
3use std::ops::Range;
4use std::path::PathBuf;
5
6use fallow_types::discover::FileId;
7use fallow_types::extract::ExportName;
8
9/// A single module in the graph.
10#[derive(Debug)]
11pub struct ModuleNode {
12    /// Unique identifier for this module.
13    pub file_id: FileId,
14    /// Absolute path to the module file.
15    pub path: PathBuf,
16    /// Range into the flat `edges` array.
17    pub edge_range: Range<usize>,
18    /// Exports declared by this module.
19    pub exports: Vec<ExportSymbol>,
20    /// Re-exports from this module (export { x } from './y', export * from './z').
21    pub re_exports: Vec<ReExportEdge>,
22    /// Whether this module is an entry point.
23    pub is_entry_point: bool,
24    /// Whether this module is reachable from any entry point.
25    pub is_reachable: bool,
26    /// Whether this module has CJS exports (module.exports / exports.*).
27    pub has_cjs_exports: bool,
28}
29
30/// A re-export edge, tracking which exports are forwarded from which module.
31#[derive(Debug)]
32pub struct ReExportEdge {
33    /// The module being re-exported from.
34    pub source_file: FileId,
35    /// The name imported from the source (or "*" for star re-exports).
36    pub imported_name: String,
37    /// The name exported from this module.
38    pub exported_name: String,
39    /// Whether this is a type-only re-export.
40    pub is_type_only: bool,
41}
42
43/// An export with reference tracking.
44#[derive(Debug)]
45pub struct ExportSymbol {
46    /// The exported name (named or default).
47    pub name: ExportName,
48    /// Whether this is a type-only export.
49    pub is_type_only: bool,
50    /// Whether this export has a `@public` JSDoc/TSDoc tag.
51    /// Exports marked `@public` are never reported as unused.
52    pub is_public: bool,
53    /// Source span of the export declaration.
54    pub span: oxc_span::Span,
55    /// Which files reference this export.
56    pub references: Vec<SymbolReference>,
57    /// Members of this export (enum members, class members).
58    pub members: Vec<fallow_types::extract::MemberInfo>,
59}
60
61/// A reference to an export from another file.
62#[derive(Debug, Clone)]
63pub struct SymbolReference {
64    /// The file that references this export.
65    pub from_file: FileId,
66    /// How the export is referenced.
67    pub kind: ReferenceKind,
68    /// Byte span of the import statement in the referencing file.
69    /// Used by the LSP to locate references for Code Lens navigation.
70    pub import_span: oxc_span::Span,
71}
72
73/// How an export is referenced.
74#[derive(Debug, Clone, PartialEq, Eq)]
75pub enum ReferenceKind {
76    /// A named import (`import { foo }`).
77    NamedImport,
78    /// A default import (`import Foo`).
79    DefaultImport,
80    /// A namespace import (`import * as ns`).
81    NamespaceImport,
82    /// A re-export (`export { foo } from './bar'`).
83    ReExport,
84    /// A dynamic import (`import('./foo')`).
85    DynamicImport,
86    /// A side-effect import (`import './styles'`).
87    SideEffectImport,
88}
89
90// Size assertions for types defined in this module.
91// `ExportSymbol` and `SymbolReference` are stored in Vecs per module node.
92// `ReExportEdge` is stored in a Vec per module for re-export chain resolution.
93#[cfg(target_pointer_width = "64")]
94const _: () = assert!(std::mem::size_of::<ExportSymbol>() == 88);
95#[cfg(target_pointer_width = "64")]
96const _: () = assert!(std::mem::size_of::<SymbolReference>() == 16);
97#[cfg(target_pointer_width = "64")]
98const _: () = assert!(std::mem::size_of::<ReExportEdge>() == 56);
99// `ModuleNode` is stored in a Vec — one per discovered file.
100// PathBuf has different sizes on Unix vs Windows, so restrict to Unix.
101#[cfg(all(target_pointer_width = "64", unix))]
102const _: () = assert!(std::mem::size_of::<ModuleNode>() == 96);