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)
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.