11// Module for computing SRC5 compliant types
2+ use anyhow:: { Result , Ok , bail} ;
23use cairo_lang_compiler:: db:: RootDatabase ;
34use cairo_lang_syntax:: node:: { kind:: SyntaxKind , SyntaxNode } ;
45use std:: collections:: HashMap ;
@@ -14,7 +15,7 @@ pub trait SRC5Typed {
1415 db : & RootDatabase ,
1516 cairo_structs : & [ CairoStruct ] ,
1617 cairo_enums : & [ CairoEnum ] ,
17- ) -> String ;
18+ ) -> Result < String > ;
1819}
1920
2021impl SRC5Typed for SyntaxNode {
@@ -23,7 +24,7 @@ impl SRC5Typed for SyntaxNode {
2324 db : & RootDatabase ,
2425 cairo_structs : & [ CairoStruct ] ,
2526 cairo_enums : & [ CairoEnum ] ,
26- ) -> String {
27+ ) -> Result < String > {
2728 let replacements = & mut HashMap :: new ( ) ;
2829 match self . kind ( db) {
2930 SyntaxKind :: TypeClause | SyntaxKind :: ReturnTypeClause => {
@@ -36,7 +37,7 @@ impl SRC5Typed for SyntaxNode {
3637 )
3738 }
3839 _ => {
39- panic ! ( "Node is not a Type Clause" ) ;
40+ bail ! ( "Node is not a Type Clause" ) ;
4041 }
4142 }
4243 }
@@ -49,7 +50,7 @@ fn get_src5_type_from_type_clause_nodes_kind(
4950 cairo_structs : & [ CairoStruct ] ,
5051 cairo_enums : & [ CairoEnum ] ,
5152 replacements : & mut HashMap < String , String > ,
52- ) -> String {
53+ ) -> Result < String > {
5354 let mut src5_type = String :: new ( ) ;
5455
5556 // Handle Unary expressions
@@ -60,8 +61,8 @@ fn get_src5_type_from_type_clause_nodes_kind(
6061 cairo_structs,
6162 cairo_enums,
6263 replacements,
63- ) ) ;
64- src5_type
64+ ) ? ) ;
65+ Ok ( src5_type)
6566 }
6667 // Handle Tuple expressions
6768 else if let Some ( expr_tuple) = find_children ( db, node, SyntaxKind :: ExprTuple ) {
@@ -71,8 +72,8 @@ fn get_src5_type_from_type_clause_nodes_kind(
7172 cairo_structs,
7273 cairo_enums,
7374 replacements,
74- ) ) ;
75- src5_type
75+ ) ? ) ;
76+ Ok ( src5_type)
7677 }
7778 // Handle Path expressions
7879 else if let Some ( expr_path) = find_children ( db, node, SyntaxKind :: ExprPath ) {
@@ -82,10 +83,10 @@ fn get_src5_type_from_type_clause_nodes_kind(
8283 cairo_structs,
8384 cairo_enums,
8485 replacements,
85- ) ) ;
86- src5_type
86+ ) ? ) ;
87+ Ok ( src5_type)
8788 } else {
88- panic ! ( "Unexpected Type node kind: {:?}" , node. kind( db) ) ;
89+ bail ! ( "Unexpected Type node kind: {:?}" , node. kind( db) ) ;
8990 }
9091}
9192
@@ -97,7 +98,7 @@ fn get_src5_type_from_expr_path_node(
9798 structs : & [ CairoStruct ] ,
9899 enums : & [ CairoEnum ] ,
99100 replacements : & mut HashMap < String , String > ,
100- ) -> String {
101+ ) -> Result < String > {
101102 let mut src5_type = String :: new ( ) ;
102103
103104 // Handle no generics type
@@ -118,7 +119,7 @@ fn get_src5_type_from_expr_path_node(
118119 // Resolve each member type
119120 for ty in struct_type. members_types . iter ( ) {
120121 let src5_type_for_ty =
121- get_src5_type_from_type_clause_nodes_kind ( db, ty, structs, enums, replacements) ;
122+ get_src5_type_from_type_clause_nodes_kind ( db, ty, structs, enums, replacements) ? ;
122123 src5_type. push_str ( & src5_type_for_ty) ;
123124 src5_type. push ( ',' ) ;
124125 }
@@ -133,7 +134,7 @@ fn get_src5_type_from_expr_path_node(
133134 // Resolve each member type
134135 for ty in enum_type. variants_types . iter ( ) {
135136 let src5_type_for_ty =
136- get_src5_type_from_type_clause_nodes_kind ( db, ty, structs, enums, replacements) ;
137+ get_src5_type_from_type_clause_nodes_kind ( db, ty, structs, enums, replacements) ? ;
137138 src5_type. push_str ( & src5_type_for_ty) ;
138139 src5_type. push ( ',' ) ;
139140 }
@@ -142,7 +143,7 @@ fn get_src5_type_from_expr_path_node(
142143 }
143144 src5_type. push ( ')' ) ;
144145 } else {
145- panic ! ( "Unexpected Cairo type: {}" , name) ;
146+ bail ! ( "Unexpected Cairo type: {}" , name) ;
146147 }
147148 }
148149 // Handle type with generics
@@ -171,7 +172,7 @@ fn get_src5_type_from_expr_path_node(
171172 structs,
172173 enums,
173174 replacements,
174- ) ;
175+ ) ? ;
175176 src5_type. push_str ( & src5_type_for_generic_arg) ;
176177 src5_type. push ( ',' ) ;
177178 }
@@ -190,7 +191,7 @@ fn get_src5_type_from_expr_path_node(
190191 let generic_args_list =
191192 find_children ( db, & generic_args_node, SyntaxKind :: GenericArgList ) . unwrap ( ) ;
192193 let new_replacements = & mut HashMap :: new ( ) ;
193- let generic_index = 0 ;
194+ let mut generic_index = 0 ;
194195 for node in generic_args_list. children ( db) {
195196 if node. kind ( db) == SyntaxKind :: GenericArgExpr {
196197 let src5_type_for_generic_arg = get_src5_type_from_type_clause_nodes_kind (
@@ -199,11 +200,12 @@ fn get_src5_type_from_expr_path_node(
199200 structs,
200201 enums,
201202 replacements,
202- ) ;
203+ ) ? ;
203204 new_replacements. insert (
204205 struct_type. generics [ generic_index] . clone ( ) ,
205206 src5_type_for_generic_arg,
206207 ) ;
208+ generic_index += 1 ;
207209 }
208210 }
209211 // Resolve each member type with replacements
@@ -214,7 +216,50 @@ fn get_src5_type_from_expr_path_node(
214216 structs,
215217 enums,
216218 new_replacements,
217- ) ;
219+ ) ?;
220+ src5_type. push_str ( & src5_type_for_ty) ;
221+ src5_type. push ( ',' ) ;
222+ }
223+ if src5_type. ends_with ( ',' ) {
224+ src5_type. pop ( ) ; // Remove last comma
225+ }
226+ src5_type. push ( ')' ) ;
227+ }
228+ // Handle enum types
229+ else if let Some ( enum_type) = get_cairo_enum_from_name ( & name, enums) {
230+ src5_type. push_str ( "E(" ) ;
231+ // Resolve each generic type first
232+ let generic_args_node =
233+ find_children ( db, & path_segment_generics, SyntaxKind :: GenericArgs ) . unwrap ( ) ;
234+ let generic_args_list =
235+ find_children ( db, & generic_args_node, SyntaxKind :: GenericArgList ) . unwrap ( ) ;
236+ let new_replacements = & mut HashMap :: new ( ) ;
237+ let mut generic_index = 0 ;
238+ for node in generic_args_list. children ( db) {
239+ if node. kind ( db) == SyntaxKind :: GenericArgExpr {
240+ let src5_type_for_generic_arg = get_src5_type_from_type_clause_nodes_kind (
241+ db,
242+ & node,
243+ structs,
244+ enums,
245+ replacements,
246+ ) ?;
247+ new_replacements. insert (
248+ enum_type. generics [ generic_index] . clone ( ) ,
249+ src5_type_for_generic_arg,
250+ ) ;
251+ generic_index += 1 ;
252+ }
253+ }
254+ // Resolve each variant type with replacements
255+ for ty in enum_type. variants_types . iter ( ) {
256+ let src5_type_for_ty = get_src5_type_from_type_clause_nodes_kind (
257+ db,
258+ ty,
259+ structs,
260+ enums,
261+ new_replacements,
262+ ) ?;
218263 src5_type. push_str ( & src5_type_for_ty) ;
219264 src5_type. push ( ',' ) ;
220265 }
@@ -223,12 +268,12 @@ fn get_src5_type_from_expr_path_node(
223268 }
224269 src5_type. push ( ')' ) ;
225270 } else {
226- panic ! ( "Unexpected Cairo type: {}" , name) ;
271+ bail ! ( "Unexpected Cairo type: {}" , name) ;
227272 }
228273 } else {
229- panic ! ( "Unexpected node kind" ) ;
274+ bail ! ( "Unexpected node kind" ) ;
230275 }
231- src5_type
276+ Ok ( src5_type)
232277}
233278
234279fn get_src5_type_from_expr_tuple_node (
@@ -237,7 +282,7 @@ fn get_src5_type_from_expr_tuple_node(
237282 cairo_structs : & [ CairoStruct ] ,
238283 cairo_enums : & [ CairoEnum ] ,
239284 replacements : & mut HashMap < String , String > ,
240- ) -> String {
285+ ) -> Result < String > {
241286 let mut src5_type = String :: new ( ) ;
242287 let expr_list = find_children ( db, tuple_node, SyntaxKind :: ExprList ) . unwrap ( ) ;
243288 src5_type. push ( '(' ) ;
@@ -250,7 +295,7 @@ fn get_src5_type_from_expr_tuple_node(
250295 cairo_structs,
251296 cairo_enums,
252297 replacements,
253- ) ;
298+ ) ? ;
254299 src5_type. push_str ( & src5_type_for_ty) ;
255300 src5_type. push ( ',' ) ;
256301 }
@@ -261,7 +306,7 @@ fn get_src5_type_from_expr_tuple_node(
261306 cairo_structs,
262307 cairo_enums,
263308 replacements,
264- ) ;
309+ ) ? ;
265310 src5_type. push_str ( & src5_type_for_ty) ;
266311 src5_type. push ( ',' ) ;
267312 }
@@ -272,7 +317,7 @@ fn get_src5_type_from_expr_tuple_node(
272317 cairo_structs,
273318 cairo_enums,
274319 replacements,
275- ) ;
320+ ) ? ;
276321 src5_type. push_str ( & src5_type_for_ty) ;
277322 src5_type. push ( ',' ) ;
278323 }
@@ -283,7 +328,7 @@ fn get_src5_type_from_expr_tuple_node(
283328 src5_type. pop ( ) ; // Remove last comma
284329 }
285330 src5_type. push ( ')' ) ;
286- src5_type
331+ Ok ( src5_type)
287332}
288333
289334fn get_src5_type_from_expr_unary_node (
@@ -292,7 +337,7 @@ fn get_src5_type_from_expr_unary_node(
292337 cairo_structs : & [ CairoStruct ] ,
293338 cairo_enums : & [ CairoEnum ] ,
294339 replacements : & mut HashMap < String , String > ,
295- ) -> String {
340+ ) -> Result < String > {
296341 let mut src5_type = String :: new ( ) ;
297342 let leading_type_node = find_children ( db, unary_node, SyntaxKind :: TerminalAt ) . unwrap ( ) ;
298343 src5_type. push_str ( & leading_type_node. get_text_without_trivia ( db) ) ;
@@ -305,7 +350,7 @@ fn get_src5_type_from_expr_unary_node(
305350 cairo_structs,
306351 cairo_enums,
307352 replacements,
308- ) ) ;
353+ ) ? ) ;
309354 }
310355 // Handle Tuple expressions
311356 else if let Some ( expr_tuple) = find_children ( db, unary_node, SyntaxKind :: ExprTuple ) {
@@ -315,7 +360,7 @@ fn get_src5_type_from_expr_unary_node(
315360 cairo_structs,
316361 cairo_enums,
317362 replacements,
318- ) ) ;
363+ ) ? ) ;
319364 }
320365 // Handle Unary expressions
321366 else if let Some ( expr_unary) = find_children ( db, unary_node, SyntaxKind :: ExprUnary ) {
@@ -325,11 +370,11 @@ fn get_src5_type_from_expr_unary_node(
325370 cairo_structs,
326371 cairo_enums,
327372 replacements,
328- ) ) ;
373+ ) ? ) ;
329374 } else {
330- panic ! ( "Unexpected Expr node kind: {:?}" , unary_node. kind( db) ) ;
375+ bail ! ( "Unexpected Expr node kind: {:?}" , unary_node. kind( db) ) ;
331376 }
332- src5_type
377+ Ok ( src5_type)
333378}
334379
335380fn get_cairo_struct_from_name < ' a > (
0 commit comments