Skip to content

Commit 0200e03

Browse files
committed
refactor: further python semantics updates
1 parent 2bb0700 commit 0200e03

File tree

1 file changed

+37
-27
lines changed

1 file changed

+37
-27
lines changed

fortls/objects.py

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import re
77
from dataclasses import dataclass
88
from typing import Pattern
9+
from typing import Type as T
910

1011
from fortls.constants import (
1112
ASSOC_TYPE_ID,
@@ -570,7 +571,7 @@ def __init__(self, file_ast, line_number: int, name: str, keywords: list = None)
570571
self.sline: int = line_number
571572
self.eline: int = line_number
572573
self.name: str = name
573-
self.children: list = []
574+
self.children: list[T[Scope]] = []
574575
self.members: list = []
575576
self.use: list[Use | Import] = []
576577
self.keywords: list = keywords
@@ -621,7 +622,7 @@ def update_fqsn(self, enc_scope=None):
621622
def add_member(self, member):
622623
self.members.append(member)
623624

624-
def get_children(self, public_only=False):
625+
def get_children(self, public_only=False) -> list[T[FortranObj]]:
625626
if not public_only:
626627
return copy.copy(self.children)
627628
pub_children = []
@@ -634,40 +635,40 @@ def get_children(self, public_only=False):
634635
pub_children.append(child)
635636
return pub_children
636637

637-
def check_definitions(self, obj_tree):
638+
def check_definitions(self, obj_tree) -> list[Diagnostic]:
638639
"""Check for definition errors in scope"""
639-
FQSN_dict = {}
640+
fqsn_dict: dict[str, int] = {}
641+
errors: list[Diagnostic] = []
642+
known_types: dict[str, FortranObj] = {}
643+
640644
for child in self.children:
641645
# Skip masking/double checks for interfaces
642646
if child.get_type() == INTERFACE_TYPE_ID:
643647
continue
644648
# Check other variables in current scope
645-
if child.FQSN in FQSN_dict:
646-
if child.sline < FQSN_dict[child.FQSN]:
647-
FQSN_dict[child.FQSN] = child.sline - 1
649+
if child.FQSN in fqsn_dict:
650+
if child.sline < fqsn_dict[child.FQSN]:
651+
fqsn_dict[child.FQSN] = child.sline - 1
648652
else:
649-
FQSN_dict[child.FQSN] = child.sline - 1
650-
#
653+
fqsn_dict[child.FQSN] = child.sline - 1
654+
651655
contains_line = -1
652-
after_contains_list = (SUBROUTINE_TYPE_ID, FUNCTION_TYPE_ID)
653656
if self.get_type() in (
654657
MODULE_TYPE_ID,
655658
SUBMODULE_TYPE_ID,
656659
SUBROUTINE_TYPE_ID,
657660
FUNCTION_TYPE_ID,
658661
):
659-
if self.contains_start is None:
660-
contains_line = self.eline
661-
else:
662-
contains_line = self.contains_start
662+
contains_line = (
663+
self.contains_start if self.contains_start is not None else self.eline
664+
)
663665
# Detect interface definitions
664666
is_interface = (
665667
self.parent is not None
666668
and self.parent.get_type() == INTERFACE_TYPE_ID
667669
and not self.is_mod_scope()
668670
)
669-
errors = []
670-
known_types = {}
671+
671672
for child in self.children:
672673
if child.name.startswith("#"):
673674
continue
@@ -679,8 +680,9 @@ def check_definitions(self, obj_tree):
679680
if def_error is not None:
680681
errors.append(def_error)
681682
# Detect contains errors
682-
if (contains_line >= child.sline) and (
683-
child.get_type(no_link=True) in after_contains_list
683+
if contains_line >= child.sline and child.get_type(no_link=True) in (
684+
SUBROUTINE_TYPE_ID,
685+
FUNCTION_TYPE_ID,
684686
):
685687
new_diag = Diagnostic(
686688
line_number,
@@ -689,12 +691,13 @@ def check_definitions(self, obj_tree):
689691
)
690692
errors.append(new_diag)
691693
# Skip masking/double checks for interfaces and members
692-
if (self.get_type() == INTERFACE_TYPE_ID) or (
693-
child.get_type() == INTERFACE_TYPE_ID
694+
if (
695+
self.get_type() == INTERFACE_TYPE_ID
696+
or child.get_type() == INTERFACE_TYPE_ID
694697
):
695698
continue
696699
# Check other variables in current scope
697-
if child.FQSN in FQSN_dict and line_number > FQSN_dict[child.FQSN]:
700+
if child.FQSN in fqsn_dict and line_number > fqsn_dict[child.FQSN]:
698701
new_diag = Diagnostic(
699702
line_number,
700703
message=f'Variable "{child.name}" declared twice in scope',
@@ -703,22 +706,26 @@ def check_definitions(self, obj_tree):
703706
)
704707
new_diag.add_related(
705708
path=self.file_ast.path,
706-
line=FQSN_dict[child.FQSN],
709+
line=fqsn_dict[child.FQSN],
707710
message="First declaration",
708711
)
709712
errors.append(new_diag)
710713
continue
711714
# Check for masking from parent scope in subroutines, functions, and blocks
712-
if (self.parent is not None) and (
713-
self.get_type() in (SUBROUTINE_TYPE_ID, FUNCTION_TYPE_ID, BLOCK_TYPE_ID)
715+
if self.parent is not None and self.get_type() in (
716+
SUBROUTINE_TYPE_ID,
717+
FUNCTION_TYPE_ID,
718+
BLOCK_TYPE_ID,
714719
):
715720
parent_var = find_in_scope(self.parent, child.name, obj_tree)
716721
if parent_var is not None:
717722
# Ignore if function return variable
718-
if (self.get_type() == FUNCTION_TYPE_ID) and (
719-
parent_var.FQSN == self.FQSN
723+
if (
724+
self.get_type() == FUNCTION_TYPE_ID
725+
and parent_var.FQSN == self.FQSN
720726
):
721727
continue
728+
722729
new_diag = Diagnostic(
723730
line_number,
724731
message=(
@@ -733,6 +740,7 @@ def check_definitions(self, obj_tree):
733740
message="First declaration",
734741
)
735742
errors.append(new_diag)
743+
736744
return errors
737745

738746
def check_use(self, obj_tree):
@@ -854,7 +862,9 @@ def require_inherit(self):
854862
return True
855863

856864
def resolve_link(self, obj_tree):
857-
def get_ancestor_interfaces(ancestor_children: list[FortranObj]):
865+
def get_ancestor_interfaces(
866+
ancestor_children: list[Scope],
867+
) -> list[T[Interface]]:
858868
interfaces = []
859869
for child in ancestor_children:
860870
if child.get_type() != INTERFACE_TYPE_ID:

0 commit comments

Comments
 (0)