@@ -2277,6 +2277,14 @@ class FunctionDef(ScopedAstNode):
2277
2277
is_external : bool
2278
2278
True for a function which cannot be explicitly imported or renamed.
2279
2279
2280
+ is_imported : bool, default : False
2281
+ True for a function that is imported.
2282
+
2283
+ is_semantic : bool, optional
2284
+ True for a function that is annotated.
2285
+ It is used to indicate if the function has been visited in the semantic stage or not.
2286
+ It is only used by the clone method, where we might clone a syntactic function in the semantic stage.
2287
+
2280
2288
functions : list, tuple
2281
2289
A list of functions defined within this function.
2282
2290
@@ -2331,7 +2339,8 @@ class FunctionDef(ScopedAstNode):
2331
2339
'_decorators' ,'_headers' ,'_is_recursive' ,'_is_pure' ,
2332
2340
'_is_elemental' ,'_is_private' ,'_is_header' ,
2333
2341
'_functions' ,'_interfaces' ,'_docstring' , '_is_external' ,
2334
- '_result_pointer_map' )
2342
+ '_result_pointer_map' ,'_is_imported' , '_is_semantic' )
2343
+
2335
2344
_attribute_nodes = ('_arguments' ,'_results' ,'_body' ,
2336
2345
'_global_vars' ,'_imports' ,'_functions' ,'_interfaces' )
2337
2346
@@ -2353,6 +2362,8 @@ def __init__(
2353
2362
is_private = False ,
2354
2363
is_header = False ,
2355
2364
is_external = False ,
2365
+ is_imported = False ,
2366
+ is_semantic = None ,
2356
2367
functions = (),
2357
2368
interfaces = (),
2358
2369
result_pointer_map = {},
@@ -2448,11 +2459,13 @@ def __init__(
2448
2459
self ._is_private = is_private
2449
2460
self ._is_header = is_header
2450
2461
self ._is_external = is_external
2462
+ self ._is_imported = is_imported
2451
2463
self ._functions = functions
2452
2464
self ._interfaces = interfaces
2453
2465
self ._result_pointer_map = result_pointer_map
2454
2466
self ._docstring = docstring
2455
2467
super ().__init__ (scope )
2468
+ self ._is_semantic = self .pyccel_staging != 'syntactic' if is_semantic is None else is_semantic
2456
2469
2457
2470
@property
2458
2471
def name (self ):
@@ -2596,6 +2609,15 @@ def is_external(self):
2596
2609
from a f77 module """
2597
2610
return self ._is_external
2598
2611
2612
+ @property
2613
+ def is_imported (self ):
2614
+ """
2615
+ Indicates if the function was imported from another file.
2616
+
2617
+ Indicates if the function was imported from another file.
2618
+ """
2619
+ return self ._is_imported
2620
+
2599
2621
@property
2600
2622
def is_inline (self ):
2601
2623
""" True if the function should be printed inline """
@@ -2610,6 +2632,16 @@ def is_static(self):
2610
2632
"""
2611
2633
return self ._is_static
2612
2634
2635
+ @property
2636
+ def is_semantic (self ):
2637
+ """
2638
+ Indicates if the function was created with semantic information.
2639
+
2640
+ Indicates if the function has been annotated with type descriptors
2641
+ in the semantic stage.
2642
+ """
2643
+ return self ._is_semantic
2644
+
2613
2645
@property
2614
2646
def functions (self ):
2615
2647
""" List of functions within this function """
@@ -2661,7 +2693,6 @@ def clone(self, newname, **new_kwargs):
2661
2693
new_func .rename (newname )
2662
2694
return new_func
2663
2695
2664
-
2665
2696
def rename (self , newname ):
2666
2697
"""
2667
2698
Rename the FunctionDef name
@@ -2700,6 +2731,8 @@ def __getnewargs__(self):
2700
2731
'is_header' :self ._is_header ,
2701
2732
'functions' :self ._functions ,
2702
2733
'is_external' :self ._is_external ,
2734
+ 'is_imported' :self ._is_imported ,
2735
+ 'is_semantic' :self ._is_semantic ,
2703
2736
'interfaces' :self ._interfaces ,
2704
2737
'docstring' :self ._docstring ,
2705
2738
'scope' :self ._scope }
@@ -2756,19 +2789,27 @@ class InlineFunctionDef(FunctionDef):
2756
2789
"""
2757
2790
Represents a function definition for an inline function.
2758
2791
2792
+ Represents a function definition for an inline function.
2793
+
2759
2794
Parameters
2760
2795
----------
2761
- See FunctionDef
2762
-
2763
- namespace_imports : Scope
2764
- The objects in the scope which are available due to imports
2796
+ *args : list
2797
+ The FunctionDef class arguments.
2798
+ namespace_imports : dict
2799
+ The imports available in the function Scope.
2800
+ global_funcs : iterable, optional
2801
+ The global functions used in the function.
2802
+ **kwargs : dict
2803
+ The FunctionDef class keyword arguments.
2765
2804
"""
2766
2805
__slots__ = ('_namespace_imports' ,'_orig_args' ,'_new_args' ,'_new_local_vars' , '_if_block_replacements' ,
2767
2806
'_global_funcs' )
2768
2807
2769
2808
def __init__ (self , * args , namespace_imports = None , global_funcs = None , ** kwargs ):
2809
+ if namespace_imports is not None :
2810
+ assert isinstance (namespace_imports , dict )
2770
2811
self ._namespace_imports = namespace_imports
2771
- self ._global_funcs = global_funcs
2812
+ self ._global_funcs = tuple ( global_funcs ) if global_funcs is not None else None
2772
2813
super ().__init__ (* args , ** kwargs )
2773
2814
self ._orig_args = tuple (a .var for a in self .arguments )
2774
2815
self ._new_args = None
@@ -2861,6 +2902,15 @@ def global_funcs(self):
2861
2902
""" List of global functions used in the function """
2862
2903
return self ._global_funcs
2863
2904
2905
+ def __getnewargs__ (self ):
2906
+ """
2907
+ This method returns the positional and keyword arguments
2908
+ used to create an instance of this class.
2909
+ """
2910
+ args , kwargs = super ().__getnewargs__ ()
2911
+ kwargs .update ({'namespace_imports' :self ._namespace_imports , 'global_funcs' :self ._global_funcs })
2912
+ return args , kwargs
2913
+
2864
2914
class PyccelFunctionDef (FunctionDef ):
2865
2915
"""
2866
2916
Class used for storing `PyccelInternalFunction` objects in a FunctionDef.
@@ -2930,29 +2980,40 @@ class Interface(PyccelAstNode):
2930
2980
is_argument : bool
2931
2981
True if the interface is used for a function argument.
2932
2982
2983
+ is_imported : bool
2984
+ True if the interface is imported from another file.
2985
+
2986
+ syntactic_node : FunctionDef, default: None
2987
+ The syntactic node that is not annotated.
2988
+
2933
2989
Examples
2934
2990
--------
2935
2991
>>> from pyccel.ast.core import Interface, FunctionDef
2936
2992
>>> f = FunctionDef('F', [], [], [])
2937
2993
>>> Interface('I', [f])
2938
2994
"""
2939
- __slots__ = ('_name' ,'_functions' ,'_is_argument' )
2995
+ __slots__ = ('_name' ,'_functions' ,'_is_argument' , '_is_imported' , '_syntactic_node' )
2940
2996
_attribute_nodes = ('_functions' ,)
2941
2997
2942
2998
def __init__ (
2943
2999
self ,
2944
3000
name ,
2945
3001
functions ,
2946
3002
is_argument = False ,
3003
+ is_imported = False ,
3004
+ syntactic_node = None ,
2947
3005
):
2948
3006
2949
3007
if not isinstance (name , str ):
2950
3008
raise TypeError ('Expecting an str' )
2951
- if not isinstance (functions , list ):
2952
- raise TypeError ('Expecting a list' )
3009
+
3010
+ assert iterable (functions )
3011
+
2953
3012
self ._name = name
2954
- self ._functions = functions
3013
+ self ._functions = tuple ( functions )
2955
3014
self ._is_argument = is_argument
3015
+ self ._is_imported = is_imported
3016
+ self ._syntactic_node = syntactic_node
2956
3017
super ().__init__ ()
2957
3018
2958
3019
@property
@@ -2970,6 +3031,24 @@ def is_argument(self):
2970
3031
"""True if the interface is used for a function argument."""
2971
3032
return self ._is_argument
2972
3033
3034
+ @property
3035
+ def is_imported (self ):
3036
+ """
3037
+ Indicates if the function was imported from another file.
3038
+
3039
+ Indicates if the function was imported from another file.
3040
+ """
3041
+ return self ._is_imported
3042
+
3043
+ @property
3044
+ def syntactic_node (self ):
3045
+ """
3046
+ The syntactic node that is not annotated.
3047
+
3048
+ The syntactic node that is not annotated.
3049
+ """
3050
+ return self ._syntactic_node
3051
+
2973
3052
@property
2974
3053
def docstring (self ):
2975
3054
"""
@@ -2979,6 +3058,83 @@ def docstring(self):
2979
3058
"""
2980
3059
return self ._functions [0 ].docstring
2981
3060
3061
+ @property
3062
+ def is_semantic (self ):
3063
+ """
3064
+ Flag to check if the node is annotated.
3065
+
3066
+ Flag to check if the node has been annotated with type descriptors
3067
+ in the semantic stage.
3068
+ """
3069
+ return self ._functions [0 ].is_semantic
3070
+
3071
+ @property
3072
+ def is_inline (self ):
3073
+ """
3074
+ Flag to check if the node is inlined.
3075
+
3076
+ Flag to check if the node is inlined.
3077
+ """
3078
+ return self ._functions [0 ].is_inline
3079
+
3080
+ def rename (self , newname ):
3081
+ """
3082
+ Rename the Interface name to a newname.
3083
+
3084
+ Rename the Interface name to a newname.
3085
+
3086
+ Parameters
3087
+ ----------
3088
+ newname : str
3089
+ New name for the Interface.
3090
+ """
3091
+
3092
+ self ._name = newname
3093
+
3094
+ def clone (self , newname , ** new_kwargs ):
3095
+ """
3096
+ Create an almost identical Interface with name `newname`.
3097
+
3098
+ Create an almost identical Interface with name `newname`.
3099
+ Additional parameters can be passed to alter the resulting
3100
+ FunctionDef.
3101
+
3102
+ Parameters
3103
+ ----------
3104
+ newname : str
3105
+ New name for the Interface.
3106
+
3107
+ **new_kwargs : dict
3108
+ Any new keyword arguments to be passed to the new Interface.
3109
+
3110
+ Returns
3111
+ -------
3112
+ Interface
3113
+ The clone of the interface.
3114
+ """
3115
+
3116
+ args , kwargs = self .__getnewargs__ ()
3117
+ kwargs .update (new_kwargs )
3118
+ cls = type (self )
3119
+ new_func = cls (* args , ** kwargs )
3120
+ new_func .rename (newname )
3121
+ return new_func
3122
+
3123
+ def __getnewargs__ (self ):
3124
+ """
3125
+ This method returns the positional and keyword arguments
3126
+ used to create an instance of this class.
3127
+ """
3128
+ args = (
3129
+ self ._name ,
3130
+ self ._functions )
3131
+
3132
+ kwargs = {
3133
+ 'is_argument' : self ._is_argument ,
3134
+ 'is_imported' :self ._is_imported ,
3135
+ 'syntactic_node' :self ._syntactic_node }
3136
+ return args , kwargs
3137
+
2982
3138
def point (self , args , use_final_precision = False ):
2983
3139
"""Returns the actual function that will be called, depending on the passed arguments."""
2984
3140
fs_args = [[j for j in i .arguments ] for i in
0 commit comments