def translation_unit_based_rule(translation_unit):
    violations = []
    for token in translation_unit.cursor.walk_preorder():
        violation = checker.extract_violation(token, ID, f"{MSG} for {translation_unit.spelling}")
        if violation:
            violations.append(violation)
    return violations
def translation_unit_based_rule(translation_unit):
    """Checks for nested namespaces in one translation unit"""
    violations = []
    nested_namespaces = defaultdict(list)

    # Set up a list of nested namspaces
    for token in translation_unit.cursor.walk_preorder():
        if token.kind == cindex.CursorKind.NAMESPACE:
            if token.is_definition():
                if token.location.file.name == translation_unit.spelling:
                    # TODO Consider use a child-token traversal
                    # The decision about the nesting level of namespace can
                    # be derived from the clang naming count of a special token
                    number_of_nestings = token.get_usr().count("@N")
                    if number_of_nestings > MAX_DEPTH_ALLOWED:
                        nested_namespaces[token.spelling].append(
                            (token, number_of_nestings))

    # Create violations based on nested namespaces found
    for _, nestings_per_namespace in nested_namespaces.items():
        for nesting_per_namespace, number_of_nestings in nestings_per_namespace:
            violation = checker.extract_violation(
                nesting_per_namespace,
                ID,
                f"Multiple of {number_of_nestings} nested namespace(s) in one translation unit",
            )
            if violation:
                violations.append(violation)
    return violations
示例#3
0
def token_based_rule(token):
    """Checks whether an upper case "u" is provided for unsigned int literals"""
    violation = None
    if token.kind == cindex.CursorKind.INTEGER_LITERAL:
        if token.type.spelling == "unsigned int":
            for child_token in token.get_tokens():
                if "u" in child_token.spelling:
                    violation = checker.extract_violation(
                        child_token, ID,
                        "Lower Case suffix for unsigned integer")
    return violation
示例#4
0
def check_for_clang_warnings(translation_unit):
    """Interprets clang diagnostics warnings (aka compiler warnings) as violations
    The checker differs from the other ones as it operates on the translation unit directly"""
    violations = []
    checker.log_progress_for_checker(translation_unit, __name__)

    for diagnostic in translation_unit.diagnostics:
        if diagnostic.option and diagnostic.location.file:
            if diagnostic.option.startswith("-W"):
                the_id = ID_PREFIX + diagnostic.option[2:].upper().replace(
                    "-", "_")
                violation = checker.extract_violation(diagnostic, the_id,
                                                      diagnostic.spelling)
            violations.append(violation)
    return violations
def translation_unit_based_rule(translation_unit):
    violations = []
    classes = []
    for token in translation_unit.cursor.walk_preorder():
        if token.kind == cindex.CursorKind.CLASS_DECL:
            if token.is_definition():
                if token.location.file.name == translation_unit.spelling:
                    classes.append(token)

    for the_class in classes:
        computed_name, basename = compute_expected_name(
            the_class, translation_unit.spelling)
        if computed_name != basename:
            violation = checker.extract_violation(
                the_class,
                ID,
                f"File name should be named '{computed_name}' as derived from the class '{the_class.spelling}'",
            )
            if violation:
                violations.append(violation)
    return violations
def translation_unit_based_rule(translation_unit):
    """Checks for multiple classes in one translation unit"""
    violations = []
    classes = []

    for token in translation_unit.cursor.walk_preorder():
        if token.kind == cindex.CursorKind.CLASS_DECL:
            if token.is_definition():
                if token.location.file.name == translation_unit.spelling:
                    classes.append(token)

    if len(classes) > ALLOWED_NUMBER_OF_CLASSES_PER_FILE:
        for the_class_token in classes:
            violation = checker.extract_violation(
                the_class_token,
                ID,
                f"Multiple of {len(classes)} classes 'class {the_class_token.spelling}' in one translation unit",
            )
            if violation:
                violations.append(violation)
    return violations
def translation_unit_based_rule(translation_unit):
    """Find variable declrations which could be made const"""
    # TODO Check usage of a variable when handing over as a non-const reference
    violations = []

    # All non-const variable declaration are suspected to be read-only
    all_non_const_variable_declarations = {}
    for token in translation_unit.cursor.walk_preorder():
        if token.kind == cindex.CursorKind.VAR_DECL:
            if not token.type.is_const_qualified():
                all_non_const_variable_declarations[hash(token)] = token

    # Check which of those variable declarations are being used as a reference in a binary operation (:= written)
    for token in translation_unit.cursor.walk_preorder():
        referenced = check_references(token)
        if referenced:
            all_non_const_variable_declarations[hash(referenced)] = None
        if (token.kind == cindex.CursorKind.BINARY_OPERATOR
                or token.kind == cindex.CursorKind.UNARY_OPERATOR or token.kind
                == cindex.CursorKind.COMPOUND_ASSIGNMENT_OPERATOR):
            for child in token.get_children():
                if child.kind == cindex.CursorKind.DECL_REF_EXPR:
                    if child.referenced:
                        for reference in child.referenced.walk_preorder():
                            if reference.kind == cindex.CursorKind.VAR_DECL:
                                all_non_const_variable_declarations[hash(
                                    reference)] = None

    # Create violations based on non-const read-only variables
    # If the used token is not None, we have a violation
    for _, the_used_token in all_non_const_variable_declarations.items():
        if the_used_token:
            violation = checker.extract_violation(
                the_used_token,
                ID,
                f"The variable '{the_used_token.spelling}' could be made const",
            )
            if violation:
                violations.append(violation)
    return violations
def token_based_rule(token):
    violation = None
    violation = checker.extract_violation(token, ID, f"{MSG} for {token.spelling}")
    return violation