codegraph_parser_api/entities/
function.rs

1use crate::complexity::ComplexityMetrics;
2use serde::{Deserialize, Serialize};
3
4/// Represents a function parameter
5#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
6pub struct Parameter {
7    /// Parameter name
8    pub name: String,
9
10    /// Type annotation (if available)
11    pub type_annotation: Option<String>,
12
13    /// Default value (if any)
14    pub default_value: Option<String>,
15
16    /// Is this a variadic parameter? (e.g., *args, **kwargs)
17    pub is_variadic: bool,
18}
19
20impl Parameter {
21    pub fn new(name: impl Into<String>) -> Self {
22        Self {
23            name: name.into(),
24            type_annotation: None,
25            default_value: None,
26            is_variadic: false,
27        }
28    }
29
30    pub fn with_type(mut self, type_ann: impl Into<String>) -> Self {
31        self.type_annotation = Some(type_ann.into());
32        self
33    }
34
35    pub fn with_default(mut self, default: impl Into<String>) -> Self {
36        self.default_value = Some(default.into());
37        self
38    }
39
40    pub fn variadic(mut self) -> Self {
41        self.is_variadic = true;
42        self
43    }
44}
45
46/// Represents a function/method in any language
47#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
48pub struct FunctionEntity {
49    /// Function name
50    pub name: String,
51
52    /// Full signature (including parameters and return type)
53    pub signature: String,
54
55    /// Visibility: "public", "private", "protected", "internal"
56    pub visibility: String,
57
58    /// Starting line number (1-indexed)
59    pub line_start: usize,
60
61    /// Ending line number (1-indexed)
62    pub line_end: usize,
63
64    /// Is this an async/coroutine function?
65    pub is_async: bool,
66
67    /// Is this a test function?
68    pub is_test: bool,
69
70    /// Is this a static method?
71    pub is_static: bool,
72
73    /// Is this an abstract method?
74    pub is_abstract: bool,
75
76    /// Function parameters
77    pub parameters: Vec<Parameter>,
78
79    /// Return type annotation (if available)
80    pub return_type: Option<String>,
81
82    /// Documentation/docstring
83    pub doc_comment: Option<String>,
84
85    /// Decorators/attributes (e.g., `@property`, `@deprecated`)
86    pub attributes: Vec<String>,
87
88    /// Parent class (if this is a method)
89    pub parent_class: Option<String>,
90
91    /// Complexity metrics for this function
92    pub complexity: Option<ComplexityMetrics>,
93}
94
95impl FunctionEntity {
96    pub fn new(name: impl Into<String>, line_start: usize, line_end: usize) -> Self {
97        let name = name.into();
98        Self {
99            signature: name.clone(),
100            name,
101            visibility: "public".to_string(),
102            line_start,
103            line_end,
104            is_async: false,
105            is_test: false,
106            is_static: false,
107            is_abstract: false,
108            parameters: Vec::new(),
109            return_type: None,
110            doc_comment: None,
111            attributes: Vec::new(),
112            parent_class: None,
113            complexity: None,
114        }
115    }
116
117    // Builder methods
118    pub fn with_signature(mut self, sig: impl Into<String>) -> Self {
119        self.signature = sig.into();
120        self
121    }
122
123    pub fn with_visibility(mut self, vis: impl Into<String>) -> Self {
124        self.visibility = vis.into();
125        self
126    }
127
128    pub fn async_fn(mut self) -> Self {
129        self.is_async = true;
130        self
131    }
132
133    pub fn test_fn(mut self) -> Self {
134        self.is_test = true;
135        self
136    }
137
138    pub fn static_fn(mut self) -> Self {
139        self.is_static = true;
140        self
141    }
142
143    pub fn abstract_fn(mut self) -> Self {
144        self.is_abstract = true;
145        self
146    }
147
148    pub fn with_parameters(mut self, params: Vec<Parameter>) -> Self {
149        self.parameters = params;
150        self
151    }
152
153    pub fn with_return_type(mut self, ret: impl Into<String>) -> Self {
154        self.return_type = Some(ret.into());
155        self
156    }
157
158    pub fn with_doc(mut self, doc: impl Into<String>) -> Self {
159        self.doc_comment = Some(doc.into());
160        self
161    }
162
163    pub fn with_attributes(mut self, attrs: Vec<String>) -> Self {
164        self.attributes = attrs;
165        self
166    }
167
168    pub fn with_parent_class(mut self, parent: impl Into<String>) -> Self {
169        self.parent_class = Some(parent.into());
170        self
171    }
172
173    pub fn with_complexity(mut self, metrics: ComplexityMetrics) -> Self {
174        self.complexity = Some(metrics);
175        self
176    }
177
178    /// Get the cyclomatic complexity, returning 1 if not calculated
179    pub fn cyclomatic_complexity(&self) -> u32 {
180        self.complexity
181            .as_ref()
182            .map(|c| c.cyclomatic_complexity)
183            .unwrap_or(1)
184    }
185
186    /// Get the complexity grade (A-F), returning 'A' if not calculated
187    pub fn complexity_grade(&self) -> char {
188        self.complexity.as_ref().map(|c| c.grade()).unwrap_or('A')
189    }
190}