#!/usr/bin/env python
#
# Copyright 2007 Neal Norwitz
# Portions Copyright 2007 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 an Abstract Syntax Tree (AST) for C++."""

# FIXME:
#  * Tokens should never be exported, need to convert to Nodes
#    (return types, parameters, etc.)
#  * Handle static class data for templatized classes
#  * Handle casts (both C++ and C-style)
#  * Handle conditions and loops (if/else, switch, for, while/do)
#
# TODO much, much later:
#  * Handle #define
#  * exceptions


try:
  # Python 3.x
  import builtins
except ImportError:
  # Python 2.x
  import __builtin__ as builtins

import sys
import traceback

from cpp import keywords
from cpp import tokenize
from cpp import utils


if not hasattr(builtins, 'reversed'):
  # Support Python 2.3 and earlier.
  def reversed(seq):
    for i in range(len(seq)-1, -1, -1):
      yield seq[i]

if not hasattr(builtins, 'next'):
  # Support Python 2.5 and earlier.
  def next(obj):
    return obj.next()


VISIBILITY_PUBLIC, VISIBILITY_PROTECTED, VISIBILITY_PRIVATE = range(3)

FUNCTION_NONE = 0x00
FUNCTION_CONST = 0x01
FUNCTION_VIRTUAL = 0x02
FUNCTION_PURE_VIRTUAL = 0x04
FUNCTION_CTOR = 0x08
FUNCTION_DTOR = 0x10
FUNCTION_ATTRIBUTE = 0x20
FUNCTION_UNKNOWN_ANNOTATION = 0x40
FUNCTION_THROW = 0x80
FUNCTION_OVERRIDE = 0x100

"""
These are currently unused.  Should really handle these properly at some point.

TYPE_MODIFIER_INLINE   = 0x010000
TYPE_MODIFIER_EXTERN   = 0x020000
TYPE_MODIFIER_STATIC   = 0x040000
TYPE_MODIFIER_CONST    = 0x080000
TYPE_MODIFIER_REGISTER = 0x100000
TYPE_MODIFIER_VOLATILE = 0x200000
TYPE_MODIFIER_MUTABLE  = 0x400000

TYPE_MODIFIER_MAP = {
    'inline': TYPE_MODIFIER_INLINE,
    'extern': TYPE_MODIFIER_EXTERN,
    'static': TYPE_MODIFIER_STATIC,
    'const': TYPE_MODIFIER_CONST,
    'register': TYPE_MODIFIER_REGISTER,
    'volatile': TYPE_MODIFIER_VOLATILE,
    'mutable': TYPE_MODIFIER_MUTABLE,
    }
"""

_INTERNAL_TOKEN = 'internal'
_NAMESPACE_POP = 'ns-pop'


# TODO(nnorwitz): use this as a singleton for templated_types, etc
# where we don't want to create a new empty dict each time.  It is also const.
class _NullDict(object):
  __contains__ = lambda self: False
  keys = values = items = iterkeys = itervalues = iteritems = lambda self: ()


# TODO(nnorwitz): move AST nodes into a separate module.
class Node(object):
  """Base AST node."""

  def __init__(self, start, end):
    self.start = start
    self.end = end

  def IsDeclaration(self):
    """Returns bool if this node is a declaration."""
    return False

  def IsDefinition(self):
    """Returns bool if this node is a definition."""
    return False

  def IsExportable(self):
    """Returns bool if this node exportable from a header file."""
    return False

  def Requires(self, node):
    """Does this AST node require the definition of the node passed in?"""
    return False

  def XXX__str__(self):
    return self._StringHelper(self.__class__.__name__, '')

  def _StringHelper(self, name, suffix):
    if not utils.DEBUG:
      return '%s(%s)' % (name, suffix)
    return '%s(%d, %d, %s)' % (name, self.start, self.end, suffix)

  def __repr__(self):
    return str(self)


class Define(Node):
  def __init__(self, start, end, name, definition):
    Node.__init__(self, start, end)
    self.name = name
    self.definition = definition

  def __str__(self):
    value = '%s %s' % (self.name, self.definition)
    return self._StringHelper(self.__class__.__name__, value)


class Include(Node):
  def __init__(self, start, end, filename, system):
    Node.__init__(self, start, end)
    self.filename = filename
    self.system = system

  def __str__(self):
    fmt = '"%s"'
    if self.system:
      fmt = '<%s>'
    return self._StringHelper(self.__class__.__name__, fmt % self.filename)


class Goto(Node):
  def __init__(self, start, end, label):
    Node.__init__(self, start, end)
    self.label = label

  def __str__(self):
    return self._StringHelper(self.__class__.__name__, str(self.label))


class Expr(Node):
  def __init__(self, start, end, expr):
    Node.__init__(self, start, end)
    self.expr = expr

  def Requires(self, node):
    # TODO(nnorwitz): impl.
    return False

  def __str__(self):
    return self._StringHelper(self.__class__.__name__, str(self.expr))


class Return(Expr):
  pass


class Delete(Expr):
  pass


class Friend(Expr):
  def __init__(self, start, end, expr, namespace):
    Expr.__init__(self, start, end, expr)
    self.namespace = namespace[:]


class Using(Node):
  def __init__(self, start, end, names):
    Node.__init__(self, start, end)
    self.names = names

  def __str__(self):
    return self._StringHelper(self.__class__.__name__, str(self.names))


class Parameter(Node):
  def __init__(self, start, end, name, parameter_type, default):
    Node.__init__(self, start, end)
    self.name = name
    self.type = parameter_type
    self.default = default

  def Requires(self, node):
    # TODO(nnorwitz): handle namespaces, etc.
    return self.type.name == node.name

  def __str__(self):
    name = str(self.type)
    suffix = '%s %s' % (name, self.name)
    if self.default:
      suffix += ' = ' + ''.join([d.name for d in self.default])
    return self._StringHelper(self.__class__.__name__, suffix)


class _GenericDeclaration(Node):
  def __init__(self, start, end, name, namespace):
    Node.__init__(self, start, end)
    self.name = name
    self.namespace = namespace[:]

  def FullName(self):
    prefix = ''
    if self.namespace and self.namespace[-1]:
      prefix = '::'.join(self.namespace) + '::'
    return prefix + self.name

  def _TypeStringHelper(self, suffix):
    if self.namespace:
      names = [n or '<anonymous>' for n in self.namespace]
      suffix += ' in ' + '::'.join(names)
    return self._StringHelper(self.__class__.__name__, suffix)


# TODO(nnorwitz): merge with Parameter in some way?
class VariableDeclaration(_GenericDeclaration):
  def __init__(self, start, end, name, var_type, initial_value, namespace):
    _GenericDeclaration.__init__(self, start, end, name, namespace)
    self.type = var_type
    self.initial_value = initial_value

  def Requires(self, node):
    # TODO(nnorwitz): handle namespaces, etc.
    return self.type.name == node.name

  def ToString(self):
    """Return a string that tries to reconstitute the variable decl."""
    suffix = '%s %s' % (self.type, self.name)
    if self.initial_value:
      suffix += ' = ' + self.initial_value
    return suffix

  def __str__(self):
    return self._StringHelper(self.__class__.__name__, self.ToString())


class Typedef(_GenericDeclaration):
  def __init__(self, start, end, name, alias, namespace):
    _GenericDeclaration.__init__(self, start, end, name, namespace)
    self.alias = alias

  def IsDefinition(self):
    return True

  def IsExportable(self):
    return True

  def Requires(self, node):
    # TODO(nnorwitz): handle namespaces, etc.
    name = node.name
    for token in self.alias:
      if token is not None and name == token.name:
        return True
    return False

  def __str__(self):
    suffix = '%s, %s' % (self.name, self.alias)
    return self._TypeStringHelper(suffix)


class _NestedType(_GenericDeclaration):
  def __init__(self, start, end, name, fields, namespace):
    _GenericDeclaration.__init__(self, start, end, name, namespace)
    self.fields = fields

  def IsDefinition(self):
    return True

  def IsExportable(self):
    return True

  def __str__(self):
    suffix = '%s, {%s}' % (self.name, self.fields)
    return self._TypeStringHelper(suffix)


class Union(_NestedType):
  pass


class Enum(_NestedType):
  pass


class Class(_GenericDeclaration):
  def __init__(self, start, end, name, bases, templated_types, body, namespace):
    _GenericDeclaration.__init__(self, start, end, name, namespace)
    self.bases = bases
    self.body = body
    self.templated_types = templated_types

  def IsDeclaration(self):
    return self.bases is None and self.body is None

  def IsDefinition(self):
    return not self.IsDeclaration()

  def IsExportable(self):
    return not self.IsDeclaration()

  def Requires(self, node):
    # TODO(nnorwitz): handle namespaces, etc.
    if self.bases:
      for token_list in self.bases:
        # TODO(nnorwitz): bases are tokens, do name comparision.
        for token in token_list:
          if token.name == node.name:
            return True
    # TODO(nnorwitz): search in body too.
    return False

  def __str__(self):
    name = self.name
    if self.templated_types:
      name += '<%s>' % self.templated_types
    suffix = '%s, %s, %s' % (name, self.bases, self.body)
    return self._TypeStringHelper(suffix)


class Struct(Class):
  pass


class Function(_GenericDeclaration):
  def __init__(self, start, end, name, return_type, parameters,
               modifiers, templated_types, body, namespace):
    _GenericDeclaration.__init__(self, start, end, name, namespace)
    converter = TypeConverter(namespace)
    self.return_type = converter.CreateReturnType(return_type)
    self.parameters = converter.ToParameters(parameters)
    self.modifiers = modifiers
    self.body = body
    self.templated_types = templated_types

  def IsDeclaration(self):
    return self.body is None

  def IsDefinition(self):
    return self.body is not None

  def IsExportable(self):
    if self.return_type and 'static' in self.return_type.modifiers:
      return False
    return None not in self.namespace

  def Requires(self, node):
    if self.parameters:
      # TODO(nnorwitz): parameters are tokens, do name comparision.
      for p in self.parameters:
        if p.name == node.name:
          return True
    # TODO(nnorwitz): search in body too.
    return False

  def __str__(self):
    # TODO(nnorwitz): add templated_types.
    suffix = ('%s %s(%s), 0x%02x, %s' %
              (self.return_type, self.name, self.parameters,
               self.modifiers, self.body))
    return self._TypeStringHelper(suffix)


class Method(Function):
  def __init__(self, start, end, name, in_class, return_type, parameters,
               modifiers, templated_types, body, namespace):
    Function.__init__(self, start, end, name, return_type, parameters,
                      modifiers, templated_types, body, namespace)
    # TODO(nnorwitz): in_class could also be a namespace which can
    # mess up finding functions properly.
    self.in_class = in_class


class Type(_GenericDeclaration):
  """Type used for any variable (eg class, primitive, struct, etc)."""

  def __init__(self, start, end, name, templated_types, modifiers,
               reference, pointer, array):
    """
        Args:
          name: str name of main type
          templated_types: [Class (Type?)] template type info between <>
          modifiers: [str] type modifiers (keywords) eg, const, mutable, etc.
          reference, pointer, array: bools
        """
    _GenericDeclaration.__init__(self, start, end, name, [])
    self.templated_types = templated_types
    if not name and modifiers:
      self.name = modifiers.pop()
    self.modifiers = modifiers
    self.reference = reference
    self.pointer = pointer
    self.array = array

  def __str__(self):
    prefix = ''
    if self.modifiers:
      prefix = ' '.join(self.modifiers) + ' '
    name = str(self.name)
    if self.templated_types:
      name += '<%s>' % self.templated_types
    suffix = prefix + name
    if self.reference:
      suffix += '&'
    if self.pointer:
      suffix += '*'
    if self.array:
      suffix += '[]'
    return self._TypeStringHelper(suffix)

  # By definition, Is* are always False.  A Type can only exist in
  # some sort of variable declaration, parameter, or return value.
  def IsDeclaration(self):
    return False

  def IsDefinition(self):
    return False

  def IsExportable(self):
    return False


class TypeConverter(object):

  def __init__(self, namespace_stack):
    self.namespace_stack = namespace_stack

  def _GetTemplateEnd(self, tokens, start):
    count = 1
    end = start
    while 1:
      token = tokens[end]
      end += 1
      if token.name == '<':
        count += 1
      elif token.name == '>':
        count -= 1
        if count == 0:
          break
    return tokens[start:end-1], end

  def ToType(self, tokens):
    """Convert [Token,...] to [Class(...), ] useful for base classes.
        For example, code like class Foo : public Bar<x, y> { ... };
        the "Bar<x, y>" portion gets converted to an AST.

        Returns:
          [Class(...), ...]
        """
    result = []
    name_tokens = []
    reference = pointer = array = False

    def AddType(templated_types):
      # Partition tokens into name and modifier tokens.
      names = []
      modifiers = []
      for t in name_tokens:
        if keywords.IsKeyword(t.name):
          modifiers.append(t.name)
        else:
          names.append(t.name)
      name = ''.join(names)
      if name_tokens:
        result.append(Type(name_tokens[0].start, name_tokens[-1].end,
                           name, templated_types, modifiers,
                           reference, pointer, array))
      del name_tokens[:]

    i = 0
    end = len(tokens)
    while i < end:
      token = tokens[i]
      if token.name == '<':
        new_tokens, new_end = self._GetTemplateEnd(tokens, i+1)
        AddType(self.ToType(new_tokens))
        # If there is a comma after the template, we need to consume
        # that here otherwise it becomes part of the name.
        i = new_end
        reference = pointer = array = False
      elif token.name == ',':
        AddType([])
        reference = pointer = array = False
      elif token.name == '*':
        pointer = True
      elif token.name == '&':
        reference = True
      elif token.name == '[':
        pointer = True
      elif token.name == ']':
        pass
      else:
        name_tokens.append(token)
      i += 1

    if name_tokens:
      # No '<' in the tokens, just a simple name and no template.
      AddType([])
    return result

  def DeclarationToParts(self, parts, needs_name_removed):
    name = None
    default = []
    if needs_name_removed:
      # Handle default (initial) values properly.
      for i, t in enumerate(parts):
        if t.name == '=':
          default = parts[i+1:]
          name = parts[i-1].name
          if name == ']' and parts[i-2].name == '[':
            name = parts[i-3].name
            i -= 1
          parts = parts[:i-1]
          break
      else:
        if parts[-1].token_type == tokenize.NAME:
          name = parts.pop().name
        else:
          # TODO(nnorwitz): this is a hack that happens for code like
          # Register(Foo<T>); where it thinks this is a function call
          # but it's actually a declaration.
          name = '???'
    modifiers = []
    type_name = []
    other_tokens = []
    templated_types = []
    i = 0
    end = len(parts)
    while i < end:
      p = parts[i]
      if keywords.IsKeyword(p.name):
        modifiers.append(p.name)
      elif p.name == '<':
        templated_tokens, new_end = self._GetTemplateEnd(parts, i+1)
        templated_types = self.ToType(templated_tokens)
        i = new_end - 1
        # Don't add a spurious :: to data members being initialized.
        next_index = i + 1
        if next_index < end and parts[next_index].name == '::':
          i += 1
      elif p.name in ('[', ']', '='):
        # These are handled elsewhere.
        other_tokens.append(p)
      elif p.name not in ('*', '&', '>'):
        # Ensure that names have a space between them.
        if (type_name and type_name[-1].token_type == tokenize.NAME and
                p.token_type == tokenize.NAME):
          type_name.append(tokenize.Token(tokenize.SYNTAX, ' ', 0, 0))
        type_name.append(p)
      else:
        other_tokens.append(p)
      i += 1
    type_name = ''.join([t.name for t in type_name])
    return name, type_name, templated_types, modifiers, default, other_tokens

  def ToParameters(self, tokens):
    if not tokens:
      return []

    result = []
    name = type_name = ''
    type_modifiers = []
    pointer = reference = array = False
    first_token = None
    default = []

    def AddParameter(end):
      if default:
        del default[0]  # Remove flag.
      parts = self.DeclarationToParts(type_modifiers, True)
      (name, type_name, templated_types, modifiers,
       unused_default, unused_other_tokens) = parts
      parameter_type = Type(first_token.start, first_token.end,
                            type_name, templated_types, modifiers,
                            reference, pointer, array)
      p = Parameter(first_token.start, end, name,
                    parameter_type, default)
      result.append(p)

    template_count = 0
    brace_count = 0
    for s in tokens:
      if not first_token:
        first_token = s

      # Check for braces before templates, as we can have unmatched '<>'
      # inside default arguments.
      if s.name == '{':
        brace_count += 1
      elif s.name == '}':
        brace_count -= 1
      if brace_count > 0:
        type_modifiers.append(s)
        continue

      if s.name == '<':
        template_count += 1
      elif s.name == '>':
        template_count -= 1
      if template_count > 0:
        type_modifiers.append(s)
        continue

      if s.name == ',':
        AddParameter(s.start)
        name = type_name = ''
        type_modifiers = []
        pointer = reference = array = False
        first_token = None
        default = []
      elif s.name == '*':
        pointer = True
      elif s.name == '&':
        reference = True
      elif s.name == '[':
        array = True
      elif s.name == ']':
        pass  # Just don't add to type_modifiers.
      elif s.name == '=':
        # Got a default value.  Add any value (None) as a flag.
        default.append(None)
      elif default:
        default.append(s)
      else:
        type_modifiers.append(s)
    AddParameter(tokens[-1].end)
    return result

  def CreateReturnType(self, return_type_seq):
    if not return_type_seq:
      return None
    start = return_type_seq[0].start
    end = return_type_seq[-1].end
    _, name, templated_types, modifiers, default, other_tokens = \
        self.DeclarationToParts(return_type_seq, False)
    names = [n.name for n in other_tokens]
    reference = '&' in names
    pointer = '*' in names
    array = '[' in names
    return Type(start, end, name, templated_types, modifiers,
                reference, pointer, array)

  def GetTemplateIndices(self, names):
    # names is a list of strings.
    start = names.index('<')
    end = len(names) - 1
    while end > 0:
      if names[end] == '>':
        break
      end -= 1
    return start, end+1

class AstBuilder(object):
  def __init__(self, token_stream, filename, in_class='', visibility=None,
               namespace_stack=[]):
    self.tokens = token_stream
    self.filename = filename
    # TODO(nnorwitz): use a better data structure (deque) for the queue.
    # Switching directions of the "queue" improved perf by about 25%.
    # Using a deque should be even better since we access from both sides.
    self.token_queue = []
    self.namespace_stack = namespace_stack[:]
    self.in_class = in_class
    if in_class is None:
      self.in_class_name_only = None
    else:
      self.in_class_name_only = in_class.split('::')[-1]
    self.visibility = visibility
    self.in_function = False
    self.current_token = None
    # Keep the state whether we are currently handling a typedef or not.
    self._handling_typedef = False

    self.converter = TypeConverter(self.namespace_stack)

  def HandleError(self, msg, token):
    printable_queue = list(reversed(self.token_queue[-20:]))
    sys.stderr.write('Got %s in %s @ %s %s\n' %
                     (msg, self.filename, token, printable_queue))

  def Generate(self):
    while 1:
      token = self._GetNextToken()
      if not token:
        break

      # Get the next token.
      self.current_token = token

      # Dispatch on the next token type.
      if token.token_type == _INTERNAL_TOKEN:
        if token.name == _NAMESPACE_POP:
          self.namespace_stack.pop()
        continue

      try:
        result = self._GenerateOne(token)
        if result is not None:
          yield result
      except:
        self.HandleError('exception', token)
        raise

  def _CreateVariable(self, pos_token, name, type_name, type_modifiers,
                      ref_pointer_name_seq, templated_types, value=None):
    reference = '&' in ref_pointer_name_seq
    pointer = '*' in ref_pointer_name_seq
    array = '[' in ref_pointer_name_seq
    var_type = Type(pos_token.start, pos_token.end, type_name,
                    templated_types, type_modifiers,
                    reference, pointer, array)
    return VariableDeclaration(pos_token.start, pos_token.end,
                               name, var_type, value, self.namespace_stack)

  def _GenerateOne(self, token):
    if token.token_type == tokenize.NAME:
      if (keywords.IsKeyword(token.name) and
          not keywords.IsBuiltinType(token.name)):
        if token.name == 'enum':
          # Pop the next token and only put it back if it's not
          # 'class'.  This allows us to support the two-token
          # 'enum class' keyword as if it were simply 'enum'.
          next = self._GetNextToken()
          if next.name != 'class':
            self._AddBackToken(next)

        method = getattr(self, 'handle_' + token.name)
        return method()
      elif token.name == self.in_class_name_only:
        # The token name is the same as the class, must be a ctor if
        # there is a paren.  Otherwise, it's the return type.
        # Peek ahead to get the next token to figure out which.
        next = self._GetNextToken()
        self._AddBackToken(next)
        if next.token_type == tokenize.SYNTAX and next.name == '(':
          return self._GetMethod([token], FUNCTION_CTOR, None, True)
        # Fall through--handle like any other method.

      # Handle data or function declaration/definition.
      syntax = tokenize.SYNTAX
      temp_tokens, last_token = \
          self._GetVarTokensUpToIgnoringTemplates(syntax,
                                                  '(', ';', '{', '[')
      temp_tokens.insert(0, token)
      if last_token.name == '(':
        # If there is an assignment before the paren,
        # this is an expression, not a method.
        expr = bool([e for e in temp_tokens if e.name == '='])
        if expr:
          new_temp = self._GetTokensUpTo(tokenize.SYNTAX, ';')
          temp_tokens.append(last_token)
          temp_tokens.extend(new_temp)
          last_token = tokenize.Token(tokenize.SYNTAX, ';', 0, 0)

      if last_token.name == '[':
        # Handle array, this isn't a method, unless it's an operator.
        # TODO(nnorwitz): keep the size somewhere.
        # unused_size = self._GetTokensUpTo(tokenize.SYNTAX, ']')
        temp_tokens.append(last_token)
        if temp_tokens[-2].name == 'operator':
          temp_tokens.append(self._GetNextToken())
        else:
          temp_tokens2, last_token = \
              self._GetVarTokensUpTo(tokenize.SYNTAX, ';')
          temp_tokens.extend(temp_tokens2)

      if last_token.name == ';':
        # Handle data, this isn't a method.
        parts = self.converter.DeclarationToParts(temp_tokens, True)
        (name, type_name, templated_types, modifiers, default,
         unused_other_tokens) = parts

        t0 = temp_tokens[0]
        names = [t.name for t in temp_tokens]
        if templated_types:
          start, end = self.converter.GetTemplateIndices(names)
          names = names[:start] + names[end:]
        default = ''.join([t.name for t in default])
        return self._CreateVariable(t0, name, type_name, modifiers,
                                    names, templated_types, default)
      if last_token.name == '{':
        self._AddBackTokens(temp_tokens[1:])
        self._AddBackToken(last_token)
        method_name = temp_tokens[0].name
        method = getattr(self, 'handle_' + method_name, None)
        if not method:
          # Must be declaring a variable.
          # TODO(nnorwitz): handle the declaration.
          return None
        return method()
      return self._GetMethod(temp_tokens, 0, None, False)
    elif token.token_type == tokenize.SYNTAX:
      if token.name == '~' and self.in_class:
        # Must be a dtor (probably not in method body).
        token = self._GetNextToken()
        # self.in_class can contain A::Name, but the dtor will only
        # be Name.  Make sure to compare against the right value.
        if (token.token_type == tokenize.NAME and
                token.name == self.in_class_name_only):
          return self._GetMethod([token], FUNCTION_DTOR, None, True)
      # TODO(nnorwitz): handle a lot more syntax.
    elif token.token_type == tokenize.PREPROCESSOR:
      # TODO(nnorwitz): handle more preprocessor directives.
      # token starts with a #, so remove it and strip whitespace.
      name = token.name[1:].lstrip()
      if name.startswith('include'):
        # Remove "include".
        name = name[7:].strip()
        assert name
        # Handle #include \<newline> "header-on-second-line.h".
        if name.startswith('\\'):
          name = name[1:].strip()
        assert name[0] in '<"', token
        assert name[-1] in '>"', token
        system = name[0] == '<'
        filename = name[1:-1]
        return Include(token.start, token.end, filename, system)
      if name.startswith('define'):
        # Remove "define".
        name = name[6:].strip()
        assert name
        value = ''
        for i, c in enumerate(name):
          if c.isspace():
            value = name[i:].lstrip()
            name = name[:i]
            break
        return Define(token.start, token.end, name, value)
      if name.startswith('if') and name[2:3].isspace():
        condition = name[3:].strip()
        if condition.startswith('0') or condition.startswith('(0)'):
          self._SkipIf0Blocks()
    return None

  def _GetTokensUpTo(self, expected_token_type, expected_token):
    return self._GetVarTokensUpTo(expected_token_type, expected_token)[0]

  def _GetVarTokensUpTo(self, expected_token_type, *expected_tokens):
    last_token = self._GetNextToken()
    tokens = []
    while (last_token.token_type != expected_token_type or
           last_token.name not in expected_tokens):
      tokens.append(last_token)
      last_token = self._GetNextToken()
    return tokens, last_token

  # Same as _GetVarTokensUpTo, but skips over '<...>' which could contain an
  # expected token.
  def _GetVarTokensUpToIgnoringTemplates(self, expected_token_type,
                                         *expected_tokens):
    last_token = self._GetNextToken()
    tokens = []
    nesting = 0
    while (nesting > 0 or
           last_token.token_type != expected_token_type or
           last_token.name not in expected_tokens):
      tokens.append(last_token)
      last_token = self._GetNextToken()
      if last_token.name == '<':
        nesting += 1
      elif last_token.name == '>':
        nesting -= 1
    return tokens, last_token

  # TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necesary.
  def _IgnoreUpTo(self, token_type, token):
    unused_tokens = self._GetTokensUpTo(token_type, token)

  def _SkipIf0Blocks(self):
    count = 1
    while 1:
      token = self._GetNextToken()
      if token.token_type != tokenize.PREPROCESSOR:
        continue

      name = token.name[1:].lstrip()
      if name.startswith('endif'):
        count -= 1
        if count == 0:
          break
      elif name.startswith('if'):
        count += 1

  def _GetMatchingChar(self, open_paren, close_paren, GetNextToken=None):
    if GetNextToken is None:
      GetNextToken = self._GetNextToken
    # Assumes the current token is open_paren and we will consume
    # and return up to the close_paren.
    count = 1
    token = GetNextToken()
    while 1:
      if token.token_type == tokenize.SYNTAX:
        if token.name == open_paren:
          count += 1
        elif token.name == close_paren:
          count -= 1
          if count == 0:
            break
      yield token
      token = GetNextToken()
    yield token

  def _GetParameters(self):
    return self._GetMatchingChar('(', ')')

  def GetScope(self):
    return self._GetMatchingChar('{', '}')

  def _GetNextToken(self):
    if self.token_queue:
      return self.token_queue.pop()
    try:
      return next(self.tokens)
    except StopIteration:
      return

  def _AddBackToken(self, token):
    if token.whence == tokenize.WHENCE_STREAM:
      token.whence = tokenize.WHENCE_QUEUE
      self.token_queue.insert(0, token)
    else:
      assert token.whence == tokenize.WHENCE_QUEUE, token
      self.token_queue.append(token)

  def _AddBackTokens(self, tokens):
    if tokens:
      if tokens[-1].whence == tokenize.WHENCE_STREAM:
        for token in tokens:
          token.whence = tokenize.WHENCE_QUEUE
        self.token_queue[:0] = reversed(tokens)
      else:
        assert tokens[-1].whence == tokenize.WHENCE_QUEUE, tokens
        self.token_queue.extend(reversed(tokens))

  def GetName(self, seq=None):
    """Returns ([tokens], next_token_info)."""
    GetNextToken = self._GetNextToken
    if seq is not None:
      it = iter(seq)
      GetNextToken = lambda: next(it)
    next_token = GetNextToken()
    tokens = []
    last_token_was_name = False
    while (next_token.token_type == tokenize.NAME or
           (next_token.token_type == tokenize.SYNTAX and
            next_token.name in ('::', '<'))):
      # Two NAMEs in a row means the identifier should terminate.
      # It's probably some sort of variable declaration.
      if last_token_was_name and next_token.token_type == tokenize.NAME:
        break
      last_token_was_name = next_token.token_type == tokenize.NAME
      tokens.append(next_token)
      # Handle templated names.
      if next_token.name == '<':
        tokens.extend(self._GetMatchingChar('<', '>', GetNextToken))
        last_token_was_name = True
      next_token = GetNextToken()
    return tokens, next_token

  def GetMethod(self, modifiers, templated_types):
    return_type_and_name = self._GetTokensUpTo(tokenize.SYNTAX, '(')
    assert len(return_type_and_name) >= 1
    return self._GetMethod(return_type_and_name, modifiers, templated_types,
                           False)

  def _GetMethod(self, return_type_and_name, modifiers, templated_types,
                 get_paren):
    template_portion = None
    if get_paren:
      token = self._GetNextToken()
      assert token.token_type == tokenize.SYNTAX, token
      if token.name == '<':
        # Handle templatized dtors.
        template_portion = [token]
        template_portion.extend(self._GetMatchingChar('<', '>'))
        token = self._GetNextToken()
      assert token.token_type == tokenize.SYNTAX, token
      assert token.name == '(', token

    name = return_type_and_name.pop()
    # Handle templatized ctors.
    if name.name == '>':
      index = 1
      while return_type_and_name[index].name != '<':
        index += 1
      template_portion = return_type_and_name[index:] + [name]
      del return_type_and_name[index:]
      name = return_type_and_name.pop()
    elif name.name == ']':
      rt = return_type_and_name
      assert rt[-1].name == '[', return_type_and_name
      assert rt[-2].name == 'operator', return_type_and_name
      name_seq = return_type_and_name[-2:]
      del return_type_and_name[-2:]
      name = tokenize.Token(tokenize.NAME, 'operator[]',
                            name_seq[0].start, name.end)
      # Get the open paren so _GetParameters() below works.
      unused_open_paren = self._GetNextToken()

    # TODO(nnorwitz): store template_portion.
    return_type = return_type_and_name
    indices = name
    if return_type:
      indices = return_type[0]

    # Force ctor for templatized ctors.
    if name.name == self.in_class and not modifiers:
      modifiers |= FUNCTION_CTOR
    parameters = list(self._GetParameters())
    del parameters[-1]              # Remove trailing ')'.

    # Handling operator() is especially weird.
    if name.name == 'operator' and not parameters:
      token = self._GetNextToken()
      assert token.name == '(', token
      parameters = list(self._GetParameters())
      del parameters[-1]          # Remove trailing ')'.

    token = self._GetNextToken()
    while token.token_type == tokenize.NAME:
      modifier_token = token
      token = self._GetNextToken()
      if modifier_token.name == 'const':
        modifiers |= FUNCTION_CONST
      elif modifier_token.name == '__attribute__':
        # TODO(nnorwitz): handle more __attribute__ details.
        modifiers |= FUNCTION_ATTRIBUTE
        assert token.name == '(', token
        # Consume everything between the (parens).
        unused_tokens = list(self._GetMatchingChar('(', ')'))
        token = self._GetNextToken()
      elif modifier_token.name == 'throw':
        modifiers |= FUNCTION_THROW
        assert token.name == '(', token
        # Consume everything between the (parens).
        unused_tokens = list(self._GetMatchingChar('(', ')'))
        token = self._GetNextToken()
      elif modifier_token.name == 'override':
        modifiers |= FUNCTION_OVERRIDE
      elif modifier_token.name == modifier_token.name.upper():
        # HACK(nnorwitz):  assume that all upper-case names
        # are some macro we aren't expanding.
        modifiers |= FUNCTION_UNKNOWN_ANNOTATION
      else:
        self.HandleError('unexpected token', modifier_token)

    assert token.token_type == tokenize.SYNTAX, token
    # Handle ctor initializers.
    if token.name == ':':
      # TODO(nnorwitz): anything else to handle for initializer list?
      while token.name != ';' and token.name != '{':
        token = self._GetNextToken()

    # Handle pointer to functions that are really data but look
    # like method declarations.
    if token.name == '(':
      if parameters[0].name == '*':
        # name contains the return type.
        name = parameters.pop()
        # parameters contains the name of the data.
        modifiers = [p.name for p in parameters]
        # Already at the ( to open the parameter list.
        function_parameters = list(self._GetMatchingChar('(', ')'))
        del function_parameters[-1]  # Remove trailing ')'.
        # TODO(nnorwitz): store the function_parameters.
        token = self._GetNextToken()
        assert token.token_type == tokenize.SYNTAX, token
        assert token.name == ';', token
        return self._CreateVariable(indices, name.name, indices.name,
                                    modifiers, '', None)
      # At this point, we got something like:
      #  return_type (type::*name_)(params);
      # This is a data member called name_ that is a function pointer.
      # With this code: void (sq_type::*field_)(string&);
      # We get: name=void return_type=[] parameters=sq_type ... field_
      # TODO(nnorwitz): is return_type always empty?
      # TODO(nnorwitz): this isn't even close to being correct.
      # Just put in something so we don't crash and can move on.
      real_name = parameters[-1]
      modifiers = [p.name for p in self._GetParameters()]
      del modifiers[-1]           # Remove trailing ')'.
      return self._CreateVariable(indices, real_name.name, indices.name,
                                  modifiers, '', None)

    if token.name == '{':
      body = list(self.GetScope())
      del body[-1]                # Remove trailing '}'.
    else:
      body = None
      if token.name == '=':
        token = self._GetNextToken()

        if token.name == 'default' or token.name == 'delete':
          # Ignore explicitly defaulted and deleted special members
          # in C++11.
          token = self._GetNextToken()
        else:
          # Handle pure-virtual declarations.
          assert token.token_type == tokenize.CONSTANT, token
          assert token.name == '0', token
          modifiers |= FUNCTION_PURE_VIRTUAL
          token = self._GetNextToken()

      if token.name == '[':
        # TODO(nnorwitz): store tokens and improve parsing.
        # template <typename T, size_t N> char (&ASH(T (&seq)[N]))[N];
        tokens = list(self._GetMatchingChar('[', ']'))
        token = self._GetNextToken()

      assert token.name == ';', (token, return_type_and_name, parameters)

    # Looks like we got a method, not a function.
    if len(return_type) > 2 and return_type[-1].name == '::':
      return_type, in_class = \
          self._GetReturnTypeAndClassName(return_type)
      return Method(indices.start, indices.end, name.name, in_class,
                    return_type, parameters, modifiers, templated_types,
                    body, self.namespace_stack)
    return Function(indices.start, indices.end, name.name, return_type,
                    parameters, modifiers, templated_types, body,
                    self.namespace_stack)

  def _GetReturnTypeAndClassName(self, token_seq):
    # Splitting the return type from the class name in a method
    # can be tricky.  For example, Return::Type::Is::Hard::To::Find().
    # Where is the return type and where is the class name?
    # The heuristic used is to pull the last name as the class name.
    # This includes all the templated type info.
    # TODO(nnorwitz): if there is only One name like in the
    # example above, punt and assume the last bit is the class name.

    # Ignore a :: prefix, if exists so we can find the first real name.
    i = 0
    if token_seq[0].name == '::':
      i = 1
    # Ignore a :: suffix, if exists.
    end = len(token_seq) - 1
    if token_seq[end-1].name == '::':
      end -= 1

    # Make a copy of the sequence so we can append a sentinel
    # value. This is required for GetName will has to have some
    # terminating condition beyond the last name.
    seq_copy = token_seq[i:end]
    seq_copy.append(tokenize.Token(tokenize.SYNTAX, '', 0, 0))
    names = []
    while i < end:
      # Iterate through the sequence parsing out each name.
      new_name, next = self.GetName(seq_copy[i:])
      assert new_name, 'Got empty new_name, next=%s' % next
      # We got a pointer or ref.  Add it to the name.
      if next and next.token_type == tokenize.SYNTAX:
        new_name.append(next)
      names.append(new_name)
      i += len(new_name)

    # Now that we have the names, it's time to undo what we did.

    # Remove the sentinel value.
    names[-1].pop()
    # Flatten the token sequence for the return type.
    return_type = [e for seq in names[:-1] for e in seq]
    # The class name is the last name.
    class_name = names[-1]
    return return_type, class_name

  def handle_bool(self):
    pass

  def handle_char(self):
    pass

  def handle_int(self):
    pass

  def handle_long(self):
    pass

  def handle_short(self):
    pass

  def handle_double(self):
    pass

  def handle_float(self):
    pass

  def handle_void(self):
    pass

  def handle_wchar_t(self):
    pass

  def handle_unsigned(self):
    pass

  def handle_signed(self):
    pass

  def _GetNestedType(self, ctor):
    name = None
    name_tokens, token = self.GetName()
    if name_tokens:
      name = ''.join([t.name for t in name_tokens])

    # Handle forward declarations.
    if token.token_type == tokenize.SYNTAX and token.name == ';':
      return ctor(token.start, token.end, name, None,
                  self.namespace_stack)

    if token.token_type == tokenize.NAME and self._handling_typedef:
      self._AddBackToken(token)
      return ctor(token.start, token.end, name, None,
                  self.namespace_stack)

    # Must be the type declaration.
    fields = list(self._GetMatchingChar('{', '}'))
    del fields[-1]                  # Remove trailing '}'.
    if token.token_type == tokenize.SYNTAX and token.name == '{':
      next = self._GetNextToken()
      new_type = ctor(token.start, token.end, name, fields,
                      self.namespace_stack)
      # A name means this is an anonymous type and the name
      # is the variable declaration.
      if next.token_type != tokenize.NAME:
        return new_type
      name = new_type
      token = next

    # Must be variable declaration using the type prefixed with keyword.
    assert token.token_type == tokenize.NAME, token
    return self._CreateVariable(token, token.name, name, [], '', None)

  def handle_struct(self):
    # Special case the handling typedef/aliasing of structs here.
    # It would be a pain to handle in the class code.
    name_tokens, var_token = self.GetName()
    if name_tokens:
      next_token = self._GetNextToken()
      is_syntax = (var_token.token_type == tokenize.SYNTAX and
                   var_token.name[0] in '*&')
      is_variable = (var_token.token_type == tokenize.NAME and
                     next_token.name == ';')
      variable = var_token
      if is_syntax and not is_variable:
        variable = next_token
        temp = self._GetNextToken()
        if temp.token_type == tokenize.SYNTAX and temp.name == '(':
          # Handle methods declared to return a struct.
          t0 = name_tokens[0]
          struct = tokenize.Token(tokenize.NAME, 'struct',
                                  t0.start-7, t0.start-2)
          type_and_name = [struct]
          type_and_name.extend(name_tokens)
          type_and_name.extend((var_token, next_token))
          return self._GetMethod(type_and_name, 0, None, False)
        assert temp.name == ';', (temp, name_tokens, var_token)
      if is_syntax or (is_variable and not self._handling_typedef):
        modifiers = ['struct']
        type_name = ''.join([t.name for t in name_tokens])
        position = name_tokens[0]
        return self._CreateVariable(position, variable.name, type_name,
                                    modifiers, var_token.name, None)
      name_tokens.extend((var_token, next_token))
      self._AddBackTokens(name_tokens)
    else:
      self._AddBackToken(var_token)
    return self._GetClass(Struct, VISIBILITY_PUBLIC, None)

  def handle_union(self):
    return self._GetNestedType(Union)

  def handle_enum(self):
    return self._GetNestedType(Enum)

  def handle_auto(self):
    # TODO(nnorwitz): warn about using auto?  Probably not since it
    # will be reclaimed and useful for C++0x.
    pass

  def handle_register(self):
    pass

  def handle_const(self):
    pass

  def handle_inline(self):
    pass

  def handle_extern(self):
    pass

  def handle_static(self):
    pass

  def handle_virtual(self):
    # What follows must be a method.
    token = token2 = self._GetNextToken()
    if token.name == 'inline':
      # HACK(nnorwitz): handle inline dtors by ignoring 'inline'.
      token2 = self._GetNextToken()
    if token2.token_type == tokenize.SYNTAX and token2.name == '~':
      return self.GetMethod(FUNCTION_VIRTUAL + FUNCTION_DTOR, None)
    assert token.token_type == tokenize.NAME or token.name == '::', token
    return_type_and_name, _ = self._GetVarTokensUpToIgnoringTemplates(
        tokenize.SYNTAX, '(')  # )
    return_type_and_name.insert(0, token)
    if token2 is not token:
      return_type_and_name.insert(1, token2)
    return self._GetMethod(return_type_and_name, FUNCTION_VIRTUAL,
                           None, False)

  def handle_volatile(self):
    pass

  def handle_mutable(self):
    pass

  def handle_public(self):
    assert self.in_class
    self.visibility = VISIBILITY_PUBLIC

  def handle_protected(self):
    assert self.in_class
    self.visibility = VISIBILITY_PROTECTED

  def handle_private(self):
    assert self.in_class
    self.visibility = VISIBILITY_PRIVATE

  def handle_friend(self):
    tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';')
    assert tokens
    t0 = tokens[0]
    return Friend(t0.start, t0.end, tokens, self.namespace_stack)

  def handle_static_cast(self):
    pass

  def handle_const_cast(self):
    pass

  def handle_dynamic_cast(self):
    pass

  def handle_reinterpret_cast(self):
    pass

  def handle_new(self):
    pass

  def handle_delete(self):
    tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';')
    assert tokens
    return Delete(tokens[0].start, tokens[0].end, tokens)

  def handle_typedef(self):
    token = self._GetNextToken()
    if (token.token_type == tokenize.NAME and
            keywords.IsKeyword(token.name)):
      # Token must be struct/enum/union/class.
      method = getattr(self, 'handle_' + token.name)
      self._handling_typedef = True
      tokens = [method()]
      self._handling_typedef = False
    else:
      tokens = [token]

    # Get the remainder of the typedef up to the semi-colon.
    tokens.extend(self._GetTokensUpTo(tokenize.SYNTAX, ';'))

    # TODO(nnorwitz): clean all this up.
    assert tokens
    name = tokens.pop()
    indices = name
    if tokens:
      indices = tokens[0]
    if not indices:
      indices = token
    if name.name == ')':
      # HACK(nnorwitz): Handle pointers to functions "properly".
      if (len(tokens) >= 4 and
              tokens[1].name == '(' and tokens[2].name == '*'):
        tokens.append(name)
        name = tokens[3]
    elif name.name == ']':
      # HACK(nnorwitz): Handle arrays properly.
      if len(tokens) >= 2:
        tokens.append(name)
        name = tokens[1]
    new_type = tokens
    if tokens and isinstance(tokens[0], tokenize.Token):
      new_type = self.converter.ToType(tokens)[0]
    return Typedef(indices.start, indices.end, name.name,
                   new_type, self.namespace_stack)

  def handle_typeid(self):
    pass  # Not needed yet.

  def handle_typename(self):
    pass  # Not needed yet.

  def _GetTemplatedTypes(self):
    result = {}
    tokens = list(self._GetMatchingChar('<', '>'))
    len_tokens = len(tokens) - 1    # Ignore trailing '>'.
    i = 0
    while i < len_tokens:
      key = tokens[i].name
      i += 1
      if keywords.IsKeyword(key) or key == ',':
        continue
      type_name = default = None
      if i < len_tokens:
        i += 1
        if tokens[i-1].name == '=':
          assert i < len_tokens, '%s %s' % (i, tokens)
          default, unused_next_token = self.GetName(tokens[i:])
          i += len(default)
        else:
          if tokens[i-1].name != ',':
            # We got something like: Type variable.
            # Re-adjust the key (variable) and type_name (Type).
            key = tokens[i-1].name
            type_name = tokens[i-2]

      result[key] = (type_name, default)
    return result

  def handle_template(self):
    token = self._GetNextToken()
    assert token.token_type == tokenize.SYNTAX, token
    assert token.name == '<', token
    templated_types = self._GetTemplatedTypes()
    # TODO(nnorwitz): for now, just ignore the template params.
    token = self._GetNextToken()
    if token.token_type == tokenize.NAME:
      if token.name == 'class':
        return self._GetClass(Class, VISIBILITY_PRIVATE, templated_types)
      elif token.name == 'struct':
        return self._GetClass(Struct, VISIBILITY_PUBLIC, templated_types)
      elif token.name == 'friend':
        return self.handle_friend()
    self._AddBackToken(token)
    tokens, last = self._GetVarTokensUpTo(tokenize.SYNTAX, '(', ';')
    tokens.append(last)
    self._AddBackTokens(tokens)
    if last.name == '(':
      return self.GetMethod(FUNCTION_NONE, templated_types)
    # Must be a variable definition.
    return None

  def handle_true(self):
    pass  # Nothing to do.

  def handle_false(self):
    pass  # Nothing to do.

  def handle_asm(self):
    pass  # Not needed yet.

  def handle_class(self):
    return self._GetClass(Class, VISIBILITY_PRIVATE, None)

  def _GetBases(self):
    # Get base classes.
    bases = []
    while 1:
      token = self._GetNextToken()
      assert token.token_type == tokenize.NAME, token
      # TODO(nnorwitz): store kind of inheritance...maybe.
      if token.name not in ('public', 'protected', 'private'):
        # If inheritance type is not specified, it is private.
        # Just put the token back so we can form a name.
        # TODO(nnorwitz): it would be good to warn about this.
        self._AddBackToken(token)
      else:
        # Check for virtual inheritance.
        token = self._GetNextToken()
        if token.name != 'virtual':
          self._AddBackToken(token)
        else:
          # TODO(nnorwitz): store that we got virtual for this base.
          pass
      base, next_token = self.GetName()
      bases_ast = self.converter.ToType(base)
      assert len(bases_ast) == 1, bases_ast
      bases.append(bases_ast[0])
      assert next_token.token_type == tokenize.SYNTAX, next_token
      if next_token.name == '{':
        token = next_token
        break
      # Support multiple inheritance.
      assert next_token.name == ',', next_token
    return bases, token

  def _GetClass(self, class_type, visibility, templated_types):
    class_name = None
    class_token = self._GetNextToken()
    if class_token.token_type != tokenize.NAME:
      assert class_token.token_type == tokenize.SYNTAX, class_token
      token = class_token
    else:
      # Skip any macro (e.g. storage class specifiers) after the
      # 'class' keyword.
      next_token = self._GetNextToken()
      if next_token.token_type == tokenize.NAME:
        self._AddBackToken(next_token)
      else:
        self._AddBackTokens([class_token, next_token])
      name_tokens, token = self.GetName()
      class_name = ''.join([t.name for t in name_tokens])
    bases = None
    if token.token_type == tokenize.SYNTAX:
      if token.name == ';':
        # Forward declaration.
        return class_type(class_token.start, class_token.end,
                          class_name, None, templated_types, None,
                          self.namespace_stack)
      if token.name in '*&':
        # Inline forward declaration.  Could be method or data.
        name_token = self._GetNextToken()
        next_token = self._GetNextToken()
        if next_token.name == ';':
          # Handle data
          modifiers = ['class']
          return self._CreateVariable(class_token, name_token.name,
                                      class_name,
                                      modifiers, token.name, None)
        else:
          # Assume this is a method.
          tokens = (class_token, token, name_token, next_token)
          self._AddBackTokens(tokens)
          return self.GetMethod(FUNCTION_NONE, None)
      if token.name == ':':
        bases, token = self._GetBases()

    body = None
    if token.token_type == tokenize.SYNTAX and token.name == '{':
      assert token.token_type == tokenize.SYNTAX, token
      assert token.name == '{', token

      ast = AstBuilder(self.GetScope(), self.filename, class_name,
                       visibility, self.namespace_stack)
      body = list(ast.Generate())

      if not self._handling_typedef:
        token = self._GetNextToken()
        if token.token_type != tokenize.NAME:
          assert token.token_type == tokenize.SYNTAX, token
          assert token.name == ';', token
        else:
          new_class = class_type(class_token.start, class_token.end,
                                 class_name, bases, None,
                                 body, self.namespace_stack)

          modifiers = []
          return self._CreateVariable(class_token,
                                      token.name, new_class,
                                      modifiers, token.name, None)
    else:
      if not self._handling_typedef:
        self.HandleError('non-typedef token', token)
      self._AddBackToken(token)

    return class_type(class_token.start, class_token.end, class_name,
                      bases, templated_types, body, self.namespace_stack)

  def handle_namespace(self):
    # Support anonymous namespaces.
    name = None
    name_tokens, token = self.GetName()
    if name_tokens:
      name = ''.join([t.name for t in name_tokens])
    self.namespace_stack.append(name)
    assert token.token_type == tokenize.SYNTAX, token
    # Create an internal token that denotes when the namespace is complete.
    internal_token = tokenize.Token(_INTERNAL_TOKEN, _NAMESPACE_POP,
                                    None, None)
    internal_token.whence = token.whence
    if token.name == '=':
      # TODO(nnorwitz): handle aliasing namespaces.
      name, next_token = self.GetName()
      assert next_token.name == ';', next_token
      self._AddBackToken(internal_token)
    else:
      assert token.name == '{', token
      tokens = list(self.GetScope())
      # Replace the trailing } with the internal namespace pop token.
      tokens[-1] = internal_token
      # Handle namespace with nothing in it.
      self._AddBackTokens(tokens)
    return None

  def handle_using(self):
    tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';')
    assert tokens
    return Using(tokens[0].start, tokens[0].end, tokens)

  def handle_explicit(self):
    assert self.in_class
    # Nothing much to do.
    # TODO(nnorwitz): maybe verify the method name == class name.
    # This must be a ctor.
    return self.GetMethod(FUNCTION_CTOR, None)

  def handle_this(self):
    pass  # Nothing to do.

  def handle_operator(self):
    # Pull off the next token(s?) and make that part of the method name.
    pass

  def handle_sizeof(self):
    pass

  def handle_case(self):
    pass

  def handle_switch(self):
    pass

  def handle_default(self):
    token = self._GetNextToken()
    assert token.token_type == tokenize.SYNTAX
    assert token.name == ':'

  def handle_if(self):
    pass

  def handle_else(self):
    pass

  def handle_return(self):
    tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';')
    if not tokens:
      return Return(self.current_token.start, self.current_token.end, None)
    return Return(tokens[0].start, tokens[0].end, tokens)

  def handle_goto(self):
    tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';')
    assert len(tokens) == 1, str(tokens)
    return Goto(tokens[0].start, tokens[0].end, tokens[0].name)

  def handle_try(self):
    pass  # Not needed yet.

  def handle_catch(self):
    pass  # Not needed yet.

  def handle_throw(self):
    pass  # Not needed yet.

  def handle_while(self):
    pass

  def handle_do(self):
    pass

  def handle_for(self):
    pass

  def handle_break(self):
    self._IgnoreUpTo(tokenize.SYNTAX, ';')

  def handle_continue(self):
    self._IgnoreUpTo(tokenize.SYNTAX, ';')


def BuilderFromSource(source, filename):
  """Utility method that returns an AstBuilder from source code.

    Args:
      source: 'C++ source code'
      filename: 'file1'

    Returns:
      AstBuilder
    """
  return AstBuilder(tokenize.GetTokens(source), filename)


def PrintIndentifiers(filename, should_print):
  """Prints all identifiers for a C++ source file.

    Args:
      filename: 'file1'
      should_print: predicate with signature: bool Function(token)
    """
  source = utils.ReadFile(filename, False)
  if source is None:
    sys.stderr.write('Unable to find: %s\n' % filename)
    return

  #print('Processing %s' % actual_filename)
  builder = BuilderFromSource(source, filename)
  try:
    for node in builder.Generate():
      if should_print(node):
        print(node.name)
  except KeyboardInterrupt:
    return
  except:
    pass


def PrintAllIndentifiers(filenames, should_print):
  """Prints all identifiers for each C++ source file in filenames.

    Args:
      filenames: ['file1', 'file2', ...]
      should_print: predicate with signature: bool Function(token)
    """
  for path in filenames:
    PrintIndentifiers(path, should_print)


def main(argv):
  for filename in argv[1:]:
    source = utils.ReadFile(filename)
    if source is None:
      continue

    print('Processing %s' % filename)
    builder = BuilderFromSource(source, filename)
    try:
      entire_ast = filter(None, builder.Generate())
    except KeyboardInterrupt:
      return
    except:
      # Already printed a warning, print the traceback and continue.
      traceback.print_exc()
    else:
      if utils.DEBUG:
        for ast in entire_ast:
          print(ast)


if __name__ == '__main__':
  main(sys.argv)
