# lint_rules.lint_rules.ifs_coding_standards_2011

Implementation of rules in the IFS coding standards document (2011) for loki-lint.

Classes

`BannedStatementsRule`() |
`CodeBodyRule`() |
`DrHookRule`() |
`ExplicitKindRule`() |
`Fortran90OperatorsRule`() |
`ImplicitNoneRule`() |
`LimitSubroutineStatementsRule`() |
`MaxDummyArgsRule`() |
`ModuleNamingRule`() |
`MplCdstringRule`() |

class BannedStatementsRule

  Bases: `GenericRule`

  type = 2

    The rule type as one of the categories in `RuleType`

  docs = {'id': '4.11', 'title': 'Banned statements.'}

    `dict` with description of the rule

    Typically, this should include `"id"` and `"title"`. Allows for Python’s format specification mini-language in `"title"` to fill values using data from `config`, with the field name corresponding to the config key.

  config = {'banned': ['STOP', 'PRINT', 'RETURN', 'ENTRY', 'DIMENSION', 'DOUBLE PRECISION', 'COMPLEX', 'GO TO', 'CONTINUE', 'FORMAT', 'COMMON', 'EQUIVALENCE']}

    Dict of configuration keys and their default values

    These values can be overriden externally in the linter config file and are passed automatically to the `check()` routine.

  classmethod check_subroutine(subroutine, rule_report, config, **kwargs)

    Check for banned statements in intrinsic nodes.

class CodeBodyRule

  Bases: `GenericRule`

  type = 2

    The rule type as one of the categories in `RuleType`

  docs = {'id': '1.3', 'title': 'Rules for Code Body: Nesting of conditional blocks should not be more than {max_nesting_depth} levels deep;'}

    `dict` with description of the rule

    Typically, this should include `"id"` and `"title"`. Allows for Python’s format specification mini-language in `"title"` to fill values using data from `config`, with the field name corresponding to the config key.

  config = {'max_nesting_depth': 3}

    Dict of configuration keys and their default values

    These values can be overriden externally in the linter config file and are passed automatically to the `check()` routine.

  class NestingDepthVisitor(max_nesting_depth)

    Bases: `Visitor`

    classmethod default_retval()

      Default return value for handler methods.

      This method returns an object to use to populate return values. If your visitor combines values in a tree-walk, it may be useful to provide an object to combine the results into. `default_retval()` may be defined by the visitor to be called to provide an empty object of appropriate type.

      Return type:

        None

    visit(o, *args, **kwargs)

      Apply this `Visitor` to an IR tree.

      Parameters:

        - o (`Node`) – The node to visit.

        - *args – Optional arguments to pass to the visit methods.

        - **kwargs – Optional keyword arguments to pass to the visit methods.

    visit_Conditional(o, **kwargs)
    visit_MultiConditional(o, **kwargs)
    visit_TypeConditional(o, **kwargs)
  classmethod check_subroutine(subroutine, rule_report, config, **kwargs)

    Check the code body: Nesting of conditional blocks.

class DrHookRule

  Bases: `GenericRule`

  type = 3

    The rule type as one of the categories in `RuleType`

  docs = {'id': '1.9', 'title': 'Rules for DR_HOOK'}

    `dict` with description of the rule

    Typically, this should include `"id"` and `"title"`. Allows for Python’s format specification mini-language in `"title"` to fill values using data from `config`, with the field name corresponding to the config key.

  non_exec_nodes = (<class 'loki.ir.nodes.Comment'>, <class 'loki.ir.nodes.CommentBlock'>, <class 'loki.ir.nodes.Pragma'>, <class 'loki.ir.nodes.PreprocessorDirective'>)
  classmethod check_subroutine(subroutine, rule_report, config, **kwargs)

    Check that first and last executable statements in the subroutine are conditionals with calls to DR_HOOK in their body and that the correct arguments are given to the call.

class ExplicitKindRule

  Bases: `GenericRule`

  type = 3

    The rule type as one of the categories in `RuleType`

  docs = {'id': '4.7', 'title': 'Variables and constants must be declared with explicit kind, using the kinds defined in "PARKIND1" and "PARKIND2".'}

    `dict` with description of the rule

    Typically, this should include `"id"` and `"title"`. Allows for Python’s format specification mini-language in `"title"` to fill values using data from `config`, with the field name corresponding to the config key.

  config = {'allowed_type_kinds': {'INTEGER': ['JPIM', 'JPIT', 'JPIB', 'JPIA', 'JPIS', 'JPIH'], 'REAL': ['JPRB', 'JPRM', 'JPRS', 'JPRT', 'JPRH', 'JPRD', 'JPHOOK']}, 'constant_types': ['REAL'], 'declaration_types': ['INTEGER', 'REAL']}

    Dict of configuration keys and their default values

    These values can be overriden externally in the linter config file and are passed automatically to the `check()` routine.

  static check_kind_declarations(subroutine, types, allowed_type_kinds, rule_report)

    Helper function that carries out the check for explicit kind specification on all declarations.

  static check_kind_literals(subroutine, types, allowed_type_kinds, rule_report)

    Helper function that carries out the check for explicit kind specification on all literals.

  classmethod check_subroutine(subroutine, rule_report, config, **kwargs)

    Check for explicit kind information in constants and variable declarations.

class Fortran90OperatorsRule

  Bases: `GenericRule`

  type = 2

    The rule type as one of the categories in `RuleType`

  docs = {'id': '4.15', 'title': 'Use Fortran 90 comparison operators.'}

    `dict` with description of the rule

    Typically, this should include `"id"` and `"title"`. Allows for Python’s format specification mini-language in `"title"` to fill values using data from `config`, with the field name corresponding to the config key.

  fixable = True

    Regex patterns for each operator that match F77 and F90 operators as named groups, thus allowing to easily find out which operator was used.

  class ComparisonRetriever

    Bases: `Visitor`

    Bespoke expression retriever that extracts 3-tuples containing `(node, expression root, comparison)` for all `Comparison` nodes.

    retriever = <loki.expression.mappers.ExpressionRetriever object>
    visit_Node(o, **kwargs)

      Generic visitor method that will call the `ExpressionRetriever` only on `pymbolic.primitives.Expression` children, collecting `(node, expression root, comparison)` tuples for all matches.

    visit_tuple(o, **kwargs)

      Specialized handling of tuples to concatenate the nested tuples returned by `visit_Node()`.

    visit_list(o, **kwargs)

      Specialized handling of tuples to concatenate the nested tuples returned by `visit_Node()`.

  classmethod check_subroutine(subroutine, rule_report, config, **kwargs)

    Check for the use of Fortran 90 comparison operators.

  classmethod fix_subroutine(subroutine, rule_report, config)

    Replace by Fortran 90 comparison operators.

class ImplicitNoneRule

  Bases: `GenericRule`

  type = 3

    The rule type as one of the categories in `RuleType`

  docs = {'id': '4.4', 'title': '"IMPLICIT NONE" is mandatory in all routines.'}

    `dict` with description of the rule

    Typically, this should include `"id"` and `"title"`. Allows for Python’s format specification mini-language in `"title"` to fill values using data from `config`, with the field name corresponding to the config key.

  static check_for_implicit_none(ast)

    Check for intrinsic nodes that match the regex.

  classmethod check_subroutine(subroutine, rule_report, config, **kwargs)

    Check for IMPLICIT NONE in the subroutine’s spec or any enclosing scope.

class LimitSubroutineStatementsRule

  Bases: `GenericRule`

  type = 2

    The rule type as one of the categories in `RuleType`

  docs = {'id': '2.2', 'title': 'Subroutines should have no more than {max_num_statements} executable statements.'}

    `dict` with description of the rule

    Typically, this should include `"id"` and `"title"`. Allows for Python’s format specification mini-language in `"title"` to fill values using data from `config`, with the field name corresponding to the config key.

  config = {'max_num_statements': 300}

    Dict of configuration keys and their default values

    These values can be overriden externally in the linter config file and are passed automatically to the `check()` routine.

  exec_nodes = (<class 'loki.ir.nodes.Assignment'>, <class 'loki.ir.nodes.MaskedStatement'>, <class 'loki.ir.nodes.Intrinsic'>, <class 'loki.ir.nodes.Allocation'>, <class 'loki.ir.nodes.Deallocation'>, <class 'loki.ir.nodes.Nullify'>, <class 'loki.ir.nodes.CallStatement'>)
  match_non_exec_intrinsic_node = re.compile('\\s*(?:PRINT|FORMAT)', re.IGNORECASE)
  classmethod check_subroutine(subroutine, rule_report, config, **kwargs)

    Count the number of nodes in the subroutine and check if they exceed a given maximum number.

class MaxDummyArgsRule

  Bases: `GenericRule`

  type = 1

    The rule type as one of the categories in `RuleType`

  docs = {'id': '3.6', 'title': 'Routines should have no more than {max_num_arguments} dummy arguments.'}

    `dict` with description of the rule

    Typically, this should include `"id"` and `"title"`. Allows for Python’s format specification mini-language in `"title"` to fill values using data from `config`, with the field name corresponding to the config key.

  config = {'max_num_arguments': 50}

    Dict of configuration keys and their default values

    These values can be overriden externally in the linter config file and are passed automatically to the `check()` routine.

  classmethod check_subroutine(subroutine, rule_report, config, **kwargs)

    Count the number of dummy arguments and report if given maximum number exceeded.

class ModuleNamingRule

  Bases: `GenericRule`

  type = 2

    The rule type as one of the categories in `RuleType`

  docs = {'id': '1.5', 'title': 'Naming Schemes for Modules: All modules should end with "_mod". Module filename should match the name of the module it contains.'}

    `dict` with description of the rule

    Typically, this should include `"id"` and `"title"`. Allows for Python’s format specification mini-language in `"title"` to fill values using data from `config`, with the field name corresponding to the config key.

  classmethod check_module(module, rule_report, config)

    Check the module name and the name of the source file.

class MplCdstringRule

  Bases: `GenericRule`

  type = 3

    The rule type as one of the categories in `RuleType`

  docs = {'id': '3.12', 'title': 'Calls to MPL subroutines should provide a "CDSTRING" identifying the caller.'}

    `dict` with description of the rule

    Typically, this should include `"id"` and `"title"`. Allows for Python’s format specification mini-language in `"title"` to fill values using data from `config`, with the field name corresponding to the config key.

  classmethod check_subroutine(subroutine, rule_report, config, **kwargs)

    Check all calls to MPL subroutines for a CDSTRING.