| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2008, Google Inc. | 3 # Copyright 2008, Google Inc. |
| 4 # All rights reserved. | 4 # All rights reserved. |
| 5 # | 5 # |
| 6 # Redistribution and use in source and binary forms, with or without | 6 # Redistribution and use in source and binary forms, with or without |
| 7 # modification, are permitted provided that the following conditions are | 7 # modification, are permitted provided that the following conditions are |
| 8 # met: | 8 # met: |
| 9 # | 9 # |
| 10 # * Redistributions of source code must retain the above copyright | 10 # * Redistributions of source code must retain the above copyright |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 *something*. Please tell it *what* to return. Perhaps you can use | 179 *something*. Please tell it *what* to return. Perhaps you can use |
| 180 the pattern DoAll(some_action, Return(some_value))?""" | 180 the pattern DoAll(some_action, Return(some_value))?""" |
| 181 return _GenericDiagnoser('NRS', 'Need to Return Something', | 181 return _GenericDiagnoser('NRS', 'Need to Return Something', |
| 182 regex, diagnosis, msg) | 182 regex, diagnosis, msg) |
| 183 | 183 |
| 184 | 184 |
| 185 def _NeedToReturnNothingDiagnoser(msg): | 185 def _NeedToReturnNothingDiagnoser(msg): |
| 186 """Diagnoses the NRN disease, given the error messages by gcc.""" | 186 """Diagnoses the NRN disease, given the error messages by gcc.""" |
| 187 | 187 |
| 188 regex = (_FILE_LINE_RE + r'instantiated from here\n' | 188 regex = (_FILE_LINE_RE + r'instantiated from here\n' |
| 189 r'.*gmock-actions\.h.*error: return-statement with a value, ' | 189 r'.*gmock-actions\.h.*error: instantiation of ' |
| 190 r'in function returning \'void\'') | 190 r'\'testing::internal::ReturnAction<R>::Impl<F>::value_\' ' |
| 191 r'as type \'void\'') |
| 191 diagnosis = """ | 192 diagnosis = """ |
| 192 You are using an action that returns *something*, but it needs to return | 193 You are using an action that returns *something*, but it needs to return |
| 193 void. Please use a void-returning action instead. | 194 void. Please use a void-returning action instead. |
| 194 | 195 |
| 195 All actions but the last in DoAll(...) must return void. Perhaps you need | 196 All actions but the last in DoAll(...) must return void. Perhaps you need |
| 196 to re-arrange the order of actions in a DoAll(), if you are using one?""" | 197 to re-arrange the order of actions in a DoAll(), if you are using one?""" |
| 197 return _GenericDiagnoser('NRN', 'Need to Return Nothing', | 198 return _GenericDiagnoser('NRN', 'Need to Return Nothing', |
| 198 regex, diagnosis, msg) | 199 regex, diagnosis, msg) |
| 199 | 200 |
| 200 | 201 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 ?""" | 330 ?""" |
| 330 for m in _FindAllMatches(regex, msg): | 331 for m in _FindAllMatches(regex, msg): |
| 331 symbol = m.groupdict()['symbol'] | 332 symbol = m.groupdict()['symbol'] |
| 332 if symbol in _COMMON_GMOCK_SYMBOLS: | 333 if symbol in _COMMON_GMOCK_SYMBOLS: |
| 333 yield ('NUS', 'Need to Use Symbol', diagnosis % m.groupdict()) | 334 yield ('NUS', 'Need to Use Symbol', diagnosis % m.groupdict()) |
| 334 | 335 |
| 335 | 336 |
| 336 def _NeedToUseReturnNullDiagnoser(msg): | 337 def _NeedToUseReturnNullDiagnoser(msg): |
| 337 """Diagnoses the NRNULL disease, given the error messages by gcc.""" | 338 """Diagnoses the NRNULL disease, given the error messages by gcc.""" |
| 338 | 339 |
| 339 regex = (_FILE_LINE_RE + r'instantiated from here\n' | 340 regex = ('instantiated from \'testing::internal::ReturnAction<R>' |
| 340 r'.*gmock-actions\.h.*error: invalid conversion from ' | 341 '::operator testing::Action<Func>\(\) const.*\n' + |
| 341 r'\'long int\' to \'(?P<type>.+\*)') | 342 _FILE_LINE_RE + r'instantiated from here\n' |
| 343 r'.*error: no matching function for call to \'implicit_cast\(' |
| 344 r'long int&\)') |
| 342 diagnosis = """ | 345 diagnosis = """ |
| 343 You are probably calling Return(NULL) and the compiler isn't sure how to turn | 346 You are probably calling Return(NULL) and the compiler isn't sure how to turn |
| 344 NULL into a %(type)s*. Use ReturnNull() instead. | 347 NULL into the right type. Use ReturnNull() instead. |
| 345 Note: the line number may be off; please fix all instances of Return(NULL).""" | 348 Note: the line number may be off; please fix all instances of Return(NULL).""" |
| 346 return _GenericDiagnoser('NRNULL', 'Need to use ReturnNull', | 349 return _GenericDiagnoser('NRNULL', 'Need to use ReturnNull', |
| 347 regex, diagnosis, msg) | 350 regex, diagnosis, msg) |
| 348 | 351 |
| 349 | 352 |
| 350 _TTB_DIAGNOSIS = """ | 353 _TTB_DIAGNOSIS = """ |
| 351 In a mock class template, types or typedefs defined in the base class | 354 In a mock class template, types or typedefs defined in the base class |
| 352 template are *not* automatically visible. This is how C++ works. Before | 355 template are *not* automatically visible. This is how C++ works. Before |
| 353 you can use a type or typedef named %(type)s defined in base class Base<T>, you | 356 you can use a type or typedef named %(type)s defined in base class Base<T>, you |
| 354 need to make it visible. One way to do it is: | 357 need to make it visible. One way to do it is: |
| 355 | 358 |
| 356 typedef typename Base<T>::%(type)s %(type)s;""" | 359 typedef typename Base<T>::%(type)s %(type)s;""" |
| 357 | 360 |
| 358 | 361 |
| 359 def _TypeInTemplatedBaseDiagnoser1(msg): | 362 def _TypeInTemplatedBaseDiagnoser1(msg): |
| 360 """Diagnoses the TTB disease, given the error messages by gcc. | 363 """Diagnoses the TTB disease, given the error messages by gcc. |
| 361 | 364 |
| 362 This version works when the type is used as the mock function's return | 365 This version works when the type is used as the mock function's return |
| 363 type. | 366 type. |
| 364 """ | 367 """ |
| 365 | 368 |
| 366 regex = (r'In member function \'int .*\n' + _FILE_LINE_RE + | 369 gcc_4_3_1_regex = ( |
| 367 r'error: a function call cannot appear in a constant-expression') | 370 r'In member function \'int .*\n' + _FILE_LINE_RE + |
| 371 r'error: a function call cannot appear in a constant-expression') |
| 372 gcc_4_4_0_regex = ( |
| 373 r'error: a function call cannot appear in a constant-expression' |
| 374 + _FILE_LINE_RE + r'error: template argument 1 is invalid\n') |
| 368 diagnosis = _TTB_DIAGNOSIS % {'type': 'Foo'} | 375 diagnosis = _TTB_DIAGNOSIS % {'type': 'Foo'} |
| 369 return _GenericDiagnoser('TTB', 'Type in Template Base', | 376 return (list(_GenericDiagnoser('TTB', 'Type in Template Base', |
| 370 regex, diagnosis, msg) | 377 gcc_4_3_1_regex, diagnosis, msg)) + |
| 378 list(_GenericDiagnoser('TTB', 'Type in Template Base', |
| 379 gcc_4_4_0_regex, diagnosis, msg))) |
| 371 | 380 |
| 372 | 381 |
| 373 def _TypeInTemplatedBaseDiagnoser2(msg): | 382 def _TypeInTemplatedBaseDiagnoser2(msg): |
| 374 """Diagnoses the TTB disease, given the error messages by gcc. | 383 """Diagnoses the TTB disease, given the error messages by gcc. |
| 375 | 384 |
| 376 This version works when the type is used as the mock function's sole | 385 This version works when the type is used as the mock function's sole |
| 377 parameter type. | 386 parameter type. |
| 378 """ | 387 """ |
| 379 | 388 |
| 380 regex = (r'In member function \'int .*\n' | 389 regex = (_FILE_LINE_RE + |
| 381 + _FILE_LINE_RE + | |
| 382 r'error: \'(?P<type>.+)\' was not declared in this scope\n' | 390 r'error: \'(?P<type>.+)\' was not declared in this scope\n' |
| 383 r'.*error: template argument 1 is invalid\n') | 391 r'.*error: template argument 1 is invalid\n') |
| 384 return _GenericDiagnoser('TTB', 'Type in Template Base', | 392 return _GenericDiagnoser('TTB', 'Type in Template Base', |
| 385 regex, _TTB_DIAGNOSIS, msg) | 393 regex, _TTB_DIAGNOSIS, msg) |
| 386 | 394 |
| 387 | 395 |
| 388 def _TypeInTemplatedBaseDiagnoser3(msg): | 396 def _TypeInTemplatedBaseDiagnoser3(msg): |
| 389 """Diagnoses the TTB disease, given the error messages by gcc. | 397 """Diagnoses the TTB disease, given the error messages by gcc. |
| 390 | 398 |
| 391 This version works when the type is used as a parameter of a mock | 399 This version works when the type is used as a parameter of a mock |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 _TypeInTemplatedBaseDiagnoser2, | 456 _TypeInTemplatedBaseDiagnoser2, |
| 449 _TypeInTemplatedBaseDiagnoser3, | 457 _TypeInTemplatedBaseDiagnoser3, |
| 450 _WrongMockMethodMacroDiagnoser, | 458 _WrongMockMethodMacroDiagnoser, |
| 451 _WrongParenPositionDiagnoser, | 459 _WrongParenPositionDiagnoser, |
| 452 ] | 460 ] |
| 453 | 461 |
| 454 | 462 |
| 455 def Diagnose(msg): | 463 def Diagnose(msg): |
| 456 """Generates all possible diagnoses given the gcc error message.""" | 464 """Generates all possible diagnoses given the gcc error message.""" |
| 457 | 465 |
| 466 diagnoses = [] |
| 458 for diagnoser in _DIAGNOSERS: | 467 for diagnoser in _DIAGNOSERS: |
| 459 for diagnosis in diagnoser(msg): | 468 for diag in diagnoser(msg): |
| 460 yield '[%s - %s]\n%s' % diagnosis | 469 diagnosis = '[%s - %s]\n%s' % diag |
| 470 if not diagnosis in diagnoses: |
| 471 diagnoses.append(diagnosis) |
| 472 return diagnoses |
| 461 | 473 |
| 462 | 474 |
| 463 def main(): | 475 def main(): |
| 464 print ('Google Mock Doctor v%s - ' | 476 print ('Google Mock Doctor v%s - ' |
| 465 'diagnoses problems in code using Google Mock.' % _VERSION) | 477 'diagnoses problems in code using Google Mock.' % _VERSION) |
| 466 | 478 |
| 467 if sys.stdin.isatty(): | 479 if sys.stdin.isatty(): |
| 468 print ('Please copy and paste the compiler errors here. Press c-D when ' | 480 print ('Please copy and paste the compiler errors here. Press c-D when ' |
| 469 'you are done:') | 481 'you are done:') |
| 470 else: | 482 else: |
| 471 print 'Waiting for compiler errors on stdin . . .' | 483 print 'Waiting for compiler errors on stdin . . .' |
| 472 | 484 |
| 473 msg = sys.stdin.read().strip() | 485 msg = sys.stdin.read().strip() |
| 474 diagnoses = list(Diagnose(msg)) | 486 diagnoses = Diagnose(msg) |
| 475 count = len(diagnoses) | 487 count = len(diagnoses) |
| 476 if not count: | 488 if not count: |
| 477 print '\nGcc complained:' | 489 print '\nGcc complained:' |
| 478 print '8<------------------------------------------------------------' | 490 print '8<------------------------------------------------------------' |
| 479 print msg | 491 print msg |
| 480 print '------------------------------------------------------------>8' | 492 print '------------------------------------------------------------>8' |
| 481 print """ | 493 print """ |
| 482 Uh-oh, I'm not smart enough to figure out what the problem is. :-( | 494 Uh-oh, I'm not smart enough to figure out what the problem is. :-( |
| 483 However... | 495 However... |
| 484 If you send your source code and gcc's error messages to | 496 If you send your source code and gcc's error messages to |
| (...skipping 13 matching lines...) Expand all Loading... |
| 498 print '\n#%s:' % (i,) | 510 print '\n#%s:' % (i,) |
| 499 print d | 511 print d |
| 500 print """ | 512 print """ |
| 501 How did I do? If you think I'm wrong or unhelpful, please send your | 513 How did I do? If you think I'm wrong or unhelpful, please send your |
| 502 source code and gcc's error messages to googlemock@googlegroups.com. Then | 514 source code and gcc's error messages to googlemock@googlegroups.com. Then |
| 503 you can be helped and I can get smarter -- I promise I won't be upset!""" | 515 you can be helped and I can get smarter -- I promise I won't be upset!""" |
| 504 | 516 |
| 505 | 517 |
| 506 if __name__ == '__main__': | 518 if __name__ == '__main__': |
| 507 main() | 519 main() |
| OLD | NEW |