mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
123 lines
5.5 KiB
Python
123 lines
5.5 KiB
Python
# Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
|
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
|
|
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
"""Supports checking WebKit style in Python files."""
|
|
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
from StringIO import StringIO
|
|
|
|
from webkitpy.common.system.filesystem import FileSystem
|
|
from webkitpy.common.system.executive import Executive
|
|
from webkitpy.common.webkit_finder import WebKitFinder
|
|
from webkitpy.thirdparty import pep8
|
|
|
|
|
|
class PythonChecker(object):
|
|
"""Processes text lines for checking style."""
|
|
def __init__(self, file_path, handle_style_error):
|
|
self._file_path = file_path
|
|
self._handle_style_error = handle_style_error
|
|
|
|
def check(self, lines):
|
|
self._check_pep8(lines)
|
|
self._check_pylint(lines)
|
|
|
|
def _check_pep8(self, lines):
|
|
# Initialize pep8.options, which is necessary for
|
|
# Checker.check_all() to execute.
|
|
pep8.process_options(arglist=[self._file_path])
|
|
|
|
pep8_checker = pep8.Checker(self._file_path)
|
|
|
|
def _pep8_handle_error(line_number, offset, text, check):
|
|
# FIXME: Incorporate the character offset into the error output.
|
|
# This will require updating the error handler __call__
|
|
# signature to include an optional "offset" parameter.
|
|
pep8_code = text[:4]
|
|
pep8_message = text[5:]
|
|
|
|
category = "pep8/" + pep8_code
|
|
|
|
self._handle_style_error(line_number, category, 5, pep8_message)
|
|
|
|
pep8_checker.report_error = _pep8_handle_error
|
|
pep8_errors = pep8_checker.check_all()
|
|
|
|
def _check_pylint(self, lines):
|
|
output = self._run_pylint(self._file_path)
|
|
errors = self._parse_pylint_output(output)
|
|
for line_number, category, message in errors:
|
|
self._handle_style_error(line_number, category, 5, message)
|
|
|
|
def _run_pylint(self, path):
|
|
wkf = WebKitFinder(FileSystem())
|
|
executive = Executive()
|
|
env = os.environ.copy()
|
|
env['PYTHONPATH'] = ('%s%s%s%s%s' % (wkf.path_from_webkit_base('Tools', 'Scripts'),
|
|
os.pathsep,
|
|
wkf.path_from_webkit_base('Source', 'build', 'scripts'),
|
|
os.pathsep,
|
|
wkf.path_from_webkit_base('Tools', 'Scripts', 'webkitpy', 'thirdparty')))
|
|
return executive.run_command([sys.executable, wkf.path_from_depot_tools_base('pylint.py'),
|
|
'--output-format=parseable',
|
|
'--errors-only',
|
|
'--rcfile=' + wkf.path_from_webkit_base('Tools', 'Scripts', 'webkitpy', 'pylintrc'),
|
|
path],
|
|
env=env,
|
|
error_handler=executive.ignore_error)
|
|
|
|
def _parse_pylint_output(self, output):
|
|
# We filter out these messages because they are bugs in pylint that produce false positives.
|
|
# FIXME: Does it make sense to combine these rules with the rules in style/checker.py somehow?
|
|
FALSE_POSITIVES = [
|
|
# possibly http://www.logilab.org/ticket/98613 ?
|
|
"Instance of 'Popen' has no 'poll' member",
|
|
"Instance of 'Popen' has no 'returncode' member",
|
|
"Instance of 'Popen' has no 'stdin' member",
|
|
"Instance of 'Popen' has no 'stdout' member",
|
|
"Instance of 'Popen' has no 'stderr' member",
|
|
"Instance of 'Popen' has no 'wait' member",
|
|
]
|
|
|
|
lint_regex = re.compile('([^:]+):([^:]+): \[([^]]+)\] (.*)')
|
|
errors = []
|
|
for line in output.splitlines():
|
|
if any(msg in line for msg in FALSE_POSITIVES):
|
|
continue
|
|
|
|
match_obj = lint_regex.match(line)
|
|
if not match_obj:
|
|
continue
|
|
|
|
line_number = int(match_obj.group(2))
|
|
category_and_method = match_obj.group(3).split(', ')
|
|
category = 'pylint/' + (category_and_method[0])
|
|
if len(category_and_method) > 1:
|
|
message = '[%s] %s' % (category_and_method[1], match_obj.group(4))
|
|
else:
|
|
message = match_obj.group(4)
|
|
errors.append((line_number, category, message))
|
|
return errors
|