1f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#!/usr/bin/env python 2f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# 3f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# Copyright 2008 Google Inc. All Rights Reserved. 4f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# 5f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# Licensed under the Apache License, Version 2.0 (the "License"); 6f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# you may not use this file except in compliance with the License. 7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# You may obtain a copy of the License at 8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# 9f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# http://www.apache.org/licenses/LICENSE-2.0 10f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# 11f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# Unless required by applicable law or agreed to in writing, software 12f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# distributed under the License is distributed on an "AS IS" BASIS, 13f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# See the License for the specific language governing permissions and 15f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# limitations under the License. 16f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 17f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch"""Generate Google Mock classes from base classes. 18f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 19f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochThis program will read in a C++ source file and output the Google Mock 20f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclasses for the specified classes. If no class is specified, all 21f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclasses in the source file are emitted. 22f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 23f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochUsage: 24f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch gmock_class.py header-file.h [ClassName]... 25f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 26f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochOutput is sent to stdout. 27f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch""" 28f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 29f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch__author__ = 'nnorwitz@google.com (Neal Norwitz)' 30f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 31f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 32f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochimport os 33f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochimport re 34f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochimport sys 35f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochfrom cpp import ast 37f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochfrom cpp import utils 38f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# Preserve compatibility with Python 2.3. 40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtry: 41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch _dummy = set 42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochexcept NameError: 43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch import sets 44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch set = sets.Set 45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch_VERSION = (1, 0, 1) # The version of this script. 47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# How many spaces to indent. Can set me with the INDENT environment variable. 48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch_INDENT = 2 49f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 50f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 51f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochdef _GenerateMethods(output_lines, source, class_node): 52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch function_type = (ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL | 53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast.FUNCTION_OVERRIDE) 54f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ctor_or_dtor = ast.FUNCTION_CTOR | ast.FUNCTION_DTOR 55f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch indent = ' ' * _INDENT 56f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 57f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for node in class_node.body: 58f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # We only care about virtual functions. 59f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (isinstance(node, ast.Function) and 60f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node.modifiers & function_type and 61f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch not node.modifiers & ctor_or_dtor): 62f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # Pick out all the elements we need from the original function. 63f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const = '' 64f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if node.modifiers & ast.FUNCTION_CONST: 65f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const = 'CONST_' 66f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return_type = 'void' 67f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if node.return_type: 68f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # Add modifiers like 'const'. 69f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch modifiers = '' 70f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if node.return_type.modifiers: 71f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch modifiers = ' '.join(node.return_type.modifiers) + ' ' 72f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return_type = modifiers + node.return_type.name 73f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch template_args = [arg.name for arg in node.return_type.templated_types] 74f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if template_args: 75f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return_type += '<' + ', '.join(template_args) + '>' 76f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if len(template_args) > 1: 77f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for line in [ 78f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch '// The following line won\'t really compile, as the return', 79f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch '// type has multiple template arguments. To fix it, use a', 80f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch '// typedef for the return type.']: 81f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch output_lines.append(indent + line) 82f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if node.return_type.pointer: 83f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return_type += '*' 84f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if node.return_type.reference: 85f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return_type += '&' 86f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch num_parameters = len(node.parameters) 87f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if len(node.parameters) == 1: 88f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch first_param = node.parameters[0] 89f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if source[first_param.start:first_param.end].strip() == 'void': 90f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # We must treat T(void) as a function with no parameters. 91f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch num_parameters = 0 92f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch tmpl = '' 93f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if class_node.templated_types: 94f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch tmpl = '_T' 95f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch mock_method_macro = 'MOCK_%sMETHOD%d%s' % (const, num_parameters, tmpl) 96f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 97f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch args = '' 98f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if node.parameters: 99f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # Due to the parser limitations, it is impossible to keep comments 100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # while stripping the default parameters. When defaults are 101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # present, we choose to strip them and comments (and produce 102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # compilable code). 103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # TODO(nnorwitz@google.com): Investigate whether it is possible to 104f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # preserve parameter name when reconstructing parameter text from 105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # the AST. 106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if len([param for param in node.parameters if param.default]) > 0: 107f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch args = ', '.join(param.type.name for param in node.parameters) 108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch else: 109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # Get the full text of the parameters from the start 110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # of the first parameter to the end of the last parameter. 111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch start = node.parameters[0].start 112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch end = node.parameters[-1].end 113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # Remove // comments. 114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch args_strings = re.sub(r'//.*', '', source[start:end]) 115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # Condense multiple spaces and eliminate newlines putting the 116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # parameters together on a single line. Ensure there is a 117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # space in an argument which is split by a newline without 118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # intervening whitespace, e.g.: int\nBar 119f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch args = re.sub(' +', ' ', args_strings.replace('\n', ' ')) 120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 121f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # Create the mock method definition. 122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch output_lines.extend(['%s%s(%s,' % (indent, mock_method_macro, node.name), 123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch '%s%s(%s));' % (indent*3, return_type, args)]) 124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 125f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochdef _GenerateMocks(filename, source, ast_list, desired_class_names): 127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch processed_class_names = set() 128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch lines = [] 129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for node in ast_list: 130f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (isinstance(node, ast.Class) and node.body and 131f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # desired_class_names being None means that all classes are selected. 132f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (not desired_class_names or node.name in desired_class_names)): 133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch class_name = node.name 134f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch parent_name = class_name 135f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch processed_class_names.add(class_name) 136f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch class_node = node 137f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # Add namespace before the class. 138f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if class_node.namespace: 139f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch lines.extend(['namespace %s {' % n for n in class_node.namespace]) # } 140f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch lines.append('') 141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # Add template args for templated classes. 143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if class_node.templated_types: 144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # TODO(paulchang): The AST doesn't preserve template argument order, 145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # so we have to make up names here. 146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # TODO(paulchang): Handle non-type template arguments (e.g. 147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # template<typename T, int N>). 148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch template_arg_count = len(class_node.templated_types.keys()) 149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch template_args = ['T%d' % n for n in range(template_arg_count)] 150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch template_decls = ['typename ' + arg for arg in template_args] 151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch lines.append('template <' + ', '.join(template_decls) + '>') 152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch parent_name += '<' + ', '.join(template_args) + '>' 153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # Add the class prolog. 155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch lines.append('class Mock%s : public %s {' # } 156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch % (class_name, parent_name)) 157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch lines.append('%spublic:' % (' ' * (_INDENT // 2))) 158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # Add all the methods. 160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch _GenerateMethods(lines, source, class_node) 161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # Close the class. 163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if lines: 164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # If there are no virtual methods, no need for a public label. 165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if len(lines) == 2: 166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch del lines[-1] 167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # Only close the class if there really is a class. 169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch lines.append('};') 170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch lines.append('') # Add an extra newline. 171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # Close the namespace. 173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if class_node.namespace: 174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for i in range(len(class_node.namespace)-1, -1, -1): 175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch lines.append('} // namespace %s' % class_node.namespace[i]) 176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch lines.append('') # Add an extra newline. 177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if desired_class_names: 179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch missing_class_name_list = list(desired_class_names - processed_class_names) 180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if missing_class_name_list: 181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch missing_class_name_list.sort() 182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch sys.stderr.write('Class(es) not found in %s: %s\n' % 183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (filename, ', '.join(missing_class_name_list))) 184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch elif not processed_class_names: 185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch sys.stderr.write('No class found in %s\n' % filename) 186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 187f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return lines 188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochdef main(argv=sys.argv): 191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if len(argv) < 2: 192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch sys.stderr.write('Google Mock Class Generator v%s\n\n' % 193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch '.'.join(map(str, _VERSION))) 194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch sys.stderr.write(__doc__) 195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return 1 196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch global _INDENT 198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch try: 199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch _INDENT = int(os.environ['INDENT']) 200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch except KeyError: 201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch pass 202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch except: 203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch sys.stderr.write('Unable to use indent of %s\n' % os.environ.get('INDENT')) 204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch filename = argv[1] 206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch desired_class_names = None # None means all classes in the source file. 207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if len(argv) >= 3: 208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch desired_class_names = set(argv[2:]) 209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch source = utils.ReadFile(filename) 210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if source is None: 211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return 1 212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch builder = ast.BuilderFromSource(source, filename) 214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch try: 215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch entire_ast = filter(None, builder.Generate()) 216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch except KeyboardInterrupt: 217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return 218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch except: 219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch # An error message was already printed since we couldn't parse. 220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch sys.exit(1) 221f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch else: 222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch lines = _GenerateMocks(filename, source, entire_ast, desired_class_names) 223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch sys.stdout.write('\n'.join(lines)) 224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 225f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochif __name__ == '__main__': 227f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch main(sys.argv) 228