11use super :: * ;
22use crate :: builtins:: { PyComplex , PyTuple } ;
3- use ruff_python_ast:: ExprContext ;
43
54#[ derive( Debug ) ]
65pub ( super ) struct Constant {
@@ -83,59 +82,64 @@ pub(crate) enum ConstantLiteral {
8382 Str ( String ) ,
8483 Bytes ( Vec < u8 > ) ,
8584 Int ( ruff:: Int ) ,
86- Tuple ( Vec < Constant > ) ,
85+ Tuple {
86+ value : Vec < Constant > ,
87+ ctx : ruff:: ExprContext ,
88+ } ,
8789 Float ( f64 ) ,
88- Complex { real : f64 , imag : f64 } ,
90+ Complex {
91+ real : f64 ,
92+ imag : f64 ,
93+ } ,
8994 Ellipsis ,
9095}
9196
9297// constructor
9398impl Node for Constant {
9499 fn ast_to_object ( self , vm : & VirtualMachine , source_code : & SourceCodeOwned ) -> PyObjectRef {
95100 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 ;
98103 let value = match value {
99104 ConstantLiteral :: None => vm. ctx . none ( ) ,
100105 ConstantLiteral :: Bool ( value) => vm. ctx . new_bool ( value) . to_pyobject ( vm) ,
101106 ConstantLiteral :: Str ( value) => {
102- if !value. is_ascii ( ) {
103- is_unicode = true ;
104- }
107+ string_kind = Some ( !value. is_ascii ( ) ) ;
105108 vm. ctx . new_str ( value) . to_pyobject ( vm)
106109 }
107110 ConstantLiteral :: Bytes ( value) => vm. ctx . new_bytes ( value) . to_pyobject ( vm) ,
108111 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+ }
118120 ConstantLiteral :: Float ( value) => vm. ctx . new_float ( value) . into_pyobject ( vm) ,
119121 ConstantLiteral :: Complex { real, imag } => vm
120122 . ctx
121123 . new_complex ( num_complex:: Complex :: new ( real, imag) )
122124 . into_pyobject ( vm) ,
123125 ConstantLiteral :: Ellipsis => vm. ctx . ellipsis ( ) ,
124126 } ;
125- // TODO: Figure out how this works
126- let kind = vm. ctx . new_str ( "u" ) . to_pyobject ( vm) ;
127127 let node = NodeAst
128128 . into_ref_with_type ( vm, pyast:: NodeExprConstant :: static_type ( ) . to_owned ( ) )
129129 . unwrap ( ) ;
130130 let dict = node. as_object ( ) . dict ( ) . unwrap ( ) ;
131131 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)
135136 } 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 ( ) ;
139143 }
140144 node_add_location ( & dict, range, vm, source_code) ;
141145 node. into ( )
@@ -177,7 +181,12 @@ impl Node for Constant {
177181 . cloned ( )
178182 . map ( |object| Node :: ast_from_object ( vm, source_code, object) )
179183 . 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+ }
181190 } else if cls. is ( vm. ctx . types . float_type ) {
182191 let float = value_object. try_into_value ( vm) ?;
183192 ConstantLiteral :: Float ( float)
@@ -247,11 +256,10 @@ fn constant_to_ruff_expr(value: Constant) -> ruff::Expr {
247256 range,
248257 value : ruff:: Number :: Int ( value) ,
249258 } ) ,
250- ConstantLiteral :: Tuple ( value) => ruff:: Expr :: Tuple ( ruff:: ExprTuple {
259+ ConstantLiteral :: Tuple { value, ctx } => ruff:: Expr :: Tuple ( ruff:: ExprTuple {
251260 range,
252261 elts : value. into_iter ( ) . map ( constant_to_ruff_expr) . collect ( ) ,
253- // TODO
254- ctx : ExprContext :: Invalid ,
262+ ctx,
255263 // TODO: Does this matter?
256264 parenthesized : true ,
257265 } ) ,
@@ -270,3 +278,68 @@ fn constant_to_ruff_expr(value: Constant) -> ruff::Expr {
270278 }
271279 }
272280}
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