From e35fdd936d133bf8a48de140a3c666897588a053 Mon Sep 17 00:00:00 2001 From: shiqian Date: Wed, 10 Dec 2008 05:08:54 +0000 Subject: Initial drop of Google Mock. The files are incomplete and thus may not build correctly yet. --- scripts/generator/cpp/gmock_class.py | 148 +++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100755 scripts/generator/cpp/gmock_class.py (limited to 'scripts/generator/cpp/gmock_class.py') diff --git a/scripts/generator/cpp/gmock_class.py b/scripts/generator/cpp/gmock_class.py new file mode 100755 index 00000000..f2b3521f --- /dev/null +++ b/scripts/generator/cpp/gmock_class.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python +# +# Copyright 2008 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Generate a Google Mock class from a production class. + +This program will read in a C++ source file and output the Google Mock class +for the specified class. + +Usage: + gmock_class.py header-file.h ClassName + +Output is sent to stdout. +""" + +__author__ = 'nnorwitz@google.com (Neal Norwitz)' + + +import os +import re +import sys + +from cpp import ast +from cpp import utils + +# How many spaces to indent. Can me set with INDENT environment variable. +_INDENT = 2 + + +def _GenerateMethods(output_lines, source, class_node): + function_type = ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL + ctor_or_dtor = ast.FUNCTION_CTOR | ast.FUNCTION_DTOR + + for node in class_node.body: + # We only care about virtual functions. + if (isinstance(node, ast.Function) and + node.modifiers & function_type and + not node.modifiers & ctor_or_dtor): + # Pick out all the elements we need from the original function. + const = '' + if node.modifiers & ast.FUNCTION_CONST: + const = 'CONST_' + return_type = 'void' + if node.return_type: + return_type = node.return_type.name + if node.return_type.pointer: + return_type += '*' + if node.return_type.reference: + return_type += '&' + prefix = 'MOCK_%sMETHOD%d' % (const, len(node.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 + args = re.sub(' +', ' ', source[start:end].replace('\n', '')) + + # Create the prototype. + indent = ' ' * _INDENT + line = ('%s%s(%s,\n%s%s(%s));' % + (indent, prefix, node.name, indent*3, return_type, args)) + output_lines.append(line) + + +def _GenerateMock(filename, source, ast_list, class_name): + lines = [] + for node in ast_list: + if isinstance(node, ast.Class) and node.body and node.name == class_name: + class_node = node + # Add namespace before the class. + if class_node.namespace: + lines.extend(['namespace %s {' % n for n in class_node.namespace]) # } + lines.append('') + + # Add the class prolog. + lines.append('class Mock%s : public %s {' % (class_name, class_name)) # } + lines.append('%spublic:' % (' ' * (_INDENT // 2))) + + # Add all the methods. + _GenerateMethods(lines, source, class_node) + + # Close the class. + if lines: + # If there are no virtual methods, no need for a public label. + if len(lines) == 2: + del lines[-1] + + # Only close the class if there really is a class. + lines.append('};') + lines.append('') # Add an extra newline. + + # Close the namespace. + if class_node.namespace: + for i in range(len(class_node.namespace)-1, -1, -1): + lines.append('} // namespace %s' % class_node.namespace[i]) + lines.append('') # Add an extra newline. + + if lines: + sys.stdout.write('\n'.join(lines)) + else: + sys.stderr.write('Class %s not found\n' % class_name) + + +def main(argv=sys.argv): + if len(argv) != 3: + sys.stdout.write(__doc__) + return 1 + + global _INDENT + try: + _INDENT = int(os.environ['INDENT']) + except KeyError: + pass + except: + sys.stderr.write('Unable to use indent of %s\n' % os.environ.get('INDENT')) + + filename, class_name = argv[1:] + source = utils.ReadFile(filename) + if source is None: + return 1 + + builder = ast.BuilderFromSource(source, filename) + try: + entire_ast = filter(None, builder.Generate()) + except KeyboardInterrupt: + return + except: + # An error message was already printed since we couldn't parse. + pass + else: + _GenerateMock(filename, source, entire_ast, class_name) + + +if __name__ == '__main__': + main(sys.argv) -- cgit v1.2.3 From 987a978c3c525cbc796824493436195872b89a0b Mon Sep 17 00:00:00 2001 From: nnorwitz Date: Wed, 6 May 2009 05:01:46 +0000 Subject: Issue 44: "const" is missing for const return types The modifiers (things like const, volatile, etc) were not being added to return types. --- scripts/generator/cpp/gmock_class.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts/generator/cpp/gmock_class.py') diff --git a/scripts/generator/cpp/gmock_class.py b/scripts/generator/cpp/gmock_class.py index f2b3521f..99a89655 100755 --- a/scripts/generator/cpp/gmock_class.py +++ b/scripts/generator/cpp/gmock_class.py @@ -54,7 +54,11 @@ def _GenerateMethods(output_lines, source, class_node): const = 'CONST_' return_type = 'void' if node.return_type: - return_type = node.return_type.name + # Add modifier bits like const. + modifiers = '' + if node.return_type.modifiers: + modifiers = ' '.join(node.return_type.modifiers) + ' ' + return_type = modifiers + node.return_type.name if node.return_type.pointer: return_type += '*' if node.return_type.reference: -- cgit v1.2.3 From 60df3efe3971fb54d3a10c557fbc30ff32512bb5 Mon Sep 17 00:00:00 2001 From: nnorwitz Date: Wed, 6 May 2009 05:31:57 +0000 Subject: Fix grammar in comment --- scripts/generator/cpp/gmock_class.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts/generator/cpp/gmock_class.py') diff --git a/scripts/generator/cpp/gmock_class.py b/scripts/generator/cpp/gmock_class.py index 99a89655..a4435de4 100755 --- a/scripts/generator/cpp/gmock_class.py +++ b/scripts/generator/cpp/gmock_class.py @@ -35,7 +35,7 @@ import sys from cpp import ast from cpp import utils -# How many spaces to indent. Can me set with INDENT environment variable. +# How many spaces to indent. Can set me with INDENT environment variable. _INDENT = 2 -- cgit v1.2.3 From ce60784fb51a5a0e28c14edd53bacbf0d2abb36b Mon Sep 17 00:00:00 2001 From: nnorwitz Date: Wed, 6 May 2009 05:57:09 +0000 Subject: Allow any number of ClassNames to be specified on the command line. 0 ClassNames means emit all classes found in the file. --- scripts/generator/cpp/gmock_class.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'scripts/generator/cpp/gmock_class.py') diff --git a/scripts/generator/cpp/gmock_class.py b/scripts/generator/cpp/gmock_class.py index a4435de4..ab2da32d 100755 --- a/scripts/generator/cpp/gmock_class.py +++ b/scripts/generator/cpp/gmock_class.py @@ -20,7 +20,7 @@ This program will read in a C++ source file and output the Google Mock class for the specified class. Usage: - gmock_class.py header-file.h ClassName + gmock_class.py header-file.h [ClassName1] [ClassName2] ... Output is sent to stdout. """ @@ -79,10 +79,12 @@ def _GenerateMethods(output_lines, source, class_node): output_lines.append(line) -def _GenerateMock(filename, source, ast_list, class_name): +def _GenerateMock(filename, source, ast_list, desired_class_names): lines = [] for node in ast_list: - if isinstance(node, ast.Class) and node.body and node.name == class_name: + if (isinstance(node, ast.Class) and node.body and + (desired_class_names is None or node.name in desired_class_names)): + class_name = node.name class_node = node # Add namespace before the class. if class_node.namespace: @@ -115,11 +117,15 @@ def _GenerateMock(filename, source, ast_list, class_name): if lines: sys.stdout.write('\n'.join(lines)) else: - sys.stderr.write('Class %s not found\n' % class_name) + if desired_class_names is None: + sys.stderr.write('No classes not found\n') + else: + class_names = ', '.join(sorted(desired_class_names)) + sys.stderr.write('Class(es) not found: %s\n' % class_names) def main(argv=sys.argv): - if len(argv) != 3: + if len(argv) < 2: sys.stdout.write(__doc__) return 1 @@ -131,7 +137,10 @@ def main(argv=sys.argv): except: sys.stderr.write('Unable to use indent of %s\n' % os.environ.get('INDENT')) - filename, class_name = argv[1:] + filename = argv[1] + class_name = None + if len(argv) >= 3: + class_name = set(argv[2:]) source = utils.ReadFile(filename) if source is None: return 1 -- cgit v1.2.3 From 84b8e4c65d0847ab4262bb70619182292482529a Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 7 May 2009 20:38:25 +0000 Subject: Cleans up the mock generator script: - updates the doc string. - adds a version number. - fixes the condition for error messages in _GenerateMocks(). --- scripts/generator/cpp/gmock_class.py | 51 +++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 21 deletions(-) (limited to 'scripts/generator/cpp/gmock_class.py') diff --git a/scripts/generator/cpp/gmock_class.py b/scripts/generator/cpp/gmock_class.py index ab2da32d..ba11f9e6 100755 --- a/scripts/generator/cpp/gmock_class.py +++ b/scripts/generator/cpp/gmock_class.py @@ -14,13 +14,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Generate a Google Mock class from a production class. +"""Generate Google Mock classes from base classes. -This program will read in a C++ source file and output the Google Mock class -for the specified class. +This program will read in a C++ source file and output the Google Mock +classes for the specified classes. If no class is specified, all +classes in the source file are emitted. Usage: - gmock_class.py header-file.h [ClassName1] [ClassName2] ... + gmock_class.py header-file.h [ClassName]... Output is sent to stdout. """ @@ -35,7 +36,8 @@ import sys from cpp import ast from cpp import utils -# How many spaces to indent. Can set me with INDENT environment variable. +_VERSION = (1, 0, 1) # The version of this script. +# How many spaces to indent. Can set me with the INDENT environment variable. _INDENT = 2 @@ -54,7 +56,7 @@ def _GenerateMethods(output_lines, source, class_node): const = 'CONST_' return_type = 'void' if node.return_type: - # Add modifier bits like const. + # Add modifiers like 'const'. modifiers = '' if node.return_type.modifiers: modifiers = ' '.join(node.return_type.modifiers) + ' ' @@ -79,12 +81,15 @@ def _GenerateMethods(output_lines, source, class_node): output_lines.append(line) -def _GenerateMock(filename, source, ast_list, desired_class_names): +def _GenerateMocks(filename, source, ast_list, desired_class_names): + processed_class_names = set() lines = [] for node in ast_list: - if (isinstance(node, ast.Class) and node.body and - (desired_class_names is None or node.name in desired_class_names)): + if (isinstance(node, ast.Class) and node.body and + # desired_class_names being None means that all classes are selected. + (not desired_class_names or node.name in desired_class_names)): class_name = node.name + processed_class_names.add(class_name) class_node = node # Add namespace before the class. if class_node.namespace: @@ -114,19 +119,23 @@ def _GenerateMock(filename, source, ast_list, desired_class_names): lines.append('} // namespace %s' % class_node.namespace[i]) lines.append('') # Add an extra newline. - if lines: - sys.stdout.write('\n'.join(lines)) - else: - if desired_class_names is None: - sys.stderr.write('No classes not found\n') - else: - class_names = ', '.join(sorted(desired_class_names)) - sys.stderr.write('Class(es) not found: %s\n' % class_names) + sys.stdout.write('\n'.join(lines)) + + if desired_class_names: + missing_class_names = ', '.join( + sorted(desired_class_names - processed_class_names)) + if missing_class_names: + sys.stderr.write('Class(es) not found in %s: %s\n' % + (filename, missing_class_names)) + elif not processed_class_names: + sys.stderr.write('No class found in %s\n' % filename) def main(argv=sys.argv): if len(argv) < 2: - sys.stdout.write(__doc__) + sys.stderr.write('Google Mock Class Generator v%s\n\n' % + '.'.join(map(str, _VERSION))) + sys.stderr.write(__doc__) return 1 global _INDENT @@ -138,9 +147,9 @@ def main(argv=sys.argv): sys.stderr.write('Unable to use indent of %s\n' % os.environ.get('INDENT')) filename = argv[1] - class_name = None + desired_class_names = None # None means all classes in the source file. if len(argv) >= 3: - class_name = set(argv[2:]) + desired_class_names = set(argv[2:]) source = utils.ReadFile(filename) if source is None: return 1 @@ -154,7 +163,7 @@ def main(argv=sys.argv): # An error message was already printed since we couldn't parse. pass else: - _GenerateMock(filename, source, entire_ast, class_name) + _GenerateMocks(filename, source, entire_ast, desired_class_names) if __name__ == '__main__': -- cgit v1.2.3 From d955e83bee3919b871616223b777bab2f04942d9 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 7 May 2009 21:20:57 +0000 Subject: Makes the mock generator work with python2.3.5, which comes with Mac OS X Tiger. --- scripts/generator/cpp/gmock_class.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'scripts/generator/cpp/gmock_class.py') diff --git a/scripts/generator/cpp/gmock_class.py b/scripts/generator/cpp/gmock_class.py index ba11f9e6..29204247 100755 --- a/scripts/generator/cpp/gmock_class.py +++ b/scripts/generator/cpp/gmock_class.py @@ -31,6 +31,7 @@ __author__ = 'nnorwitz@google.com (Neal Norwitz)' import os import re +import sets import sys from cpp import ast @@ -82,7 +83,7 @@ def _GenerateMethods(output_lines, source, class_node): def _GenerateMocks(filename, source, ast_list, desired_class_names): - processed_class_names = set() + processed_class_names = sets.Set() lines = [] for node in ast_list: if (isinstance(node, ast.Class) and node.body and @@ -122,11 +123,11 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names): sys.stdout.write('\n'.join(lines)) if desired_class_names: - missing_class_names = ', '.join( - sorted(desired_class_names - processed_class_names)) - if missing_class_names: + missing_class_name_list = list(desired_class_names - processed_class_names) + if missing_class_name_list: + missing_class_name_list.sort() sys.stderr.write('Class(es) not found in %s: %s\n' % - (filename, missing_class_names)) + (filename, ', '.join(missing_class_name_list))) elif not processed_class_names: sys.stderr.write('No class found in %s\n' % filename) @@ -149,7 +150,7 @@ def main(argv=sys.argv): filename = argv[1] desired_class_names = None # None means all classes in the source file. if len(argv) >= 3: - desired_class_names = set(argv[2:]) + desired_class_names = sets.Set(argv[2:]) source = utils.ReadFile(filename) if source is None: return 1 -- cgit v1.2.3 From c2ad46a5df4414fc2b804c53525f4578f01a3dfe Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 2 Jun 2009 20:41:21 +0000 Subject: Improves gmock generator and adds a test for it (by Neal Norwitz). --- scripts/generator/cpp/gmock_class.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'scripts/generator/cpp/gmock_class.py') diff --git a/scripts/generator/cpp/gmock_class.py b/scripts/generator/cpp/gmock_class.py index 29204247..3ad0bcdd 100755 --- a/scripts/generator/cpp/gmock_class.py +++ b/scripts/generator/cpp/gmock_class.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2008 Google Inc. +# Copyright 2008 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -73,7 +73,13 @@ def _GenerateMethods(output_lines, source, class_node): # of the first parameter to the end of the last parameter. start = node.parameters[0].start end = node.parameters[-1].end - args = re.sub(' +', ' ', source[start:end].replace('\n', '')) + # 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 prototype. indent = ' ' * _INDENT @@ -120,8 +126,6 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names): lines.append('} // namespace %s' % class_node.namespace[i]) lines.append('') # Add an extra newline. - sys.stdout.write('\n'.join(lines)) - if desired_class_names: missing_class_name_list = list(desired_class_names - processed_class_names) if missing_class_name_list: @@ -129,7 +133,9 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names): sys.stderr.write('Class(es) not found in %s: %s\n' % (filename, ', '.join(missing_class_name_list))) elif not processed_class_names: - sys.stderr.write('No class found in %s\n' % filename) + sys.stderr.write('No class found in %s\n' % filename) + + return lines def main(argv=sys.argv): @@ -164,7 +170,8 @@ def main(argv=sys.argv): # An error message was already printed since we couldn't parse. pass else: - _GenerateMocks(filename, source, entire_ast, desired_class_names) + lines = _GenerateMocks(filename, source, entire_ast, desired_class_names) + sys.stdout.write('\n'.join(lines)) if __name__ == '__main__': -- cgit v1.2.3 From 4b16e8ed2785136d863fb52961539c27c9716497 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 5 Oct 2010 06:11:56 +0000 Subject: Enables gmock_gen to handle return types that are templates (based on Pride Haveit's patch); also fixes deprecation warnings when using gmock_gen with python 2.6 (by Aaron Jacobs). --- scripts/generator/cpp/gmock_class.py | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'scripts/generator/cpp/gmock_class.py') diff --git a/scripts/generator/cpp/gmock_class.py b/scripts/generator/cpp/gmock_class.py index 3ad0bcdd..645c295b 100755 --- a/scripts/generator/cpp/gmock_class.py +++ b/scripts/generator/cpp/gmock_class.py @@ -31,12 +31,18 @@ __author__ = 'nnorwitz@google.com (Neal Norwitz)' import os import re -import sets import sys from cpp import ast from cpp import utils +# Preserve compatibility with Python 2.3. +try: + _dummy = set +except NameError: + import sets + set = sets.Set + _VERSION = (1, 0, 1) # The version of this script. # How many spaces to indent. Can set me with the INDENT environment variable. _INDENT = 2 @@ -45,6 +51,7 @@ _INDENT = 2 def _GenerateMethods(output_lines, source, class_node): function_type = ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL ctor_or_dtor = ast.FUNCTION_CTOR | ast.FUNCTION_DTOR + indent = ' ' * _INDENT for node in class_node.body: # We only care about virtual functions. @@ -62,11 +69,20 @@ def _GenerateMethods(output_lines, source, class_node): if node.return_type.modifiers: modifiers = ' '.join(node.return_type.modifiers) + ' ' return_type = modifiers + node.return_type.name + template_args = [arg.name for arg in node.return_type.templated_types] + if template_args: + return_type += '<' + ', '.join(template_args) + '>' + if len(template_args) > 1: + for line in [ + '// The following line won\'t really compile, as the return', + '// type has multiple template arguments. To fix it, use a', + '// typedef for the return type.']: + output_lines.append(indent + line) if node.return_type.pointer: return_type += '*' if node.return_type.reference: return_type += '&' - prefix = 'MOCK_%sMETHOD%d' % (const, len(node.parameters)) + mock_method_macro = 'MOCK_%sMETHOD%d' % (const, len(node.parameters)) args = '' if node.parameters: # Get the full text of the parameters from the start @@ -81,15 +97,13 @@ def _GenerateMethods(output_lines, source, class_node): # intervening whitespace, e.g.: int\nBar args = re.sub(' +', ' ', args_strings.replace('\n', ' ')) - # Create the prototype. - indent = ' ' * _INDENT - line = ('%s%s(%s,\n%s%s(%s));' % - (indent, prefix, node.name, indent*3, return_type, args)) - output_lines.append(line) + # Create the mock method definition. + output_lines.extend(['%s%s(%s,' % (indent, mock_method_macro, node.name), + '%s%s(%s));' % (indent*3, return_type, args)]) def _GenerateMocks(filename, source, ast_list, desired_class_names): - processed_class_names = sets.Set() + processed_class_names = set() lines = [] for node in ast_list: if (isinstance(node, ast.Class) and node.body and @@ -156,7 +170,7 @@ def main(argv=sys.argv): filename = argv[1] desired_class_names = None # None means all classes in the source file. if len(argv) >= 3: - desired_class_names = sets.Set(argv[2:]) + desired_class_names = set(argv[2:]) source = utils.ReadFile(filename) if source is None: return 1 -- cgit v1.2.3 From f4eeaedb39b6935f6236fe55a52bd9af0b8390ef Mon Sep 17 00:00:00 2001 From: vladlosev Date: Fri, 20 May 2011 21:44:14 +0000 Subject: Fixes issue 139 and issue 140. --- scripts/generator/cpp/gmock_class.py | 40 +++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'scripts/generator/cpp/gmock_class.py') 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), -- cgit v1.2.3 From 45fef502fac471efa4bf25b3d4104943463912eb Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 6 Sep 2013 22:52:14 +0000 Subject: makes googlemock generator handle some class templates; pulls in gtest r662 --- scripts/generator/cpp/gmock_class.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'scripts/generator/cpp/gmock_class.py') diff --git a/scripts/generator/cpp/gmock_class.py b/scripts/generator/cpp/gmock_class.py index 427d206a..3c8a877d 100755 --- a/scripts/generator/cpp/gmock_class.py +++ b/scripts/generator/cpp/gmock_class.py @@ -88,7 +88,11 @@ def _GenerateMethods(output_lines, source, class_node): 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) + tmpl = '' + if class_node.templated_types: + tmpl = '_T' + mock_method_macro = 'MOCK_%sMETHOD%d%s' % (const, num_parameters, tmpl) + args = '' if node.parameters: # Due to the parser limitations, it is impossible to keep comments @@ -126,6 +130,7 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names): # desired_class_names being None means that all classes are selected. (not desired_class_names or node.name in desired_class_names)): class_name = node.name + parent_name = class_name processed_class_names.add(class_name) class_node = node # Add namespace before the class. @@ -133,8 +138,21 @@ def _GenerateMocks(filename, source, ast_list, desired_class_names): lines.extend(['namespace %s {' % n for n in class_node.namespace]) # } lines.append('') + # Add template args for templated classes. + if class_node.templated_types: + # TODO(paulchang): The AST doesn't preserve template argument order, + # so we have to make up names here. + # TODO(paulchang): Handle non-type template arguments (e.g. + # template). + template_arg_count = len(class_node.templated_types.keys()) + template_args = ['T%d' % n for n in range(template_arg_count)] + template_decls = ['typename ' + arg for arg in template_args] + lines.append('template <' + ', '.join(template_decls) + '>') + parent_name += '<' + ', '.join(template_args) + '>' + # Add the class prolog. - lines.append('class Mock%s : public %s {' % (class_name, class_name)) # } + lines.append('class Mock%s : public %s {' # } + % (class_name, parent_name)) lines.append('%spublic:' % (' ' * (_INDENT // 2))) # Add all the methods. -- cgit v1.2.3 From c26f969579d62444ae7d422b37e0037ceca97a7a Mon Sep 17 00:00:00 2001 From: kosak Date: Wed, 12 Mar 2014 23:27:35 +0000 Subject: Make the gmock generator work with the 'override' keyword. Also pull in gtest 680. --- scripts/generator/cpp/gmock_class.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts/generator/cpp/gmock_class.py') diff --git a/scripts/generator/cpp/gmock_class.py b/scripts/generator/cpp/gmock_class.py index 3c8a877d..443accf0 100755 --- a/scripts/generator/cpp/gmock_class.py +++ b/scripts/generator/cpp/gmock_class.py @@ -49,7 +49,8 @@ _INDENT = 2 def _GenerateMethods(output_lines, source, class_node): - function_type = ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL + function_type = (ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL | + ast.FUNCTION_OVERRIDE) ctor_or_dtor = ast.FUNCTION_CTOR | ast.FUNCTION_DTOR indent = ' ' * _INDENT -- cgit v1.2.3 From 055b6b17d2354691af4b20f035f36c134fba2ac9 Mon Sep 17 00:00:00 2001 From: kosak Date: Mon, 17 Nov 2014 02:46:37 +0000 Subject: Prevent gmock_gen from returning exit code zero on a failure to parse. --- scripts/generator/cpp/gmock_class.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts/generator/cpp/gmock_class.py') diff --git a/scripts/generator/cpp/gmock_class.py b/scripts/generator/cpp/gmock_class.py index 443accf0..f9966cbb 100755 --- a/scripts/generator/cpp/gmock_class.py +++ b/scripts/generator/cpp/gmock_class.py @@ -217,7 +217,7 @@ def main(argv=sys.argv): return except: # An error message was already printed since we couldn't parse. - pass + sys.exit(1) else: lines = _GenerateMocks(filename, source, entire_ast, desired_class_names) sys.stdout.write('\n'.join(lines)) -- cgit v1.2.3