Beispiel #1
0
class PerlCriticBear:
    """
    Check the code with perlcritic. This will run perlcritic over
    each of the files seperately.
    """

    LANGUAGES = {'Perl'}
    REQUIREMENTS = {
        DistributionRequirement(apt_get='perl'),
        DistributionRequirement(apt_get='libperl-critic-perl')
    }
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Syntax', 'Formatting', 'Code Simplification'}

    @staticmethod
    def create_arguments(filename,
                         file,
                         config_file,
                         perlcritic_profile: str = ''):
        """
        :param perlcritic_profile: Location of the perlcriticrc config file.
        """
        args = ('--no-color', )
        if perlcritic_profile:
            args += ('--profile', perlcritic_profile)
        return args + (filename, )
Beispiel #2
0
class GhcModBear:  # pragma nt: no cover
    """
    Syntax checking with ``ghc`` for Haskell files.

    See <https://hackage.haskell.org/package/ghc-mod> for more information!
    """

    LANGUAGES = {'Haskell'}
    REQUIREMENTS = {
        AnyOneOfRequirements(
            [CabalRequirement('ghc-mod', '5.6.0.0'),
             DistributionRequirement('ghc-mod')
             ]
        ),
    }
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    ASCIINEMA_URL = 'https://asciinema.org/a/98873'
    CAN_DETECT = {'Syntax'}

    @staticmethod
    def create_arguments(filename, file, config_file):
        # -b '. ' is the argument given for ghc-mod for seperation of messages
        return '-b', '. ', 'check', filename
Beispiel #3
0
class CheckstyleBear:
    """
    Check Java code for possible style, semantic and design issues.

    For more information, consult
    <http://checkstyle.sourceforge.net/checks.html>.
    """

    LANGUAGES = {'Java'}
    REQUIREMENTS = {DistributionRequirement(apt_get='default-jre')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Formatting', 'Smell'}

    def setup_dependencies(self):
        type(self).checkstyle_jar_file = self.download_cached_file(
            'http://sourceforge.net/projects/checkstyle/files/checkstyle/6.19'
            '/checkstyle-6.19-all.jar',
            'checkstyle-6.19.jar')

    def create_arguments(
            self, filename, file, config_file,
            checkstyle_configs: known_checkstyle_or_path = 'google',
            use_spaces: bool = True,
            indent_size: int = 2,
            ):
        """
        :param checkstyle_configs:
            A file containing configs to use in ``checkstyle``. It can also
            have the special values:

            - google - Google's Java style. More info at
              <http://checkstyle.sourceforge.net/style_configs.html>.
            - sun - Sun's Java style. These are the same
              as the default Eclipse checks. More info at
              <http://checkstyle.sourceforge.net/style_configs.html>.
            - android-check-easy - The easy Android configs provided by the
              android-check eclipse plugin. More info at
              <https://github.com/noveogroup/android-check>.
            - android-check-hard - The hard Android confis provided by the
              android-check eclipse plugin. More info at
              <https://github.com/noveogroup/android-check>.
            - geosoft - The Java style followed by GeoSoft. More info at
              <http://geosoft.no/development/javastyle.html>
        """
        check_invalid_configuration(
            checkstyle_configs, use_spaces, indent_size)

        if checkstyle_configs in ('google', 'sun'):
            # Checkstyle included these two rulesets since version 6.2
            # Locate the file as an absolute resource into the checkstyle jar
            checkstyle_configs = '/%s_checks.xml' % checkstyle_configs
        elif checkstyle_configs in _online_styles:
            checkstyle_configs = self.download_cached_file(
                _online_styles[checkstyle_configs],
                checkstyle_configs + '.xml')

        return ('-jar', self.checkstyle_jar_file, '-c',
                checkstyle_configs, filename)
Beispiel #4
0
class CPPCheckBear:
    """
    Report possible security weaknesses for C/C++.
    For more information, consult <https://github.com/danmar/cppcheck>.
    """

    LANGUAGES = {'C', 'C++'}
    REQUIREMENTS = {DistributionRequirement(apt_get='cppcheck')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Security', 'Unused Code', 'Unreachable Code', 'Smell'}

    @staticmethod
    def create_arguments(filename, file, config_file,
                         enable: typed_list(str)=[]):
        """
        :param enable:
            Choose specific issues to report. Issues that can be
            reported are: all, warning, style, performance,
            portability, information, unusedFunction,
            missingInclude
        """
        args = ('--template={line}:{severity}:{id}:{message}',)

        if enable:
            args += ('--enable=' + ','.join(enable),)

        return args + (filename,)
class VerilogLintBear:
    """
    Analyze Verilog code using ``verilator`` and checks for all lint
    related and code style related warning messages. It supports the
    synthesis subset of Verilog, plus initial statements, proper
    blocking/non-blocking assignments, functions, tasks.

    It also warns about unused code when a specified signal is never sinked,
    and unoptimized code due to some construct, with which the
    optimization of the specified signal or block is disabled.

    This is done using the ``--lint-only`` command. For more information visit
    <http://www.veripool.org/projects/verilator/wiki/Manual-verilator>.
    """
    LANGUAGES = {'Verilog'}
    REQUIREMENTS = {
        DistributionRequirement(
            apt_get='verilator',
            brew=None,
            dnf='verilator',
            portage=None,
            yum='verilator',
            zypper='verilator',
        ),
    }
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    ASCIINEMA_URL = 'https://asciinema.org/a/45275'
    CAN_DETECT = {'Formatting', 'Code Simplification', 'Syntax', 'Unused Code'}

    @staticmethod
    def create_arguments(filename, file, config_file):
        return '--lint-only', filename
class ScalaLintBear:
    """
    Check Scala code for codestyle, but also semantical problems,
    e.g. cyclomatic complexity.
    """

    LANGUAGES = {'Scala'}
    REQUIREMENTS = {DistributionRequirement(apt_get='default-jre')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    INCLUDE_LOCAL_FILES = {'scalastyle.jar', 'scalalint_config.xml'}
    CAN_DETECT = {'Formatting', 'Complexity'}

    def setup_dependencies(self):
        type(self).jar = self.download_cached_file(
            'https://oss.sonatype.org/content/repositories/releases/org/'
            'scalastyle/scalastyle_2.10/0.8.0/scalastyle_2.10-0.8.0-batch.jar',
            'scalastyle.jar')

    @staticmethod
    def create_arguments(filename,
                         file,
                         config_file,
                         scalalint_config: str = scalastyle_config_file):
        """
        :param scalalint_config: Path to a custom configuration file.
        """
        return ('-jar', ScalaLintBear.jar, filename, '--config',
                scalalint_config)
Beispiel #7
0
class DartLintBear:
    """
    Checks the code with ``dart-linter``.

    This bear expects dart commands to be on your ``PATH``. Please ensure
    /path/to/dart-sdk/bin is in your ``PATH``.
    """
    LANGUAGES = {'Dart'}
    REQUIREMENTS = {DistributionRequirement(brew='dart')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Syntax', 'Formatting'}

    @staticmethod
    def create_arguments(
        filename,
        file,
        config_file,
        use_spaces: bool = True,
        indent_size: int = 2,
    ):
        # use_spaces must be True and indent_size must be 2 because
        # dartanalyzer only supports these settings
        # see https://github.com/dart-lang/dart_style/issues/261
        if (indent_size != 2 or not use_spaces):
            raise ValueError('DartLintBear only supports `use_spaces=True` '
                             'and `indent_size=2`')
        return filename,
Beispiel #8
0
class PHPMessDetectorBear:
    """
    The bear takes a given PHP source code base and looks for several
    potential problems within that source. These problems can be things like:

    - Possible bugs
    - Suboptimal code
    - Overcomplicated expressions
    - Unused parameters, methods, properties
    """

    LANGUAGES = {'PHP'}
    REQUIREMENTS = {DistributionRequirement(apt_get='phpmd')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {
        'Formatting', 'Complexity', 'Unused Code', 'Redundancy',
        'Variable Misuse'
    }
    SEE_MORE = 'https://phpmd.org/about.html'

    @staticmethod
    def create_arguments(filename, file, config_file,
                         phpmd_rulesets: typed_list(str)):
        """
        :param phpmd_rulesets:
            A list of rulesets to use for analysis.
            Available rulesets: cleancode, codesize, controversial, design,
            naming, unusedcode.
        """
        return filename, 'text', ','.join(phpmd_rulesets)
class LicenseCheckBear:
    """
    Attempts to check the given file for a license, by searching the start
    of the file for text belonging to various licenses.

    For Ubuntu/Debian users, the ``licensecheck_lines`` option has to be used
    in accordance with the ``licensecheck_tail`` option.
    """
    LANGUAGES = {'All'}
    REQUIREMENTS = {
        DistributionRequirement(apt_get='devscripts', dnf='licensecheck')
    }
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'License'}

    @staticmethod
    def create_arguments(filename,
                         file,
                         config_file,
                         licensecheck_lines: int = 60,
                         licensecheck_tail: int = 5000):
        """
        :param licensecheck_lines:
            Specify how many lines of the file header should be parsed for
            license information. Set to 0 to parse the whole file (and ignore
            ``licensecheck_tail``).
        :param licensecheck_tail:
            Specify how many bytes to parse at end of file. Set to 0 to disable
            parsing from end of file.
        """
        return ('--lines', str(licensecheck_lines), '--tail',
                str(licensecheck_tail), filename)
class ShellCheckBear:  # pragma nt: no cover
    """
    Check bash/shell scripts for syntactical problems (with understandable
    messages), semantical problems as well as subtle caveats and pitfalls.

    A gallery of bad code that can be detected is available at
    <https://github.com/koalaman/shellcheck/blob/master/README.md>.
    """

    LANGUAGES = {'sh', 'bash', 'ksh', 'dash'}
    REQUIREMENTS = {AnyOneOfRequirements(
            [CabalRequirement('ShellCheck', '0.4.1'),
             DistributionRequirement('shellcheck')
             ]
        ),
    }
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Syntax', 'Security', 'Undefined Element', 'Unused Code'}

    @staticmethod
    def create_arguments(filename, file, config_file, shell: str = 'sh',
                         shellcheck_ignore: list = None,
                         ):
        """
        :param shell: Target shell being used.
        :param shellcheck_ignore: List of linting rules that should be ignored.
        """
        args = ('--f', 'gcc', '-s', shell, filename)
        if shellcheck_ignore:
            args += ('-e', ','.join(shellcheck_ignore))

        return args
Beispiel #11
0
class XMLBear:
    """
    Checks the code with ``xmllint``.

    See http://xmlsoft.org/xmllint.html
    """
    LANGUAGES = {'XML'}
    REQUIREMENTS = {
        DistributionRequirement(
            'libxml2',
            apt_get='libxml2-utils',
            portage='dev-libs/libxml2',
        ),
    }
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Formatting', 'Syntax'}

    _output_regex = re.compile(
        r'.*:(?P<line>\d+):.*(?P<severity>error|warning)\s?: '
        r'(?P<message>.*)\n.*\n.*')

    @staticmethod
    def create_arguments(filename, file, config_file,
                         xml_schema: path='',
                         xml_dtd: path_or_url=''):
        """
        :param xml_schema: ``W3C XML Schema`` file used for validation.
        :param xml_dtd:    ``Document type Definition (DTD)`` file or
                           url used for validation.
        """
        args = (filename,)
        if xml_schema:
            args += ('-schema', xml_schema)
        if xml_dtd:
            args += ('-dtdvalid', xml_dtd)

        return args

    def process_output(self, output, filename, file):
        stdout, stderr = output
        if stdout:
            # Return issues from stderr and stdout if stdout is not empty
            return itertools.chain(
                self.process_output_regex(
                    stderr, filename, file,
                    output_regex=self._output_regex),
                self.process_output_corrected(
                    stdout, filename, file,
                    diff_severity=RESULT_SEVERITY.INFO,
                    result_message='XML can be formatted better.'))
        else:
            # Return issues from stderr if stdout is empty
            return self.process_output_regex(
                stderr, filename, file,
                output_regex=self._output_regex)
class HaskellLintBear:
    """
    Check Haskell code for possible problems. This bear can propose patches for
    using alternative functions, simplifying code and removing redundancies.

    See <http://community.haskell.org/~ndm/darcs/hlint/hlint.htm> for more
    information.
    """

    LANGUAGES = {'Haskell'}
    REQUIREMENTS = {
        AnyOneOfRequirements([
            CabalRequirement(package='hlint', version='1.9.27'),
            DistributionRequirement(apt_get='hlint'),
        ], ),
    }
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Duplication'}
    CAN_FIX = {'Unused Code', 'Code Simplification'}

    severity_map = {
        'Error': RESULT_SEVERITY.MAJOR,
        'Warning': RESULT_SEVERITY.NORMAL,
        'Suggestion': RESULT_SEVERITY.INFO
    }

    @staticmethod
    def create_arguments(filename, file, config_file):
        return '--json', filename

    def process_output(self, output, filename, file):
        output = json.loads(output)

        for issue in output:
            diff = Diff(file)
            from_lines = issue['from'].splitlines()
            to_lines = issue['to'].splitlines()
            assert len(from_lines) == len(to_lines)
            for other_lines in range(1, len(from_lines)):
                assert from_lines[other_lines] == to_lines[other_lines]
            line_nr = issue['startLine']
            line_to_change = file[line_nr - 1]
            newline = line_to_change.replace(from_lines[0], to_lines[0])
            diff.change_line(line_nr, line_to_change, newline)

            yield Result.from_values(
                origin=self,
                message=issue['hint'],
                file=filename,
                severity=self.severity_map[issue['severity']],
                line=issue['startLine'],
                column=issue['startColumn'],
                end_line=issue['endLine'],
                end_column=issue['endColumn'],
                diffs={filename: diff})
Beispiel #13
0
class CPPCheckBear:
    """
    Report possible security weaknesses for C/C++.
    For more information, consult <https://github.com/danmar/cppcheck>.
    """

    LANGUAGES = {'C', 'CPP'}
    REQUIREMENTS = {DistributionRequirement('cppcheck')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Security', 'Unused Code', 'Unreachable Code', 'Smell'}

    def create_arguments(
        self,
        config_file,
        enable: typed_list(str) = [],
        language: str = None,
    ):
        """
        :param enable:
            Choose specific issues to report. Issues that can be
            reported are: all, warning, style, performance,
            portability, information, unusedFunction,
            missingInclude

        :param language:
            Choose specific language for linting. Language can be
            either c or c++
        """
        args = ('--template={file}:{line}:{severity}:{id}:{message}', )
        files = tuple(self.file_dict.keys())

        if enable:
            args += ('--enable=' + ','.join(enable), )

        if language is not None:
            try:
                lang = Language[language]
                if isinstance(lang, Language.CPP):
                    args += ('--language=c++', )
                elif isinstance(lang, Language.C):
                    args += ('--language=c', )
                else:
                    logging.error('Language can be either c or c++')
                    return
            except Exception:
                logging.error('Language can be either c or c++')
                return
        return args + files
Beispiel #14
0
class RubySyntaxBear:
    """
    Checks the code with ``ruby -wc`` on each file separately.
    """
    LANGUAGES = {'Ruby'}
    REQUIREMENTS = {DistributionRequirement(apt_get='ruby')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Syntax'}

    @staticmethod
    def create_arguments(filename, file, config_file):
        return '-wc', filename
Beispiel #15
0
class PHPLintBear:
    """
    Checks the code with ``php -l``. This runs it on each file separately.
    """
    LANGUAGES = {'PHP'}
    REQUIREMENTS = {DistributionRequirement(apt_get='php-cli')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Syntax'}

    @staticmethod
    def create_arguments(filename, file, config_file):
        return ('-l', '-n', '-d', 'display_errors=On', '-d', 'log_errors=Off',
                filename)
Beispiel #16
0
class CSharpLintBear:
    """
    Checks C# code for syntactical correctness using the ``mcs`` compiler.
    """

    LANGUAGES = {'C#'}
    REQUIREMENTS = {DistributionRequirement(apt_get='mono-mcs')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Syntax'}

    @staticmethod
    def create_arguments(filename, file, config_file):
        return filename,
Beispiel #17
0
class LuaLintBear:
    """
    Check Lua code for possible semantic problems, like unused code.

    Read more at <https://github.com/mpeterv/luacheck>.
    """

    LANGUAGES = {'Lua'}
    REQUIREMENTS = {DistributionRequirement(apt_get='luarocks')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Unreachable Code', 'Unused Code', 'Variable Misuse'}

    @staticmethod
    def create_arguments(filename, file, config_file):
        return '-', '--formatter=plain', '--ranges', '--codes'
Beispiel #18
0
class RLintBear:
    """
    Checks the code with ``lintr``.
    """
    LANGUAGES = {'R'}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    REQUIREMENTS = {
        RscriptRequirement('lintr'),
        DistributionRequirement(apt_get='r-base', version='>=3.1.1')
    }
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Syntax', 'Formatting'}

    @staticmethod
    def create_arguments(filename, file, config_file):
        return ('-e', 'library(lintr)', '-e',
                'lintr::lint("' + escape(filename, '\\"') + '")')
class LatexLintBear:  # pragma nt: no cover
    """
    Checks the code with ``chktex``.
    """
    LANGUAGES = {'Tex'}
    REQUIREMENTS = {DistributionRequirement('chktex', zypper='texlive-chktex')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Syntax', 'Formatting'}

    @staticmethod
    def create_arguments(filename, file, config_file):
        return (
            '--format',
            '%k %n in {0} line %l: %m!n'.format(filename),
            filename,
        )
Beispiel #20
0
class CSecurityBear:
    """
    Report possible security weaknesses for C/C++.

    For more information, consult <http://www.dwheeler.com/flawfinder/>.
    """

    LANGUAGES = {'C', 'C++'}
    REQUIREMENTS = {DistributionRequirement('flawfinder')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    ASCIINEMA_URL = 'https://asciinema.org/a/7z8ol9mpsgtuo1096c6jk8hi6'
    CAN_DETECT = {'Security', 'Memory Leak', 'Code Simplification'}

    @staticmethod
    def create_arguments(filename, file, config_file):
        return '--columns', '--dataonly', '--quiet', '--singleline', filename
Beispiel #21
0
class VHDLLintBear:  # pragma nt: no cover
    """
    Check VHDL code for common codestyle problems.

    Rules include:

     * Signals, variables, ports, types, subtypes, etc. must be lowercase.
     * Constants and generics must be uppercase.
     * Entities, architectures and packages must be "mixedcase" (may be 100%
       uppercase, but not 100% lowercase).
     * Ports must be suffixed using _i, _o or _io denoting its kind.
     * Labels must be placed in a separated line. Exception: component
       instantiation.
     * End statements must be documented indicating what are finishing.
     * Buffer ports are forbidden.
     * VHDL constructions of the "entity xxxx is" and similars must be in one
       line. You can't put "entity xxxxx" in one line and "is" in another.
     * No more than one VHDL construction is allowed in one line of code.

    See <http://fpgalibre.sourceforge.net/ingles.html#tp46> for more
    information.
    """

    LANGUAGES = {'VHDL'}
    REQUIREMENTS = {DistributionRequirement('perl')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Formatting'}

    @classmethod
    def check_prerequisites(cls):
        if which('perl') is None:
            return 'perl is not installed.'
        elif which('bakalint.pl') is None:
            return ('bakalint is missing. Download it from '
                    '<http://fpgalibre.sourceforge.net/ingles.html#tp46> and '
                    'put it into your PATH.')
        else:
            return True

    @staticmethod
    def create_arguments(filename, file, config_file):
        return which('bakalint.pl'), '--input', filename
Beispiel #22
0
class RLintBear:  # pragma nt: no cover
    """
    Checks the code with ``lintr``.
    """
    LANGUAGES = {'R'}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    REQUIREMENTS = {
        RscriptRequirement('lintr', version='>=1.0.2'),
        DistributionRequirement(apt_get='r-base', version='>=3.1.1')
    }
    LICENSE = 'AGPL-3.0'
    ASCIINEMA_URL = 'https://asciinema.org/a/178910'
    CAN_DETECT = {'Syntax', 'Formatting'}
    SEE_MORE = 'https://github.com/jimhester/lintr'

    @staticmethod
    def create_arguments(filename, file, config_file):
        return ('-e', 'library(lintr)', '-e',
                'lintr::lint("' + escape(filename, '\\"') + '")')
Beispiel #23
0
class JuliaLintBear:
    """
    Provide analysis related to common bugs and potential issues in Julia like
    dead code, undefined variable usage, duplicate keys in dicts, incorrect
    ADT usage, wrongfully using ellipsis, and much more.

    See <https://lintjl.readthedocs.org/en/stable/> for more information
    on the analysis provided.
    """
    LANGUAGES = {'Julia'}
    REQUIREMENTS = {DistributionRequirement(apt_get='julia')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {'Unused Code', 'Syntax', 'Redundancy', 'Duplication',
                  'Unreachable Code', 'Security', 'Formatting'}

    @staticmethod
    def create_arguments(filename, file, config_file):
        lintcode = ('import Lint.lintfile; display(lintfile("' +
                    escape(filename, '"\\') + '"))')
        return '-e', lintcode
Beispiel #24
0
class GNUIndentBear:
    """
    This bear checks and corrects spacing and indentation via the well known
    Indent utility.

    C++ support is considered experimental.
    """

    LANGUAGES = {'C', 'C++'}
    REQUIREMENTS = {DistributionRequirement('indent')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_FIX = {'Formatting'}

    @staticmethod
    @deprecate_settings(indent_size='tab_width')
    def create_arguments(
        filename,
        file,
        config_file,
        max_line_length: int = 79,
        use_spaces: bool = True,
        blank_lines_after_declarations: bool = False,
        blank_lines_after_procedures: bool = False,
        blank_lines_after_commas: bool = False,
        braces_on_if_line: bool = False,
        braces_on_func_def_line: bool = False,
        cuddle_else: bool = False,
        while_and_brace_on_same_line: bool = False,
        case_indentation: int = 0,
        space_before_semicolon_after_empty_loop: bool = True,
        delete_optional_blank_lines: bool = True,
        declaration_indent: int = 0,
        brace_indent: int = 2,
        gnu_style: bool = False,
        k_and_r_style: bool = False,
        linux_style: bool = False,
        indent_size: int = SpacingHelper.DEFAULT_TAB_WIDTH,
        indent_cli_options: str = '',
    ):
        """
        :param max_line_length:
            Maximum number of characters for a line.
            When set to 0, infinite line length is allowed.
        :param use_spaces:
            True if spaces are to be used, else tabs.
        :param blank_lines_after_declarations:
            Forces blank lines after the declarations.

            Example: If ``blank_lines_after_declarations = True`` then::

                int a;
                return ...;

            changes to::

                int a;

                return ...;

        :param blank_lines_after_procedures:
            Force blank lines after procedure bodies.
        :param blank_lines_after_commas:
            Forces newline after comma in declaration.

            Example: If ``blank_lines_after_commas = True`` then::

                int a, b;

            changes to::

                int a,
                b;

        :param braces_on_if_line:
            Puts the brace ``{`` on same line with if.

            Example: If ``braces_on_if_line = True``  then::

                if (x > 0)
                {

            changes to::

                if (x > 0) {

        :param braces_on_func_def_line:
            Puts the brace `{` on same line with the function declaration.
        :param cuddle_else:
            Cuddle else and preceding ``}``.

            Example: If ``cuddle_else = True`` then::

                if (...) {
                    ....
                }
                else {

            changes to::

                if (...) {
                    ....
                } else {

        :param while_and_brace_on_same_line:
            Cuddles while of ``do {} while``; and preceding ``}``.
        :param case_indentation:
            Specifies the number of spaces by which ``case`` in the ``switch``
            are indented.
        :param space_before_semicolon_after_empty_loop:
            Forces a blank before the semicolon ``;`` on one-line ``for`` and
            ``while`` statements.
        :param delete_optional_blank_lines:
             Deletes blank lines that are not needed. An example of needed
             blank line, is the blank line following a declaration when
             ``blank_line_after_declaration=True``.
        :param declaration_indent:
            Forces variables names to be aligned in column ``n`` with
            ``n = declaration_indent``  in declaration.

            Example: If ``declaration_indent = 8`` then::

                int a;
                float b;

            changes to::

                int     a;
                float   b;

        :param brace_indent:
            Specifies the number of spaces by which braces are indented. Its
            default value is 2.
        :param gnu_style:
            Uses GNU coding style.
        :param k_and_r_style:
            Uses Kernighan & Ritchie coding style.
        :param linux_style:
            Uses Linux coding style.
        :param indent_size:
            Number of spaces per indentation level.
        :param indent_cli_options:
            Any command line options the indent binary understands. They
            will be simply passed through.
        """
        # The limit is set to an arbitrary high value
        if not max_line_length:
            max_line_length = sys.maxsize

        indent_options = (
            '--no-tabs' if use_spaces else '--use-tabs',
            '--line-length',
            str(max_line_length),
            '--indent-level',
            str(indent_size),
            '--tab-size',
            str(indent_size),
        )
        indent_options += (('--cuddle-do-while', )
                           if while_and_brace_on_same_line else
                           ('--dont-cuddle-do-while', ))
        indent_options += (('--swallow-optional-blank-lines', )
                           if delete_optional_blank_lines else ('-nsob', ))
        indent_options += (('--blank-lines-after-declarations', )
                           if blank_lines_after_declarations else ('-nbad', ))
        indent_options += (('--blank-lines-after-commas', )
                           if blank_lines_after_commas else ('-nbc', ))
        indent_options += (('--blank-lines-after-procedures', )
                           if blank_lines_after_procedures else ('-nbap', ))
        indent_options += (('-di' + str(declaration_indent), )
                           if declaration_indent != 0 else ())
        indent_options += (('--case-indentation' + str(case_indentation), )
                           if case_indentation != 0 else ())
        indent_options += (('--space-special-semicolon', )
                           if space_before_semicolon_after_empty_loop else
                           ('-nss', ))
        indent_options += ('--brace-indent' + str(brace_indent), )
        indent_options += (('--braces-on-func-def-line', )
                           if braces_on_func_def_line else ('-blf', ))
        indent_options += ((('-ce', ) if cuddle_else else ('-nce', )) +
                           ('-br', )) if braces_on_if_line else ('-bl', )
        indent_style_option = ()
        indent_style_option += ('--gnu-style', ) if gnu_style else ()
        indent_style_option += (('--k-and-r-style', ) if k_and_r_style
                                and indent_style_option is () else ())
        indent_style_option += (('--linux-style', ) if linux_style
                                and indent_style_option is () else ())

        # If a style is chosen the other configs aren't passed to `indent`
        return (indent_style_option if indent_style_option is not () else
                indent_options) + tuple(shlex.split(indent_cli_options))
class PHPCodeSnifferBear:
    """
    Ensures that your PHP, JavaScript or CSS code remains clean and consistent.

    See <https://github.com/squizlabs/PHP_CodeSniffer> for more information.
    """

    LANGUAGES = {'PHP', 'JavaScript', 'CSS'}
    REQUIREMENTS = {
        AnyOneOfRequirements([
            DistributionRequirement(
                apt_get='php-codesniffer',
                zypper='php-pear-php_codesniffer',
            ),
            ComposerRequirement('squizlabs/php_codesniffer'),
        ], ),
    }
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_DETECT = {
        'Formatting', 'Syntax', 'Documentation', 'Code Simplification'
    }
    ASCIINEMA_URL = 'https://asciinema.org/a/efawv96vdalck73tc3hwcabov'

    @staticmethod
    def create_arguments(filename, file, config_file):
        return '--report=emacs', '--standard=' + config_file, filename

    @staticmethod
    def generate_config(filename,
                        file,
                        max_line_length: int = 79,
                        line_ending_character: str = '\\n',
                        indent_size: int = SpacingHelper.DEFAULT_TAB_WIDTH,
                        use_spaces: bool = True,
                        allow_multiple_statements_per_line: bool = False,
                        force_lower_case_keywords: bool = True,
                        force_lower_case_constants: bool = True,
                        blank_line_after_namespace_declaration: bool = True,
                        check_use_blocks: bool = True,
                        check_class_declaration: bool = True,
                        check_property_declaration: bool = True,
                        force_scope_modifier_on_method: bool = True,
                        function_declaration_argument_spacing: int = 1,
                        allow_multiline_function_declaration: bool = True):
        """
        :param max_line_length:
            Maximum number of characters for a line.
        :param line_ending_character:
            Checks that end of line characters correspond to the one provided.
        :param indent_size:
            Number of spaces per indentation level.
        :param use_spaces:
            True if spaces are to be used instead of tabs.
        :param allow_multiple_statements_per_line:
            Allows having multiple statements on one line.
        :param force_lower_case_keyword:
            Checks that ``PHP`` keywords are lowercase.
        :param force_lower_case_constant:
            Checks that all uses of ``true``, ``false`` and ``null`` are
            lowercase.
        :param blank_line_after_namespace_declaration:
            Ensures that there is a blank line after a namespace declaration.
        :param check_use_blocks:
            Ensures that there is one blank line after a ``use`` block,
            that there is only one use block per line, and that all ``use``
            declaration are done after namespaces declaration.
        :param check_class_declaration:
            Ensures that ``extends`` and ``implements`` keywords are declared
            on the same line as the class name, that the opening brace for a
            class is on the next line, and that the closing brace for a class
            is on the next line after the body. Allows splitting implements
            list accross multiple lines.
        :param check_property_declaration:
            Ensures that visibility is declared on all properties, that the
            ``var`` keyword is not used to declare a property, that there is
            not more that one property declared on a line, that properties are
            not prefixed with an underscore.
        :param force_scope_modifier_on_method:
            Verifies that class methods have scope modifiers.
        :param function_declaration_argument_spacing:
            Number of spaces between arguments in function declaration.
        :param allow_multiline_function_declaration:
            Allows argument lists to be split accross multiple lines correctly
            indented.
        """
        rules_map = {
            'Generic.WhiteSpace.DisallowTabIndent':
            use_spaces,
            'Generic.Formatting.DisallowMultipleStatements':
            not allow_multiple_statements_per_line,
            'Generic.PHP.LowerCaseKeyword':
            force_lower_case_keywords,
            'Generic.PHP.LowerCaseConstant':
            force_lower_case_constants,
            'PSR2.Namespaces.UseDeclaration':
            check_use_blocks,
            'PSR2.Namespaces.NamespaceDeclaration':
            blank_line_after_namespace_declaration,
            'PSR2.Classes.ClassDeclaration':
            check_class_declaration,
            'PSR2.Classes.PropertyDeclaration':
            check_property_declaration,
            'Squiz.Scope.MethodScope':
            force_scope_modifier_on_method,
            'Squiz.Functions.MultiLineFunctionDeclaration':
            allow_multiline_function_declaration
        }
        rules = ''
        for k, v in rules_map.items():
            rules += '<rule ref="{}"/>\n'.format(k) if v else ''
        configs = '''<?xml version="1.0"?>
<ruleset name="Custom Standard">
 <description>A custom coding standard</description>
 <!-- Include the whole PSR-1 standard -->
 <rule ref="PSR1"/>
 <rule ref="Generic.Files.LineLength">
  <properties>
   <property name="lineLimit" value="{max_line_length}"/>
   <property name="absoluteLineLimit" value="{absolute_line_length}"/>
  </properties>
 </rule>
 <rule ref="Generic.Files.LineEndings">
  <properties>
   <property name="eolChar" value="{line_ending_character}"/>
  </properties>
 </rule>
 <rule ref="Generic.WhiteSpace.ScopeIndent">
  <properties>
   <property name="ignoreIndentationTokens" type="array"
   value="T_COMMENT,T_DOC_COMMENT_OPEN_TAG"/>
  </properties>
  <properties>
   <property name="indent" value="{indent_size}"/>
  </properties>
  <properties>
   <property name="exact" value="true"/>
  </properties>
 </rule>
 {some_rules}
 <rule ref="Squiz.WhiteSpace.ScopeKeywordSpacing"/>
 <rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing">
  <properties>
   <property name="equalsSpacing"
   value="{function_declaration_argument_spacing}"/>
  </properties>
 </rule>
 <rule
 ref="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingAfterHint">
  <severity>0</severity>
 </rule>
</ruleset>
'''.format(max_line_length=max_line_length,
           absolute_line_length=0,
           line_ending_character=line_ending_character,
           indent_size=indent_size,
           some_rules=rules,
           function_declaration_argument_spacing=(
               function_declaration_argument_spacing))
        return configs
Beispiel #26
0
class TailorBear:
    """
    Analyze Swift code and check for code style related
    warning messages.

    For more information on the analysis visit <https://tailor.sh/>
    """
    LANGUAGES = {'Swift'}
    REQUIREMENT = {DistributionRequirement(brew='tailor')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    ASCIINEMA_URL = 'https://asciinema.org/a/45666'
    CAN_DETECT = {'Formatting'}

    severity_map = {
        'warning': RESULT_SEVERITY.NORMAL,
        'error': RESULT_SEVERITY.MAJOR
    }

    def process_output(self, output, filename, file):
        output = json.loads(output)

        for item in output['files'][0]['violations']:
            column = (item['location']['column']
                      if 'column' in item['location'].keys() else None)

            yield Result.from_values(
                origin='{} ({})'.format(self.name, item['rule']),
                message=item['message'],
                file=filename,
                line=item['location']['line'],
                column=column,
                severity=self.severity_map[item['severity']])

    @staticmethod
    def create_arguments(filename,
                         file,
                         config_file,
                         max_line_length: int = 79,
                         max_class_length: int = 0,
                         max_closure_length: int = 0,
                         max_file_length: int = 0,
                         max_function_length: int = 0,
                         max_name_length: int = 0,
                         max_struct_length: int = 0,
                         min_name_length: int = 1,
                         tailor_config: path = ''):
        """
        Bear configuration arguments.
        Using '0' will disable the check.

        :param max_line_length:     maximum number of characters in a Line
                                    <0-999>.
        :param max_class_length:    maximum number of lines in a Class <0-999>.
        :param max_closure_length:  maximum number of lines in a Closure
                                    <0-999>.
        :param max_file_length:     maximum number of lines in a File <0-999>.
        :param max_function_length: maximum number of lines in a Function
                                    <0-999>.
        :param max_name_length:     maximum length of Identifier name <0-999>.
        :param max_struct_length:   maximum number od lines in a Struct
                                    <0-999>.
        :param min_name_length:     minimum number of characters in Identifier
                                    name <1-999>.
        :param tailor_config:       path to Tailor configuration file.
        """
        args = ('--format=json', '--max-line-length',
                str(max_line_length), '--max-class-length',
                str(max_class_length), '--max-closure-length',
                str(max_closure_length), '--max-file-length',
                str(max_file_length), '--max-function-length',
                str(max_function_length), '--max-name-length',
                str(max_name_length), '--max-struct-length',
                str(max_struct_length), '--min-name-length',
                str(min_name_length))
        if tailor_config:
            args += ('--config=' + tailor_config, )
        return args + (filename, )
class ArtisticStyleBear:
    """
    Artistic Style is a source code indenter, formatter,
    and beautifier for the C, C++, C++/CLI, Objective-C,
    C# and Java programming languages.
    """

    LANGUAGES = {'C', 'C++', 'Objective-C', 'C#', 'Java'}
    REQUIREMENTS = {DistributionRequirement(apt_get='astyle', dnf='astyle')}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    LICENSE = 'AGPL-3.0'
    CAN_FIX = {'Formatting'}
    SEE_MORE = 'http://astyle.sourceforge.net/astyle.html'

    @staticmethod
    def create_arguments(
            filename,
            file,
            config_file,
            bracket_style: str = '',
            use_spaces: bool = None,
            indent_size: int = 4,
            require_braces_at_namespace: bool = True,
            require_braces_at_class: bool = True,
            require_braces_at_inline: bool = True,
            require_braces_at_extern: bool = False,
            allow_indent_classes: bool = True,
            allow_indent_modifiers: bool = True,
            allow_indent_switches: bool = True,
            allow_indent_cases: bool = True,
            allow_indent_namespaces: bool = False,
            allow_indent_labels: bool = True,
            allow_indent_preproc_block: bool = True,
            allow_indent_preproc_definition: bool = True,
            allow_indent_preproc_conditionals: bool = True,
            allow_indent_column_one_comments: bool = True,
            allow_pad_header_blocks: bool = True,
            allow_pad_operators: bool = True,
            allow_pad_parenthesis: bool = False,
            allow_pad_parenthesis_out: bool = False,
            allow_pad_parenthesis_in: bool = False,
            prohibit_empty_lines_in_func: bool = False,
            break_closing_braces: bool = False,
            break_elseifs: bool = False,
            break_one_line_headers: bool = False,
            require_braces_at_one_line_conditionals: bool = False,
            prohibit_braces_from_one_line_conditionals: bool = False,
            prohibit_comment_prefix: bool = True):
        """
        :param bracket_style:
            Defines the brace style to use.
            Possible values are ``allman, java, kr, stroustrup, whitesmith,
            vtk, banner, gnu, linux, horstmann, google, mozilla, pico and
            lisp.``
            For example: Allman style uses braces that are broken from the
            previous block. If set to ``allman``, prefer::

                int Foo(bool isBar)
                {
                    if (isBar)
                    {
                        bar();
                        return 1;
                    }
                    else
                        return 0;
                }

            For example: Java style uses braces that are attached to the
            end of the last line of the previous block.
            If set to ``java``, prefer::

                int Foo(bool isBar) {
                    if (isBar) {
                        bar();
                        return 1;
                    } else
                        return 0;
                }

            For example: Kernighan & Ritchie style uses linux braces.
            Opening braces are broken from ``namespaces``, ``classes`` and
            ``function`` definitions. The braces are attached to everything
            else, including arrays, structs, enums, and statements within
            a function. If set to ``kr``, prefer::

                int Foo(bool isBar)
                {
                    if (isBar) {
                        bar();
                        return 1;
                    } else
                        return 0;
                }

            For example: Stroustrup style uses linux braces with closing
            headers broken from closing braces. Opening braces are broken from
            function definitions only. The opening braces are attached to
            everything else, including ``namespaces``, ``classes``, ``arrays``,
            ``structs``, enums, and statements within a function.
            If set to ``stroustrup``, prefer::

                int Foo(bool isBar)
                {
                    if (isBar) {
                        bar();
                        return 1;
                    }
                    else
                        return 0;
                }

            For example: Whitesmith style uses broken, indented braces.
            Switch blocks and class blocks are indented to prevent a
            'hanging indent' with the following case statements and C++ class
            modifiers (``public``, ``private``, ``protected``).
            If set to ``whitesmith``, prefer::

                int Foo(bool isBar)
                    {
                    if (isBar)
                        {
                        bar();
                        return 1;
                        }
                    else
                        return 0;
                    }

            For example: VTK (Visualization Toolkit) style uses broken,
            indented braces, except for the opening brace. Switch blocks are
            indented to prevent a 'hanging indent' with following case
            statements. If set to ``vtk``, prefer::

                int Foo(bool isBar)
                {
                    if (isBar)
                        {
                        bar();
                        return 1;
                        }
                    else
                        return 0;
                }

            For example: Banner style uses attached, indented braces.
            Switch blocks and class blocks are indented to prevent a
            'hanging indent' with following case statements and C++ class
            modifiers (``public``, ``private``, ``protected``).
            If set to ``banner``, prefer::

                int Foo(bool isBar) {
                    if (isBar) {
                        bar();
                        return 1;
                        }
                    else
                        return 0;
                    }

            For example: GNU style uses broken braces and indented blocks.
            Extra indentation is added to blocks within a function only. Other
            braces and blocks are broken, but NOT indented. This style
            frequently is used with an indent of 2 spaces. If set to ``gnu``,
            prefer::

                int Foo(bool isBar)
                {
                    if (isBar)
                        {
                            bar();
                            return 1;
                        }
                    else
                        return 0;
                }

            For example: Linux style uses linux braces. Opening braces are
            broken from namespace, class, and function definitions. The braces
            are attached to everything else, including ``arrays``, ``structs``,
            ``enums``, and statements within a function. The minimum
            conditional indent is one-half indent. If you want a different
            minimum conditional indent, use the K&R style instead. This style
            works best with a large indent. It frequently is used with an
            indent of 8 spaces. If set to ``linux``, prefer::

                int Foo(bool isBar)
                {
                        if (isFoo) {
                                bar();
                                return 1;
                        } else
                                return 0;
                }

            For example: Horstmann style uses broken braces and run-in
            statements. ``Switches`` are indented to allow a run-in to the
            opening ``switch`` block. This style frequently is used with an
            indent of 3 spaces. If set to ``horstmann``, prefer::

                int Foo(bool isBar)
                {   if (isBar)
                    {   bar();
                        return 1;
                    }
                    else
                        return 0;
                }

            For example: Google style uses attached braces and indented
            class access modifiers. This is not actually a unique brace
            style, but is Java style with a non-brace variation. This style
            frequently is used with an indent of 2 spaces. If set to
            ``google``, prefer::

                int Foo(bool isBar) {
                    if (isBar) {
                        bar();
                        return 1;
                    } else
                        return 0;
                }

            For example: Mozilla style uses linux braces. Opening braces
            are broken from ``classes``, ``structs``, ``enums``, and
            ``function`` definitions. The braces are attached to everything
            else, including ``namespaces``, ``arrays``, and ``statements``
            within a ``function``. This style frequently is used with an
            indent of 2 spaces. If set to ``mozilla``, prefer::

                int Foo(bool isBar)
                {
                    if (isBar) {
                        bar();
                        return 1;
                    } else
                        return 0;
                }

            For example: Pico style uses broken braces and run-in
            statements with attached closing braces. The closing brace is
            attached to the last line in the block. ``Switches`` are indented
            to allow a run-in to the opening ``switch`` block. This style
            frequently is used with an indent of 2 spaces.
            If set to ``pico``, prefer::

                int Foo(bool isBar)
                {   if (isBar)
                    {   bar();
                        return 1; }
                    else
                        return 0; }

            For example: Lisp style uses attached opening and closing
            braces. The closing brace is attached to the last line in the
            block. If set to ``lisp``,
            prefer::

                int Foo(bool isBar) {
                if (isBar) {
                    bar()
                    return 1; }
                else
                    return 0; }

        :param use_spaces:
            In the following examples, ``q`` space is indicated with a ``.``
            (dot), a tab is indicated by a > (greater than).
            For example: If ``None``, the default option of 4 spaces will be
            used as below::

                void Foo() {
                ....if (isBar1
                ............&& isBar2)
                ........bar();
                }

            For example: If set to ``True``, spaces will be used for
            indentation.
            For example: If set to ``False``, tabs will be used for
            indentation, and spaces for continuation line alignment as below::

                void Foo() {
                >   if (isBar1
                >   ........&& isBar2)
                >   >   bar();
                }

        :param indent_size:
            Number of spaces per indentation level.
            For example: If ``use_spaces`` is ``True`` and ``indent_size`` is
            ``3``, prefer::

                void Foo() {
                ...if (isBar1
                .........&& isBar2)
                ......bar();
                }

        :param require_braces_at_namespace:
            Attach braces to a namespace statement. This is done
            regardless of the brace style being used.
            For example: If set to ``True``, prefer::

                namespace FooName {
                ...
                }

        :param require_braces_at_class:
            Attach braces to a class statement. This is done regardless of the
            brace style being used.
            For example: If set to ``True``, prefer::

                class FooClass {
                ...
                };

        :param require_braces_at_inline:
            Attach braces to class and struct inline function definitions. This
            option has precedence for all styles except ``Horstmann`` and
            ``Pico`` (run-in styles). It is effective for C++ files only.
            For example: If set to ``True``, prefer::

                class FooClass
                {
                    void Foo() {
                    ...
                    }
                };

        :param require_braces_at_extern:
            Attach braces to a braced extern "C" statement. This is done
            regardless of the brace style being used. This option is effective
            for C++ files only.
            For example: If set to ``True``, prefer::

                #ifdef __cplusplus
                extern "C" {
                #endif

        :param allow_indent_classes:
            Indent ``class`` and ``struct`` blocks so that the entire block is
            indented. The ``struct`` blocks are indented only if an access
            modifier, ``public:``, ``protected:`` or ``private:``, is declared
            somewhere in the ``struct``. This option is effective for C++ files
            only. For example: If set to ``True``, prefer this::

                class Foo
                {
                    public:
                        Foo();
                        virtual ~Foo();
                };

            over this::

                class Foo
                {
                public:
                    Foo();
                    virtual ~Foo();
                };

        :param allow_indent_modifiers:
            Indent ``class`` and ``struct`` access modifiers, ``public:``,
            ``protected:`` and ``private:``, one half indent. The rest of the
            class is not indented. This option is effective for C++ files only.
            For example: If set to ``True``, prefer this::

                class Foo
                {
                  public:
                    Foo();
                    virtual ~Foo();
                };

            over this::

                class Foo
                {
                public:
                    Foo();
                    virtual ~Foo();
                };

        :param allow_indent_switches:
            Indent ``switch`` blocks so that the ``case X:`` statements are
            indented in the switch block. The entire case block is indented.
            For example: If set to ``True``, prefer this::

                switch (foo)
                {
                    case 1:
                        a += 1;
                        break;

                    case 2:
                    {
                        a += 2;
                        break;
                    }
                }

            over this::

                switch (foo)
                {
                case 1:
                    a += 1;
                    break;

                case 2:
                {
                    a += 2;
                    break;
                }
                }

        :param allow_indent_cases:
            Indent ``case X:`` blocks from the ``case X:`` headers. Case
            statements not enclosed in blocks are NOT indented.
            For example: If set to ``True``, prefer this::

                switch (foo)
                {
                    case 1:
                        a += 1;
                        break;

                    case 2:
                        {
                            a += 2;
                            break;
                        }
                }

            over this::

                switch (foo)
                {
                    case 1:
                        a += 1;
                        break;

                    case 2:
                    {
                        a += 2;
                        break;
                    }
                }

        :param allow_indent_namespaces:
            Add extra indentation to namespace blocks. This option has no
            effect on Java files.
            For example: If set to ``True``, prefer this::

                namespace foospace
                {
                    class Foo
                    {
                        public:
                            Foo();
                            virtual ~Foo();
                    };
                }

            over this::

                namespace foospace
                {
                class Foo
                {
                    public:
                        Foo();
                        virtual ~Foo();
                };
                }

        :param allow_indent_labels:
            Add extra indentation to labels so they appear 1 indent less than
            the current indentation, rather than being flushed to the
            left (the default).
            For example: If set to ``True``, prefer this::

                void Foo() {
                    while (isFoo) {
                        if (isFoo)
                            goto error;
                        ...
                    error:
                        ...
                        }
                }

            over this::

                void Foo() {
                    while (isFoo) {
                        if (isFoo)
                            goto error;
                        ...
                error:
                        ...
                        }
                }

        :param allow_indent_preproc_block:
            Indent preprocessor blocks at brace level zero and immediately
            within a namespace. There are restrictions on what will be
            indented. Blocks within methods, classes, arrays, etc., will not
            be indented. Blocks containing braces or multi-line define
            statements will not be indented. Without this option the
            preprocessor block is not indented.
            For example: If set to ``True``, prefer this::

                #ifdef _WIN32
                    #include <windows.h>
                    #ifndef NO_EXPORT
                        #define EXPORT
                    #endif
                #endif

            over this::

                #ifdef _WIN32
                #include <windows.h>
                #ifndef NO_EXPORT
                #define EXPORT
                #endif
                #endif

        :param allow_indent_preproc_definition:
            Indent multi-line preprocessor definitions ending with a backslash.
            Should be used with ``convert_tabs_to_spaces`` for proper results.
            Does a pretty good job, but cannot perform miracles in obfuscated
            preprocessor definitions. Without this option the preprocessor
            statements remain unchanged.
            For example: If set to ``True``, prefer this::

                #define Is_Bar(arg,a,b) \
                    (Is_Foo((arg), (a)) \
                     || Is_Foo((arg), (b)))

            over this::

                #define Is_Bar(arg,a,b) \
                (Is_Foo((arg), (a)) \
                || Is_Foo((arg), (b)))

        :param allow_indent_preproc_conditionals:
            Indent preprocessor conditional statements to the same level as the
            source code.
            For example: If set to ``True``, prefer this::

                        isFoo = true;
                        #ifdef UNICODE
                        text = wideBuff;
                        #else
                        text = buff;
                        #endif
            over this::

                        isFoo = true;
                #ifdef UNICODE
                        text = wideBuff;
                #else
                        text = buff;
                #endif

        :param allow_indent_column_one_comments:
            Indent C++ comments beginning in column one. By default C++
            comments beginning in column one are assumed to be commented-out
            code and not indented. This option will allow the comments to be
            indented with the code.
            For example: If set to ``True``, prefer this::

                void Foo()\n"
                {
                    // comment
                    if (isFoo)
                        bar();
                }

            over this::

                void Foo()\n"
                {
                // comment
                    if (isFoo)
                        bar();
                }

        :param allow_pad_header_blocks:
            Pad empty lines around header blocks
            (e.g. ``if``, ``for``, ``while``...).
            For example: If set to ``True``, prefer this::

                isFoo = true;

                if (isFoo) {
                    bar();
                } else {
                    anotherBar();
                }

                isBar = false;

            over this::

                isFoo = true;
                if (isFoo) {
                    bar();
                } else {
                    anotherBar();
                }
                isBar = false;

        :param allow_pad_operators:
            Insert space padding around operators. This will also pad commas.
            For example: If set to ``True``, prefer this::

                if (foo == 2)
                    a = bar((b - c) * a, d--);

            over this::

                if (foo==2)
                    a=bar((b-c)*a,d--);

        :param allow_pad_parenthesis:
            Insert space padding around parenthesis on both the outside and the
            inside.
            For example: If set to ``True``, prefer this::

                if ( isFoo ( ( a+2 ), b ) )
                    bar ( a, b );

            over this::

                if (isFoo((a+2), b))
                    bar(a, b);

        :param allow_pad_parenthesis_out:
            Insert space padding around parenthesis on the outside only.
            Parenthesis that are empty will not be padded.
            For example: If set to ``True``, prefer this::

                if (isFoo ( (a+2), b) )
                    bar (a, b);

            over this::

                if (isFoo((a+2), b))
                    bar(a, b);

        :param allow_pad_parenthesis_in:
            Insert space padding around parenthesis on the inside only.
            For example: If set to ``True``, prefer this::

                if ( isFoo( ( a+2 ), b ) )
                    bar( a, b );

            over this::

                if (isFoo((a+2), b))
                    bar(a, b);

        :param prohibit_empty_lines_in_func:
            Delete empty lines within a function or method. Empty lines outside
            of functions or methods are NOT deleted.
            For example: If set to ``True``, prefer this::

                void Foo()
                {
                    foo1 = 1;
                    foo2 = 2;
                }

            over this::

                void Foo()
                {

                    foo1 = 1;

                    foo2 = 2;

                }

        :param break_closing_braces:
            When used with some specific ``bracket_style``, this breaks closing
            headers (e.g. ``else``, ``catch``, ...) from their immediately
            preceding closing braces. Closing header braces are always broken
            with the other styles.
            For example: If set to ``True``, prefer this::

                void Foo(bool isFoo) {
                    if (isFoo) {
                        bar();
                    }
                    else {
                        anotherBar();
                    }
                }

            over this::

                void Foo(bool isFoo) {
                    if (isFoo) {
                        bar();
                    } else {
                        anotherBar();
                    }
                }

        :param break_elseifs:
            Break ``else if`` header combinations into separate lines.
            For example: If set to ``True``, prefer this::

                if (isFoo) {
                    bar();
                }
                else
                    if (isFoo1()) {
                        bar1();
                    }
                    else
                        if (isFoo2()) {
                            bar2();
                        }

            over this::

                if (isFoo) {
                    bar();
                }
                else if (isFoo1()) {
                    bar1();
                }
                else if (isFoo2()) {
                    bar2;
                }

        :param break_one_line_headers:
            Break one line headers (e.g. ``if``, ``while``, ``else``, ...) from
            a statement residing on the same line. If the statement is enclosed
            in braces, the braces will be formatted according to the requested
            brace style.
            For example: If set to ``True``, prefer this::

                void Foo(bool isFoo)
                {
                    if (isFoo1)
                        bar1();

                    if (isFoo2) {
                        bar2();
                    }
                }

            over this::

                void Foo(bool isFoo)
                {
                    if (isFoo1) bar1();

                    if (isFoo2) { bar2(); }
                }

        :param require_braces_at_one_line_conditionals:
            Add braces to unbraced one line conditional statements
            (e.g. ``if``, ``for``, ``while``...). The statement must be on a
            single line. The braces will be added according to the requested
            brace style.
            For example: If set to ``True``, prefer this::

                if (isFoo) {
                    isFoo = false;
                }

            over this::

                if (isFoo)
                    isFoo = false;

        :param prohibit_braces_from_one_line_conditionals:
            Remove braces from conditional statements
            (e.g. ``if``, ``for``, ``while``...). The statement must be a
            single statement on a single line.
            For example: If set to ``True``, prefer this::

                if (isFoo)
                    isFoo = false;

            over this::

                if (isFoo)
                {
                    isFoo = false;
                }

        :param prohibit_comment_prefix:
            Remove the preceding '*' in a multi-line comment that begins a
            line. A trailing '*', if present, is also removed. Text that is
            less than one indent is indented to one indent. Text greater than
            one indent is not changed. Multi-line comments that begin a line,
            but without the preceding '*', are indented to one indent for
            consistency. This can slightly modify the indentation of commented
            out blocks of code. Lines containing all '*' are left unchanged.
            Extra spacing is removed from the comment close '*/'.
            For example: If set to ``True``, prefer this::

                /*
                    comment line 1
                    comment line 2
                */

            over this::

                /*
                 * comment line 1
                 * comment line 2
                 */

        """
        rules_map = {
            '--attach-namespaces': require_braces_at_namespace,
            '--attach-classes': require_braces_at_class,
            '--attach-inlines': require_braces_at_inline,
            '--attach-extern-c': require_braces_at_extern,
            '--indent-classes': allow_indent_classes,
            '--indent-modifiers': allow_indent_modifiers,
            '--indent-switches': allow_indent_switches,
            '--indent-cases': allow_indent_cases,
            '--indent-namespaces': allow_indent_namespaces,
            '--indent-labels': allow_indent_labels,
            '--indent-preproc-block': allow_indent_preproc_block,
            '--indent-preproc-define': allow_indent_preproc_definition,
            '--indent-preproc-cond': allow_indent_preproc_conditionals,
            '--indent-col1-comments': allow_indent_column_one_comments,
            '--break-blocks': allow_pad_header_blocks,
            '--pad-oper': allow_pad_operators,
            '--pad-paren': allow_pad_parenthesis,
            '--pad-paren-out': allow_pad_parenthesis_out,
            '--pad-paren-in': allow_pad_parenthesis_in,
            '--delete-empty-lines': prohibit_empty_lines_in_func,
            '--break-closing-brackets': break_closing_braces,
            '--break-elseifs': break_elseifs,
            '--break-one-line-headers': break_one_line_headers,
            '--add-brackets': require_braces_at_one_line_conditionals,
            '--remove-brackets': prohibit_braces_from_one_line_conditionals,
            '--remove-comment-prefix': prohibit_comment_prefix
        }
        args = ['--suffix=none', '--dry-run']
        if bracket_style:
            args.append('--style=' + bracket_style)
        if use_spaces is True:
            args.append('-s' + str(indent_size))
        elif use_spaces is False:
            args.append('-t' + str(indent_size))
        args += (k for k, v in rules_map.items() if v)
        return args
Beispiel #28
0
class FormatRBear:
    """
    Check and correct formatting of R Code using known formatR utility.
    """
    LANGUAGES = {'R'}
    AUTHORS = {'The coala developers'}
    AUTHORS_EMAILS = {'*****@*****.**'}
    REQUIREMENTS = {
        AnyOneOfRequirements(
            [DistributionRequirement(
                apt_get='r-cran-formatr',
                zypper='R-formatR',
             ),
             RscriptRequirement('formatR'),
             ]
        )
    }
    LICENSE = 'AGPL-3.0'
    ASCIINEMA_URL = 'https://asciinema.org/a/0y0oxtak18v492jdyfqwpw1n4'
    CAN_FIX = {'Formatting'}

    @staticmethod
    @deprecate_settings(indent_size='tab_width')
    def create_arguments(filename, file, config_file,
                         r_keep_comments: bool = True,
                         r_keep_blank_lines: bool = True,
                         r_braces_on_next_line: bool = None,
                         r_use_arrows: bool = None,
                         indent_size:
                             int = SpacingHelper.DEFAULT_TAB_WIDTH,
                         r_max_expression_length: int = 0,
                         ):
        """
        :param r_keep_comments:
            Determines whether comments are kept or not.
        :param r_keep_blank_lines:
            Determines whether blank lines are kept or not.
        :param r_braces_on_next_line:
            Determines whether a brace should be placed on the next line.

            Example:
            If ``True``::

                if (...) {

            changes to::

                if (...)
                {

            If ``False`` the brace is placed on the same line.
        :param r_use_arrows:
            Determines whether the assignment operator ``=`` should be replaced
            by an arrow ``<-`` or not.

            Example: If  ``True``, ``x = 1`` changes to ``x <- 1``.
        :param indent_size:
            Number of spaces per indentation level.
        :param r_max_expression_length:
            Maximum number of characters for an expression.

            Example: If ``20`` then::

                1 + 1 + 1 + 1 + 1 + 1 + 1

            changes to::

                1 + 1 + 1 + 1 + 1 + 1 +
                    1
        """
        options = {'source="' + escape(filename, '"\\') + '"',
                   'blank=' + _map_to_r_bool(r_keep_blank_lines),
                   'comment=' + _map_to_r_bool(r_keep_comments),
                   'indent=' + str(indent_size)}
        if r_max_expression_length:
            options.add('width.cutoff=' + str(r_max_expression_length))
        if r_braces_on_next_line is not None:
            options.add('brace.newline=' +
                        _map_to_r_bool(r_braces_on_next_line))
        if r_use_arrows is not None:
            options.add('arrow=' + _map_to_r_bool(r_use_arrows))

        rcode = 'library(formatR);formatR::tidy_source({})'.format(
            ','.join(options))
        return '-e', rcode