Skip to content

Commit aaa0bf6

Browse files
committed
umpl support is basically done
1 parent 1051bf6 commit aaa0bf6

File tree

2 files changed

+111
-31
lines changed

2 files changed

+111
-31
lines changed

git-function-history-lib/src/languages/python.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -252,11 +252,7 @@ pub(crate) fn find_function_in_file(
252252
fn get_functions_recurisve(
253253
body: Vec<Located<StmtKind>>,
254254
map: &HashMap<usize, &usize>,
255-
functions: &mut Vec<(
256-
Located<StmtKind>,
257-
Vec<Located<StmtKind>>,
258-
Vec<Located<StmtKind>>,
259-
)>,
255+
functions: &mut FnState,
260256
current_parent: &mut Vec<Located<StmtKind>>,
261257
current_class: &mut Vec<Located<StmtKind>>,
262258
lookup_name: &str,
@@ -277,15 +273,15 @@ fn get_functions_recurisve(
277273
);
278274
}
279275
}
280-
276+
type FnState = Vec<(
277+
Located<StmtKind>,
278+
Vec<Located<StmtKind>>,
279+
Vec<Located<StmtKind>>,
280+
)>;
281281
fn get_functions(
282282
stmt: Located<StmtKind>,
283283
map: &HashMap<usize, &usize>,
284-
functions: &mut Vec<(
285-
Located<StmtKind>,
286-
Vec<Located<StmtKind>>,
287-
Vec<Located<StmtKind>>,
288-
)>,
284+
functions: &mut FnState,
289285
current_parent: &mut Vec<Located<StmtKind>>,
290286
current_class: &mut Vec<Located<StmtKind>>,
291287
lookup_name: &str,

git-function-history-lib/src/languages/umpl.rs

Lines changed: 104 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,44 @@ pub struct UMPLParentFunction {
2424

2525
impl fmt::Display for UMPLFunction {
2626
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27-
todo!()
27+
for i in &self.parents {
28+
write!(f, "{}\n...\n", i.top)?;
29+
}
30+
write!(f, "{}", self.body)?;
31+
for i in &self.parents {
32+
write!(f, "\n...\n{}", i.bottom)?;
33+
}
34+
Ok(())
2835
}
2936
}
3037

3138
impl FunctionTrait for UMPLFunction {
3239
impl_function_trait!(UMPLFunction);
3340

3441
fn get_total_lines(&self) -> (usize, usize) {
35-
todo!()
42+
let mut start = self.lines.0;
43+
let mut end = self.lines.1;
44+
for parent in &self.parents {
45+
if parent.lines.0 < start {
46+
start = parent.lines.0;
47+
end = parent.lines.1;
48+
}
49+
}
50+
(start, end)
3651
}
3752

3853
fn get_tops(&self) -> Vec<(String, usize)> {
39-
todo!()
54+
self.parents
55+
.iter()
56+
.map(|f| (f.top.clone(), f.lines.0))
57+
.collect()
4058
}
4159

4260
fn get_bottoms(&self) -> Vec<(String, usize)> {
43-
todo!()
61+
self.parents
62+
.iter()
63+
.map(|f| (f.bottom.clone(), f.lines.1))
64+
.collect()
4465
}
4566
}
4667

@@ -53,53 +74,104 @@ pub(crate) fn find_function_in_file(
5374
let tokens = lexed.scan_tokens();
5475
let mut parsed = umpl::parser::Parser::new(tokens);
5576
let ast = parsed.parse();
56-
let res = find_function_recurse(name, ast, &vec![]);
57-
if res.len() > 0 {
77+
let res = find_function_recurse(name, file_contents, ast, &vec![]);
78+
if !res.is_empty() {
5879
return Ok(res);
5980
}
6081
Err("no function found")?
6182
}
6283

6384
fn find_function_recurse(
6485
name: &str,
86+
file_contents: &str,
6587
ast: Vec<Thing>,
6688
current: &Vec<UMPLParentFunction>,
67-
) -> Vec<(UMPLFunction)> {
89+
) -> Vec<UMPLFunction> {
6890
let mut results = Vec::new();
6991
for node in ast {
7092
match node {
7193
Thing::Function(fns) => {
7294
if fns.name.to_string() == name {
95+
let lines = (fns.line as usize, fns.end_line as usize);
96+
let body = file_contents
97+
.lines()
98+
.enumerate()
99+
.filter(|line| line.0 >= lines.0 - 1 && line.0 < lines.1)
100+
.map(|line| format!("{}\n", line.1))
101+
.collect::<String>();
73102
let new_fn = UMPLFunction {
74-
lines: (fns.line as usize, fns.end_line as usize),
103+
lines,
75104
name: fns.name.to_string(),
76-
// TODO: get the function body
77-
body: String::new(),
105+
body: super::make_lined(&body, lines.0),
78106
args_count: fns.num_arguments as usize,
79107
parents: current.clone(),
80108
};
81109
results.push(new_fn);
82110
} else {
83111
let mut new_current = current.clone();
84112
// turn into a parent function
113+
let lines = (fns.line as usize, fns.end_line as usize);
114+
let bottom = if let Some(line) = file_contents.lines().nth(lines.1 - 1) {
115+
super::make_lined(line, lines.1)
116+
} else {
117+
results.append(&mut find_function_recurse(
118+
name,
119+
file_contents,
120+
fns.body,
121+
&new_current,
122+
));
123+
continue;
124+
};
125+
// FIXME: this should find the last line of the `top` by looking at its first element of is ast instead of finding the the first `⧼` (which could be commented out)
126+
let Some(top_end) = file_contents.lines().enumerate().skip(lines.0 -1).find_map(|line| {
127+
line.1.contains('⧼').then_some(line.0)
128+
}) else {
129+
results.append(&mut find_function_recurse(name, file_contents, fns.body, &new_current));
130+
continue;
131+
};
132+
let top = file_contents
133+
.lines()
134+
.enumerate()
135+
.filter(|line| line.0 >= lines.0 - 1 && line.0 <= top_end)
136+
.map(|line| format!("{}\n", line.1))
137+
.collect::<String>();
85138
let pfn = UMPLParentFunction {
86-
lines: (fns.line as usize, fns.end_line as usize),
139+
lines,
87140
name: fns.name.to_string(),
88-
// TODO: get the top and bottom lines
89-
top: String::new(),
90-
bottom: String::new(),
141+
top: super::make_lined(&top, lines.0),
142+
bottom,
91143
args_count: fns.num_arguments as usize,
92144
};
93145
new_current.push(pfn);
94-
results.append(&mut find_function_recurse(name, fns.body, &new_current));
146+
results.append(&mut find_function_recurse(
147+
name,
148+
file_contents,
149+
fns.body,
150+
&new_current,
151+
));
95152
}
96153
}
97154
Thing::LoopStatement(loops) => {
98-
results.append(&mut find_function_recurse(name, loops.body, current));
155+
results.append(&mut find_function_recurse(
156+
name,
157+
file_contents,
158+
loops.body,
159+
current,
160+
));
99161
}
100162
Thing::IfStatement(ifs) => {
101-
results.append(&mut find_function_recurse(name, ifs.body_true, current));
102-
results.append(&mut find_function_recurse(name, ifs.body_false, current));
163+
results.append(&mut find_function_recurse(
164+
name,
165+
file_contents,
166+
ifs.body_true,
167+
current,
168+
));
169+
results.append(&mut find_function_recurse(
170+
name,
171+
file_contents,
172+
ifs.body_false,
173+
current,
174+
));
103175
}
104176
_ => {}
105177
}
@@ -108,10 +180,22 @@ fn find_function_recurse(
108180
}
109181

110182
#[derive(Debug, Clone, PartialEq, Eq)]
111-
pub enum UMPLFilter {}
183+
pub enum UMPLFilter {
184+
HasParameterCount(usize),
185+
HasParentWithParamCount(usize),
186+
HasParentWithName(String),
187+
HasParents,
188+
}
112189

113190
impl UMPLFilter {
114191
pub fn matches(&self, function: &UMPLFunction) -> bool {
115-
false
192+
match self {
193+
Self::HasParameterCount(count) => function.args_count == *count,
194+
Self::HasParentWithParamCount(count) => {
195+
function.parents.iter().any(|p| p.args_count == *count)
196+
}
197+
Self::HasParentWithName(name) => function.parents.iter().any(|p| p.name == *name),
198+
Self::HasParents => !function.parents.is_empty(),
199+
}
116200
}
117201
}

0 commit comments

Comments
 (0)