@@ -58,10 +58,11 @@ class mock_method:
5858 'operator~' : 'complement_operator'
5959 }
6060
61- def __init__ (self , result_type , name , is_const , args_size , args , args_prefix = 'arg' ):
61+ def __init__ (self , result_type , name , is_const , is_template , args_size , args , args_prefix = 'arg' ):
6262 self .result_type = result_type
6363 self .name = name
6464 self .is_const = is_const
65+ self .is_template = is_template
6566 self .args_size = args_size
6667 self .args = args
6768 self .args_prefix = args_prefix
@@ -110,9 +111,10 @@ def to_string(self, gap = ' '):
110111
111112 mock .append (gap )
112113 mock .append (
113- "MOCK_%(const)sMETHOD%(nr)s(%(name)s, %(result_type)s(%(args)s));" % {
114+ "MOCK_%(const)sMETHOD%(nr)s%(template)s (%(name)s, %(result_type)s(%(args)s));" % {
114115 'const' : self .is_const and 'CONST_' or '' ,
115116 'nr' : self .args_size ,
117+ 'template' : self .is_template and '_T' or '' ,
116118 'name' : name ,
117119 'result_type' : self .result_type ,
118120 'args' : self .args
@@ -121,6 +123,9 @@ def to_string(self, gap = ' '):
121123 return '' .join (mock )
122124
123125class mock_generator :
126+ def __is_template_class (self , decl ):
127+ return '<' in decl
128+
124129 def __is_const_function (self , tokens ):
125130 for token in reversed (tokens ):
126131 if token == 'const' :
@@ -151,6 +156,36 @@ def __get_result_type(self, tokens, name):
151156 result_type .append (' ' )
152157 return '' .join (result_type )
153158
159+ def __pretty_template (self , decl ):
160+ first = False
161+ typename = []
162+ typenames = []
163+ for token in decl .split ("::" )[- 1 ]:
164+ if token == '<' :
165+ first = True
166+ elif token == ',' :
167+ typenames .append ('' .join (typename ))
168+ typename = []
169+ elif token == '>' :
170+ typenames .append ('' .join (typename ))
171+ typename = []
172+ elif token == ' ' :
173+ continue
174+ elif first :
175+ typename .append (token )
176+
177+ result = []
178+ if len (typenames ) > 0 :
179+ result .append ("template<" )
180+ for i , t in enumerate (typenames ):
181+ i != 0 and result .append (", " )
182+ result .append ("typename " )
183+ result .append (t )
184+ result .append (">" )
185+ result .append ("\n " )
186+
187+ return '' .join (result )
188+
154189 def __pretty_mock_methods (self , mock_methods ):
155190 result = []
156191 for i , mock_method in enumerate (mock_methods ):
@@ -173,31 +208,44 @@ def __pretty_namespaces_end(self, decl):
173208 result .append ("} // namespace " + namespace )
174209 return '' .join (result )
175210
176- def __get_mock_methods (self , node , mock_methods , class_decl = "" ):
211+ def __get_interface (self , decl ):
212+ result = []
213+ ignore = False
214+ for token in decl .split ("::" )[- 1 ]:
215+ if token == '<' :
216+ ignore = True
217+ if not ignore :
218+ result .append (token )
219+ if token == '>' :
220+ ignore = False
221+ return '' .join (result )
222+
223+ def __get_mock_methods (self , node , mock_methods , decl = "" ):
177224 name = str (node .displayname , self .encode )
178225 if node .kind == CursorKind .CXX_METHOD :
179- tokens = [str (token .spelling , self .encode ) for token in node .get_tokens ()]
180226 spelling = str (node .spelling , self .encode )
227+ tokens = [str (token .spelling , self .encode ) for token in node .get_tokens ()]
181228 file = str (node .location .file .name , self .encode )
182229 if self .__is_pure_virtual_function (tokens ):
183- mock_methods .setdefault (class_decl , [file ]).append (
230+ mock_methods .setdefault (decl , [file ]).append (
184231 mock_method (
185232 self .__get_result_type (tokens , spelling ),
186233 spelling ,
187234 self .__is_const_function (tokens ),
235+ self .__is_template_class (decl ),
188236 len (list (node .get_arguments ())),
189237 name [len (node .spelling ) + 1 : - 1 ]
190238 )
191239 )
192- elif node .kind in [CursorKind .STRUCT_DECL , CursorKind .CLASS_DECL , CursorKind .NAMESPACE ]:
193- class_decl = class_decl == "" and name or class_decl + (name == "" and "" or "::" ) + name
194- if class_decl .startswith (self .decl ):
195- [self .__get_mock_methods (c , mock_methods , class_decl ) for c in node .get_children ()]
240+ elif node .kind in [CursorKind .CLASS_TEMPLATE , CursorKind . STRUCT_DECL , CursorKind .CLASS_DECL , CursorKind .NAMESPACE ]:
241+ decl = decl == "" and name or decl + (name == "" and "" or "::" ) + name
242+ if decl .startswith (self .decl ):
243+ [self .__get_mock_methods (c , mock_methods , decl ) for c in node .get_children ()]
196244 else :
197- [self .__get_mock_methods (c , mock_methods , class_decl ) for c in node .get_children ()]
245+ [self .__get_mock_methods (c , mock_methods , decl ) for c in node .get_children ()]
198246
199247 def __generate_file (self , decl , mock_methods , file_type , file_template_type ):
200- interface = decl . split ( "::" )[ - 1 ]
248+ interface = self . __get_interface ( decl )
201249 mock_file = {
202250 'hpp' : self .mock_file_hpp % { 'interface' : interface },
203251 'cpp' : self .mock_file_cpp % { 'interface' : interface },
@@ -214,6 +262,8 @@ def __generate_file(self, decl, mock_methods, file_type, file_template_type):
214262 'file' : os .path .basename (mock_methods [0 ]),
215263 'namespaces_begin' : self .__pretty_namespaces_begin (decl ),
216264 'interface' : interface ,
265+ 'template_interface' : decl .split ("::" )[- 1 ],
266+ 'template' : self .__pretty_template (decl ),
217267 'mock_methods' : self .__pretty_mock_methods (mock_methods [1 :]),
218268 'namespaces_end' : self .__pretty_namespaces_end (decl )
219269 })
0 commit comments