Skip to main content

cha_core/
model.rs

1/// Where a referenced type is defined, from the perspective of the file that
2/// uses it. Used by abstraction-boundary analyses to distinguish "own domain"
3/// types from "pulled in from a library" types.
4#[derive(Debug, Clone, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
5#[serde(rename_all = "snake_case", tag = "kind", content = "module")]
6pub enum TypeOrigin {
7    /// Declared inside the project (resolved via project-wide type registry
8    /// or an import pointing at a project-local path).
9    Local,
10    /// Imported from an external module / crate / package. Carries the module
11    /// name if known (Rust crate path root, Go module path, npm package name,
12    /// C header filename without extension). May be empty if only structure
13    /// says "external" (e.g. `#include <...>` without the header name).
14    External(String),
15    /// Built-in primitive / standard library scalar (int, bool, &str, char…).
16    Primitive,
17    /// Could not be resolved. Detection treats this as potentially external
18    /// but with lower confidence.
19    #[default]
20    Unknown,
21}
22
23/// A function parameter's (or return value's) type, with resolved origin.
24/// Produced by parsers after combining AST type text with the file's imports.
25#[derive(Debug, Clone, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
26pub struct TypeRef {
27    /// Innermost identifier after stripping references, generics, containers.
28    /// e.g. `&mut Vec<tree_sitter::Node>` → `"Node"`.
29    pub name: String,
30    /// Original source text as written, for messages and debugging.
31    /// e.g. `"&mut Vec<tree_sitter::Node>"`.
32    pub raw: String,
33    /// Where the type is declared.
34    pub origin: TypeOrigin,
35}
36
37/// Extracted function info from AST.
38#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
39pub struct FunctionInfo {
40    pub name: String,
41    pub start_line: usize,
42    pub end_line: usize,
43    /// 0-based column of the function name identifier.
44    pub name_col: usize,
45    /// 0-based end column of the function name identifier.
46    pub name_end_col: usize,
47    pub line_count: usize,
48    /// Cyclomatic complexity (1 + number of branch points).
49    pub complexity: usize,
50    /// Hash of the function body AST structure for duplicate detection.
51    pub body_hash: Option<u64>,
52    /// Whether this function is exported (pub/export).
53    pub is_exported: bool,
54    /// Number of parameters.
55    pub parameter_count: usize,
56    /// Names of external identifiers referenced in the body (for Feature Envy).
57    pub external_refs: Vec<String>,
58    /// Max method chain depth in the body (for Message Chains).
59    pub chain_depth: usize,
60    /// Number of switch/match arms (for Switch Statements).
61    pub switch_arms: usize,
62    /// Whether this function only delegates to another object's method (for Middle Man).
63    pub is_delegating: bool,
64    /// Parameter types **in declaration order**, each resolved to a TypeRef.
65    /// Preserves position (first param = index 0) so positional analyses work.
66    pub parameter_types: Vec<TypeRef>,
67    /// Number of comment lines in the function body.
68    pub comment_lines: usize,
69    /// Field names referenced in this function body (for Temporary Field).
70    pub referenced_fields: Vec<String>,
71    /// Field names checked for null/None in this function (for Null Object pattern).
72    pub null_check_fields: Vec<String>,
73    /// The field/variable name being dispatched on in switch/match (for Strategy/State).
74    pub switch_dispatch_target: Option<String>,
75    /// Number of optional parameters (for Builder pattern).
76    pub optional_param_count: usize,
77    /// Names of functions/methods called in this function body (for call graph).
78    pub called_functions: Vec<String>,
79    /// Cognitive complexity score [SonarSource 2017] — nesting-aware understandability metric.
80    pub cognitive_complexity: usize,
81    /// Declared return type (None if not annotated or inferred), resolved the
82    /// same way as parameter types. Drives return_type_leak detection.
83    pub return_type: Option<TypeRef>,
84}
85
86/// Extracted class/struct info from AST.
87#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
88pub struct ClassInfo {
89    pub name: String,
90    pub start_line: usize,
91    pub end_line: usize,
92    /// 0-based column of the class/struct name identifier.
93    pub name_col: usize,
94    /// 0-based end column of the class/struct name identifier.
95    pub name_end_col: usize,
96    pub method_count: usize,
97    pub line_count: usize,
98    /// Whether this class is exported.
99    pub is_exported: bool,
100    /// Number of methods that only delegate to another object.
101    pub delegating_method_count: usize,
102    /// Number of fields/properties.
103    pub field_count: usize,
104    /// Field names declared in this class.
105    pub field_names: Vec<String>,
106    /// Field types (parallel to field_names).
107    pub field_types: Vec<String>,
108    /// Whether the class has non-accessor methods (business logic).
109    pub has_behavior: bool,
110    /// Whether this is an interface or abstract class.
111    pub is_interface: bool,
112    /// Parent class/trait name (for Refused Bequest).
113    pub parent_name: Option<String>,
114    /// Number of overridden methods (for Refused Bequest).
115    pub override_count: usize,
116    /// Number of self-method calls in the longest method (for Template Method).
117    pub self_call_count: usize,
118    /// Whether the class has a listener/callback collection field.
119    pub has_listener_field: bool,
120    /// Whether the class has a notify/emit method.
121    pub has_notify_method: bool,
122}
123
124/// Extracted import info.
125#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
126pub struct ImportInfo {
127    pub source: String,
128    pub line: usize,
129    /// 0-based column of the import statement.
130    pub col: usize,
131    /// True for module declarations (e.g. Rust `mod foo;`).
132    pub is_module_decl: bool,
133}
134
135/// A comment extracted from source code by the language parser.
136#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
137pub struct CommentInfo {
138    pub text: String,
139    pub line: usize,
140}
141
142/// Unified source model produced by parsing.
143#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
144pub struct SourceModel {
145    pub language: String,
146    pub total_lines: usize,
147    pub functions: Vec<FunctionInfo>,
148    pub classes: Vec<ClassInfo>,
149    pub imports: Vec<ImportInfo>,
150    pub comments: Vec<CommentInfo>,
151    /// Type aliases: (alias, original). e.g. typedef, using, type =
152    pub type_aliases: Vec<(String, String)>,
153}