@@ -2966,7 +2966,6 @@ def _visit_DottedName(self, expr):
2966
2966
2967
2967
# look for a class method
2968
2968
if isinstance (rhs , FunctionCall ):
2969
- method = cls_base .get_method (rhs_name )
2970
2969
macro = self .scope .find (rhs_name , 'macros' )
2971
2970
if macro is not None :
2972
2971
master = macro .master
@@ -2976,7 +2975,15 @@ def _visit_DottedName(self, expr):
2976
2975
args = macro .apply (args )
2977
2976
return FunctionCall (master , args , self ._current_function )
2978
2977
2978
+ method = cls_base .get_method (rhs_name )
2979
+
2979
2980
args = [FunctionCallArgument (visited_lhs ), * self ._handle_function_args (rhs .args )]
2981
+ if not method .is_semantic :
2982
+ if not method .is_inline :
2983
+ method = self ._annotate_the_called_function_def (method )
2984
+ else :
2985
+ method = self ._annotate_the_called_function_def (method , function_call_args = args )
2986
+
2980
2987
if cls_base .name == 'numpy.ndarray' :
2981
2988
numpy_class = method .cls_name
2982
2989
self .insert_import ('numpy' , AsName (numpy_class , numpy_class .name ))
@@ -2992,6 +2999,12 @@ def _visit_DottedName(self, expr):
2992
2999
# class property?
2993
3000
else :
2994
3001
method = cls_base .get_method (rhs_name )
3002
+ if not method .is_semantic :
3003
+ if not method .is_inline :
3004
+ method = self ._annotate_the_called_function_def (method )
3005
+ else :
3006
+ method = self ._annotate_the_called_function_def (method ,
3007
+ function_call_args = (FunctionCallArgument (visited_lhs ),))
2995
3008
assert 'property' in method .decorators
2996
3009
if cls_base .name == 'numpy.ndarray' :
2997
3010
numpy_class = method .cls_name
@@ -4348,7 +4361,7 @@ def unpack(ann):
4348
4361
if cls_name :
4349
4362
# update the class methods
4350
4363
if not is_interface :
4351
- bound_class .add_new_method ( func )
4364
+ bound_class .update_method ( expr , func )
4352
4365
4353
4366
new_semantic_funcs += [func ]
4354
4367
if expr .python_ast :
@@ -4374,7 +4387,7 @@ def unpack(ann):
4374
4387
if expr .python_ast :
4375
4388
new_semantic_funcs .set_current_ast (expr .python_ast )
4376
4389
if cls_name :
4377
- bound_class .add_new_interface ( new_semantic_funcs )
4390
+ bound_class .update_interface ( expr , new_semantic_funcs )
4378
4391
self .insert_function (new_semantic_funcs )
4379
4392
4380
4393
return EmptyNode ()
@@ -4455,78 +4468,71 @@ def _visit_ClassDef(self, expr):
4455
4468
docstring = docstring , class_type = dtype )
4456
4469
self .scope .parent_scope .insert_class (cls )
4457
4470
4458
- methods = list (expr .methods )
4459
- init_func = None
4471
+ methods = expr .methods
4472
+ for method in methods :
4473
+ cls .add_new_method (method )
4460
4474
4461
- if not any (method .name == '__init__' for method in methods ):
4475
+ syntactic_init_func = next ((method for method in methods if method .name == '__init__' ), None )
4476
+ if syntactic_init_func is None :
4462
4477
argument = FunctionDefArgument (Variable (dtype , 'self' , cls_base = cls ), bound_argument = True )
4463
4478
self .scope .insert_symbol ('__init__' )
4464
4479
scope = self .create_new_function_scope ('__init__' )
4465
4480
init_func = FunctionDef ('__init__' , [argument ], (), [], cls_name = cls .name , scope = scope )
4466
4481
self .exit_function_scope ()
4467
4482
self .insert_function (init_func )
4468
4483
cls .add_new_method (init_func )
4469
- methods .append (init_func )
4470
-
4471
- for (i , method ) in enumerate (methods ):
4472
- m_name = method .name
4473
- if m_name == '__init__' :
4474
- if init_func is None :
4475
- self ._visit (method )
4476
- init_func = self .scope .functions .pop (m_name )
4477
-
4478
- if isinstance (init_func , Interface ):
4479
- errors .report ("Pyccel does not support interface constructor" , symbol = method ,
4480
- severity = 'fatal' )
4481
- methods .pop (i )
4482
-
4483
- # create a new attribute to check allocation
4484
- deallocater_lhs = Variable (dtype , 'self' , cls_base = cls , is_argument = True )
4485
- deallocater = DottedVariable (lhs = deallocater_lhs , name = self .scope .get_new_name ('is_freed' ),
4486
- class_type = PythonNativeBool (), is_private = True )
4487
- cls .add_new_attribute (deallocater )
4488
- deallocater_assign = Assign (deallocater , LiteralFalse ())
4489
- init_func .body .insert2body (deallocater_assign , back = False )
4490
- break
4491
-
4492
- if not init_func :
4493
- errors .report (UNDEFINED_INIT_METHOD , symbol = name ,
4494
- bounding_box = (self .current_ast_node .lineno , self .current_ast_node .col_offset ),
4495
- severity = 'error' )
4484
+ else :
4485
+ self ._visit (syntactic_init_func )
4486
+ init_func = self .scope .functions .pop ('__init__' )
4496
4487
4497
- for i in methods :
4498
- self ._visit (i )
4488
+ if isinstance (init_func , Interface ):
4489
+ errors .report ("Pyccel does not support interface constructor" , symbol = init_func ,
4490
+ severity = 'fatal' )
4499
4491
4500
- if not any (method .name == '__del__' for method in methods ):
4492
+ # create a new attribute to check allocation
4493
+ deallocater_lhs = Variable (dtype , 'self' , cls_base = cls , is_argument = True )
4494
+ deallocater = DottedVariable (lhs = deallocater_lhs , name = self .scope .get_new_name ('is_freed' ),
4495
+ class_type = PythonNativeBool (), is_private = True )
4496
+ cls .add_new_attribute (deallocater )
4497
+ deallocater_assign = Assign (deallocater , LiteralFalse ())
4498
+ init_func .body .insert2body (deallocater_assign , back = False )
4499
+
4500
+ syntactic_method = next ((m for m in cls .methods if not m .is_semantic ), None )
4501
+ while syntactic_method :
4502
+ self ._visit (syntactic_method )
4503
+ syntactic_method = next ((m for m in cls .methods if not m .is_semantic ), None )
4504
+
4505
+ syntactic_del_func = next ((method for method in methods if method .name == '__del__' ), None )
4506
+ if syntactic_del_func is None :
4501
4507
argument = FunctionDefArgument (Variable (dtype , 'self' , cls_base = cls ), bound_argument = True )
4502
4508
self .scope .insert_symbol ('__del__' )
4503
4509
scope = self .create_new_function_scope ('__del__' )
4504
4510
del_method = FunctionDef ('__del__' , [argument ], (), [Pass ()], scope = scope )
4505
4511
self .exit_function_scope ()
4506
4512
self .insert_function (del_method )
4507
4513
cls .add_new_method (del_method )
4508
-
4509
- for method in cls .methods :
4510
- if method . name == '__del__' :
4511
- self . _current_function = method . name
4512
- attribute = []
4513
- for attr in cls . attributes :
4514
- if not attr . on_stack :
4515
- attribute . append ( attr )
4516
- elif isinstance (attr . class_type , CustomDataType ) and not attr . is_alias :
4517
- attribute . append ( attr )
4518
- if attribute :
4519
- # Create a new list that store local attributes
4520
- self . _allocs . append ( set ())
4521
- self ._pointer_targets .append ({} )
4522
- self ._allocs [ - 1 ]. update ( attribute )
4523
- method . body . insert2body ( * self ._garbage_collector ( method . body ) )
4524
- self . _pointer_targets . pop ( )
4525
- condition = If ( IfSection ( PyccelNot ( deallocater ),
4526
- [ method . body ] + [ Assign ( deallocater , LiteralTrue ())]))
4527
- method . body = [ condition ]
4528
- self . _current_function = None
4529
- break
4514
+ else :
4515
+ del_method = cls .get_method ( '__del__' )
4516
+
4517
+ # Add destructors to __del__ method
4518
+ self . _current_function = del_method . name
4519
+ attribute = []
4520
+ for attr in cls . attributes :
4521
+ if not attr . on_stack :
4522
+ attribute . append (attr )
4523
+ elif isinstance ( attr . class_type , CustomDataType ) and not attr . is_alias :
4524
+ attribute . append ( attr )
4525
+ if attribute :
4526
+ # Create a new list that store local attributes
4527
+ self ._allocs .append (set () )
4528
+ self ._pointer_targets . append ({} )
4529
+ self ._allocs [ - 1 ]. update ( attribute )
4530
+ del_method . body . insert2body ( * self . _garbage_collector ( del_method . body ) )
4531
+ self . _pointer_targets . pop ()
4532
+ condition = If ( IfSection ( PyccelNot ( deallocater ),
4533
+ [ del_method . body ] + [ Assign ( deallocater , LiteralTrue ())]))
4534
+ del_method . body = [ condition ]
4535
+ self . _current_function = None
4530
4536
4531
4537
self .exit_class_scope ()
4532
4538
0 commit comments