1919class FortranAST :
2020 def __init__ (self , file_obj = None ):
2121 self .file = file_obj
22- self .path : str = None
23- if file_obj is not None :
24- self .path = file_obj .path
22+ self .path : str | None = file_obj .path if file_obj is not None else None
2523 self .global_dict : dict = {}
2624 self .scope_list : list = []
2725 self .variable_list : list = []
@@ -39,10 +37,10 @@ def __init__(self, file_obj=None):
3937 self .none_scope = None
4038 self .inc_scope = None
4139 self .current_scope = None
42- self .END_SCOPE_REGEX : Pattern = None
43- self .enc_scope_name : str = None
40+ self .end_scope_regex : Pattern | None = None
41+ self .enc_scope_name : str | None = None
4442 self .last_obj = None
45- self .pending_doc : str = None
43+ self .pending_doc : str | None = None
4644
4745 def create_none_scope (self ):
4846 """Create empty scope to hold non-module contained items"""
@@ -60,7 +58,7 @@ def get_enc_scope_name(self):
6058 def add_scope (
6159 self ,
6260 new_scope : Scope ,
63- END_SCOPE_REGEX : Pattern [str ],
61+ end_scope_regex : Pattern [str ],
6462 exportable : bool = True ,
6563 req_container : bool = False ,
6664 ):
@@ -80,10 +78,10 @@ def add_scope(
8078 else :
8179 self .current_scope .add_child (new_scope )
8280 self .scope_stack .append (self .current_scope )
83- if self .END_SCOPE_REGEX is not None :
84- self .end_stack .append (self .END_SCOPE_REGEX )
81+ if self .end_scope_regex is not None :
82+ self .end_stack .append (self .end_scope_regex )
8583 self .current_scope = new_scope
86- self .END_SCOPE_REGEX = END_SCOPE_REGEX
84+ self .end_scope_regex = end_scope_regex
8785 self .enc_scope_name = self .get_enc_scope_name ()
8886 self .last_obj = new_scope
8987 if self .pending_doc is not None :
@@ -102,9 +100,9 @@ def end_scope(self, line_number: int, check: bool = True):
102100 else :
103101 self .current_scope = None
104102 if len (self .end_stack ) > 0 :
105- self .END_SCOPE_REGEX = self .end_stack .pop ()
103+ self .end_scope_regex = self .end_stack .pop ()
106104 else :
107- self .END_SCOPE_REGEX = None
105+ self .end_scope_regex = None
108106 self .enc_scope_name = self .get_enc_scope_name ()
109107
110108 def add_variable (self , new_var : Variable ):
@@ -170,11 +168,11 @@ def add_error(self, msg: str, sev: int, ln: int, sch: int, ech: int = None):
170168 def start_ppif (self , line_number : int ):
171169 self .pp_if .append ([line_number - 1 , - 1 ])
172170
173- def end_ppif (self , line_number ):
171+ def end_ppif (self , line_number : int ):
174172 if len (self .pp_if ) > 0 :
175173 self .pp_if [- 1 ][1 ] = line_number - 1
176174
177- def get_scopes (self , line_number : int = None ):
175+ def get_scopes (self , line_number : int | None = None ):
178176 """Get a list of all the scopes present in the line number provided.
179177
180178 Parameters
@@ -191,65 +189,69 @@ def get_scopes(self, line_number: int = None):
191189 return self .scope_list
192190 scope_list = []
193191 for scope in self .scope_list :
194- if (line_number >= scope .sline ) and (line_number <= scope .eline ):
195- if type (scope .parent ) == Interface :
196- for use_stmnt in scope .use :
197- if type (use_stmnt ) != Import :
198- continue
199- # Exclude the parent and all other scopes
200- if use_stmnt .import_type == ImportTypes .NONE :
201- return [scope ]
202- scope_list .append (scope )
203- scope_list .extend (iter (scope .get_ancestors ()))
192+ if not scope .sline <= line_number <= scope .eline :
193+ continue
194+ if type (scope .parent ) is Interface :
195+ for use_stmnt in scope .use :
196+ if type (use_stmnt ) is not Import :
197+ continue
198+ # Exclude the parent and all other scopes
199+ if use_stmnt .import_type == ImportTypes .NONE :
200+ return [scope ]
201+ scope_list .append (scope )
202+ scope_list .extend (iter (scope .get_ancestors ()))
204203 if scope_list or self .none_scope is None :
205204 return scope_list
206- else :
207- return [self .none_scope ]
205+ return [self .none_scope ]
208206
209207 def get_inner_scope (self , line_number : int ):
210208 scope_sline = - 1
211209 curr_scope = None
212210 for scope in self .scope_list :
213- if scope .sline > scope_sline and (
214- (line_number >= scope .sline ) and (line_number <= scope .eline )
215- ):
211+ if scope .sline > scope_sline and scope .sline <= line_number <= scope .eline :
216212 curr_scope = scope
217213 scope_sline = scope .sline
218214 if (curr_scope is None ) and (self .none_scope is not None ):
219215 return self .none_scope
220216 return curr_scope
221217
222218 def get_object (self , FQSN : str ):
223- FQSN_split = FQSN .split ("::" )
224- curr_obj = self .global_dict .get (FQSN_split [0 ])
225- if curr_obj is None :
226- # Look for non-exportable scopes
227- for scope in self .scope_list :
228- if FQSN_split [0 ] == scope .FQSN :
229- curr_obj = scope
230- break
231- if curr_obj is None :
219+ def find_child_by_name (parent , name ):
220+ for child in parent .children :
221+ if child .name == name :
222+ return child
223+ if child .name .startswith ("#GEN_INT" ):
224+ found = next (
225+ (
226+ int_child
227+ for int_child in child .get_children ()
228+ if int_child .name == name
229+ ),
230+ None ,
231+ )
232+ if found :
233+ return found
232234 return None
233- if len ( FQSN_split ) > 1 :
234- for name in FQSN_split [ 1 :]:
235- next_obj = None
236- for child in curr_obj . children :
237- if child . name . startswith ( "#GEN_INT" ):
238- for int_child in child . get_children () :
239- if int_child . name == name :
240- next_obj = int_child
241- break
242- if next_obj is not None :
243- break
244- if child . name == name :
245- next_obj = child
246- break
247- if next_obj is None :
248- return None
249- curr_obj = next_obj
250- return curr_obj
251-
252- def resolve_includes (self , workspace , path : str = None ):
235+
236+ parts = FQSN . split ( "::" )
237+ current = self . global_dict . get ( parts [ 0 ])
238+
239+ # Look for non-exportable scopes
240+ if current is None :
241+ current = next (
242+ ( scope for scope in self . scope_list if scope . FQSN == parts [ 0 ]), None
243+ )
244+ if current is None :
245+ return None
246+
247+ for part in parts [ 1 :]:
248+ current = find_child_by_name ( current , part )
249+ if current is None :
250+ return None
251+
252+ return current
253+
254+ def resolve_includes (self , workspace , path : str | None = None ):
253255 file_dir = os .path .dirname (self .path )
254256 for inc in self .include_statements :
255257 file_path = os .path .normpath (os .path .join (file_dir , inc .path ))
0 commit comments