# Copyright (c) 2014 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import os import re from tracing import tracing_project class JSChecker(object): def __init__(self, input_api, file_filter=None): self.input_api = input_api if file_filter: self.file_filter = file_filter else: self.file_filter = lambda x: True def RegexCheck(self, line_number, line, regex, message): """Searches for |regex| in |line| to check for a particular style violation, returning a message like the one below if the regex matches. The |regex| must have exactly one capturing group so that the relevant part of |line| can be highlighted. If more groups are needed, use "(?:...)" to make a non-capturing group. Sample message: line 6: Use var instead of const. const foo = bar(); ^^^^^ """ match = re.search(regex, line) if match: assert len(match.groups()) == 1 start = match.start(1) length = match.end(1) - start return ' line %d: %s\n%s\n%s' % ( line_number, message, line, self.error_highlight(start, length)) return '' def ConstCheck(self, i, line): """Check for use of the 'const' keyword.""" if re.search(r'\*\s+@const', line): # Probably a JsDoc line return '' return self.RegexCheck(i, line, r'(?:^|\s|\()(const)\s', 'Use var instead of const.') def error_highlight(self, start, length): """Takes a start position and a length, and produces a row of '^'s to highlight the corresponding part of a string. """ return start * ' ' + length * '^' def _makeErrorOrWarning(self, error_text, filename): return error_text def RunChecks(self): """Check for violations of the Chromium JavaScript style guide. See http://chromium.org/developers/web-development-style-guide#TOC-JavaScript """ import sys import warnings old_path = sys.path old_filters = warnings.filters try: base_path = os.path.abspath(os.path.join( os.path.dirname(__file__), '..', '..')) closure_linter_path = os.path.join( base_path, 'tracing', 'third_party', 'closure_linter') gflags_path = os.path.join( base_path, 'tracing', 'third_party', 'python_gflags') sys.path.insert(0, closure_linter_path) sys.path.insert(0, gflags_path) warnings.filterwarnings('ignore', category=DeprecationWarning) from closure_linter import checker, errors from closure_linter.common import errorhandler finally: sys.path = old_path warnings.filters = old_filters class ErrorHandlerImpl(errorhandler.ErrorHandler): """Filters out errors that don't apply to Chromium JavaScript code.""" def __init__(self): self._errors = [] def HandleFile(self, filename, first_token): self._filename = filename def HandleError(self, error): if (self._valid(error)): error.filename = self._filename self._errors.append(error) def GetErrors(self): return self._errors def HasErrors(self): return bool(self._errors) def _valid(self, error): """Check whether an error is valid. Most errors are valid, with a few exceptions which are listed here. """ is_grit_statement = bool( re.search("