Example #1
0
    def test_from_clang_range(self):
        # Simulating a clang SourceRange is easier than setting one up without
        # actually parsing a complete C file.
        ClangRange = namedtuple("ClangRange", "start end")
        ClangPosition = namedtuple("ClangPosition", "file line column")
        ClangFile = namedtuple("ClangFile", "name")
        file = ClangFile("t.c".encode())
        start = ClangPosition(file, 1, 2)
        end = ClangPosition(file, 3, 4)

        uut = SourceRange.from_clang_range(ClangRange(start, end))
        compare = SourceRange.from_values("t.c", 1, 2, 3, 4)
        self.assertEqual(uut, compare)
Example #2
0
    def test_from_clang_range(self):
        # Simulating a clang SourceRange is easier than setting one up without
        # actually parsing a complete C file.
        ClangRange = namedtuple("ClangRange", "start end")
        ClangPosition = namedtuple("ClangPosition", "file line column")
        ClangFile = namedtuple("ClangFile", "name")
        file = ClangFile("t.c")
        start = ClangPosition(file, 1, 2)
        end = ClangPosition(file, 3, 4)

        uut = SourceRange.from_clang_range(ClangRange(start, end))
        compare = SourceRange.from_values("t.c", 1, 2, 3, 4)
        self.assertEqual(uut, compare)
    def test_from_clang_range(self):
        # Simulating a clang SourceRange is easier than setting one up without
        # actually parsing a complete C file.
        ClangRange = namedtuple('ClangRange', 'start end')
        ClangPosition = namedtuple('ClangPosition', 'file line column')
        ClangFile = namedtuple('ClangFile', 'name')
        file = ClangFile('t.c')
        start = ClangPosition(file, 1, 2)
        end = ClangPosition(file, 3, 4)

        uut = SourceRange.from_clang_range(ClangRange(start, end))
        compare = SourceRange.from_values('t.c', 1, 2, 3, 4)
        self.assertEqual(uut, compare)
Example #4
0
    def run(self, filename, file, clang_cli_options: typed_list(str)=None):
        """
        Check code for syntactical or semantical problems using Clang.

        This bear supports automatic fixes.

        :param clang_cli_options: Any options that will be passed through to
                                  Clang.
        """
        index = Index.create()
        diagnostics = index.parse(
            filename,
            args=clang_cli_options,
            unsaved_files=[(filename, ''.join(file))]).diagnostics
        for diag in diagnostics:
            severity = {0: RESULT_SEVERITY.INFO,
                        1: RESULT_SEVERITY.INFO,
                        2: RESULT_SEVERITY.NORMAL,
                        3: RESULT_SEVERITY.MAJOR,
                        4: RESULT_SEVERITY.MAJOR}.get(diag.severity)
            affected_code = tuple(SourceRange.from_clang_range(range)
                                  for range in diag.ranges)

            diffs = None
            fixits = list(diag.fixits)
            if len(fixits) > 0:
                # FIXME: coala doesn't support choice of diffs, for now
                # append first one only, often there's only one anyway
                diffs = {filename: Diff.from_clang_fixit(fixits[0], file)}

                # No affected code yet? Let's derive it from the fix!
                if len(affected_code) == 0:
                    affected_code = diffs[filename].affected_code(filename)

            # Still no affected code? Position is the best we can get...
            if len(affected_code) == 0 and diag.location.file is not None:
                affected_code = (SourceRange.from_values(
                    diag.location.file.name,
                    diag.location.line,
                    diag.location.column),)

            yield Result(
                self,
                diag.spelling,
                severity=severity,
                affected_code=affected_code,
                diffs=diffs)
Example #5
0
    def run(self, filename, file,
            cyclomatic_complexity: int = 8,
            ):
        """
        Check for all functions if they are too complicated using the
        cyclomatic complexity metric.

        You can read more about this metric at
        <https://www.wikiwand.com/en/Cyclomatic_complexity>.

        :param cyclomatic_complexity:  Maximum cyclomatic complexity that is
                                considered to be normal. The value of 10 had
                                received substantial corroborating evidence.
                                But the general recommendation: "For each
                                module, either limit cyclomatic complexity to
                                [the agreed-upon limit] or provide a written
                                explanation of why the limit was exceeded."
        """

        root = Index.create().parse(filename).cursor
        for cursor, complexity in self.complexities(root, filename):
            if complexity > cyclomatic_complexity:
                affected_code = (SourceRange.from_clang_range(cursor.extent),)
                yield Result(
                    self,
                    "The function '{function}' should be simplified. Its "
                    'cyclomatic complexity is {complexity} which exceeds '
                    'maximal recommended value '
                    'of {rec_value}.'.format(
                        function=cursor.displayname,
                        complexity=complexity,
                        rec_value=cyclomatic_complexity),
                    affected_code=affected_code,
                    additional_info=(
                        'The cyclomatic complexity is a metric that measures '
                        'how complicated a function is by counting branches '
                        'and exits of each function.\n\n'
                        'Your function seems to be complicated and should be '
                        'refactored so that it can be understood by other '
                        'people easily.\n\nSee '
                        '<http://www.wikiwand.com/en/Cyclomatic_complexity>'
                        ' for more information.'))
Example #6
0
    def run(self, filename, file, max_complexity: int = 8):
        """
        Check for all functions if they are too complicated using the cyclomatic
        complexity metric.

        You can read more about this metric at
        <https://www.wikiwand.com/en/Cyclomatic_complexity>.

        :param max_complexity:  Maximum cyclomatic complexity that is
                                considered to be normal. The value of 10 had
                                received substantial corroborating evidence.
                                But the general recommendation: "For each
                                module, either limit cyclomatic complexity to
                                [the agreed-upon limit] or provide a written
                                explanation of why the limit was exceeded."
        """

        root = Index.create().parse(filename).cursor
        for cursor, complexity in self.complexities(root, filename):
            if complexity > max_complexity:
                affected_code = (SourceRange.from_clang_range(cursor.extent),)
                yield Result(
                    self,
                    "The function '{function}' should be simplified. Its "
                    "cyclomatic complexity is {complexity} which exceeds "
                    "maximal recommended value "
                    "of {rec_value}.".format(
                        function=cursor.displayname, complexity=complexity, rec_value=max_complexity
                    ),
                    affected_code=affected_code,
                    additional_info=(
                        "The cyclomatic complexity is a metric that measures "
                        "how complicated a function is by counting branches "
                        "and exits of each function.\n\n"
                        "Your function seems to be complicated and should be "
                        "refactored so that it can be understood by other "
                        "people easily.\n\nSee "
                        "<http://www.wikiwand.com/en/Cyclomatic_complexity>"
                        " for more information."
                    ),
                )