Coverage for src/castep_linter/fortran/variable_declaration.py: 100%
53 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-23 18:07 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-23 18:07 +0000
1"""Module holding the VariableDeclaration type"""
2from enum import Enum, auto
3from typing import ClassVar, Dict, List, Optional, Set, Tuple
5from castep_linter.fortran.argument_parser import ArgParser, ArgType
6from castep_linter.fortran.fortran_node import Fortran, FortranNode
7from castep_linter.fortran.fortran_statement import FortranStatementParser
8from castep_linter.fortran.identifier import Identifier
11class FType(Enum):
12 """Intrinsic variable types in fortran"""
14 REAL = auto()
15 DOUBLE = auto()
16 COMPLEX = auto()
17 INTEGER = auto()
18 LOGICAL = auto()
19 CHARACTER = auto()
20 OTHER = auto()
23def parse_fort_type(var_decl_node: FortranNode) -> FType:
24 """Parse a variable declaration for type"""
25 try:
26 fortran_type = var_decl_node.get(Fortran.INTRINSIC_TYPE).raw.upper()
27 if fortran_type == "DOUBLE PRECISION":
28 return FType.DOUBLE
29 else:
30 return FType[fortran_type]
31 except KeyError:
32 return FType.OTHER
35def parse_fort_type_qualifiers(var_decl_node: FortranNode) -> Set[str]:
36 """Parse a variable declaration for qualifiers, eg parameter"""
37 qualifiers = set()
38 for type_qualifier in var_decl_node.get_children_by_name(Fortran.TYPE_QUALIFIER):
39 qualifier = type_qualifier.raw.lower()
40 qualifiers.add(qualifier)
41 return qualifiers
44def parse_fort_var_size(var_decl_node: FortranNode) -> ArgParser:
45 """Parse a variable declaration for a size, eg kind=8"""
46 try:
47 fortran_size = var_decl_node.get(Fortran.SIZE)
48 except KeyError:
49 return ArgParser()
51 return ArgParser(fortran_size.get(Fortran.ARGUMENT_LIST))
54def parse_fort_var_names(var_decl_node: FortranNode) -> Dict[Identifier, Optional[str]]:
55 """Parse variable declaration statement for variables and optionally assignments"""
56 myvars: Dict[Identifier, Optional[str]] = {}
57 for assignment in var_decl_node.get_children_by_name(Fortran.ASSIGNMENT_STMT):
58 lhs, rhs = assignment.split()
59 # lhs, rhs = split_relational_node(assignment)
60 varname = Identifier.from_node(lhs)
61 if rhs.is_type(Fortran.STRING_LITERAL):
62 myvars[varname] = rhs.parse_string_literal()
63 else:
64 myvars[varname] = None
65 return myvars
68class VariableDeclaration(FortranStatementParser):
69 """Class representing a variable declaration"""
71 ALLOWED_NODES: ClassVar[List[Fortran]] = [Fortran.VARIABLE_DECLARATION]
73 def __init__(self, var_decl_node: FortranNode) -> None:
74 super().__init__(var_decl_node)
76 self.type = parse_fort_type(var_decl_node)
77 self.qualifiers = parse_fort_type_qualifiers(var_decl_node)
78 self.vars = parse_fort_var_names(var_decl_node)
79 self.args = parse_fort_var_size(var_decl_node)
81 def get_arg(
82 self, keyword: Identifier, position: Optional[int] = None
83 ) -> Tuple[ArgType, FortranNode]:
84 """Get an argument from the call expression"""
85 return self.args.get(keyword, position)