[SCM] WebKit Debian packaging branch, debian/experimental, updated. debian/1.3.8-1-1049-g2e11a8e

levin at chromium.org levin at chromium.org
Fri Jan 21 14:42:34 UTC 2011


The following commit has been merged in the debian/experimental branch:
commit ad70c0b5ea699083532795cca98f260d45ec172d
Author: levin at chromium.org <levin at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Sun Dec 26 20:27:49 2010 +0000

    2010-12-26  David Levin  <levin at chromium.org>
    
            Reviewed by Eric Seidel.
    
            check-webkit-style should be able to parse function declaration parameters.
            https://bugs.webkit.org/show_bug.cgi?id=51451
    
            * Scripts/webkitpy/style/checkers/cpp.py:
            (Position.__init__): Holds simple position information (row, column).
            (Parameter.__init__): Holds information about a parameter.
            (SingleLineView.__init): Converts multiple lines into a single line for simpler searches.
            (SingleLineView.convert_column_to_row): Returns the original row given a column.
            (create_skeleton_parameters): Simplifies a parameter list for easier searching.
            (find_parameter_name_index): Finds where the parameter name is.
            (parameter_list): Generates the list of parameters for a function.
            (_FunctionState.begin): Added information to allow determining the parameters
            on demand.
            (_FunctionState.get_parameter_list): Returns a tuple of function parameters.
            (detect_functions): Improve function detection for operator functions and
            determine where the parameters end and pass that to _FunctionState.begin.
            * Scripts/webkitpy/style/checkers/cpp_unittest.py:
            (CppFunctionsTest.test_parameter): Verifies Parameter functionality.
            (CppFunctionsTest.test_single_line_view): Verifies SingleLineView functionality.
            (CppFunctionsTest.test_create_skeleton_parameters): Verifies create_skeleton_parameters.
            (CppFunctionsTest.test_find_parameter_name_index): Verifies find_parameter_name_index.
            (CppFunctionsTest.test_parameter_list): Does some minimal verification for parameter list.
            Much more thorough verification is done as part of FunctionDetectionTest.test_parameter_list.
            (FunctionDetectionTest.perform_function_detection): Added support for verifying
            the parameters found.
            (FunctionDetectionTest.test_function_declaration_detection): Added more function
            detection test to verify that we catch the operator functions.
            (FunctionDetectionTest.test_ignore_macros): Verify that function detection ignores macros.
            (FunctionDetectionTest.test_parameter_list): Added tests to verify the parameter parsing.
            (CheckForFunctionLengthsTest.test_function_length_check_definition_severity1_for_bad_test_doesnt_break): Removed
            because the error. The test is about the bad function name. Fixing the name makes the test exactly like
            test_function_length_check_definition_severity1_for_test.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@74670 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index 06bcdf2..e89f2c4 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,40 @@
+2010-12-26  David Levin  <levin at chromium.org>
+
+        Reviewed by Eric Seidel.
+
+        check-webkit-style should be able to parse function declaration parameters.
+        https://bugs.webkit.org/show_bug.cgi?id=51451
+
+        * Scripts/webkitpy/style/checkers/cpp.py:
+        (Position.__init__): Holds simple position information (row, column).
+        (Parameter.__init__): Holds information about a parameter.
+        (SingleLineView.__init): Converts multiple lines into a single line for simpler searches.
+        (SingleLineView.convert_column_to_row): Returns the original row given a column.
+        (create_skeleton_parameters): Simplifies a parameter list for easier searching.
+        (find_parameter_name_index): Finds where the parameter name is.
+        (parameter_list): Generates the list of parameters for a function.
+        (_FunctionState.begin): Added information to allow determining the parameters
+        on demand.
+        (_FunctionState.get_parameter_list): Returns a tuple of function parameters.
+        (detect_functions): Improve function detection for operator functions and
+        determine where the parameters end and pass that to _FunctionState.begin.
+        * Scripts/webkitpy/style/checkers/cpp_unittest.py:
+        (CppFunctionsTest.test_parameter): Verifies Parameter functionality.
+        (CppFunctionsTest.test_single_line_view): Verifies SingleLineView functionality.
+        (CppFunctionsTest.test_create_skeleton_parameters): Verifies create_skeleton_parameters.
+        (CppFunctionsTest.test_find_parameter_name_index): Verifies find_parameter_name_index.
+        (CppFunctionsTest.test_parameter_list): Does some minimal verification for parameter list.
+        Much more thorough verification is done as part of FunctionDetectionTest.test_parameter_list.
+        (FunctionDetectionTest.perform_function_detection): Added support for verifying
+        the parameters found.
+        (FunctionDetectionTest.test_function_declaration_detection): Added more function
+        detection test to verify that we catch the operator functions.
+        (FunctionDetectionTest.test_ignore_macros): Verify that function detection ignores macros.
+        (FunctionDetectionTest.test_parameter_list): Added tests to verify the parameter parsing.
+        (CheckForFunctionLengthsTest.test_function_length_check_definition_severity1_for_bad_test_doesnt_break): Removed
+        because the error. The test is about the bad function name. Fixing the name makes the test exactly like
+        test_function_length_check_definition_severity1_for_test.
+
 2010-12-25  Patrick Gansterer  <paroga at webkit.org>
 
         Unreviewed WinCE buildfix after r74334.
diff --git a/Tools/Scripts/webkitpy/style/checkers/cpp.py b/Tools/Scripts/webkitpy/style/checkers/cpp.py
index 94e5bdd..f721b9f 100644
--- a/Tools/Scripts/webkitpy/style/checkers/cpp.py
+++ b/Tools/Scripts/webkitpy/style/checkers/cpp.py
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2009 Google Inc. All rights reserved.
+# Copyright (C) 2009, 2010 Google Inc. All rights reserved.
 # Copyright (C) 2009 Torch Mobile Inc.
 # Copyright (C) 2009 Apple Inc. All rights reserved.
 # Copyright (C) 2010 Chris Jerdonek (cjerdonek at webkit.org)
@@ -308,6 +308,133 @@ class _IncludeState(dict):
         return error_message
 
 
+class Position(object):
+    """Holds the position of something."""
+    def __init__(self, row, column):
+        self.row = row
+        self.column = column
+
+
+class Parameter(object):
+    """Information about one function parameter."""
+    def __init__(self, parameter, parameter_name_index, row):
+        self.type = parameter[:parameter_name_index].strip()
+        # Remove any initializers from the parameter name (e.g. int i = 5).
+        self.name = sub(r'=.*', '', parameter[parameter_name_index:]).strip()
+        self.row = row
+
+
+class SingleLineView(object):
+    """Converts multiple lines into a single line (with line breaks replaced by a
+       space) to allow for easier searching."""
+    def __init__(self, lines, start_position, end_position):
+        """Create a SingleLineView instance.
+
+        Args:
+          lines: a list of multiple lines to combine into a single line.
+          start_position: offset within lines of where to start the single line.
+          end_position: just after where to end (like a slice operation).
+        """
+        # Get the rows of interest.
+        trimmed_lines = lines[start_position.row:end_position.row + 1]
+
+        # Remove the columns on the last line that aren't included.
+        trimmed_lines[-1] = trimmed_lines[-1][:end_position.column]
+
+        # Remove the columns on the first line that aren't included.
+        trimmed_lines[0] = trimmed_lines[0][start_position.column:]
+
+        # Create a single line with all of the parameters.
+        self.single_line = ' '.join(trimmed_lines)
+
+        # Keep the row lengths, so we can calculate the original row number
+        # given a column in the single line (adding 1 due to the space added
+        # during the join).
+        self._row_lengths = [len(line) + 1 for line in trimmed_lines]
+        self._starting_row = start_position.row
+
+    def convert_column_to_row(self, single_line_column_number):
+        """Convert the column number from the single line into the original
+        line number.
+
+        Special cases:
+        * Columns in the added spaces are considered part of the previous line.
+        * Columns beyond the end of the line are consider part the last line
+        in the view."""
+        total_columns = 0
+        row_offset = 0
+        while row_offset < len(self._row_lengths) - 1 and single_line_column_number >= total_columns + self._row_lengths[row_offset]:
+            total_columns += self._row_lengths[row_offset]
+            row_offset += 1
+        return self._starting_row + row_offset
+
+
+def create_skeleton_parameters(all_parameters):
+    """Converts a parameter list to a skeleton version.
+
+    The skeleton only has one word for the parameter name, one word for the type,
+    and commas after each parameter and only there. Everything in the skeleton
+    remains in the same columns as the original."""
+    all_simplifications = (
+        # Remove template parameters, function declaration parameters, etc.
+        r'(<[^<>]*?>)|(\([^\(\)]*?\))|(\{[^\{\}]*?\})',
+        # Remove all initializers.
+        r'=[^,]*',
+        # Remove :: and everything before it.
+        r'[^,]*::',
+        # Remove modifiers like &, *.
+        r'[&*]',
+        # Remove const modifiers.
+        r'\bconst\s+(?=[A-Za-z])',
+        # Remove numerical modifiers like long.
+        r'\b(unsigned|long|short)\s+(?=unsigned|long|short|int|char|double|float)')
+
+    skeleton_parameters = all_parameters
+    for simplification in all_simplifications:
+        skeleton_parameters = iteratively_replace_matches_with_char(simplification, ' ', skeleton_parameters)
+    # If there are any parameters, then add a , after the last one to
+    # make a regular pattern of a , following every parameter.
+    if skeleton_parameters.strip():
+        skeleton_parameters += ','
+    return skeleton_parameters
+
+
+def find_parameter_name_index(skeleton_parameter):
+    """Determines where the parametere name starts given the skeleton parameter."""
+    # The first space from the right in the simplified parameter is where the parameter
+    # name starts unless the first space is before any content in the simplified parameter.
+    before_name_index = skeleton_parameter.rstrip().rfind(' ')
+    if before_name_index != -1 and skeleton_parameter[:before_name_index].strip():
+        return before_name_index + 1
+    return len(skeleton_parameter)
+
+
+def parameter_list(elided_lines, start_position, end_position):
+    """Generator for a function's parameters."""
+    # Create new positions that omit the outer parenthesis of the parameters.
+    start_position = Position(row=start_position.row, column=start_position.column + 1)
+    end_position = Position(row=end_position.row, column=end_position.column - 1)
+    single_line_view = SingleLineView(elided_lines, start_position, end_position)
+    skeleton_parameters = create_skeleton_parameters(single_line_view.single_line)
+    end_index = -1
+
+    while True:
+        # Find the end of the next parameter.
+        start_index = end_index + 1
+        end_index = skeleton_parameters.find(',', start_index)
+
+        # No comma means that all parameters have been parsed.
+        if end_index == -1:
+            return
+        row = single_line_view.convert_column_to_row(end_index)
+
+        # Parse the parameter into a type and parameter name.
+        skeleton_parameter = skeleton_parameters[start_index:end_index]
+        name_offset = find_parameter_name_index(skeleton_parameter)
+        parameter = single_line_view.single_line[start_index:end_index]
+        yield Parameter(parameter, name_offset, row)
+
+
 class _FunctionState(object):
     """Tracks current function name and the number of lines in its body.
 
@@ -329,7 +456,8 @@ class _FunctionState(object):
         self.body_start_line_number = -1000
         self.ending_line_number = -1000
 
-    def begin(self, function_name, body_start_line_number, ending_line_number, is_declaration):
+    def begin(self, function_name, body_start_line_number, ending_line_number, is_declaration,
+              parameter_start_position, parameter_end_position, clean_lines):
         """Start analyzing function body.
 
         Args:
@@ -337,6 +465,9 @@ class _FunctionState(object):
             body_start_line_number: The line number of the { or the ; for a protoype.
             ending_line_number: The line number where the function ends.
             is_declaration: True if this is a prototype.
+            parameter_start_position: position in elided of the '(' for the parameters.
+            parameter_end_position: position in elided of the ')' for the parameters.
+            clean_lines: A CleansedLines instance containing the file.
         """
         self.in_a_function = True
         self.lines_in_function = -1  # Don't count the open brace line.
@@ -344,6 +475,17 @@ class _FunctionState(object):
         self.body_start_line_number = body_start_line_number
         self.ending_line_number = ending_line_number
         self.is_declaration = is_declaration
+        self.parameter_start_position = parameter_start_position
+        self.parameter_end_position = parameter_end_position
+        self._clean_lines = clean_lines
+        self._parameter_list = None
+
+    def parameter_list(self):
+        if not self._parameter_list:
+            # Store the final result as a tuple since that is immutable.
+            self._parameter_list = tuple(parameter_list(self._clean_lines.elided, self.parameter_start_position, self.parameter_end_position))
+
+        return self._parameter_list
 
     def count(self, line_number):
         """Count line in current function body."""
@@ -1213,7 +1355,11 @@ def detect_functions(clean_lines, line_number, function_state, error):
     raw = clean_lines.raw_lines
     raw_line = raw[line_number]
 
-    regexp = r'\s*(\w(\w|::|\*|\&|\s|<|>|,|~)*)\('  # decls * & space::name( ...
+    # Lines ending with a \ indicate a macro. Don't try to check them.
+    if raw_line.endswith('\\'):
+        return
+
+    regexp = r'\s*(\w(\w|::|\*|\&|\s|<|>|,|~|(operator\s*(/|-|=|!|\+)+))*)\('  # decls * & space::name( ...
     match_result = match(regexp, line)
     if not match_result:
         return
@@ -1232,7 +1378,7 @@ def detect_functions(clean_lines, line_number, function_state, error):
             # Replace template constructs with _ so that no spaces remain in the function name,
             # while keeping the column numbers of other characters the same as "line".
             line_with_no_templates = iteratively_replace_matches_with_char(r'<[^<>]*>', '_', line)
-            match_function = search(r'((\w|:|<|>|,|~)*)\(', line_with_no_templates)
+            match_function = search(r'((\w|:|<|>|,|~|(operator\s*(/|-|=|!|\+)+))*)\(', line_with_no_templates)
             if not match_function:
                 return  # The '(' must have been inside of a template.
 
@@ -1246,13 +1392,22 @@ def detect_functions(clean_lines, line_number, function_state, error):
                     function += parameter_regexp.group(1)
             else:
                 function += '()'
+
+            parameter_start_position = Position(line_number, match_function.end(1))
+            close_result = close_expression(clean_lines, line_number, parameter_start_position.column)
+            if close_result[1] == len(clean_lines.elided):
+                # No end was found.
+                return
+            parameter_end_position = Position(close_result[1], close_result[2])
+
             is_declaration = bool(search(r'^[^{]*;', start_line))
             if is_declaration:
                 ending_line_number = start_line_number
             else:
                 open_brace_index = start_line.find('{')
                 ending_line_number = close_expression(clean_lines, start_line_number, open_brace_index)[1]
-            function_state.begin(function, start_line_number, ending_line_number, is_declaration)
+            function_state.begin(function, start_line_number, ending_line_number, is_declaration,
+                                 parameter_start_position, parameter_end_position, clean_lines)
             return
 
     # No body for the function (or evidence of a non-function) was found.
diff --git a/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py b/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py
index 70df1ea..4f84693 100644
--- a/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py
+++ b/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 # -*- coding: utf-8; -*-
 #
-# Copyright (C) 2009 Google Inc. All rights reserved.
+# Copyright (C) 2009, 2010 Google Inc. All rights reserved.
 # Copyright (C) 2009 Torch Mobile Inc.
 # Copyright (C) 2009 Apple Inc. All rights reserved.
 # Copyright (C) 2010 Chris Jerdonek (cjerdonek at webkit.org)
@@ -119,6 +119,93 @@ class CppFunctionsTest(unittest.TestCase):
         self.assertFalse(cpp_style._FileState(clean_lines, 'h').is_c_or_objective_c())
         self.assertTrue(cpp_style._FileState(clean_objc_lines, 'h').is_c_or_objective_c())
 
+    def test_parameter(self):
+        # Test type.
+        parameter = cpp_style.Parameter('ExceptionCode', 13, 1)
+        self.assertEquals(parameter.type, 'ExceptionCode')
+        self.assertEquals(parameter.name, '')
+        self.assertEquals(parameter.row, 1)
+
+        # Test type and name.
+        parameter = cpp_style.Parameter('PassRefPtr<MyClass> parent', 19, 1)
+        self.assertEquals(parameter.type, 'PassRefPtr<MyClass>')
+        self.assertEquals(parameter.name, 'parent')
+        self.assertEquals(parameter.row, 1)
+
+        # Test type, no name, with default value.
+        parameter = cpp_style.Parameter('MyClass = 0', 7, 0)
+        self.assertEquals(parameter.type, 'MyClass')
+        self.assertEquals(parameter.name, '')
+        self.assertEquals(parameter.row, 0)
+
+        # Test type, name, and default value.
+        parameter = cpp_style.Parameter('MyClass a = 0', 7, 0)
+        self.assertEquals(parameter.type, 'MyClass')
+        self.assertEquals(parameter.name, 'a')
+        self.assertEquals(parameter.row, 0)
+
+    def test_single_line_view(self):
+        start_position = cpp_style.Position(row=1, column=1)
+        end_position = cpp_style.Position(row=3, column=1)
+        single_line_view = cpp_style.SingleLineView(['0', 'abcde', 'fgh', 'i'], start_position, end_position)
+        self.assertEquals(single_line_view.single_line, 'bcde fgh i')
+        self.assertEquals(single_line_view.convert_column_to_row(0), 1)
+        self.assertEquals(single_line_view.convert_column_to_row(4), 1)
+        self.assertEquals(single_line_view.convert_column_to_row(5), 2)
+        self.assertEquals(single_line_view.convert_column_to_row(8), 2)
+        self.assertEquals(single_line_view.convert_column_to_row(9), 3)
+        self.assertEquals(single_line_view.convert_column_to_row(100), 3)
+
+        start_position = cpp_style.Position(row=0, column=3)
+        end_position = cpp_style.Position(row=0, column=4)
+        single_line_view = cpp_style.SingleLineView(['abcdef'], start_position, end_position)
+        self.assertEquals(single_line_view.single_line, 'd')
+
+    def test_create_skeleton_parameters(self):
+        self.assertEquals(cpp_style.create_skeleton_parameters(''), '')
+        self.assertEquals(cpp_style.create_skeleton_parameters(' '), ' ')
+        self.assertEquals(cpp_style.create_skeleton_parameters('long'), 'long,')
+        self.assertEquals(cpp_style.create_skeleton_parameters('const unsigned long int'), '                    int,')
+        self.assertEquals(cpp_style.create_skeleton_parameters('long int*'), '     int ,')
+        self.assertEquals(cpp_style.create_skeleton_parameters('PassRefPtr<Foo> a'), 'PassRefPtr      a,')
+        self.assertEquals(cpp_style.create_skeleton_parameters(
+                'ComplexTemplate<NestedTemplate1<MyClass1, MyClass2>, NestedTemplate1<MyClass1, MyClass2> > param, int second'),
+                          'ComplexTemplate                                                                            param, int second,')
+        self.assertEquals(cpp_style.create_skeleton_parameters('int = 0, Namespace::Type& a'), 'int    ,            Type  a,')
+        # Create skeleton parameters is a bit too aggressive with function variables, but
+        # it allows for parsing other parameters and declarations like this are rare.
+        self.assertEquals(cpp_style.create_skeleton_parameters('void (*fn)(int a, int b), Namespace::Type& a'),
+                          'void                    ,            Type  a,')
+
+        # This doesn't look like functions declarations but the simplifications help to eliminate false positives.
+        self.assertEquals(cpp_style.create_skeleton_parameters('b{d}'), 'b   ,')
+
+    def test_find_parameter_name_index(self):
+        self.assertEquals(cpp_style.find_parameter_name_index(' int a '), 5)
+        self.assertEquals(cpp_style.find_parameter_name_index(' PassRefPtr     '), 16)
+        self.assertEquals(cpp_style.find_parameter_name_index('double'), 6)
+
+    def test_parameter_list(self):
+        elided_lines = ['int blah(PassRefPtr<MyClass> paramName,',
+                        'const Other1Class& foo,',
+                        'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const * param = new ComplexTemplate<Class1, NestedTemplate<P1, P2> >(34, 42),',
+                        'int* myCount = 0);']
+        start_position = cpp_style.Position(row=0, column=8)
+        end_position = cpp_style.Position(row=3, column=16)
+
+        expected_parameters = ({'type': 'PassRefPtr<MyClass>', 'name': 'paramName', 'row': 0},
+                               {'type': 'const Other1Class&', 'name': 'foo', 'row': 1},
+                               {'type': 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const *', 'name': 'param', 'row': 2},
+                               {'type': 'int*', 'name': 'myCount', 'row': 3})
+        index = 0
+        for parameter in cpp_style.parameter_list(elided_lines, start_position, end_position):
+            expected_parameter = expected_parameters[index]
+            self.assertEquals(parameter.type, expected_parameter['type'])
+            self.assertEquals(parameter.name, expected_parameter['name'])
+            self.assertEquals(parameter.row, expected_parameter['row'])
+            index += 1
+        self.assertEquals(index, len(expected_parameters))
+
 
 class CppStyleTestBase(unittest.TestCase):
     """Provides some useful helper functions for cpp_style tests.
@@ -250,6 +337,16 @@ class FunctionDetectionTest(CppStyleTestBase):
         self.assertEquals(function_state.body_start_line_number, function_information['body_start_line_number'])
         self.assertEquals(function_state.ending_line_number, function_information['ending_line_number'])
         self.assertEquals(function_state.is_declaration, function_information['is_declaration'])
+        expected_parameters = function_information.get('parameter_list')
+        if expected_parameters:
+            actual_parameters = function_state.parameter_list()
+            self.assertEquals(len(actual_parameters), len(expected_parameters))
+            for index in range(len(expected_parameters)):
+                actual_parameter = actual_parameters[index]
+                expected_parameter = expected_parameters[index]
+                self.assertEquals(actual_parameter.type, expected_parameter['type'])
+                self.assertEquals(actual_parameter.name, expected_parameter['name'])
+                self.assertEquals(actual_parameter.row, expected_parameter['row'])
 
     def test_basic_function_detection(self):
         self.perform_function_detection(
@@ -268,6 +365,37 @@ class FunctionDetectionTest(CppStyleTestBase):
              'ending_line_number': 0,
              'is_declaration': True})
 
+        self.perform_function_detection(
+            ['CheckedInt<T> operator /(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
+            {'name': 'operator /',
+             'body_start_line_number': 0,
+             'ending_line_number': 0,
+             'is_declaration': True})
+
+        self.perform_function_detection(
+            ['CheckedInt<T> operator -(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
+            {'name': 'operator -',
+             'body_start_line_number': 0,
+             'ending_line_number': 0,
+            'is_declaration': True})
+
+        self.perform_function_detection(
+            ['CheckedInt<T> operator !=(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
+            {'name': 'operator !=',
+             'body_start_line_number': 0,
+             'ending_line_number': 0,
+             'is_declaration': True})
+
+        self.perform_function_detection(
+            ['CheckedInt<T> operator +(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs);'],
+            {'name': 'operator +',
+             'body_start_line_number': 0,
+             'ending_line_number': 0,
+             'is_declaration': True})
+
+    def test_ignore_macros(self):
+        self.perform_function_detection(['void aFunctionName(int); \\'], None)
+
     def test_non_functions(self):
         # This case exposed an error because the open brace was in quotes.
         self.perform_function_detection(
@@ -284,6 +412,70 @@ class FunctionDetectionTest(CppStyleTestBase):
         # Simple test case with something that is not a function.
         self.perform_function_detection(['class Stuff;'], None)
 
+    def test_parameter_list(self):
+        # A function with no arguments.
+        function_state = self.perform_function_detection(
+            ['void functionName();'],
+            {'name': 'functionName',
+             'body_start_line_number': 0,
+             'ending_line_number': 0,
+             'is_declaration': True,
+             'parameter_list': ()})
+
+        # A function with one argument.
+        function_state = self.perform_function_detection(
+            ['void functionName(int);'],
+            {'name': 'functionName',
+             'body_start_line_number': 0,
+             'ending_line_number': 0,
+             'is_declaration': True,
+             'parameter_list':
+                 ({'type': 'int', 'name': '', 'row': 0},)})
+
+        # A function with unsigned and short arguments
+        function_state = self.perform_function_detection(
+            ['void functionName(unsigned a, short b, long c, long long short unsigned int);'],
+            {'name': 'functionName',
+             'body_start_line_number': 0,
+             'ending_line_number': 0,
+             'is_declaration': True,
+             'parameter_list':
+                 ({'type': 'unsigned', 'name': 'a', 'row': 0},
+                  {'type': 'short', 'name': 'b', 'row': 0},
+                  {'type': 'long', 'name': 'c', 'row': 0},
+                  {'type': 'long long short unsigned int', 'name': '', 'row': 0})})
+
+        # Some parameter type with modifiers and no parameter names.
+        function_state = self.perform_function_detection(
+            ['virtual void determineARIADropEffects(Vector<String>*&, const unsigned long int*&, const MediaPlayer::Preload, Other<Other2, Other3<P1, P2> >, int);'],
+            {'name': 'determineARIADropEffects',
+             'body_start_line_number': 0,
+             'ending_line_number': 0,
+             'is_declaration': True,
+             'parameter_list':
+                 ({'type': 'Vector<String>*&', 'name': '', 'row': 0},
+                  {'type': 'const unsigned long int*&', 'name': '', 'row': 0},
+                  {'type': 'const MediaPlayer::Preload', 'name': '', 'row': 0},
+                  {'type': 'Other<Other2, Other3<P1, P2> >', 'name': '', 'row': 0},
+                  {'type': 'int', 'name': '', 'row': 0})})
+
+        # Try parsing a function with a very complex definition.
+        function_state = self.perform_function_detection(
+            ['AnotherTemplate<Class1, Class2> aFunctionName(PassRefPtr<MyClass> paramName,',
+             'const Other1Class& foo,',
+             'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const * param = new ComplexTemplate<Class1, NestedTemplate<P1, P2> >(34, 42),',
+             'int* myCount = 0);'],
+            {'name': 'aFunctionName',
+             'body_start_line_number': 3,
+             'ending_line_number': 3,
+             'is_declaration': True,
+             'parameter_list':
+                 ({'type': 'PassRefPtr<MyClass>', 'name': 'paramName', 'row': 0},
+                  {'type': 'const Other1Class&', 'name': 'foo', 'row': 1},
+                  {'type': 'const ComplexTemplate<Class1, NestedTemplate<P1, P2> >* const *', 'name': 'param', 'row': 2},
+                  {'type': 'int*', 'name': 'myCount', 'row': 3})})
+
+
 class CppStyleTest(CppStyleTestBase):
 
     # Test get line width.
@@ -2549,14 +2741,12 @@ class CheckForFunctionLengthsTest(CppStyleTestBase):
         error_level = 1
         error_lines = self.trigger_test_lines(error_level) + 1
         trigger_level = self.trigger_test_lines(self.min_confidence)
+        # Since the function name isn't valid, the function detection algorithm
+        # will skip it, so no error is produced.
         self.assert_function_lengths_check(
             ('TEST_F('
              + self.function_body(error_lines)),
-            ('Small and focused functions are preferred: '
-             'TEST_F has %d non-comment lines '
-             '(error triggered by exceeding %d lines).'
-             '  [readability/fn_size] [%d]')
-            % (error_lines, trigger_level, error_level))
+            '')
 
     def test_function_length_check_definition_severity1_with_embedded_no_lints(self):
         error_level = 1

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list