1
- use sway_types:: { integer_bits:: IntegerBits , Named } ;
1
+ use sway_error:: handler:: { ErrorEmitted , Handler } ;
2
+ use sway_types:: { integer_bits:: IntegerBits , BaseIdent , Named } ;
2
3
3
- use crate :: { language:: CallPath , Engines , GenericArgument , TypeId , TypeInfo } ;
4
+ use crate :: { language:: CallPath , transform , Engines , GenericArgument , TypeId , TypeInfo } ;
4
5
5
6
#[ derive( Clone ) ]
6
7
pub struct AbiStrContext {
@@ -14,14 +15,17 @@ impl TypeId {
14
15
/// Gives back a string that represents the type, considering what it resolves to
15
16
pub fn get_abi_type_str (
16
17
& self ,
18
+ handler : & Handler ,
17
19
ctx : & AbiStrContext ,
18
20
engines : & Engines ,
19
21
resolved_type_id : TypeId ,
20
- ) -> String {
22
+ ) -> Result < String , ErrorEmitted > {
21
23
let type_engine = engines. te ( ) ;
22
- let self_abi_str = type_engine. get ( * self ) . abi_str ( ctx, engines, true ) ;
24
+ let self_abi_str = type_engine
25
+ . get ( * self )
26
+ . abi_str ( handler, ctx, engines, true ) ?;
23
27
if self . is_generic_parameter ( engines, resolved_type_id) {
24
- format ! ( "generic {}" , self_abi_str)
28
+ Ok ( format ! ( "generic {}" , self_abi_str) )
25
29
} else {
26
30
match (
27
31
& * type_engine. get ( * self ) ,
@@ -30,23 +34,26 @@ impl TypeId {
30
34
( TypeInfo :: Custom { .. } , TypeInfo :: Struct { .. } )
31
35
| ( TypeInfo :: Custom { .. } , TypeInfo :: Enum { .. } ) => type_engine
32
36
. get ( resolved_type_id)
33
- . abi_str ( ctx, engines, true ) ,
37
+ . abi_str ( handler , ctx, engines, true ) ,
34
38
( _, TypeInfo :: Alias { ty, .. } ) => {
35
- ty. type_id ( ) . get_abi_type_str ( ctx, engines, ty. type_id ( ) )
39
+ ty. type_id ( )
40
+ . get_abi_type_str ( handler, ctx, engines, ty. type_id ( ) )
36
41
}
37
42
( TypeInfo :: Tuple ( fields) , TypeInfo :: Tuple ( resolved_fields) ) => {
38
43
assert_eq ! ( fields. len( ) , resolved_fields. len( ) ) ;
39
44
let field_strs = resolved_fields
40
45
. iter ( )
41
46
. map ( |f| {
42
47
if ctx. abi_with_fully_specified_types {
43
- type_engine. get ( f. type_id ( ) ) . abi_str ( ctx, engines, false )
48
+ type_engine
49
+ . get ( f. type_id ( ) )
50
+ . abi_str ( handler, ctx, engines, false )
44
51
} else {
45
- "_" . to_string ( )
52
+ Ok ( "_" . to_string ( ) )
46
53
}
47
54
} )
48
- . collect :: < Vec < String > > ( ) ;
49
- format ! ( "({})" , field_strs. join( ", " ) )
55
+ . collect :: < Result < Vec < String > , _ > > ( ) ? ;
56
+ Ok ( format ! ( "({})" , field_strs. join( ", " ) ) )
50
57
}
51
58
( TypeInfo :: Array ( _, length) , TypeInfo :: Array ( type_arg, resolved_length) ) => {
52
59
assert_eq ! (
@@ -56,76 +63,80 @@ impl TypeId {
56
63
let inner_type = if ctx. abi_with_fully_specified_types {
57
64
type_engine
58
65
. get ( type_arg. type_id ( ) )
59
- . abi_str ( ctx, engines, false )
66
+ . abi_str ( handler , ctx, engines, false ) ?
60
67
} else {
61
68
"_" . to_string ( )
62
69
} ;
63
- format ! ( "[{}; {:?}]" , inner_type, engines. help_out( length) )
70
+ Ok ( format ! ( "[{}; {:?}]" , inner_type, engines. help_out( length) ) )
64
71
}
65
72
( TypeInfo :: Slice ( type_arg) , TypeInfo :: Slice ( _) ) => {
66
73
let inner_type = if ctx. abi_with_fully_specified_types {
67
74
type_engine
68
75
. get ( type_arg. type_id ( ) )
69
- . abi_str ( ctx, engines, false )
76
+ . abi_str ( handler , ctx, engines, false ) ?
70
77
} else {
71
78
"_" . to_string ( )
72
79
} ;
73
- format ! ( "[{}]" , inner_type)
74
- }
75
- ( TypeInfo :: Custom { .. } , _) => {
76
- format ! ( "generic {}" , self_abi_str)
80
+ Ok ( format ! ( "[{}]" , inner_type) )
77
81
}
82
+ ( TypeInfo :: Custom { .. } , _) => Ok ( format ! ( "generic {}" , self_abi_str) ) ,
78
83
_ => type_engine
79
84
. get ( resolved_type_id)
80
- . abi_str ( ctx, engines, true ) ,
85
+ . abi_str ( handler , ctx, engines, true ) ,
81
86
}
82
87
}
83
88
}
84
89
}
85
90
86
91
impl TypeInfo {
87
- pub fn abi_str ( & self , ctx : & AbiStrContext , engines : & Engines , is_root : bool ) -> String {
92
+ pub fn abi_str (
93
+ & self ,
94
+ handler : & Handler ,
95
+ ctx : & AbiStrContext ,
96
+ engines : & Engines ,
97
+ is_root : bool ,
98
+ ) -> Result < String , ErrorEmitted > {
88
99
use TypeInfo :: * ;
89
100
let decl_engine = engines. de ( ) ;
90
101
match self {
91
- Unknown => "unknown" . into ( ) ,
92
- Never => "never" . into ( ) ,
93
- UnknownGeneric { name, .. } => name. to_string ( ) ,
94
- Placeholder ( _) => "_" . to_string ( ) ,
95
- TypeParam ( param) => format ! ( "typeparam({})" , param. name( ) ) ,
96
- StringSlice => "str" . into ( ) ,
97
- StringArray ( length) => format ! ( "str[{}]" , length. val( ) ) ,
98
- UnsignedInteger ( x) => match x {
102
+ Unknown => Ok ( "unknown" . into ( ) ) ,
103
+ Never => Ok ( "never" . into ( ) ) ,
104
+ UnknownGeneric { name, .. } => Ok ( name. to_string ( ) ) ,
105
+ Placeholder ( _) => Ok ( "_" . to_string ( ) ) ,
106
+ TypeParam ( param) => Ok ( format ! ( "typeparam({})" , param. name( ) ) ) ,
107
+ StringSlice => Ok ( "str" . into ( ) ) ,
108
+ StringArray ( length) => Ok ( format ! ( "str[{}]" , length. val( ) ) ) ,
109
+ UnsignedInteger ( x) => Ok ( match x {
99
110
IntegerBits :: Eight => "u8" ,
100
111
IntegerBits :: Sixteen => "u16" ,
101
112
IntegerBits :: ThirtyTwo => "u32" ,
102
113
IntegerBits :: SixtyFour => "u64" ,
103
114
IntegerBits :: V256 => "u256" ,
104
115
}
105
- . into ( ) ,
106
- Boolean => "bool" . into ( ) ,
116
+ . into ( ) ) ,
117
+ Boolean => Ok ( "bool" . into ( ) ) ,
107
118
Custom {
108
119
qualified_call_path : call_path,
109
120
..
110
- } => call_path. call_path . suffix . to_string ( ) ,
121
+ } => Ok ( call_path. call_path . suffix . to_string ( ) ) ,
111
122
Tuple ( fields) => {
112
123
let field_strs = fields
113
124
. iter ( )
114
- . map ( |field| field. abi_str ( ctx, engines, false ) )
115
- . collect :: < Vec < String > > ( ) ;
116
- format ! ( "({})" , field_strs. join( ", " ) )
125
+ . map ( |field| field. abi_str ( handler , ctx, engines, false ) )
126
+ . collect :: < Result < Vec < String > , ErrorEmitted > > ( ) ? ;
127
+ Ok ( format ! ( "({})" , field_strs. join( ", " ) ) )
117
128
}
118
- B256 => "b256" . into ( ) ,
119
- Numeric => "u64" . into ( ) , // u64 is the default
120
- Contract => "contract" . into ( ) ,
121
- ErrorRecovery ( _) => "unknown due to error" . into ( ) ,
129
+ B256 => Ok ( "b256" . into ( ) ) ,
130
+ Numeric => Ok ( "u64" . into ( ) ) , // u64 is the default
131
+ Contract => Ok ( "contract" . into ( ) ) ,
132
+ ErrorRecovery ( _) => Ok ( "unknown due to error" . into ( ) ) ,
122
133
UntypedEnum ( decl_id) => {
123
134
let decl = engines. pe ( ) . get_enum ( decl_id) ;
124
- format ! ( "untyped enum {}" , decl. name)
135
+ Ok ( format ! ( "untyped enum {}" , decl. name) )
125
136
}
126
137
UntypedStruct ( decl_id) => {
127
138
let decl = engines. pe ( ) . get_struct ( decl_id) ;
128
- format ! ( "untyped struct {}" , decl. name)
139
+ Ok ( format ! ( "untyped struct {}" , decl. name) )
129
140
}
130
141
Enum ( decl_ref) => {
131
142
let decl = decl_engine. get_enum ( decl_ref) ;
@@ -134,20 +145,19 @@ impl TypeInfo {
134
145
{
135
146
"" . into ( )
136
147
} else {
137
- format ! (
138
- "<{}>" ,
139
- decl. type_parameters
140
- . iter( )
141
- . map( |p| p. abi_str( engines, ctx, false ) )
142
- . collect:: <Vec <_>>( )
143
- . join( "," )
144
- )
148
+ let params = decl
149
+ . type_parameters
150
+ . iter ( )
151
+ . map ( |p| p. abi_str ( handler, engines, ctx, false ) )
152
+ . collect :: < Result < Vec < _ > , _ > > ( ) ?;
153
+ format ! ( "<{}>" , params. join( "," ) )
145
154
} ;
146
- format ! (
155
+ let abi_call_path = get_abi_call_path ( handler, & decl. call_path , & decl. attributes ) ?;
156
+ Ok ( format ! (
147
157
"enum {}{}" ,
148
- call_path_display( ctx, & decl . call_path ) ,
158
+ call_path_display( ctx, & abi_call_path ) ,
149
159
type_params
150
- )
160
+ ) )
151
161
}
152
162
Struct ( decl_ref) => {
153
163
let decl = decl_engine. get_struct ( decl_ref) ;
@@ -156,58 +166,69 @@ impl TypeInfo {
156
166
{
157
167
"" . into ( )
158
168
} else {
159
- format ! (
160
- "<{}>" ,
161
- decl. type_parameters
162
- . iter( )
163
- . map( |p| p. abi_str( engines, ctx, false ) )
164
- . collect:: <Vec <_>>( )
165
- . join( "," )
166
- )
169
+ let params = decl
170
+ . type_parameters
171
+ . iter ( )
172
+ . map ( |p| p. abi_str ( handler, engines, ctx, false ) )
173
+ . collect :: < Result < Vec < _ > , _ > > ( ) ?;
174
+ format ! ( "<{}>" , params. join( "," ) )
167
175
} ;
168
- format ! (
176
+ let abi_call_path = get_abi_call_path ( handler, & decl. call_path , & decl. attributes ) ?;
177
+ Ok ( format ! (
169
178
"struct {}{}" ,
170
- call_path_display( ctx, & decl . call_path ) ,
179
+ call_path_display( ctx, & abi_call_path ) ,
171
180
type_params
172
- )
173
- }
174
- ContractCaller { abi_name, .. } => {
175
- format ! ( "contract caller {abi_name}" )
176
- }
177
- Array ( elem_ty, length) => {
178
- format ! (
179
- "[{}; {:?}]" ,
180
- elem_ty. abi_str( ctx, engines, false ) ,
181
- engines. help_out( length)
182
- )
181
+ ) )
183
182
}
184
- RawUntypedPtr => "raw untyped ptr" . into ( ) ,
185
- RawUntypedSlice => "raw untyped slice" . into ( ) ,
186
- Ptr ( ty) => {
187
- format ! ( "__ptr {}" , ty. abi_str( ctx, engines, false ) )
188
- }
189
- Slice ( ty) => {
190
- format ! ( "__slice {}" , ty. abi_str( ctx, engines, false ) )
191
- }
192
- Alias { ty, .. } => ty. abi_str ( ctx, engines, false ) ,
183
+ ContractCaller { abi_name, .. } => Ok ( format ! ( "contract caller {abi_name}" ) ) ,
184
+ Array ( elem_ty, length) => Ok ( format ! (
185
+ "[{}; {:?}]" ,
186
+ elem_ty. abi_str( handler, ctx, engines, false ) ?,
187
+ engines. help_out( length)
188
+ ) ) ,
189
+ RawUntypedPtr => Ok ( "raw untyped ptr" . into ( ) ) ,
190
+ RawUntypedSlice => Ok ( "raw untyped slice" . into ( ) ) ,
191
+ Ptr ( ty) => Ok ( format ! (
192
+ "__ptr {}" ,
193
+ ty. abi_str( handler, ctx, engines, false ) ?
194
+ ) ) ,
195
+ Slice ( ty) => Ok ( format ! (
196
+ "__slice {}" ,
197
+ ty. abi_str( handler, ctx, engines, false ) ?
198
+ ) ) ,
199
+ Alias { ty, .. } => Ok ( ty. abi_str ( handler, ctx, engines, false ) ?) ,
193
200
TraitType {
194
201
name,
195
202
trait_type_id : _,
196
- } => format ! ( "trait type {}" , name) ,
203
+ } => Ok ( format ! ( "trait type {}" , name) ) ,
197
204
Ref {
198
205
to_mutable_value,
199
206
referenced_type,
200
207
} => {
201
- format ! (
208
+ Ok ( format ! (
202
209
"__ref {}{}" , // TODO-IG: No references in ABIs according to the RFC. Or we want to have them?
203
210
if * to_mutable_value { "mut " } else { "" } ,
204
- referenced_type. abi_str( ctx, engines, false )
205
- )
211
+ referenced_type. abi_str( handler , ctx, engines, false ) ?
212
+ ) )
206
213
}
207
214
}
208
215
}
209
216
}
210
217
218
+ fn get_abi_call_path (
219
+ handler : & Handler ,
220
+ call_path : & CallPath ,
221
+ attributes : & transform:: Attributes ,
222
+ ) -> Result < CallPath , ErrorEmitted > {
223
+ let mut abi_call_path = call_path. clone ( ) ;
224
+ if let Some ( abi_name_attr) = attributes. abi_name ( ) {
225
+ let name = abi_name_attr. args . first ( ) . unwrap ( ) ;
226
+ let span = name. get_string_span ( handler, abi_name_attr) ?;
227
+ abi_call_path. suffix = BaseIdent :: new ( span) ;
228
+ }
229
+ Ok ( abi_call_path)
230
+ }
231
+
211
232
/// `call_path_display` returns the provided `call_path` without the first prefix in case it is equal to the program name.
212
233
/// If the program name is `my_program` and the `call_path` is `my_program::MyStruct` then this function returns only `MyStruct`.
213
234
fn call_path_display ( ctx : & AbiStrContext , call_path : & CallPath ) -> String {
@@ -228,10 +249,16 @@ fn call_path_display(ctx: &AbiStrContext, call_path: &CallPath) -> String {
228
249
}
229
250
230
251
impl GenericArgument {
231
- pub ( self ) fn abi_str ( & self , ctx : & AbiStrContext , engines : & Engines , is_root : bool ) -> String {
252
+ pub ( self ) fn abi_str (
253
+ & self ,
254
+ handler : & Handler ,
255
+ ctx : & AbiStrContext ,
256
+ engines : & Engines ,
257
+ is_root : bool ,
258
+ ) -> Result < String , ErrorEmitted > {
232
259
engines
233
260
. te ( )
234
261
. get ( self . type_id ( ) )
235
- . abi_str ( ctx, engines, is_root)
262
+ . abi_str ( handler , ctx, engines, is_root)
236
263
}
237
264
}
0 commit comments