@@ -188,6 +188,8 @@ def check_scope(
188
188
strip_str = strip_str .replace ("'" , "" )
189
189
for inc in scope .file_ast .include_statements :
190
190
if strip_str == inc .path :
191
+ if inc .file is None :
192
+ return None
191
193
return fortran_include (inc .file .ast , inc .line_number , inc .path )
192
194
193
195
# Setup USE search
@@ -473,7 +475,7 @@ def __init__(self, file_ast, line_number: int, name: str):
473
475
self .base_setup (file_ast , line_number , name )
474
476
475
477
def base_setup (self , file_ast , sline : int , name : str , keywords : list = []):
476
- self .file_ast = file_ast
478
+ self .file_ast : fortran_ast = file_ast
477
479
self .sline : int = sline
478
480
self .eline : int = sline
479
481
self .name : str = name
@@ -585,7 +587,7 @@ def check_definitions(self, obj_tree):
585
587
contains_line = self .eline
586
588
else :
587
589
contains_line = self .contains_start
588
- # Detect interface defintions
590
+ # Detect interface definitions
589
591
is_interface = False
590
592
if (
591
593
(self .parent is not None )
@@ -625,9 +627,7 @@ def check_definitions(self, obj_tree):
625
627
if line_number > FQSN_dict [child .FQSN ]:
626
628
new_diag = fortran_diagnostic (
627
629
line_number ,
628
- message = 'Variable "{0}" declared twice in scope' .format (
629
- child .name
630
- ),
630
+ message = f'Variable "{ child .name } " declared twice in scope' ,
631
631
severity = 1 ,
632
632
find_word = child .name ,
633
633
)
@@ -651,8 +651,8 @@ def check_definitions(self, obj_tree):
651
651
continue
652
652
new_diag = fortran_diagnostic (
653
653
line_number ,
654
- message = 'Variable "{0}" masks variable in parent scope' . format (
655
- child .name
654
+ message = (
655
+ f'Variable " { child .name } " masks variable in parent scope'
656
656
),
657
657
severity = 2 ,
658
658
find_word = child .name ,
@@ -755,7 +755,11 @@ def get_desc(self):
755
755
756
756
class fortran_submodule (fortran_module ):
757
757
def __init__ (
758
- self , file_ast , line_number : int , name : str , ancestor_name : str = None
758
+ self ,
759
+ file_ast : fortran_ast ,
760
+ line_number : int ,
761
+ name : str ,
762
+ ancestor_name : str = None ,
759
763
):
760
764
self .base_setup (file_ast , line_number , name )
761
765
self .ancestor_name = ancestor_name
@@ -832,7 +836,7 @@ def require_link(self):
832
836
class fortran_subroutine (fortran_scope ):
833
837
def __init__ (
834
838
self ,
835
- file_ast ,
839
+ file_ast : fortran_ast ,
836
840
line_number : int ,
837
841
name : str ,
838
842
args : str = "" ,
@@ -1046,7 +1050,7 @@ def get_diagnostics(self):
1046
1050
class fortran_function (fortran_subroutine ):
1047
1051
def __init__ (
1048
1052
self ,
1049
- file_ast ,
1053
+ file_ast : fortran_ast ,
1050
1054
line_number : int ,
1051
1055
name : str ,
1052
1056
args : str = "" ,
@@ -1168,7 +1172,9 @@ def get_interface(self, name_replace=None, change_arg=-1, change_strings=None):
1168
1172
1169
1173
1170
1174
class fortran_type (fortran_scope ):
1171
- def __init__ (self , file_ast , line_number : int , name : str , keywords : list ):
1175
+ def __init__ (
1176
+ self , file_ast : fortran_ast , line_number : int , name : str , keywords : list
1177
+ ):
1172
1178
self .base_setup (file_ast , line_number , name , keywords = keywords )
1173
1179
#
1174
1180
self .in_children : list = []
@@ -1333,7 +1339,7 @@ def get_actions(self, sline, eline):
1333
1339
1334
1340
1335
1341
class fortran_block (fortran_scope ):
1336
- def __init__ (self , file_ast , line_number : int , name : str ):
1342
+ def __init__ (self , file_ast : fortran_ast , line_number : int , name : str ):
1337
1343
self .base_setup (file_ast , line_number , name )
1338
1344
1339
1345
def get_type (self , no_link = False ):
@@ -1350,7 +1356,7 @@ def req_named_end(self):
1350
1356
1351
1357
1352
1358
class fortran_do (fortran_block ):
1353
- def __init__ (self , file_ast , line_number : int , name : str ):
1359
+ def __init__ (self , file_ast : fortran_ast , line_number : int , name : str ):
1354
1360
self .base_setup (file_ast , line_number , name )
1355
1361
1356
1362
def get_type (self , no_link = False ):
@@ -1361,7 +1367,7 @@ def get_desc(self):
1361
1367
1362
1368
1363
1369
class fortran_where (fortran_block ):
1364
- def __init__ (self , file_ast , line_number : int , name : str ):
1370
+ def __init__ (self , file_ast : fortran_ast , line_number : int , name : str ):
1365
1371
self .base_setup (file_ast , line_number , name )
1366
1372
1367
1373
def get_type (self , no_link = False ):
@@ -1372,7 +1378,7 @@ def get_desc(self):
1372
1378
1373
1379
1374
1380
class fortran_if (fortran_block ):
1375
- def __init__ (self , file_ast , line_number : int , name : str ):
1381
+ def __init__ (self , file_ast : fortran_ast , line_number : int , name : str ):
1376
1382
self .base_setup (file_ast , line_number , name )
1377
1383
1378
1384
def get_type (self , no_link = False ):
@@ -1383,7 +1389,7 @@ def get_desc(self):
1383
1389
1384
1390
1385
1391
class fortran_associate (fortran_block ):
1386
- def __init__ (self , file_ast , line_number : int , name : str ):
1392
+ def __init__ (self , file_ast : fortran_ast , line_number : int , name : str ):
1387
1393
self .base_setup (file_ast , line_number , name )
1388
1394
self .assoc_links = []
1389
1395
@@ -1418,7 +1424,7 @@ def require_link(self):
1418
1424
1419
1425
1420
1426
class fortran_enum (fortran_block ):
1421
- def __init__ (self , file_ast , line_number : int , name : str ):
1427
+ def __init__ (self , file_ast : fortran_ast , line_number : int , name : str ):
1422
1428
self .base_setup (file_ast , line_number , name )
1423
1429
1424
1430
def get_type (self , no_link = False ):
@@ -1429,7 +1435,7 @@ def get_desc(self):
1429
1435
1430
1436
1431
1437
class fortran_select (fortran_block ):
1432
- def __init__ (self , file_ast , line_number : int , name : str , select_info ):
1438
+ def __init__ (self , file_ast : fortran_ast , line_number : int , name : str , select_info ):
1433
1439
self .base_setup (file_ast , line_number , name )
1434
1440
self .select_type = select_info .type
1435
1441
self .binding_name = None
@@ -1486,7 +1492,13 @@ def create_binding_variable(self, file_ast, line_number, var_desc, case_type):
1486
1492
1487
1493
1488
1494
class fortran_int (fortran_scope ):
1489
- def __init__ (self , file_ast , line_number : list , name : str , abstract : bool = False ):
1495
+ def __init__ (
1496
+ self ,
1497
+ file_ast : fortran_ast ,
1498
+ line_number : list ,
1499
+ name : str ,
1500
+ abstract : bool = False ,
1501
+ ):
1490
1502
self .base_setup (file_ast , line_number , name )
1491
1503
self .mems = []
1492
1504
self .abstract = abstract
@@ -1523,7 +1535,7 @@ def require_link(self):
1523
1535
class fortran_var (fortran_obj ):
1524
1536
def __init__ (
1525
1537
self ,
1526
- file_ast ,
1538
+ file_ast : fortran_ast ,
1527
1539
line_number : int ,
1528
1540
name : str ,
1529
1541
var_desc : str ,
@@ -1537,18 +1549,18 @@ def __init__(
1537
1549
1538
1550
def base_setup (
1539
1551
self ,
1540
- file_ast ,
1552
+ file_ast : fortran_ast ,
1541
1553
line_number : int ,
1542
1554
name : str ,
1543
1555
var_desc : str ,
1544
1556
keywords : list ,
1545
1557
keyword_info : dict ,
1546
1558
link_obj : str ,
1547
1559
):
1548
- self .file_ast = file_ast
1560
+ self .file_ast : fortran_ast = file_ast
1549
1561
self .sline : int = line_number
1550
1562
self .eline : int = line_number
1551
- self .name : int = name
1563
+ self .name : str = name
1552
1564
self .desc : str = var_desc
1553
1565
self .keywords : list = keywords
1554
1566
self .keyword_info : dict = keyword_info
@@ -1561,6 +1573,7 @@ def base_setup(
1561
1573
self .link_obj = None
1562
1574
self .type_obj = None
1563
1575
self .is_const : bool = False
1576
+ self .is_external : bool = False
1564
1577
self .param_val : str = None
1565
1578
self .link_name : str = None
1566
1579
self .FQSN : str = self .name .lower ()
@@ -1574,6 +1587,11 @@ def base_setup(
1574
1587
self .vis = - 1
1575
1588
if self .keywords .count (KEYWORD_ID_DICT ["parameter" ]) > 0 :
1576
1589
self .is_const = True
1590
+ if (
1591
+ self .keywords .count (KEYWORD_ID_DICT ["external" ]) > 0
1592
+ or self .desc .lower () == "external"
1593
+ ):
1594
+ self .is_external = True
1577
1595
1578
1596
def update_fqsn (self , enc_scope = None ):
1579
1597
if enc_scope is not None :
@@ -1665,6 +1683,10 @@ def is_parameter(self):
1665
1683
def set_parameter_val (self , val : str ):
1666
1684
self .param_val = val
1667
1685
1686
+ def set_external_attr (self ):
1687
+ self .keywords .append (KEYWORD_ID_DICT ["external" ])
1688
+ self .is_external = True
1689
+
1668
1690
def check_definition (self , obj_tree , known_types = {}, interface = False ):
1669
1691
# Check for type definition in scope
1670
1692
type_match = DEF_KIND_REGEX .match (self .desc )
@@ -1726,7 +1748,7 @@ def check_definition(self, obj_tree, known_types={}, interface=False):
1726
1748
class fortran_meth (fortran_var ):
1727
1749
def __init__ (
1728
1750
self ,
1729
- file_ast ,
1751
+ file_ast : fortran_ast ,
1730
1752
line_number : int ,
1731
1753
name : str ,
1732
1754
var_desc : str ,
@@ -1871,6 +1893,7 @@ def __init__(self, file_obj=None):
1871
1893
self .parse_errors : list = []
1872
1894
self .inherit_objs : list = []
1873
1895
self .linkable_objs : list = []
1896
+ self .external_objs : list = []
1874
1897
self .none_scope = None
1875
1898
self .inc_scope = None
1876
1899
self .current_scope = None
@@ -1945,12 +1968,14 @@ def end_scope(self, line_number: int, check: bool = True):
1945
1968
self .END_SCOPE_REGEX = None
1946
1969
self .enc_scope_name = self .get_enc_scope_name ()
1947
1970
1948
- def add_variable (self , new_var ):
1971
+ def add_variable (self , new_var : fortran_var ):
1949
1972
if self .current_scope is None :
1950
1973
self .create_none_scope ()
1951
1974
new_var .FQSN = self .none_scope .FQSN + "::" + new_var .name .lower ()
1952
1975
self .current_scope .add_child (new_var )
1953
1976
self .variable_list .append (new_var )
1977
+ if new_var .is_external :
1978
+ self .external_objs .append (new_var )
1954
1979
if new_var .require_link ():
1955
1980
self .linkable_objs .append (new_var )
1956
1981
self .last_obj = new_var
0 commit comments