def _TypeInTemplatedBaseDiagnoser()

in ext/gtest-1.8.0/googlemock/scripts/gmock_doctor.py [0:0]


def _TypeInTemplatedBaseDiagnoser(msg):
  """Diagnoses the TTB disease, given the error messages by the compiler."""

  # This version works when the type is used as the mock function's return
  # type.
  gcc_4_3_1_regex_type_in_retval = (
      r'In member function \'int .*\n' + _GCC_FILE_LINE_RE +
      r'error: a function call cannot appear in a constant-expression')
  gcc_4_4_0_regex_type_in_retval = (
      r'error: a function call cannot appear in a constant-expression'
      + _GCC_FILE_LINE_RE + r'error: template argument 1 is invalid\n')
  # This version works when the type is used as the mock function's sole
  # parameter type.
  gcc_regex_type_of_sole_param = (
      _GCC_FILE_LINE_RE +
      r'error: \'(?P<type>.+)\' was not declared in this scope\n'
      r'.*error: template argument 1 is invalid\n')
  # This version works when the type is used as a parameter of a mock
  # function that has multiple parameters.
  gcc_regex_type_of_a_param = (
      r'error: expected `;\' before \'::\' token\n'
      + _GCC_FILE_LINE_RE +
      r'error: \'(?P<type>.+)\' was not declared in this scope\n'
      r'.*error: template argument 1 is invalid\n'
      r'.*error: \'.+\' was not declared in this scope')
  clang_regex_type_of_retval_or_sole_param = (
      _CLANG_FILE_LINE_RE +
      r'error: use of undeclared identifier \'(?P<type>.*)\'\n'
      r'(.*\n)*?'
      r'(?P=file):(?P=line):\d+: error: '
      r'non-friend class member \'Result\' cannot have a qualified name'
      )
  clang_regex_type_of_a_param = (
      _CLANG_FILE_LINE_RE +
      r'error: C\+\+ requires a type specifier for all declarations\n'
      r'(.*\n)*?'
      r'(?P=file):(?P=line):(?P=column): error: '
      r'C\+\+ requires a type specifier for all declarations'
      )
  clang_regex_unknown_type = (
      _CLANG_FILE_LINE_RE +
      r'error: unknown type name \'(?P<type>[^\']+)\''
      )

  diagnosis = """
In a mock class template, types or typedefs defined in the base class
template are *not* automatically visible.  This is how C++ works.  Before
you can use a type or typedef named %(type)s defined in base class Base<T>, you
need to make it visible.  One way to do it is:

  typedef typename Base<T>::%(type)s %(type)s;"""

  for diag in _GenericDiagnoser(
      'TTB', 'Type in Template Base',
      [(gcc_4_3_1_regex_type_in_retval, diagnosis % {'type': 'Foo'}),
       (gcc_4_4_0_regex_type_in_retval, diagnosis % {'type': 'Foo'}),
       (gcc_regex_type_of_sole_param, diagnosis),
       (gcc_regex_type_of_a_param, diagnosis),
       (clang_regex_type_of_retval_or_sole_param, diagnosis),
       (clang_regex_type_of_a_param, diagnosis % {'type': 'Foo'})],
      msg):
    yield diag
  # Avoid overlap with the NUS pattern.
  for m in _FindAllMatches(clang_regex_unknown_type, msg):
    type_ = m.groupdict()['type']
    if type_ not in _COMMON_GMOCK_SYMBOLS:
      yield ('TTB', 'Type in Template Base', diagnosis % m.groupdict())