infiniloom_engine/analysis/
types.rs

1//! Core types for the analysis module
2//!
3//! These types support all 21 languages: Python, JavaScript, TypeScript, Rust, Go, Java,
4//! C, C++, C#, Ruby, Bash, PHP, Kotlin, Swift, Scala, Haskell, Elixir, Clojure, OCaml, Lua, R
5
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9/// Full type signature with parameters, return type, generics, and throws
10#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
11pub struct TypeSignature {
12    /// Function/method parameters with full type information
13    pub parameters: Vec<ParameterInfo>,
14    /// Return type (None for void/unit)
15    pub return_type: Option<TypeInfo>,
16    /// Generic type parameters (e.g., <T, U: Clone>)
17    pub generics: Vec<GenericParam>,
18    /// Exceptions/errors that can be thrown
19    pub throws: Vec<String>,
20    /// Whether the function is async
21    pub is_async: bool,
22    /// Whether the function is a generator/iterator
23    pub is_generator: bool,
24    /// Receiver type for methods (self, &self, &mut self, etc.)
25    pub receiver: Option<String>,
26}
27
28/// Parameter information with type details
29#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
30pub struct ParameterInfo {
31    /// Parameter name
32    pub name: String,
33    /// Type annotation (if available)
34    pub type_info: Option<TypeInfo>,
35    /// Whether the parameter is optional
36    pub is_optional: bool,
37    /// Default value expression (if any)
38    pub default_value: Option<String>,
39    /// Whether this is a rest/variadic parameter
40    pub is_variadic: bool,
41    /// Parameter kind (positional, keyword, etc.)
42    pub kind: ParameterKind,
43}
44
45/// Kind of parameter
46#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
47pub enum ParameterKind {
48    #[default]
49    Positional,
50    Keyword,
51    PositionalOrKeyword,
52    KeywordOnly,
53    VarPositional, // *args in Python
54    VarKeyword,    // **kwargs in Python
55}
56
57/// Type information
58#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
59pub struct TypeInfo {
60    /// The type name (e.g., "String", "Vec<T>", "int")
61    pub name: String,
62    /// Generic arguments (e.g., for Vec<String>, this would be ["String"])
63    pub generic_args: Vec<TypeInfo>,
64    /// Whether this is a nullable/optional type
65    pub is_nullable: bool,
66    /// Whether this is a reference type (&, &mut in Rust)
67    pub is_reference: bool,
68    /// Whether this is mutable
69    pub is_mutable: bool,
70    /// Array dimensions (0 for non-arrays)
71    pub array_dimensions: u32,
72    /// Union types (for TypeScript unions, Python Union, etc.)
73    pub union_types: Vec<TypeInfo>,
74}
75
76/// Generic type parameter
77#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
78pub struct GenericParam {
79    /// Parameter name (e.g., "T")
80    pub name: String,
81    /// Constraints/bounds (e.g., "Clone + Send" in Rust, "extends Comparable" in Java)
82    pub constraints: Vec<String>,
83    /// Default type (if any)
84    pub default_type: Option<String>,
85    /// Variance (covariant, contravariant, invariant)
86    pub variance: Variance,
87}
88
89/// Type variance for generics
90#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
91pub enum Variance {
92    #[default]
93    Invariant,
94    Covariant,     // out in Kotlin, + in Scala
95    Contravariant, // in in Kotlin, - in Scala
96}
97
98/// Type hierarchy information for a symbol
99#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
100pub struct TypeHierarchy {
101    /// The symbol this hierarchy is for
102    pub symbol_name: String,
103    /// Direct parent class/struct (extends)
104    pub extends: Option<String>,
105    /// Interfaces/traits implemented
106    pub implements: Vec<String>,
107    /// Full ancestor chain (parent, grandparent, etc.)
108    pub ancestors: Vec<AncestorInfo>,
109    /// Known descendants (classes that extend this)
110    pub descendants: Vec<String>,
111    /// Mixins/traits included (Ruby, Scala, etc.)
112    pub mixins: Vec<String>,
113}
114
115/// Information about an ancestor in the type hierarchy
116#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
117pub struct AncestorInfo {
118    /// Name of the ancestor
119    pub name: String,
120    /// Whether this is a class or interface/trait
121    pub kind: AncestorKind,
122    /// Depth in the hierarchy (1 = direct parent)
123    pub depth: u32,
124    /// File where the ancestor is defined (if known)
125    pub file_path: Option<String>,
126}
127
128/// Kind of ancestor
129#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
130pub enum AncestorKind {
131    #[default]
132    Class,
133    Interface,
134    Trait,
135    Protocol, // Swift
136    Mixin,
137    AbstractClass,
138}
139
140/// Structured documentation extracted from docstrings/comments
141#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
142pub struct Documentation {
143    /// Brief summary (first line/sentence)
144    pub summary: Option<String>,
145    /// Full description
146    pub description: Option<String>,
147    /// Parameter documentation
148    pub params: Vec<ParamDoc>,
149    /// Return value documentation
150    pub returns: Option<ReturnDoc>,
151    /// Exception/error documentation
152    pub throws: Vec<ThrowsDoc>,
153    /// Code examples
154    pub examples: Vec<Example>,
155    /// Other tags (@deprecated, @since, @see, etc.)
156    pub tags: HashMap<String, Vec<String>>,
157    /// Whether the symbol is deprecated
158    pub is_deprecated: bool,
159    /// Deprecation message
160    pub deprecation_message: Option<String>,
161    /// Raw docstring before parsing
162    pub raw: Option<String>,
163}
164
165/// Parameter documentation
166#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
167pub struct ParamDoc {
168    /// Parameter name
169    pub name: String,
170    /// Type (from documentation, may differ from actual type)
171    pub type_info: Option<String>,
172    /// Description
173    pub description: Option<String>,
174    /// Whether marked as optional in docs
175    pub is_optional: bool,
176    /// Default value mentioned in docs
177    pub default_value: Option<String>,
178}
179
180/// Return value documentation
181#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
182pub struct ReturnDoc {
183    /// Return type (from documentation)
184    pub type_info: Option<String>,
185    /// Description of return value
186    pub description: Option<String>,
187}
188
189/// Exception/error documentation
190#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
191pub struct ThrowsDoc {
192    /// Exception/error type
193    pub exception_type: String,
194    /// When this exception is thrown
195    pub description: Option<String>,
196}
197
198/// Code example from documentation
199#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
200pub struct Example {
201    /// Example title/description
202    pub title: Option<String>,
203    /// The code
204    pub code: String,
205    /// Language hint for syntax highlighting
206    pub language: Option<String>,
207    /// Expected output (for doctests)
208    pub expected_output: Option<String>,
209}
210
211/// Code complexity metrics
212#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
213pub struct ComplexityMetrics {
214    /// Cyclomatic complexity (number of independent paths)
215    pub cyclomatic: u32,
216    /// Cognitive complexity (how hard to understand)
217    pub cognitive: u32,
218    /// Halstead metrics
219    pub halstead: Option<HalsteadMetrics>,
220    /// Lines of code metrics
221    pub loc: LocMetrics,
222    /// Maintainability index (0-100, higher is better)
223    pub maintainability_index: Option<f32>,
224    /// Nesting depth
225    pub max_nesting_depth: u32,
226    /// Number of parameters
227    pub parameter_count: u32,
228    /// Number of return points
229    pub return_count: u32,
230}
231
232/// Halstead complexity metrics
233#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
234pub struct HalsteadMetrics {
235    /// Number of distinct operators
236    pub distinct_operators: u32,
237    /// Number of distinct operands
238    pub distinct_operands: u32,
239    /// Total operators
240    pub total_operators: u32,
241    /// Total operands
242    pub total_operands: u32,
243    /// Program vocabulary (n1 + n2)
244    pub vocabulary: u32,
245    /// Program length (N1 + N2)
246    pub length: u32,
247    /// Calculated program length
248    pub calculated_length: f32,
249    /// Volume
250    pub volume: f32,
251    /// Difficulty
252    pub difficulty: f32,
253    /// Effort
254    pub effort: f32,
255    /// Time to program (seconds)
256    pub time: f32,
257    /// Estimated bugs
258    pub bugs: f32,
259}
260
261/// Lines of code metrics
262#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
263pub struct LocMetrics {
264    /// Total lines
265    pub total: u32,
266    /// Source lines of code (non-blank, non-comment)
267    pub source: u32,
268    /// Comment lines
269    pub comments: u32,
270    /// Blank lines
271    pub blank: u32,
272}
273
274/// Dead code detection result
275#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
276pub struct DeadCodeInfo {
277    /// Unused public exports
278    pub unused_exports: Vec<UnusedExport>,
279    /// Unreachable code segments
280    pub unreachable_code: Vec<UnreachableCode>,
281    /// Unused private symbols
282    pub unused_private: Vec<UnusedSymbol>,
283    /// Unused imports
284    pub unused_imports: Vec<UnusedImport>,
285    /// Unused variables
286    pub unused_variables: Vec<UnusedVariable>,
287}
288
289/// An unused export
290#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
291pub struct UnusedExport {
292    /// Symbol name
293    pub name: String,
294    /// Symbol kind
295    pub kind: String,
296    /// File path
297    pub file_path: String,
298    /// Line number
299    pub line: u32,
300    /// Confidence level (0.0-1.0)
301    pub confidence: f32,
302    /// Reason why it's considered unused
303    pub reason: String,
304}
305
306/// Unreachable code segment
307#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
308pub struct UnreachableCode {
309    /// File path
310    pub file_path: String,
311    /// Start line
312    pub start_line: u32,
313    /// End line
314    pub end_line: u32,
315    /// Code snippet
316    pub snippet: String,
317    /// Reason (after return, after throw, etc.)
318    pub reason: String,
319}
320
321/// An unused symbol (private)
322#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
323pub struct UnusedSymbol {
324    /// Symbol name
325    pub name: String,
326    /// Symbol kind
327    pub kind: String,
328    /// File path
329    pub file_path: String,
330    /// Line number
331    pub line: u32,
332}
333
334/// An unused import
335#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
336pub struct UnusedImport {
337    /// Import name
338    pub name: String,
339    /// Full import path
340    pub import_path: String,
341    /// File path
342    pub file_path: String,
343    /// Line number
344    pub line: u32,
345}
346
347/// An unused variable
348#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
349pub struct UnusedVariable {
350    /// Variable name
351    pub name: String,
352    /// File path
353    pub file_path: String,
354    /// Line number
355    pub line: u32,
356    /// Scope (function name, etc.)
357    pub scope: Option<String>,
358}
359
360/// Breaking change between two versions
361#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
362pub struct BreakingChange {
363    /// Type of change
364    pub change_type: BreakingChangeType,
365    /// Symbol name affected
366    pub symbol_name: String,
367    /// Symbol kind
368    pub symbol_kind: String,
369    /// File path
370    pub file_path: String,
371    /// Line number in new version (None if removed)
372    pub line: Option<u32>,
373    /// Old signature/definition
374    pub old_signature: Option<String>,
375    /// New signature/definition
376    pub new_signature: Option<String>,
377    /// Detailed description of the change
378    pub description: String,
379    /// Severity (how breaking is this change)
380    pub severity: ChangeSeverity,
381    /// Migration hint
382    pub migration_hint: Option<String>,
383}
384
385/// Type of breaking change
386#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
387pub enum BreakingChangeType {
388    /// Symbol was removed
389    Removed,
390    /// Symbol signature changed
391    SignatureChanged,
392    /// Parameter added (required)
393    ParameterAdded,
394    /// Parameter removed
395    ParameterRemoved,
396    /// Parameter type changed
397    ParameterTypeChanged,
398    /// Return type changed
399    ReturnTypeChanged,
400    /// Visibility reduced (public -> private)
401    VisibilityReduced,
402    /// Symbol renamed
403    Renamed,
404    /// Type constraint added/changed
405    TypeConstraintChanged,
406    /// Generic parameter changed
407    GenericChanged,
408    /// Exception/error type changed
409    ThrowsChanged,
410    /// Async/sync changed
411    AsyncChanged,
412    /// Moved to different module/package
413    Moved,
414}
415
416/// Severity of a breaking change
417#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
418pub enum ChangeSeverity {
419    /// Will definitely break dependent code
420    Critical,
421    #[default]
422    /// Will likely break dependent code
423    High,
424    /// May break dependent code
425    Medium,
426    /// Unlikely to break code but is a change in contract
427    Low,
428}
429
430/// Result of breaking change detection
431#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
432pub struct BreakingChangeReport {
433    /// Git ref for old version
434    pub old_ref: String,
435    /// Git ref for new version
436    pub new_ref: String,
437    /// List of breaking changes
438    pub changes: Vec<BreakingChange>,
439    /// Summary statistics
440    pub summary: BreakingChangeSummary,
441}
442
443/// Summary of breaking changes
444#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
445pub struct BreakingChangeSummary {
446    /// Total breaking changes
447    pub total: u32,
448    /// Critical severity count
449    pub critical: u32,
450    /// High severity count
451    pub high: u32,
452    /// Medium severity count
453    pub medium: u32,
454    /// Low severity count
455    pub low: u32,
456    /// Files affected
457    pub files_affected: u32,
458    /// Symbols affected
459    pub symbols_affected: u32,
460}
461
462/// Multi-repository index
463#[derive(Debug, Clone, Default, Serialize, Deserialize)]
464pub struct MultiRepoIndex {
465    /// Repository entries
466    pub repositories: Vec<RepoEntry>,
467    /// Cross-repository symbol links
468    pub cross_repo_links: Vec<CrossRepoLink>,
469    /// Unified symbol index across all repos
470    pub unified_symbols: HashMap<String, Vec<UnifiedSymbolRef>>,
471}
472
473/// Entry for a repository in the multi-repo index
474#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
475pub struct RepoEntry {
476    /// Unique identifier for the repo
477    pub id: String,
478    /// Repository name
479    pub name: String,
480    /// Repository path (local or URL)
481    pub path: String,
482    /// Git commit hash
483    pub commit: Option<String>,
484    /// Number of files indexed
485    pub file_count: u32,
486    /// Number of symbols indexed
487    pub symbol_count: u32,
488    /// Last indexed timestamp
489    pub indexed_at: Option<u64>,
490}
491
492/// A cross-repository link (dependency, reference)
493#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
494pub struct CrossRepoLink {
495    /// Source repository ID
496    pub source_repo: String,
497    /// Source file path
498    pub source_file: String,
499    /// Source symbol name
500    pub source_symbol: Option<String>,
501    /// Source line number
502    pub source_line: u32,
503    /// Target repository ID
504    pub target_repo: String,
505    /// Target symbol name
506    pub target_symbol: String,
507    /// Link type
508    pub link_type: CrossRepoLinkType,
509}
510
511/// Type of cross-repository link
512#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
513pub enum CrossRepoLinkType {
514    #[default]
515    /// Import/dependency
516    Import,
517    /// Type reference
518    TypeReference,
519    /// Function call
520    Call,
521    /// Inheritance
522    Extends,
523    /// Interface implementation
524    Implements,
525}
526
527/// Reference to a symbol in the unified index
528#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
529pub struct UnifiedSymbolRef {
530    /// Repository ID
531    pub repo_id: String,
532    /// File path within repo
533    pub file_path: String,
534    /// Line number
535    pub line: u32,
536    /// Symbol kind
537    pub kind: String,
538    /// Fully qualified name
539    pub qualified_name: Option<String>,
540}