Changeset 53185 in webkit


Ignore:
Timestamp:
Jan 13, 2010 7:52:51 AM (14 years ago)
Author:
hamaji@chromium.org
Message:

2010-01-13 Chris Jerdonek <chris.jerdonek@gmail.com>

Reviewed by Shinichiro Hamaji.

Created a CategoryFilter class to encapsulate the logic of
filter rules.

https://bugs.webkit.org/show_bug.cgi?id=33454

  • Scripts/webkitpy/style/checker.py:
    • Added CategoryFilter class.
  • Scripts/webkitpy/style/checker_unittest.py:
    • Added CategoryFilter unit tests.
  • Scripts/webkitpy/style/cpp_style.py:
    • Updated filter methods to use CategoryFilter.
  • Scripts/webkitpy/style/cpp_style_unittest.py:
    • Updated references to filters.
Location:
trunk/WebKitTools
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebKitTools/ChangeLog

    r53179 r53185  
     12010-01-13  Chris Jerdonek  <chris.jerdonek@gmail.com>
     2
     3        Reviewed by Shinichiro Hamaji.
     4
     5        Created a CategoryFilter class to encapsulate the logic of
     6        filter rules.
     7
     8        https://bugs.webkit.org/show_bug.cgi?id=33454
     9
     10        * Scripts/webkitpy/style/checker.py:
     11          - Added CategoryFilter class.
     12
     13        * Scripts/webkitpy/style/checker_unittest.py:
     14          - Added CategoryFilter unit tests.
     15
     16        * Scripts/webkitpy/style/cpp_style.py:
     17          - Updated filter methods to use CategoryFilter.
     18
     19        * Scripts/webkitpy/style/cpp_style_unittest.py:
     20          - Updated references to filters.
     21
    1222010-01-12  Shinichiro Hamaji  <hamaji@chromium.org>
    223
  • trunk/WebKitTools/Scripts/webkitpy/style/checker.py

    r52906 r53185  
    231231
    232232
     233class CategoryFilter(object):
     234
     235    """Filters whether to check style categories."""
     236
     237    def __init__(self, filter_rules):
     238        """Create a category filter.
     239
     240        This method performs argument validation but does not strip
     241        leading or trailing white space.
     242
     243        Args:
     244          filter_rules: A list of strings that are filter rules, which
     245                        are strings beginning with the plus or minus
     246                        symbol (+/-). The list should include any
     247                        default filter rules at the beginning.
     248
     249        Raises:
     250          ValueError: Invalid filter rule if a rule does not start with
     251                      plus ("+") or minus ("-").
     252
     253        """
     254        for rule in filter_rules:
     255            if not (rule.startswith('+') or rule.startswith('-')):
     256                raise ValueError('Invalid filter rule "%s": every rule '
     257                                 'rule in the --filter flag must start '
     258                                 'with + or -.' % rule)
     259
     260        self._filter_rules = filter_rules
     261        self._should_check_category = {} # Cached dictionary of category to True/False
     262
     263    def __str__(self):
     264        return ",".join(self._filter_rules)
     265
     266    def __eq__(self, other):
     267        # This is useful for unit testing.
     268        # Two category filters are the same if and only if their
     269        # constituent filter rules are the same.
     270        return (str(self) == str(other))
     271
     272    def should_check(self, category):
     273        """Return whether the category should be checked.
     274
     275        The rules for determining whether a category should be checked
     276        are as follows. By default all categories should be checked.
     277        Then apply the filter rules in order from first to last, with
     278        later flags taking precedence.
     279
     280        A filter rule applies to a category if the string after the
     281        leading plus/minus (+/-) matches the beginning of the category
     282        name. A plus (+) means the category should be checked, while a
     283        minus (-) means the category should not be checked.
     284
     285        """
     286        if category in self._should_check_category:
     287            return self._should_check_category[category]
     288
     289        should_check = True # All categories checked by default.
     290        for rule in self._filter_rules:
     291            if not category.startswith(rule[1:]):
     292                continue
     293            should_check = rule.startswith('+')
     294        self._should_check_category[category] = should_check # Update cache.
     295        return should_check
     296
     297
    233298# This class should not have knowledge of the flag key names.
    234299class ProcessorOptions(object):
     
    245310                 The default is 1, which displays all errors.
    246311
    247       filter_rules: A list of strings that are boolean filter rules used
    248                     to determine whether a style category should be checked.
    249                     Each string should start with + or -. An example
    250                     string is "+whitespace/indent". The list includes any
    251                     prepended default filter rules. The default is the
    252                     empty list, which includes all categories.
     312      filter: A CategoryFilter instance. The default is the empty filter,
     313              which means that all categories should be checked.
    253314
    254315      git_commit: A string representing the git commit to check.
     
    260321    """
    261322
    262     def __init__(self, output_format, verbosity=1, filter_rules=None,
     323    def __init__(self, output_format, verbosity=1, filter=None,
    263324                 git_commit=None, extra_flag_values=None):
    264         if filter_rules is None:
    265             filter_rules = []
     325        if filter is None:
     326            filter = CategoryFilter([])
    266327        if extra_flag_values is None:
    267328            extra_flag_values = {}
     
    269330        self.output_format = output_format
    270331        self.verbosity = verbosity
    271         self.filter_rules = filter_rules
     332        self.filter = filter
    272333        self.git_commit = git_commit
    273334        self.extra_flag_values = extra_flag_values
     
    286347    cpp_style._set_output_format(options.output_format)
    287348    cpp_style._set_verbose_level(options.verbosity)
    288     cpp_style._set_filters(options.filter_rules)
     349    cpp_style._set_filter(options.filter)
    289350
    290351
     
    329390        flags['output'] = options.output_format
    330391        flags['verbose'] = options.verbosity
    331         if options.filter_rules:
    332             flags['filter'] = ','.join(options.filter_rules)
     392        if options.filter:
     393            # Only include the filter flag if rules are present.
     394            filter_string = str(options.filter)
     395            if filter_string:
     396                flags['filter'] = filter_string
    333397        if options.git_commit:
    334398            flags['git-commit'] = options.git_commit
     
    492556                             'be between 1-5.' % verbosity)
    493557
    494         for rule in filter_rules:
    495             if not (rule.startswith('+') or rule.startswith('-')):
    496                 raise ValueError('Invalid filter rule "%s": every rule '
    497                                  'rule in the --filter flag must start '
    498                                  'with + or -.' % rule)
    499 
    500         options = ProcessorOptions(output_format, verbosity, filter_rules,
     558        filter = CategoryFilter(filter_rules)
     559
     560        options = ProcessorOptions(output_format, verbosity, filter,
    501561                                   git_commit, extra_flag_values)
    502562
  • trunk/WebKitTools/Scripts/webkitpy/style/checker_unittest.py

    r52906 r53185  
    3838
    3939import checker as style
     40from checker import CategoryFilter
     41
     42
     43class CategoryFilterTest(unittest.TestCase):
     44
     45    """Tests CategoryFilter class."""
     46
     47    def test_init(self):
     48        """Test __init__ constructor."""
     49        self.assertRaises(ValueError, CategoryFilter, ["no_prefix"])
     50        CategoryFilter([]) # No ValueError: works
     51        CategoryFilter(["+"]) # No ValueError: works
     52        CategoryFilter(["-"]) # No ValueError: works
     53
     54    def test_str(self):
     55        """Test __str__ "to string" operator."""
     56        filter = CategoryFilter(["+a", "-b"])
     57        self.assertEquals(str(filter), "+a,-b")
     58
     59    def test_eq(self):
     60        """Test __eq__ equality operator."""
     61        filter1 = CategoryFilter(["+a", "+b"])
     62        filter2 = CategoryFilter(["+a", "+b"])
     63        filter3 = CategoryFilter(["+b", "+a"])
     64        self.assertEquals(filter1, filter2)
     65        self.assertNotEquals(filter1, filter3)
     66
     67    def test_should_check(self):
     68        """Test should_check() method."""
     69        filter = CategoryFilter([])
     70        self.assertTrue(filter.should_check("everything"))
     71        # Check a second time to exercise cache.
     72        self.assertTrue(filter.should_check("everything"))
     73
     74        filter = CategoryFilter(["-"])
     75        self.assertFalse(filter.should_check("anything"))
     76        # Check a second time to exercise cache.
     77        self.assertFalse(filter.should_check("anything"))
     78
     79        filter = CategoryFilter(["-", "+ab"])
     80        self.assertTrue(filter.should_check("abc"))
     81        self.assertFalse(filter.should_check("a"))
     82
     83        filter = CategoryFilter(["+", "-ab"])
     84        self.assertFalse(filter.should_check("abc"))
     85        self.assertTrue(filter.should_check("a"))
    4086
    4187
     
    4793        already_seen = []
    4894        for rule in style.WEBKIT_FILTER_RULES:
     95            # Check no leading or trailing white space.
     96            self.assertEquals(rule, rule.strip())
    4997            # All categories are on by default, so defaults should
    5098            # begin with -.
     
    76124                        filter_rules=[], git_commit=None,
    77125                        extra_flag_values={}):
    78         return style.ProcessorOptions(output_format, verbosity, filter_rules,
     126        filter = CategoryFilter(filter_rules)
     127        return style.ProcessorOptions(output_format, verbosity, filter,
    79128                                      git_commit, extra_flag_values)
    80129
     
    174223        self.assertEquals(options.output_format, 'vs7')
    175224        self.assertEquals(options.verbosity, 3)
    176         self.assertEquals(options.filter_rules, ['-', '+whitespace'])
     225        self.assertEquals(options.filter,
     226                          CategoryFilter(["-", "+whitespace"]))
    177227        self.assertEquals(options.git_commit, None)
    178228
     
    188238        self.assertEquals(options.git_commit, 'commit')
    189239        (files, options) = parse(['--filter=+foo,-bar'])
    190         self.assertEquals(options.filter_rules,
    191                           ['-', '+whitespace', '+foo', '-bar'])
     240        self.assertEquals(options.filter,
     241                          CategoryFilter(["-", "+whitespace", "+foo", "-bar"]))
    192242
    193243        # Pass extra flag values.
  • trunk/WebKitTools/Scripts/webkitpy/style/cpp_style.py

    r52906 r53185  
    249249        self.verbose_level = 1  # global setting.
    250250        self.error_count = 0    # global count of reported errors
    251         # filters to apply when emitting error messages
    252         self.filters = []
     251        # filter to apply when emitting error messages
     252        self.filter = None
    253253
    254254        # output format:
     
    267267        return last_verbose_level
    268268
    269     def set_filters(self, filters):
    270         """Sets the error-message filters.
    271 
    272         These filters are applied when deciding whether to emit a given
    273         error message.
     269    def set_filter(self, filter):
     270        """Sets the error-message filter.
    274271
    275272        Args:
    276           filters: A list of strings that are boolean filter rules used
    277                    to determine whether a style category should be checked.
    278                    Each string should start with + or -. An example
    279                    string is "+whitespace/indent". The list includes any
    280                    prepended default filter rules.
    281 
    282         Raises:
    283           ValueError: Not all filters started with '+' or '-'. For example,
    284                       "-,+whitespace,-whitespace/indent,whitespace/badfilter"
     273          filter: A CategoryFilter instance.
     274
    285275        """
    286         self.filters = []
    287         for filter in filters:
    288             clean_filter = filter.strip()
    289             if clean_filter:
    290                 self.filters.append(clean_filter)
    291         for filter in self.filters:
    292             if not (filter.startswith('+') or filter.startswith('-')):
    293                 raise ValueError('Every filter in --filter must start with '
    294                                  '+ or - (%s does not)' % filter)
     276        self.filter = filter
    295277
    296278    def reset_error_count(self):
     
    326308
    327309
    328 def _filters():
    329     """Returns the module's list of output filters, as a list."""
    330     return _cpp_style_state.filters
    331 
    332 
    333 def _set_filters(filters):
    334     """Sets the module's error-message filters.
    335 
    336     These filters are applied when deciding whether to emit a given
     310def _filter():
     311    """Returns the module's CategoryFilter instance."""
     312    return _cpp_style_state.filter
     313
     314
     315def _set_filter(filter):
     316    """Sets the module's error-message filter.
     317
     318    The filter is applied when deciding whether to emit a given
    337319    error message.
    338320
    339321    Args:
    340       filters: A list of strings that are boolean filter rules used
    341                to determine whether a style category should be checked.
    342                Each string should start with + or -. An example
    343                string is "+whitespace/indent". The list includes any
    344                prepended default filter rules.
    345     """
    346     _cpp_style_state.set_filters(filters)
     322      filter: A CategoryFilter instance.
     323
     324    """
     325    _cpp_style_state.set_filter(filter)
    347326
    348327
     
    506485        return False
    507486
    508     is_filtered = False
    509     for one_filter in _filters():
    510         if one_filter.startswith('-'):
    511             if category.startswith(one_filter[1:]):
    512                 is_filtered = True
    513         elif one_filter.startswith('+'):
    514             if category.startswith(one_filter[1:]):
    515                 is_filtered = False
    516         else:
    517             assert False  # should have been checked for in set_filter.
    518     if is_filtered:
    519         return False
    520 
    521     return True
     487    filter = _filter()
     488
     489    if filter is None:
     490        return True # All categories should be checked by default.
     491
     492    return filter.should_check(category)
    522493
    523494
  • trunk/WebKitTools/Scripts/webkitpy/style/cpp_style_unittest.py

    r52906 r53185  
    4242import unittest
    4343import cpp_style
    44 # FIXME: Remove the need to import something from checker. See the
     44# FIXME: Remove the need to import anything from checker. See the
    4545#        FIXME notes near the STYLE_CATEGORIES definition for a
    4646#        suggestion on how to best do this.
    4747from checker import STYLE_CATEGORIES
     48from checker import CategoryFilter
    4849
    4950# This class works as an error collector and replaces cpp_style.Error
     
    15721573
    15731574    def test_filter(self):
    1574         old_filters = cpp_style._cpp_style_state.filters
     1575        old_filter = cpp_style._cpp_style_state.filter
    15751576        try:
    1576             cpp_style._cpp_style_state.set_filters(['-', '+whitespace', '-whitespace/indent'])
     1577            cpp_style._cpp_style_state.set_filter(CategoryFilter(['-', '+whitespace', '-whitespace/indent']))
    15771578            self.assert_lint(
    15781579                '// Hello there ',
     
    15821583            self.assert_lint(' weird opening space', '')
    15831584        finally:
    1584             cpp_style._cpp_style_state.filters = old_filters
     1585            cpp_style._cpp_style_state.filter = old_filter
    15851586
    15861587    def test_filter_appending(self):
    1587         old_filters = cpp_style._cpp_style_state.filters
     1588        old_filter = cpp_style._cpp_style_state.filter
    15881589        try:
    15891590            # Reset filters
    1590             cpp_style._cpp_style_state.set_filters(['-whitespace'])
     1591            cpp_style._cpp_style_state.set_filter(CategoryFilter(['-whitespace']))
    15911592            self.assert_lint('// Hello there ', '')
    1592             cpp_style._cpp_style_state.set_filters(['-whitespace', '+whitespace/end_of_line'])
     1593            cpp_style._cpp_style_state.set_filter(CategoryFilter(['-whitespace', '+whitespace/end_of_line']))
    15931594            self.assert_lint(
    15941595                '// Hello there ',
     
    15971598            self.assert_lint(' weird opening space', '')
    15981599        finally:
    1599             cpp_style._cpp_style_state.filters = old_filters
     1600            cpp_style._cpp_style_state.filter = old_filter
    16001601
    16011602    def test_unnamed_namespaces_in_headers(self):
Note: See TracChangeset for help on using the changeset viewer.