@@ -24,23 +24,44 @@ pub struct UMPLParentFunction {
2424
2525impl 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
3138impl 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
6384fn 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
113190impl 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