Title: [135832] trunk/Tools
Revision
135832
Author
[email protected]
Date
2012-11-27 00:38:54 -0800 (Tue, 27 Nov 2012)

Log Message

[style] Add a style-check for enum-member names
https://bugs.webkit.org/show_bug.cgi?id=103157

Patch by Sadrul Habib Chowdhury <[email protected]> on 2012-11-27
Reviewed by Daniel Bates.

* Scripts/webkitpy/style/checkers/cpp.py:
(_EnumState):
(_EnumState.__init__):
(_EnumState.process_clean_line):
(check_enum_casing):
(check_style):
(process_line):
(_process_lines):
(CppChecker):
* Scripts/webkitpy/style/checkers/cpp_unittest.py:
(NoNonVirtualDestructorsTest.test_enum_casing):
(NoNonVirtualDestructorsTest.test_internal_braces.Foo):

Modified Paths

Diff

Modified: trunk/Tools/ChangeLog (135831 => 135832)


--- trunk/Tools/ChangeLog	2012-11-27 08:24:30 UTC (rev 135831)
+++ trunk/Tools/ChangeLog	2012-11-27 08:38:54 UTC (rev 135832)
@@ -1,3 +1,23 @@
+2012-11-27  Sadrul Habib Chowdhury  <[email protected]>
+
+        [style] Add a style-check for enum-member names
+        https://bugs.webkit.org/show_bug.cgi?id=103157
+
+        Reviewed by Daniel Bates.
+
+        * Scripts/webkitpy/style/checkers/cpp.py:
+        (_EnumState):
+        (_EnumState.__init__):
+        (_EnumState.process_clean_line):
+        (check_enum_casing):
+        (check_style):
+        (process_line):
+        (_process_lines):
+        (CppChecker):
+        * Scripts/webkitpy/style/checkers/cpp_unittest.py:
+        (NoNonVirtualDestructorsTest.test_enum_casing):
+        (NoNonVirtualDestructorsTest.test_internal_braces.Foo):
+
 2012-11-26  Ryuan Choi  <[email protected]>
 
         [EFL][jhbuild] Disable unnecessary options of elementary module

Modified: trunk/Tools/Scripts/webkitpy/style/checkers/cpp.py (135831 => 135832)


--- trunk/Tools/Scripts/webkitpy/style/checkers/cpp.py	2012-11-27 08:24:30 UTC (rev 135831)
+++ trunk/Tools/Scripts/webkitpy/style/checkers/cpp.py	2012-11-27 08:38:54 UTC (rev 135832)
@@ -1210,6 +1210,44 @@
         return self.is_c() or self.is_objective_c()
 
 
+class _EnumState(object):
+    """Maintains whether currently in an enum declaration, and checks whether
+    enum declarations follow the style guide.
+    """
+
+    def __init__(self):
+        self.in_enum_decl = False
+
+    def process_clean_line(self, line):
+        # FIXME: The regular expressions for expr_all_uppercase and expr_enum_end only accept integers
+        # and identifiers for the value of the enumerator, but do not accept any other constant
+        # expressions. However, this is sufficient for now (11/27/2012).
+        expr_all_uppercase = r'\s*[A-Z0-9_]+\s*(?:=\s*[a-zA-Z0-9]+\s*)?,?\s*$'
+        expr_starts_lowercase = r'\s*[a-z]'
+        expr_enum_end = r'}\s*(?:[a-zA-Z0-9]+\s*(?:=\s*[a-zA-Z0-9]+)?)?\s*;\s*'
+        expr_enum_start = r'\s*enum(?:\s+[a-zA-Z0-9]+)?\s*\{?\s*'
+        if self.in_enum_decl:
+            if match(r'\s*' + expr_enum_end + r'$', line):
+                self.in_enum_decl = False
+            elif match(expr_all_uppercase, line):
+                return False
+            elif match(expr_starts_lowercase, line):
+                return False
+        else:
+            if match(expr_enum_start + r'$', line):
+                self.in_enum_decl = True
+            else:
+                matched = match(expr_enum_start + r'(?P<members>.*)' + expr_enum_end + r'$', line)
+                if matched:
+                    members = matched.group('members').split(',')
+                    for member in members:
+                        if match(expr_all_uppercase, member):
+                            return False
+                        if match(expr_starts_lowercase, member):
+                            return False
+                    return True
+        return True
+
 def check_for_non_standard_constructs(clean_lines, line_number,
                                       class_state, error):
     """Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
@@ -2040,6 +2078,21 @@
             break;
 
 
+def check_enum_casing(clean_lines, line_number, enum_state, error):
+    """Looks for incorrectly named enum values.
+
+    Args:
+      clean_lines: A CleansedLines instance containing the file.
+      line_number: The number of the line to check.
+      enum_state: A _EnumState instance which maintains enum declaration state.
+      error: The function to call with any errors found.
+    """
+
+    line = clean_lines.elided[line_number]  # Get rid of comments and strings.
+    if not enum_state.process_clean_line(line):
+        error(line_number, 'readability/enum_casing', 4,
+              'enum members should use InterCaps with an initial capital letter.')
+
 def check_directive_indentation(clean_lines, line_number, file_state, error):
     """Looks for indentation of preprocessor directives.
 
@@ -2535,7 +2588,7 @@
     return len(line)
 
 
-def check_style(clean_lines, line_number, file_extension, class_state, file_state, error):
+def check_style(clean_lines, line_number, file_extension, class_state, file_state, enum_state, error):
     """Checks rules from the 'C++ style rules' section of cppguide.html.
 
     Most of these rules are hard to test (naming, comment style), but we
@@ -2550,6 +2603,7 @@
                    the current stack of nested class declarations being parsed.
       file_state: A _FileState instance which maintains information about
                   the state of things in the file.
+      enum_state: A _EnumState instance which maintains the current enum state.
       error: The function to call with any errors found.
     """
 
@@ -2604,6 +2658,7 @@
     check_for_comparisons_to_zero(clean_lines, line_number, error)
     check_for_null(clean_lines, line_number, file_state, error)
     check_indentation_amount(clean_lines, line_number, error)
+    check_enum_casing(clean_lines, line_number, enum_state, error)
 
 
 _RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"')
@@ -3478,7 +3533,7 @@
 
 def process_line(filename, file_extension,
                  clean_lines, line, include_state, function_state,
-                 class_state, file_state, error):
+                 class_state, file_state, enum_state, error):
     """Processes a single line in the file.
 
     Args:
@@ -3493,6 +3548,8 @@
                    the current stack of nested class declarations being parsed.
       file_state: A _FileState instance which maintains information about
                   the state of things in the file.
+      enum_state: A _EnumState instance which maintains an enum declaration
+                  state.
       error: A callable to which errors are reported, which takes arguments:
              line number, error level, and message
 
@@ -3508,7 +3565,7 @@
     check_pass_ptr_usage(clean_lines, line, function_state, error)
     check_for_leaky_patterns(clean_lines, line, function_state, error)
     check_for_multiline_comments_and_strings(clean_lines, line, error)
-    check_style(clean_lines, line, file_extension, class_state, file_state, error)
+    check_style(clean_lines, line, file_extension, class_state, file_state, enum_state, error)
     check_language(filename, clean_lines, line, file_extension, include_state,
                    file_state, error)
     check_for_non_standard_constructs(clean_lines, line, class_state, error)
@@ -3541,9 +3598,11 @@
     remove_multi_line_comments(lines, error)
     clean_lines = CleansedLines(lines)
     file_state = _FileState(clean_lines, file_extension)
+    enum_state = _EnumState()
     for line in xrange(clean_lines.num_lines()):
         process_line(filename, file_extension, clean_lines, line,
-                     include_state, function_state, class_state, file_state, error)
+                     include_state, function_state, class_state, file_state,
+                     enum_state, error)
     class_state.check_finished(error)
 
     check_for_include_what_you_use(filename, clean_lines, include_state, error)
@@ -3585,6 +3644,7 @@
         'readability/comparison_to_zero',
         'readability/constructors',
         'readability/control_flow',
+        'readability/enum_casing',
         'readability/fn_size',
         'readability/function',
         'readability/multiline_comment',

Modified: trunk/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py (135831 => 135832)


--- trunk/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py	2012-11-27 08:24:30 UTC (rev 135831)
+++ trunk/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py	2012-11-27 08:38:54 UTC (rev 135832)
@@ -3258,6 +3258,43 @@
                 };''',
             'The class Foo probably needs a virtual destructor')
 
+    def test_enum_casing(self):
+        self.assert_multi_line_lint(
+            '''\
+                enum Foo {
+                    FOO_ONE = 1,
+                    FOO_TWO
+                };
+                enum { FOO_ONE };
+                enum {FooOne, fooTwo};
+                enum {
+                    FOO_ONE
+                };''',
+            ['enum members should use InterCaps with an initial capital letter.  [readability/enum_casing] [4]'] * 5)
+
+        self.assert_multi_line_lint(
+            '''\
+                enum Foo {
+                    fooOne = 1,
+                    FooTwo = 2
+                };''',
+            'enum members should use InterCaps with an initial capital letter.  [readability/enum_casing] [4]')
+
+        self.assert_multi_line_lint(
+            '''\
+                enum Foo {
+                    FooOne = 1,
+                    FooTwo
+                } fooVar = FooOne;
+                enum { FooOne, FooTwo };
+                enum { FooOne, FooTwo } fooVar = FooTwo;
+                enum { FooOne= FooTwo } foo;
+                enum Enum123 {
+                    FooOne,
+                    FooTwo = FooOne,
+                };''',
+            '')
+
     def test_destructor_non_virtual_when_virtual_needed(self):
         self.assert_multi_line_lint_re(
             '''\
@@ -3280,7 +3317,7 @@
             '''\
                 class Foo {
                     enum Goo {
-                        GOO
+                        Goo
                     };
                     virtual void foo();
                 };''',
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to