From f4eeaedb39b6935f6236fe55a52bd9af0b8390ef Mon Sep 17 00:00:00 2001 From: vladlosev Date: Fri, 20 May 2011 21:44:14 +0000 Subject: [PATCH] Fixes issue 139 and issue 140. --- scripts/generator/cpp/gmock_class.py | 40 ++++++++++++++------ scripts/generator/cpp/gmock_class_test.py | 45 +++++++++++++++++++++++ 2 files changed, 73 insertions(+), 12 deletions(-) diff --git a/scripts/generator/cpp/gmock_class.py b/scripts/generator/cpp/gmock_class.py index 645c295b..427d206a 100755 --- a/scripts/generator/cpp/gmock_class.py +++ b/scripts/generator/cpp/gmock_class.py @@ -82,20 +82,36 @@ def _GenerateMethods(output_lines, source, class_node): return_type += '*' if node.return_type.reference: return_type += '&' - mock_method_macro = 'MOCK_%sMETHOD%d' % (const, len(node.parameters)) + num_parameters = len(node.parameters) + if len(node.parameters) == 1: + first_param = node.parameters[0] + if source[first_param.start:first_param.end].strip() == 'void': + # We must treat T(void) as a function with no parameters. + num_parameters = 0 + mock_method_macro = 'MOCK_%sMETHOD%d' % (const, num_parameters) args = '' if node.parameters: - # Get the full text of the parameters from the start - # of the first parameter to the end of the last parameter. - start = node.parameters[0].start - end = node.parameters[-1].end - # Remove // comments. - args_strings = re.sub(r'//.*', '', source[start:end]) - # Condense multiple spaces and eliminate newlines putting the - # parameters together on a single line. Ensure there is a - # space in an argument which is split by a newline without - # intervening whitespace, e.g.: int\nBar - args = re.sub(' +', ' ', args_strings.replace('\n', ' ')) + # Due to the parser limitations, it is impossible to keep comments + # while stripping the default parameters. When defaults are + # present, we choose to strip them and comments (and produce + # compilable code). + # TODO(nnorwitz@google.com): Investigate whether it is possible to + # preserve parameter name when reconstructing parameter text from + # the AST. + if len([param for param in node.parameters if param.default]) > 0: + args = ', '.join(param.type.name for param in node.parameters) + else: + # Get the full text of the parameters from the start + # of the first parameter to the end of the last parameter. + start = node.parameters[0].start + end = node.parameters[-1].end + # Remove // comments. + args_strings = re.sub(r'//.*', '', source[start:end]) + # Condense multiple spaces and eliminate newlines putting the + # parameters together on a single line. Ensure there is a + # space in an argument which is split by a newline without + # intervening whitespace, e.g.: int\nBar + args = re.sub(' +', ' ', args_strings.replace('\n', ' ')) # Create the mock method definition. output_lines.extend(['%s%s(%s,' % (indent, mock_method_macro, node.name), diff --git a/scripts/generator/cpp/gmock_class_test.py b/scripts/generator/cpp/gmock_class_test.py index 494720cd..7aa70276 100755 --- a/scripts/generator/cpp/gmock_class_test.py +++ b/scripts/generator/cpp/gmock_class_test.py @@ -76,6 +76,17 @@ class Foo { 'MOCK_CONST_METHOD1(Bar,\nvoid(bool flag));', self.GenerateMethodSource(source)) + def testExplicitVoid(self): + source = """ +class Foo { + public: + virtual int Bar(void); +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD0(Bar,\nint(void));', + self.GenerateMethodSource(source)) + def testStrangeNewlineInParameter(self): source = """ class Foo { @@ -88,6 +99,40 @@ a) = 0; 'MOCK_METHOD1(Bar,\nvoid(int a));', self.GenerateMethodSource(source)) + def testDefaultParameters(self): + source = """ +class Foo { + public: + virtual void Bar(int a, char c = 'x') = 0; +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD2(Bar,\nvoid(int, char));', + self.GenerateMethodSource(source)) + + def testMultipleDefaultParameters(self): + source = """ +class Foo { + public: + virtual void Bar(int a = 42, char c = 'x') = 0; +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD2(Bar,\nvoid(int, char));', + self.GenerateMethodSource(source)) + + def testRemovesCommentsWhenDefaultsArePresent(self): + source = """ +class Foo { + public: + virtual void Bar(int a = 42 /* a comment */, + char /* other comment */ c= 'x') = 0; +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD2(Bar,\nvoid(int, char));', + self.GenerateMethodSource(source)) + def testDoubleSlashCommentsInParameterListAreRemoved(self): source = """ class Foo {