import json

from coalib.bearlib.abstractions.Lint import Lint
from coalib.bears.LocalBear import LocalBear
from coalib.results.Result import Result
from coalib.results.Diff import Diff
from coalib.results.RESULT_SEVERITY import RESULT_SEVERITY


class HaskellLintBear(LocalBear, Lint):
    executable = 'hlint'
    arguments = '--json {filename}'
    severity_map = {
        "Error": RESULT_SEVERITY.MAJOR,
        "Warning": RESULT_SEVERITY.NORMAL,
        "Suggestion": RESULT_SEVERITY.INFO}
    gives_corrected = True

    def run(self, filename, file):
        '''
        Checks the given file with hlint.
        '''
        return self.lint(filename=filename, file=file)

    def _process_corrected(self, output, filename, file):
        output = json.loads("".join(output))

        for issue in output:
            assert issue["startLine"] == issue["endLine"]
            diff = Diff(file)
            line_nr = issue["startLine"]
            line_to_change = file[line_nr-1]
            newline = line_to_change.replace(issue["from"], issue["to"])
            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"],
                diffs={filename: diff})

import json

from coalib.bearlib.abstractions.Linter import linter
from coalib.results.Result import Result
from coalib.results.Diff import Diff
from coalib.results.RESULT_SEVERITY import RESULT_SEVERITY


@linter(executable='hlint')
class HaskellLintBear:
    """
    Checks the given file with ``hlint``.
    """

    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:
            assert issue["startLine"] == issue["endLine"]
            diff = Diff(file)
            line_nr = issue["startLine"]
            line_to_change = file[line_nr-1]
            newline = line_to_change.replace(issue["from"], issue["to"])
            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"],
                diffs={filename: diff})

Refactor to Linter v2 API