1
1
use super :: * ;
2
2
use crate :: builtins:: { PyComplex , PyTuple } ;
3
- use ruff_python_ast:: ExprContext ;
4
3
5
4
#[ derive( Debug ) ]
6
5
pub ( super ) struct Constant {
@@ -83,59 +82,64 @@ pub(crate) enum ConstantLiteral {
83
82
Str ( String ) ,
84
83
Bytes ( Vec < u8 > ) ,
85
84
Int ( ruff:: Int ) ,
86
- Tuple ( Vec < Constant > ) ,
85
+ Tuple {
86
+ value : Vec < Constant > ,
87
+ ctx : ruff:: ExprContext ,
88
+ } ,
87
89
Float ( f64 ) ,
88
- Complex { real : f64 , imag : f64 } ,
90
+ Complex {
91
+ real : f64 ,
92
+ imag : f64 ,
93
+ } ,
89
94
Ellipsis ,
90
95
}
91
96
92
97
// constructor
93
98
impl Node for Constant {
94
99
fn ast_to_object ( self , vm : & VirtualMachine , source_code : & SourceCodeOwned ) -> PyObjectRef {
95
100
let Self { range, value } = self ;
96
- let is_str = matches ! ( & value , ConstantLiteral :: Str ( _ ) ) ;
97
- let mut is_unicode = false ;
101
+ let mut string_kind = None ;
102
+ let mut tuple_ctx = None ;
98
103
let value = match value {
99
104
ConstantLiteral :: None => vm. ctx . none ( ) ,
100
105
ConstantLiteral :: Bool ( value) => vm. ctx . new_bool ( value) . to_pyobject ( vm) ,
101
106
ConstantLiteral :: Str ( value) => {
102
- if !value. is_ascii ( ) {
103
- is_unicode = true ;
104
- }
107
+ string_kind = Some ( !value. is_ascii ( ) ) ;
105
108
vm. ctx . new_str ( value) . to_pyobject ( vm)
106
109
}
107
110
ConstantLiteral :: Bytes ( value) => vm. ctx . new_bytes ( value) . to_pyobject ( vm) ,
108
111
ConstantLiteral :: Int ( value) => value. ast_to_object ( vm, source_code) ,
109
- ConstantLiteral :: Tuple ( value) => vm
110
- . ctx
111
- . new_tuple (
112
- value
113
- . into_iter ( )
114
- . map ( |c| c. ast_to_object ( vm, source_code) )
115
- . collect ( ) ,
116
- )
117
- . to_pyobject ( vm) ,
112
+ ConstantLiteral :: Tuple { value, ctx } => {
113
+ tuple_ctx = Some ( ctx. ast_to_object ( vm, source_code) ) ;
114
+ let value = value
115
+ . into_iter ( )
116
+ . map ( |c| c. ast_to_object ( vm, source_code) )
117
+ . collect ( ) ;
118
+ vm. ctx . new_tuple ( value) . to_pyobject ( vm)
119
+ }
118
120
ConstantLiteral :: Float ( value) => vm. ctx . new_float ( value) . into_pyobject ( vm) ,
119
121
ConstantLiteral :: Complex { real, imag } => vm
120
122
. ctx
121
123
. new_complex ( num_complex:: Complex :: new ( real, imag) )
122
124
. into_pyobject ( vm) ,
123
125
ConstantLiteral :: Ellipsis => vm. ctx . ellipsis ( ) ,
124
126
} ;
125
- // TODO: Figure out how this works
126
- let kind = vm. ctx . new_str ( "u" ) . to_pyobject ( vm) ;
127
127
let node = NodeAst
128
128
. into_ref_with_type ( vm, pyast:: NodeExprConstant :: static_type ( ) . to_owned ( ) )
129
129
. unwrap ( ) ;
130
130
let dict = node. as_object ( ) . dict ( ) . unwrap ( ) ;
131
131
dict. set_item ( "value" , value, vm) . unwrap ( ) ;
132
- if is_str {
133
- if is_unicode {
134
- dict. set_item ( "kind" , kind, vm) . unwrap ( ) ;
132
+ if let Some ( is_unicode_str) = string_kind {
133
+ // TODO: Figure out how this works
134
+ let kind = if is_unicode_str {
135
+ vm. ctx . new_str ( "u" ) . to_pyobject ( vm)
135
136
} else {
136
- dict. set_item ( "kind" , vm. ctx . empty_str . to_pyobject ( vm) , vm)
137
- . unwrap ( ) ;
138
- }
137
+ vm. ctx . empty_str . to_pyobject ( vm)
138
+ } ;
139
+ dict. set_item ( "kind" , kind, vm) . unwrap ( ) ;
140
+ }
141
+ if let Some ( tuple_ctx) = tuple_ctx {
142
+ dict. set_item ( "ctx" , tuple_ctx, vm) . unwrap ( ) ;
139
143
}
140
144
node_add_location ( & dict, range, vm, source_code) ;
141
145
node. into ( )
@@ -177,7 +181,12 @@ impl Node for Constant {
177
181
. cloned ( )
178
182
. map ( |object| Node :: ast_from_object ( vm, source_code, object) )
179
183
. collect :: < PyResult < _ > > ( ) ?;
180
- ConstantLiteral :: Tuple ( tuple)
184
+ let ctx_object = get_node_field ( vm, & object, "ctx" , "Constant" ) ?;
185
+ let ctx_object = Node :: ast_from_object ( vm, source_code, ctx_object) ?;
186
+ ConstantLiteral :: Tuple {
187
+ value : tuple,
188
+ ctx : ctx_object,
189
+ }
181
190
} else if cls. is ( vm. ctx . types . float_type ) {
182
191
let float = value_object. try_into_value ( vm) ?;
183
192
ConstantLiteral :: Float ( float)
@@ -247,11 +256,10 @@ fn constant_to_ruff_expr(value: Constant) -> ruff::Expr {
247
256
range,
248
257
value : ruff:: Number :: Int ( value) ,
249
258
} ) ,
250
- ConstantLiteral :: Tuple ( value) => ruff:: Expr :: Tuple ( ruff:: ExprTuple {
259
+ ConstantLiteral :: Tuple { value, ctx } => ruff:: Expr :: Tuple ( ruff:: ExprTuple {
251
260
range,
252
261
elts : value. into_iter ( ) . map ( constant_to_ruff_expr) . collect ( ) ,
253
- // TODO
254
- ctx : ExprContext :: Invalid ,
262
+ ctx,
255
263
// TODO: Does this matter?
256
264
parenthesized : true ,
257
265
} ) ,
@@ -270,3 +278,68 @@ fn constant_to_ruff_expr(value: Constant) -> ruff::Expr {
270
278
}
271
279
}
272
280
}
281
+
282
+ pub ( super ) fn number_literal_to_object (
283
+ vm : & VirtualMachine ,
284
+ source_code : & SourceCodeOwned ,
285
+ constant : ruff:: ExprNumberLiteral ,
286
+ ) -> PyObjectRef {
287
+ let ruff:: ExprNumberLiteral { range, value } = constant;
288
+ let c = match value {
289
+ ruff:: Number :: Int ( n) => Constant :: new_int ( n, range) ,
290
+ ruff:: Number :: Float ( n) => Constant :: new_float ( n, range) ,
291
+ ruff:: Number :: Complex { real, imag } => Constant :: new_complex ( real, imag, range) ,
292
+ } ;
293
+ c. ast_to_object ( vm, source_code)
294
+ }
295
+
296
+ pub ( super ) fn string_literal_to_object (
297
+ vm : & VirtualMachine ,
298
+ source_code : & SourceCodeOwned ,
299
+ constant : ruff:: ExprStringLiteral ,
300
+ ) -> PyObjectRef {
301
+ let ruff:: ExprStringLiteral { range, value } = constant;
302
+ let c = Constant :: new_str ( value. to_str ( ) , range) ;
303
+ c. ast_to_object ( vm, source_code)
304
+ }
305
+
306
+ pub ( super ) fn bytes_literal_to_object (
307
+ vm : & VirtualMachine ,
308
+ source_code : & SourceCodeOwned ,
309
+ constant : ruff:: ExprBytesLiteral ,
310
+ ) -> PyObjectRef {
311
+ let ruff:: ExprBytesLiteral { range, value } = constant;
312
+ let bytes = value. as_slice ( ) . iter ( ) . flat_map ( |b| b. value . iter ( ) ) ;
313
+ let c = Constant :: new_bytes ( bytes. copied ( ) , range) ;
314
+ c. ast_to_object ( vm, source_code)
315
+ }
316
+
317
+ pub ( super ) fn boolean_literal_to_object (
318
+ vm : & VirtualMachine ,
319
+ source_code : & SourceCodeOwned ,
320
+ constant : ruff:: ExprBooleanLiteral ,
321
+ ) -> PyObjectRef {
322
+ let ruff:: ExprBooleanLiteral { range, value } = constant;
323
+ let c = Constant :: new_bool ( value, range) ;
324
+ c. ast_to_object ( vm, source_code)
325
+ }
326
+
327
+ pub ( super ) fn none_literal_to_object (
328
+ vm : & VirtualMachine ,
329
+ source_code : & SourceCodeOwned ,
330
+ constant : ruff:: ExprNoneLiteral ,
331
+ ) -> PyObjectRef {
332
+ let ruff:: ExprNoneLiteral { range } = constant;
333
+ let c = Constant :: new_none ( range) ;
334
+ c. ast_to_object ( vm, source_code)
335
+ }
336
+
337
+ pub ( super ) fn ellipsis_literal_to_object (
338
+ vm : & VirtualMachine ,
339
+ source_code : & SourceCodeOwned ,
340
+ constant : ruff:: ExprEllipsisLiteral ,
341
+ ) -> PyObjectRef {
342
+ let ruff:: ExprEllipsisLiteral { range } = constant;
343
+ let c = Constant :: new_ellipsis ( range) ;
344
+ c. ast_to_object ( vm, source_code)
345
+ }
0 commit comments