Beispiel #1
0
def main(argv=None):
    """Main function.

  Args:
    argv: Sequence of command line arguments.
  """
    if argv is None:
        argv = flags.FLAGS(sys.argv)

    suffixes = ['.js']
    if FLAGS.additional_extensions:
        suffixes += ['.%s' % ext for ext in FLAGS.additional_extensions]

    files = fileflags.GetFileList(argv, 'JavaScript', suffixes)

    output_buffer = None
    if FLAGS.dry_run:
        output_buffer = StringIO.StringIO()

    fixer = error_fixer.ErrorFixer(output_buffer)

    # Check the list of files.
    for filename in files:
        runner.Run(filename, fixer)
        if FLAGS.dry_run:
            print output_buffer.getvalue()
  def _AssertInError(self, original, expected):
    """Asserts that the error fixer corrects original to expected."""

    # Trap gjslint's output parse it to get messages added.
    error_accumulator = erroraccumulator.ErrorAccumulator()
    runner.Run('testing.js', error_accumulator, source=original)
    error_nums = [e.code for e in error_accumulator.GetErrors()]

    self.assertIn(expected, error_nums)
Beispiel #3
0
    def _AssertFixes(self, original, expected, include_header=True):
        """Asserts that the error fixer corrects original to expected."""
        if include_header:
            original = self._GetHeader() + original
            expected = self._GetHeader() + expected

        actual = StringIO.StringIO()
        runner.Run('testing.js', error_fixer.ErrorFixer(actual), original)
        actual.seek(0)

        expected = [x + '\n' for x in expected]

        self.assertListEqual(actual.readlines(), expected)
Beispiel #4
0
  def _AssertErrors(self, original, expected_errors, include_header=True):
    """Asserts that the error fixer corrects original to expected."""
    if include_header:
      original = self._GetHeader() + original

    # Trap gjslint's output parse it to get messages added.
    error_accumulator = erroraccumulator.ErrorAccumulator()
    runner.Run('testing.js', error_accumulator, source=original)
    error_nums = [e.code for e in error_accumulator.GetErrors()]

    error_nums.sort()
    expected_errors.sort()
    self.assertListEqual(error_nums, expected_errors)
Beispiel #5
0
def _CheckPath(path):
    """Check a path and return any errors.

  Args:
    path: paths to check.

  Returns:
    A list of errorrecord.ErrorRecords for any found errors.
  """

    error_handler = erroraccumulator.ErrorAccumulator()
    runner.Run(path, error_handler)

    make_error_record = lambda err: errorrecord.MakeErrorRecord(path, err)
    return map(make_error_record, error_handler.GetErrors())
Beispiel #6
0
    def testFixJsStyle(self):
        test_cases = [['fixjsstyle.in.js', 'fixjsstyle.out.js'],
                      ['indentation.js', 'fixjsstyle.indentation.out.js'],
                      ['fixjsstyle.html.in.html', 'fixjsstyle.html.out.html'],
                      [
                          'fixjsstyle.oplineend.in.js',
                          'fixjsstyle.oplineend.out.js'
                      ]]
        for [running_input_file, running_output_file] in test_cases:
            print 'Checking %s vs %s' % (running_input_file,
                                         running_output_file)
            input_filename = None
            golden_filename = None
            current_filename = None
            try:
                input_filename = '%s/%s' % (_RESOURCE_PREFIX,
                                            running_input_file)
                current_filename = input_filename

                golden_filename = '%s/%s' % (_RESOURCE_PREFIX,
                                             running_output_file)
                current_filename = golden_filename
            except IOError as ex:
                raise IOError('Could not find testdata resource for %s: %s' %
                              (current_filename, ex))

            if running_input_file == 'fixjsstyle.in.js':
                with open(input_filename) as f:
                    for line in f:
                        # Go to last line.
                        pass
                    self.assertTrue(
                        line == line.rstrip(), '%s file should not end '
                        'with a new line.' % (input_filename))

            # Autofix the file, sending output to a fake file.
            actual = StringIO.StringIO()
            runner.Run(input_filename, error_fixer.ErrorFixer(actual))

            # Now compare the files.
            actual.seek(0)
            expected = open(golden_filename, 'r')

            # Uncomment to generate new golden files and run
            # open('/'.join(golden_filename.split('/')[4:]), 'w').write(actual.read())
            # actual.seek(0)

            self.assertEqual(actual.readlines(), expected.readlines())
Beispiel #7
0
    def testRunOnMissingFile(self):
        mock_error_handler = self.mox.CreateMock(errorhandler.ErrorHandler)

        def ValidateError(err):
            return (isinstance(err, error.Error)
                    and err.code is errors.FILE_NOT_FOUND
                    and err.token is None)

        mock_error_handler.HandleFile('does_not_exist.js', None)
        mock_error_handler.HandleError(mox.Func(ValidateError))
        mock_error_handler.FinishFile()

        self.mox.ReplayAll()

        runner.Run('does_not_exist.js', mock_error_handler)

        self.mox.VerifyAll()
Beispiel #8
0
  def testBadTokenization(self):
    mock_error_handler = self.mox.CreateMock(errorhandler.ErrorHandler)

    def ValidateError(err):
      return (isinstance(err, error.Error) and
              err.code is errors.FILE_IN_BLOCK and
              err.token.string == '}')

    mock_error_handler.HandleFile('foo.js', mox.IsA(tokens.Token))
    mock_error_handler.HandleError(mox.Func(ValidateError))
    mock_error_handler.HandleError(mox.IsA(error.Error))
    mock_error_handler.FinishFile()

    self.mox.ReplayAll()

    source = StringIO.StringIO(_BAD_TOKENIZATION_SCRIPT)
    runner.Run('foo.js', mock_error_handler, source)

    self.mox.VerifyAll()
Beispiel #9
0
    def ClosureLint(self, file_to_lint, source=None):
        """Lints |file_to_lint| and returns the errors."""

        import sys
        import warnings
        old_path = sys.path
        old_filters = warnings.filters

        try:
            closure_linter_path = self.input_api.os_path.join(
                self.input_api.change.RepositoryRoot(), "third_party",
                "closure_linter")
            gflags_path = self.input_api.os_path.join(
                self.input_api.change.RepositoryRoot(), "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 errors, runner
            from closure_linter.common import errorhandler
            import gflags

        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, re):
                self._errors = []
                self.re = re

            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(
                    self.re.search("</?(include|if)", error.token.line))

                # Ignore missing spaces before "(" until Promise#catch issue is solved.
                # http://crbug.com/338301
                if (error.code == errors.MISSING_SPACE
                        and error.token.string == '('
                        and 'catch(' in error.token.line):
                    return False

                # Ignore "}.bind(" errors. http://crbug.com/397697
                if (error.code == errors.MISSING_SEMICOLON_AFTER_FUNCTION
                        and '}.bind(' in error.token.line):
                    return False

                return not is_grit_statement and error.code not in [
                    errors.COMMA_AT_END_OF_LITERAL,
                    errors.JSDOC_ILLEGAL_QUESTION_WITH_PIPE,
                    errors.LINE_TOO_LONG,
                    errors.MISSING_JSDOC_TAG_THIS,
                ]

        # Whitelist Polymer-specific JsDoc tags.
        gflags.FLAGS.custom_jsdoc_tags = ('group', 'element', 'attribute',
                                          'default')
        error_handler = ErrorHandlerImpl(self.input_api.re)
        runner.Run(file_to_lint, error_handler, source=source)
        return error_handler.GetErrors()
Beispiel #10
0
    def RunChecks(self):
        """Checks for violations of the Chromium JavaScript style guide.

    See:
    http://chromium.org/developers/web-development-style-guide#TOC-JavaScript
    """
        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, 'third_party',
                                               'closure_linter')
            gflags_path = os.path.join(base_path, '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 runner, 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):
                super(ErrorHandlerImpl, self).__init__()
                self._errors = []
                self._filename = None

            def HandleFile(self, filename, _):
                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):
                """Checks whether an error is valid.

        Most errors are valid, with a few exceptions which are listed here.
        """
                if re.search('</?(include|if)', error.token.line):
                    return False  # GRIT statement.

                if (error.code == errors.MISSING_SEMICOLON
                        and error.token.string == 'of'):
                    return False  # ES6 for...of statement.

                if (error.code == errors.LINE_STARTS_WITH_OPERATOR
                        and error.token.string == '*'):
                    return False  # *[...] syntax

                if (error.code == errors.MISSING_SPACE
                        and error.token.string == '['):
                    return False  # *[...] syntax

                return error.code not in [
                    errors.JSDOC_ILLEGAL_QUESTION_WITH_PIPE,
                    errors.MISSING_JSDOC_TAG_THIS,
                    errors.MISSING_MEMBER_DOCUMENTATION,
                ]

        results = []

        affected_files = self.input_api.AffectedFiles(
            file_filter=self.file_filter, include_deletes=False)

        def ShouldCheck(f):
            if f.LocalPath().endswith('.js'):
                return True
            if f.LocalPath().endswith('.html'):
                return True
            return False

        affected_js_files = filter(ShouldCheck, affected_files)
        for f in affected_js_files:
            error_lines = []

            contents = list(f.NewContents())
            error_lines += CheckStrictMode(
                '\n'.join(contents),
                is_html_file=f.LocalPath().endswith('.html'))

            for i, line in enumerate(contents, start=1):
                error_lines += filter(None, [self.ConstCheck(i, line)])

            # Use closure_linter to check for several different errors.
            import gflags as flags
            flags.FLAGS.strict = True
            error_handler = ErrorHandlerImpl()
            runner.Run(f.AbsoluteLocalPath(), error_handler)

            for error in error_handler.GetErrors():
                highlight = _ErrorHighlight(error.token.start_index,
                                            error.token.length)
                error_msg = '  line %d: E%04d: %s\n%s\n%s' % (
                    error.token.line_number, error.code, error.message,
                    error.token.line.rstrip(), highlight)
                error_lines.append(error_msg)

            if error_lines:
                error_lines = [
                    'Found JavaScript style violations in %s:' % f.LocalPath()
                ] + error_lines
                results.append(
                    _MakeErrorOrWarning(self.output_api,
                                        '\n'.join(error_lines)))

        return results