#!/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 collections
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 comparison.
        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 comparison.
      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 necessary.
  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 = collections.OrderedDict()
    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)
