1e35fdd936d133bf8a48de140a3c666897588a05shiqian#!/usr/bin/env python 2e35fdd936d133bf8a48de140a3c666897588a05shiqian# 3e35fdd936d133bf8a48de140a3c666897588a05shiqian# Copyright 2007 Neal Norwitz 4e35fdd936d133bf8a48de140a3c666897588a05shiqian# Portions Copyright 2007 Google Inc. 5e35fdd936d133bf8a48de140a3c666897588a05shiqian# 6e35fdd936d133bf8a48de140a3c666897588a05shiqian# Licensed under the Apache License, Version 2.0 (the "License"); 7e35fdd936d133bf8a48de140a3c666897588a05shiqian# you may not use this file except in compliance with the License. 8e35fdd936d133bf8a48de140a3c666897588a05shiqian# You may obtain a copy of the License at 9e35fdd936d133bf8a48de140a3c666897588a05shiqian# 10e35fdd936d133bf8a48de140a3c666897588a05shiqian# http://www.apache.org/licenses/LICENSE-2.0 11e35fdd936d133bf8a48de140a3c666897588a05shiqian# 12e35fdd936d133bf8a48de140a3c666897588a05shiqian# Unless required by applicable law or agreed to in writing, software 13e35fdd936d133bf8a48de140a3c666897588a05shiqian# distributed under the License is distributed on an "AS IS" BASIS, 14e35fdd936d133bf8a48de140a3c666897588a05shiqian# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15e35fdd936d133bf8a48de140a3c666897588a05shiqian# See the License for the specific language governing permissions and 16e35fdd936d133bf8a48de140a3c666897588a05shiqian# limitations under the License. 17e35fdd936d133bf8a48de140a3c666897588a05shiqian 18e35fdd936d133bf8a48de140a3c666897588a05shiqian"""Generate an Abstract Syntax Tree (AST) for C++.""" 19e35fdd936d133bf8a48de140a3c666897588a05shiqian 20e35fdd936d133bf8a48de140a3c666897588a05shiqian__author__ = 'nnorwitz@google.com (Neal Norwitz)' 21e35fdd936d133bf8a48de140a3c666897588a05shiqian 22e35fdd936d133bf8a48de140a3c666897588a05shiqian 23e35fdd936d133bf8a48de140a3c666897588a05shiqian# TODO: 24e35fdd936d133bf8a48de140a3c666897588a05shiqian# * Tokens should never be exported, need to convert to Nodes 25e35fdd936d133bf8a48de140a3c666897588a05shiqian# (return types, parameters, etc.) 26e35fdd936d133bf8a48de140a3c666897588a05shiqian# * Handle static class data for templatized classes 27e35fdd936d133bf8a48de140a3c666897588a05shiqian# * Handle casts (both C++ and C-style) 28e35fdd936d133bf8a48de140a3c666897588a05shiqian# * Handle conditions and loops (if/else, switch, for, while/do) 29e35fdd936d133bf8a48de140a3c666897588a05shiqian# 30e35fdd936d133bf8a48de140a3c666897588a05shiqian# TODO much, much later: 31e35fdd936d133bf8a48de140a3c666897588a05shiqian# * Handle #define 32e35fdd936d133bf8a48de140a3c666897588a05shiqian# * exceptions 33e35fdd936d133bf8a48de140a3c666897588a05shiqian 34e35fdd936d133bf8a48de140a3c666897588a05shiqian 35e35fdd936d133bf8a48de140a3c666897588a05shiqiantry: 36e35fdd936d133bf8a48de140a3c666897588a05shiqian # Python 3.x 37e35fdd936d133bf8a48de140a3c666897588a05shiqian import builtins 38e35fdd936d133bf8a48de140a3c666897588a05shiqianexcept ImportError: 39e35fdd936d133bf8a48de140a3c666897588a05shiqian # Python 2.x 40e35fdd936d133bf8a48de140a3c666897588a05shiqian import __builtin__ as builtins 41e35fdd936d133bf8a48de140a3c666897588a05shiqian 42e35fdd936d133bf8a48de140a3c666897588a05shiqianimport sys 43e35fdd936d133bf8a48de140a3c666897588a05shiqianimport traceback 44e35fdd936d133bf8a48de140a3c666897588a05shiqian 45e35fdd936d133bf8a48de140a3c666897588a05shiqianfrom cpp import keywords 46e35fdd936d133bf8a48de140a3c666897588a05shiqianfrom cpp import tokenize 47e35fdd936d133bf8a48de140a3c666897588a05shiqianfrom cpp import utils 48e35fdd936d133bf8a48de140a3c666897588a05shiqian 49e35fdd936d133bf8a48de140a3c666897588a05shiqian 50e35fdd936d133bf8a48de140a3c666897588a05shiqianif not hasattr(builtins, 'reversed'): 51e35fdd936d133bf8a48de140a3c666897588a05shiqian # Support Python 2.3 and earlier. 52e35fdd936d133bf8a48de140a3c666897588a05shiqian def reversed(seq): 53e35fdd936d133bf8a48de140a3c666897588a05shiqian for i in range(len(seq)-1, -1, -1): 54e35fdd936d133bf8a48de140a3c666897588a05shiqian yield seq[i] 55e35fdd936d133bf8a48de140a3c666897588a05shiqian 56e35fdd936d133bf8a48de140a3c666897588a05shiqianif not hasattr(builtins, 'next'): 57e35fdd936d133bf8a48de140a3c666897588a05shiqian # Support Python 2.5 and earlier. 58e35fdd936d133bf8a48de140a3c666897588a05shiqian def next(obj): 59e35fdd936d133bf8a48de140a3c666897588a05shiqian return obj.next() 60e35fdd936d133bf8a48de140a3c666897588a05shiqian 61e35fdd936d133bf8a48de140a3c666897588a05shiqian 62e35fdd936d133bf8a48de140a3c666897588a05shiqianVISIBILITY_PUBLIC, VISIBILITY_PROTECTED, VISIBILITY_PRIVATE = range(3) 63e35fdd936d133bf8a48de140a3c666897588a05shiqian 64e35fdd936d133bf8a48de140a3c666897588a05shiqianFUNCTION_NONE = 0x00 65e35fdd936d133bf8a48de140a3c666897588a05shiqianFUNCTION_CONST = 0x01 66e35fdd936d133bf8a48de140a3c666897588a05shiqianFUNCTION_VIRTUAL = 0x02 67e35fdd936d133bf8a48de140a3c666897588a05shiqianFUNCTION_PURE_VIRTUAL = 0x04 68e35fdd936d133bf8a48de140a3c666897588a05shiqianFUNCTION_CTOR = 0x08 69e35fdd936d133bf8a48de140a3c666897588a05shiqianFUNCTION_DTOR = 0x10 70e35fdd936d133bf8a48de140a3c666897588a05shiqianFUNCTION_ATTRIBUTE = 0x20 71e35fdd936d133bf8a48de140a3c666897588a05shiqianFUNCTION_UNKNOWN_ANNOTATION = 0x40 72e35fdd936d133bf8a48de140a3c666897588a05shiqianFUNCTION_THROW = 0x80 73c26f969579d62444ae7d422b37e0037ceca97a7akosakFUNCTION_OVERRIDE = 0x100 74e35fdd936d133bf8a48de140a3c666897588a05shiqian 75e35fdd936d133bf8a48de140a3c666897588a05shiqian""" 76e35fdd936d133bf8a48de140a3c666897588a05shiqianThese are currently unused. Should really handle these properly at some point. 77e35fdd936d133bf8a48de140a3c666897588a05shiqian 78e35fdd936d133bf8a48de140a3c666897588a05shiqianTYPE_MODIFIER_INLINE = 0x010000 79e35fdd936d133bf8a48de140a3c666897588a05shiqianTYPE_MODIFIER_EXTERN = 0x020000 80e35fdd936d133bf8a48de140a3c666897588a05shiqianTYPE_MODIFIER_STATIC = 0x040000 81e35fdd936d133bf8a48de140a3c666897588a05shiqianTYPE_MODIFIER_CONST = 0x080000 82e35fdd936d133bf8a48de140a3c666897588a05shiqianTYPE_MODIFIER_REGISTER = 0x100000 83e35fdd936d133bf8a48de140a3c666897588a05shiqianTYPE_MODIFIER_VOLATILE = 0x200000 84e35fdd936d133bf8a48de140a3c666897588a05shiqianTYPE_MODIFIER_MUTABLE = 0x400000 85e35fdd936d133bf8a48de140a3c666897588a05shiqian 86e35fdd936d133bf8a48de140a3c666897588a05shiqianTYPE_MODIFIER_MAP = { 87e35fdd936d133bf8a48de140a3c666897588a05shiqian 'inline': TYPE_MODIFIER_INLINE, 88e35fdd936d133bf8a48de140a3c666897588a05shiqian 'extern': TYPE_MODIFIER_EXTERN, 89e35fdd936d133bf8a48de140a3c666897588a05shiqian 'static': TYPE_MODIFIER_STATIC, 90e35fdd936d133bf8a48de140a3c666897588a05shiqian 'const': TYPE_MODIFIER_CONST, 91e35fdd936d133bf8a48de140a3c666897588a05shiqian 'register': TYPE_MODIFIER_REGISTER, 92e35fdd936d133bf8a48de140a3c666897588a05shiqian 'volatile': TYPE_MODIFIER_VOLATILE, 93e35fdd936d133bf8a48de140a3c666897588a05shiqian 'mutable': TYPE_MODIFIER_MUTABLE, 94e35fdd936d133bf8a48de140a3c666897588a05shiqian } 95e35fdd936d133bf8a48de140a3c666897588a05shiqian""" 96e35fdd936d133bf8a48de140a3c666897588a05shiqian 97e35fdd936d133bf8a48de140a3c666897588a05shiqian_INTERNAL_TOKEN = 'internal' 98e35fdd936d133bf8a48de140a3c666897588a05shiqian_NAMESPACE_POP = 'ns-pop' 99e35fdd936d133bf8a48de140a3c666897588a05shiqian 100e35fdd936d133bf8a48de140a3c666897588a05shiqian 101e35fdd936d133bf8a48de140a3c666897588a05shiqian# TODO(nnorwitz): use this as a singleton for templated_types, etc 102e35fdd936d133bf8a48de140a3c666897588a05shiqian# where we don't want to create a new empty dict each time. It is also const. 103e35fdd936d133bf8a48de140a3c666897588a05shiqianclass _NullDict(object): 104e35fdd936d133bf8a48de140a3c666897588a05shiqian __contains__ = lambda self: False 105e35fdd936d133bf8a48de140a3c666897588a05shiqian keys = values = items = iterkeys = itervalues = iteritems = lambda self: () 106e35fdd936d133bf8a48de140a3c666897588a05shiqian 107e35fdd936d133bf8a48de140a3c666897588a05shiqian 108e35fdd936d133bf8a48de140a3c666897588a05shiqian# TODO(nnorwitz): move AST nodes into a separate module. 109e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Node(object): 110e35fdd936d133bf8a48de140a3c666897588a05shiqian """Base AST node.""" 111e35fdd936d133bf8a48de140a3c666897588a05shiqian 112e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end): 113e35fdd936d133bf8a48de140a3c666897588a05shiqian self.start = start 114e35fdd936d133bf8a48de140a3c666897588a05shiqian self.end = end 115e35fdd936d133bf8a48de140a3c666897588a05shiqian 116e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsDeclaration(self): 117e35fdd936d133bf8a48de140a3c666897588a05shiqian """Returns bool if this node is a declaration.""" 118e35fdd936d133bf8a48de140a3c666897588a05shiqian return False 119e35fdd936d133bf8a48de140a3c666897588a05shiqian 120e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsDefinition(self): 121e35fdd936d133bf8a48de140a3c666897588a05shiqian """Returns bool if this node is a definition.""" 122e35fdd936d133bf8a48de140a3c666897588a05shiqian return False 123e35fdd936d133bf8a48de140a3c666897588a05shiqian 124e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsExportable(self): 125e35fdd936d133bf8a48de140a3c666897588a05shiqian """Returns bool if this node exportable from a header file.""" 126e35fdd936d133bf8a48de140a3c666897588a05shiqian return False 127e35fdd936d133bf8a48de140a3c666897588a05shiqian 128e35fdd936d133bf8a48de140a3c666897588a05shiqian def Requires(self, node): 129e35fdd936d133bf8a48de140a3c666897588a05shiqian """Does this AST node require the definition of the node passed in?""" 130e35fdd936d133bf8a48de140a3c666897588a05shiqian return False 131e35fdd936d133bf8a48de140a3c666897588a05shiqian 132e35fdd936d133bf8a48de140a3c666897588a05shiqian def XXX__str__(self): 133e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._StringHelper(self.__class__.__name__, '') 134e35fdd936d133bf8a48de140a3c666897588a05shiqian 135e35fdd936d133bf8a48de140a3c666897588a05shiqian def _StringHelper(self, name, suffix): 136e35fdd936d133bf8a48de140a3c666897588a05shiqian if not utils.DEBUG: 137e35fdd936d133bf8a48de140a3c666897588a05shiqian return '%s(%s)' % (name, suffix) 138e35fdd936d133bf8a48de140a3c666897588a05shiqian return '%s(%d, %d, %s)' % (name, self.start, self.end, suffix) 139e35fdd936d133bf8a48de140a3c666897588a05shiqian 140e35fdd936d133bf8a48de140a3c666897588a05shiqian def __repr__(self): 141e35fdd936d133bf8a48de140a3c666897588a05shiqian return str(self) 142e35fdd936d133bf8a48de140a3c666897588a05shiqian 143e35fdd936d133bf8a48de140a3c666897588a05shiqian 144e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Define(Node): 145e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end, name, definition): 146e35fdd936d133bf8a48de140a3c666897588a05shiqian Node.__init__(self, start, end) 147e35fdd936d133bf8a48de140a3c666897588a05shiqian self.name = name 148e35fdd936d133bf8a48de140a3c666897588a05shiqian self.definition = definition 149e35fdd936d133bf8a48de140a3c666897588a05shiqian 150e35fdd936d133bf8a48de140a3c666897588a05shiqian def __str__(self): 151e35fdd936d133bf8a48de140a3c666897588a05shiqian value = '%s %s' % (self.name, self.definition) 152e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._StringHelper(self.__class__.__name__, value) 153e35fdd936d133bf8a48de140a3c666897588a05shiqian 154e35fdd936d133bf8a48de140a3c666897588a05shiqian 155e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Include(Node): 156e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end, filename, system): 157e35fdd936d133bf8a48de140a3c666897588a05shiqian Node.__init__(self, start, end) 158e35fdd936d133bf8a48de140a3c666897588a05shiqian self.filename = filename 159e35fdd936d133bf8a48de140a3c666897588a05shiqian self.system = system 160e35fdd936d133bf8a48de140a3c666897588a05shiqian 161e35fdd936d133bf8a48de140a3c666897588a05shiqian def __str__(self): 162e35fdd936d133bf8a48de140a3c666897588a05shiqian fmt = '"%s"' 163e35fdd936d133bf8a48de140a3c666897588a05shiqian if self.system: 164e35fdd936d133bf8a48de140a3c666897588a05shiqian fmt = '<%s>' 165e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._StringHelper(self.__class__.__name__, fmt % self.filename) 166e35fdd936d133bf8a48de140a3c666897588a05shiqian 167e35fdd936d133bf8a48de140a3c666897588a05shiqian 168e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Goto(Node): 169e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end, label): 170e35fdd936d133bf8a48de140a3c666897588a05shiqian Node.__init__(self, start, end) 171e35fdd936d133bf8a48de140a3c666897588a05shiqian self.label = label 172e35fdd936d133bf8a48de140a3c666897588a05shiqian 173e35fdd936d133bf8a48de140a3c666897588a05shiqian def __str__(self): 174e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._StringHelper(self.__class__.__name__, str(self.label)) 175e35fdd936d133bf8a48de140a3c666897588a05shiqian 176e35fdd936d133bf8a48de140a3c666897588a05shiqian 177e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Expr(Node): 178e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end, expr): 179e35fdd936d133bf8a48de140a3c666897588a05shiqian Node.__init__(self, start, end) 180e35fdd936d133bf8a48de140a3c666897588a05shiqian self.expr = expr 181e35fdd936d133bf8a48de140a3c666897588a05shiqian 182e35fdd936d133bf8a48de140a3c666897588a05shiqian def Requires(self, node): 183e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): impl. 184e35fdd936d133bf8a48de140a3c666897588a05shiqian return False 185e35fdd936d133bf8a48de140a3c666897588a05shiqian 186e35fdd936d133bf8a48de140a3c666897588a05shiqian def __str__(self): 187e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._StringHelper(self.__class__.__name__, str(self.expr)) 188e35fdd936d133bf8a48de140a3c666897588a05shiqian 189e35fdd936d133bf8a48de140a3c666897588a05shiqian 190e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Return(Expr): 191e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 192e35fdd936d133bf8a48de140a3c666897588a05shiqian 193e35fdd936d133bf8a48de140a3c666897588a05shiqian 194e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Delete(Expr): 195e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 196e35fdd936d133bf8a48de140a3c666897588a05shiqian 197e35fdd936d133bf8a48de140a3c666897588a05shiqian 198e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Friend(Expr): 199e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end, expr, namespace): 200e35fdd936d133bf8a48de140a3c666897588a05shiqian Expr.__init__(self, start, end, expr) 201e35fdd936d133bf8a48de140a3c666897588a05shiqian self.namespace = namespace[:] 202e35fdd936d133bf8a48de140a3c666897588a05shiqian 203e35fdd936d133bf8a48de140a3c666897588a05shiqian 204e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Using(Node): 205e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end, names): 206e35fdd936d133bf8a48de140a3c666897588a05shiqian Node.__init__(self, start, end) 207e35fdd936d133bf8a48de140a3c666897588a05shiqian self.names = names 208e35fdd936d133bf8a48de140a3c666897588a05shiqian 209e35fdd936d133bf8a48de140a3c666897588a05shiqian def __str__(self): 210e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._StringHelper(self.__class__.__name__, str(self.names)) 211e35fdd936d133bf8a48de140a3c666897588a05shiqian 212e35fdd936d133bf8a48de140a3c666897588a05shiqian 213e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Parameter(Node): 214e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end, name, parameter_type, default): 215e35fdd936d133bf8a48de140a3c666897588a05shiqian Node.__init__(self, start, end) 216e35fdd936d133bf8a48de140a3c666897588a05shiqian self.name = name 217e35fdd936d133bf8a48de140a3c666897588a05shiqian self.type = parameter_type 218e35fdd936d133bf8a48de140a3c666897588a05shiqian self.default = default 219e35fdd936d133bf8a48de140a3c666897588a05shiqian 220e35fdd936d133bf8a48de140a3c666897588a05shiqian def Requires(self, node): 221e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): handle namespaces, etc. 222e35fdd936d133bf8a48de140a3c666897588a05shiqian return self.type.name == node.name 223e35fdd936d133bf8a48de140a3c666897588a05shiqian 224e35fdd936d133bf8a48de140a3c666897588a05shiqian def __str__(self): 225e35fdd936d133bf8a48de140a3c666897588a05shiqian name = str(self.type) 226e35fdd936d133bf8a48de140a3c666897588a05shiqian suffix = '%s %s' % (name, self.name) 227e35fdd936d133bf8a48de140a3c666897588a05shiqian if self.default: 228e35fdd936d133bf8a48de140a3c666897588a05shiqian suffix += ' = ' + ''.join([d.name for d in self.default]) 229e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._StringHelper(self.__class__.__name__, suffix) 230e35fdd936d133bf8a48de140a3c666897588a05shiqian 231e35fdd936d133bf8a48de140a3c666897588a05shiqian 232e35fdd936d133bf8a48de140a3c666897588a05shiqianclass _GenericDeclaration(Node): 233e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end, name, namespace): 234e35fdd936d133bf8a48de140a3c666897588a05shiqian Node.__init__(self, start, end) 235e35fdd936d133bf8a48de140a3c666897588a05shiqian self.name = name 236e35fdd936d133bf8a48de140a3c666897588a05shiqian self.namespace = namespace[:] 237e35fdd936d133bf8a48de140a3c666897588a05shiqian 238e35fdd936d133bf8a48de140a3c666897588a05shiqian def FullName(self): 239e35fdd936d133bf8a48de140a3c666897588a05shiqian prefix = '' 240e35fdd936d133bf8a48de140a3c666897588a05shiqian if self.namespace and self.namespace[-1]: 241e35fdd936d133bf8a48de140a3c666897588a05shiqian prefix = '::'.join(self.namespace) + '::' 242e35fdd936d133bf8a48de140a3c666897588a05shiqian return prefix + self.name 243e35fdd936d133bf8a48de140a3c666897588a05shiqian 244e35fdd936d133bf8a48de140a3c666897588a05shiqian def _TypeStringHelper(self, suffix): 245e35fdd936d133bf8a48de140a3c666897588a05shiqian if self.namespace: 246e35fdd936d133bf8a48de140a3c666897588a05shiqian names = [n or '<anonymous>' for n in self.namespace] 247e35fdd936d133bf8a48de140a3c666897588a05shiqian suffix += ' in ' + '::'.join(names) 248e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._StringHelper(self.__class__.__name__, suffix) 249e35fdd936d133bf8a48de140a3c666897588a05shiqian 250e35fdd936d133bf8a48de140a3c666897588a05shiqian 251e35fdd936d133bf8a48de140a3c666897588a05shiqian# TODO(nnorwitz): merge with Parameter in some way? 252e35fdd936d133bf8a48de140a3c666897588a05shiqianclass VariableDeclaration(_GenericDeclaration): 253e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end, name, var_type, initial_value, namespace): 254e35fdd936d133bf8a48de140a3c666897588a05shiqian _GenericDeclaration.__init__(self, start, end, name, namespace) 255e35fdd936d133bf8a48de140a3c666897588a05shiqian self.type = var_type 256e35fdd936d133bf8a48de140a3c666897588a05shiqian self.initial_value = initial_value 257e35fdd936d133bf8a48de140a3c666897588a05shiqian 258e35fdd936d133bf8a48de140a3c666897588a05shiqian def Requires(self, node): 259e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): handle namespaces, etc. 260e35fdd936d133bf8a48de140a3c666897588a05shiqian return self.type.name == node.name 261e35fdd936d133bf8a48de140a3c666897588a05shiqian 262e35fdd936d133bf8a48de140a3c666897588a05shiqian def ToString(self): 263e35fdd936d133bf8a48de140a3c666897588a05shiqian """Return a string that tries to reconstitute the variable decl.""" 264e35fdd936d133bf8a48de140a3c666897588a05shiqian suffix = '%s %s' % (self.type, self.name) 265e35fdd936d133bf8a48de140a3c666897588a05shiqian if self.initial_value: 266e35fdd936d133bf8a48de140a3c666897588a05shiqian suffix += ' = ' + self.initial_value 267e35fdd936d133bf8a48de140a3c666897588a05shiqian return suffix 268e35fdd936d133bf8a48de140a3c666897588a05shiqian 269e35fdd936d133bf8a48de140a3c666897588a05shiqian def __str__(self): 270e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._StringHelper(self.__class__.__name__, self.ToString()) 271e35fdd936d133bf8a48de140a3c666897588a05shiqian 272e35fdd936d133bf8a48de140a3c666897588a05shiqian 273e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Typedef(_GenericDeclaration): 274e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end, name, alias, namespace): 275e35fdd936d133bf8a48de140a3c666897588a05shiqian _GenericDeclaration.__init__(self, start, end, name, namespace) 276e35fdd936d133bf8a48de140a3c666897588a05shiqian self.alias = alias 277e35fdd936d133bf8a48de140a3c666897588a05shiqian 278e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsDefinition(self): 279e35fdd936d133bf8a48de140a3c666897588a05shiqian return True 280e35fdd936d133bf8a48de140a3c666897588a05shiqian 281e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsExportable(self): 282e35fdd936d133bf8a48de140a3c666897588a05shiqian return True 283e35fdd936d133bf8a48de140a3c666897588a05shiqian 284e35fdd936d133bf8a48de140a3c666897588a05shiqian def Requires(self, node): 285e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): handle namespaces, etc. 286e35fdd936d133bf8a48de140a3c666897588a05shiqian name = node.name 287e35fdd936d133bf8a48de140a3c666897588a05shiqian for token in self.alias: 288e35fdd936d133bf8a48de140a3c666897588a05shiqian if token is not None and name == token.name: 289e35fdd936d133bf8a48de140a3c666897588a05shiqian return True 290e35fdd936d133bf8a48de140a3c666897588a05shiqian return False 291e35fdd936d133bf8a48de140a3c666897588a05shiqian 292e35fdd936d133bf8a48de140a3c666897588a05shiqian def __str__(self): 293e35fdd936d133bf8a48de140a3c666897588a05shiqian suffix = '%s, %s' % (self.name, self.alias) 294e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._TypeStringHelper(suffix) 295e35fdd936d133bf8a48de140a3c666897588a05shiqian 296e35fdd936d133bf8a48de140a3c666897588a05shiqian 297e35fdd936d133bf8a48de140a3c666897588a05shiqianclass _NestedType(_GenericDeclaration): 298e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end, name, fields, namespace): 299e35fdd936d133bf8a48de140a3c666897588a05shiqian _GenericDeclaration.__init__(self, start, end, name, namespace) 300e35fdd936d133bf8a48de140a3c666897588a05shiqian self.fields = fields 301e35fdd936d133bf8a48de140a3c666897588a05shiqian 302e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsDefinition(self): 303e35fdd936d133bf8a48de140a3c666897588a05shiqian return True 304e35fdd936d133bf8a48de140a3c666897588a05shiqian 305e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsExportable(self): 306e35fdd936d133bf8a48de140a3c666897588a05shiqian return True 307e35fdd936d133bf8a48de140a3c666897588a05shiqian 308e35fdd936d133bf8a48de140a3c666897588a05shiqian def __str__(self): 309e35fdd936d133bf8a48de140a3c666897588a05shiqian suffix = '%s, {%s}' % (self.name, self.fields) 310e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._TypeStringHelper(suffix) 311e35fdd936d133bf8a48de140a3c666897588a05shiqian 312e35fdd936d133bf8a48de140a3c666897588a05shiqian 313e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Union(_NestedType): 314e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 315e35fdd936d133bf8a48de140a3c666897588a05shiqian 316e35fdd936d133bf8a48de140a3c666897588a05shiqian 317e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Enum(_NestedType): 318e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 319e35fdd936d133bf8a48de140a3c666897588a05shiqian 320e35fdd936d133bf8a48de140a3c666897588a05shiqian 321e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Class(_GenericDeclaration): 322e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end, name, bases, templated_types, body, namespace): 323e35fdd936d133bf8a48de140a3c666897588a05shiqian _GenericDeclaration.__init__(self, start, end, name, namespace) 324e35fdd936d133bf8a48de140a3c666897588a05shiqian self.bases = bases 325e35fdd936d133bf8a48de140a3c666897588a05shiqian self.body = body 326e35fdd936d133bf8a48de140a3c666897588a05shiqian self.templated_types = templated_types 327e35fdd936d133bf8a48de140a3c666897588a05shiqian 328e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsDeclaration(self): 329e35fdd936d133bf8a48de140a3c666897588a05shiqian return self.bases is None and self.body is None 330e35fdd936d133bf8a48de140a3c666897588a05shiqian 331e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsDefinition(self): 332e35fdd936d133bf8a48de140a3c666897588a05shiqian return not self.IsDeclaration() 333e35fdd936d133bf8a48de140a3c666897588a05shiqian 334e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsExportable(self): 335e35fdd936d133bf8a48de140a3c666897588a05shiqian return not self.IsDeclaration() 336e35fdd936d133bf8a48de140a3c666897588a05shiqian 337e35fdd936d133bf8a48de140a3c666897588a05shiqian def Requires(self, node): 338e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): handle namespaces, etc. 339e35fdd936d133bf8a48de140a3c666897588a05shiqian if self.bases: 340e35fdd936d133bf8a48de140a3c666897588a05shiqian for token_list in self.bases: 341e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): bases are tokens, do name comparision. 342e35fdd936d133bf8a48de140a3c666897588a05shiqian for token in token_list: 343e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == node.name: 344e35fdd936d133bf8a48de140a3c666897588a05shiqian return True 345e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): search in body too. 346e35fdd936d133bf8a48de140a3c666897588a05shiqian return False 347e35fdd936d133bf8a48de140a3c666897588a05shiqian 348e35fdd936d133bf8a48de140a3c666897588a05shiqian def __str__(self): 349e35fdd936d133bf8a48de140a3c666897588a05shiqian name = self.name 350e35fdd936d133bf8a48de140a3c666897588a05shiqian if self.templated_types: 351e35fdd936d133bf8a48de140a3c666897588a05shiqian name += '<%s>' % self.templated_types 352e35fdd936d133bf8a48de140a3c666897588a05shiqian suffix = '%s, %s, %s' % (name, self.bases, self.body) 353e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._TypeStringHelper(suffix) 354e35fdd936d133bf8a48de140a3c666897588a05shiqian 355e35fdd936d133bf8a48de140a3c666897588a05shiqian 356e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Struct(Class): 357e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 358e35fdd936d133bf8a48de140a3c666897588a05shiqian 359e35fdd936d133bf8a48de140a3c666897588a05shiqian 360e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Function(_GenericDeclaration): 361e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end, name, return_type, parameters, 362e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers, templated_types, body, namespace): 363e35fdd936d133bf8a48de140a3c666897588a05shiqian _GenericDeclaration.__init__(self, start, end, name, namespace) 364e35fdd936d133bf8a48de140a3c666897588a05shiqian converter = TypeConverter(namespace) 365e35fdd936d133bf8a48de140a3c666897588a05shiqian self.return_type = converter.CreateReturnType(return_type) 366e35fdd936d133bf8a48de140a3c666897588a05shiqian self.parameters = converter.ToParameters(parameters) 367e35fdd936d133bf8a48de140a3c666897588a05shiqian self.modifiers = modifiers 368e35fdd936d133bf8a48de140a3c666897588a05shiqian self.body = body 369e35fdd936d133bf8a48de140a3c666897588a05shiqian self.templated_types = templated_types 370e35fdd936d133bf8a48de140a3c666897588a05shiqian 371e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsDeclaration(self): 372e35fdd936d133bf8a48de140a3c666897588a05shiqian return self.body is None 373e35fdd936d133bf8a48de140a3c666897588a05shiqian 374e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsDefinition(self): 375e35fdd936d133bf8a48de140a3c666897588a05shiqian return self.body is not None 376e35fdd936d133bf8a48de140a3c666897588a05shiqian 377e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsExportable(self): 378e35fdd936d133bf8a48de140a3c666897588a05shiqian if self.return_type and 'static' in self.return_type.modifiers: 379e35fdd936d133bf8a48de140a3c666897588a05shiqian return False 380e35fdd936d133bf8a48de140a3c666897588a05shiqian return None not in self.namespace 381e35fdd936d133bf8a48de140a3c666897588a05shiqian 382e35fdd936d133bf8a48de140a3c666897588a05shiqian def Requires(self, node): 383e35fdd936d133bf8a48de140a3c666897588a05shiqian if self.parameters: 384e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): parameters are tokens, do name comparision. 385e35fdd936d133bf8a48de140a3c666897588a05shiqian for p in self.parameters: 386e35fdd936d133bf8a48de140a3c666897588a05shiqian if p.name == node.name: 387e35fdd936d133bf8a48de140a3c666897588a05shiqian return True 388e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): search in body too. 389e35fdd936d133bf8a48de140a3c666897588a05shiqian return False 390e35fdd936d133bf8a48de140a3c666897588a05shiqian 391e35fdd936d133bf8a48de140a3c666897588a05shiqian def __str__(self): 392e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): add templated_types. 393e35fdd936d133bf8a48de140a3c666897588a05shiqian suffix = ('%s %s(%s), 0x%02x, %s' % 394e35fdd936d133bf8a48de140a3c666897588a05shiqian (self.return_type, self.name, self.parameters, 395e35fdd936d133bf8a48de140a3c666897588a05shiqian self.modifiers, self.body)) 396e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._TypeStringHelper(suffix) 397e35fdd936d133bf8a48de140a3c666897588a05shiqian 398e35fdd936d133bf8a48de140a3c666897588a05shiqian 399e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Method(Function): 400e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end, name, in_class, return_type, parameters, 401e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers, templated_types, body, namespace): 402e35fdd936d133bf8a48de140a3c666897588a05shiqian Function.__init__(self, start, end, name, return_type, parameters, 403e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers, templated_types, body, namespace) 404e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): in_class could also be a namespace which can 405e35fdd936d133bf8a48de140a3c666897588a05shiqian # mess up finding functions properly. 406e35fdd936d133bf8a48de140a3c666897588a05shiqian self.in_class = in_class 407e35fdd936d133bf8a48de140a3c666897588a05shiqian 408e35fdd936d133bf8a48de140a3c666897588a05shiqian 409e35fdd936d133bf8a48de140a3c666897588a05shiqianclass Type(_GenericDeclaration): 410e35fdd936d133bf8a48de140a3c666897588a05shiqian """Type used for any variable (eg class, primitive, struct, etc).""" 411e35fdd936d133bf8a48de140a3c666897588a05shiqian 412e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, start, end, name, templated_types, modifiers, 413e35fdd936d133bf8a48de140a3c666897588a05shiqian reference, pointer, array): 414e35fdd936d133bf8a48de140a3c666897588a05shiqian """ 415e35fdd936d133bf8a48de140a3c666897588a05shiqian Args: 416e35fdd936d133bf8a48de140a3c666897588a05shiqian name: str name of main type 417e35fdd936d133bf8a48de140a3c666897588a05shiqian templated_types: [Class (Type?)] template type info between <> 418e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers: [str] type modifiers (keywords) eg, const, mutable, etc. 419e35fdd936d133bf8a48de140a3c666897588a05shiqian reference, pointer, array: bools 420e35fdd936d133bf8a48de140a3c666897588a05shiqian """ 421e35fdd936d133bf8a48de140a3c666897588a05shiqian _GenericDeclaration.__init__(self, start, end, name, []) 422e35fdd936d133bf8a48de140a3c666897588a05shiqian self.templated_types = templated_types 423e35fdd936d133bf8a48de140a3c666897588a05shiqian if not name and modifiers: 424e35fdd936d133bf8a48de140a3c666897588a05shiqian self.name = modifiers.pop() 425e35fdd936d133bf8a48de140a3c666897588a05shiqian self.modifiers = modifiers 426e35fdd936d133bf8a48de140a3c666897588a05shiqian self.reference = reference 427e35fdd936d133bf8a48de140a3c666897588a05shiqian self.pointer = pointer 428e35fdd936d133bf8a48de140a3c666897588a05shiqian self.array = array 429e35fdd936d133bf8a48de140a3c666897588a05shiqian 430e35fdd936d133bf8a48de140a3c666897588a05shiqian def __str__(self): 431e35fdd936d133bf8a48de140a3c666897588a05shiqian prefix = '' 432e35fdd936d133bf8a48de140a3c666897588a05shiqian if self.modifiers: 433e35fdd936d133bf8a48de140a3c666897588a05shiqian prefix = ' '.join(self.modifiers) + ' ' 434e35fdd936d133bf8a48de140a3c666897588a05shiqian name = str(self.name) 435e35fdd936d133bf8a48de140a3c666897588a05shiqian if self.templated_types: 436e35fdd936d133bf8a48de140a3c666897588a05shiqian name += '<%s>' % self.templated_types 437e35fdd936d133bf8a48de140a3c666897588a05shiqian suffix = prefix + name 438e35fdd936d133bf8a48de140a3c666897588a05shiqian if self.reference: 439e35fdd936d133bf8a48de140a3c666897588a05shiqian suffix += '&' 440e35fdd936d133bf8a48de140a3c666897588a05shiqian if self.pointer: 441e35fdd936d133bf8a48de140a3c666897588a05shiqian suffix += '*' 442e35fdd936d133bf8a48de140a3c666897588a05shiqian if self.array: 443e35fdd936d133bf8a48de140a3c666897588a05shiqian suffix += '[]' 444e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._TypeStringHelper(suffix) 445e35fdd936d133bf8a48de140a3c666897588a05shiqian 446e35fdd936d133bf8a48de140a3c666897588a05shiqian # By definition, Is* are always False. A Type can only exist in 447e35fdd936d133bf8a48de140a3c666897588a05shiqian # some sort of variable declaration, parameter, or return value. 448e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsDeclaration(self): 449e35fdd936d133bf8a48de140a3c666897588a05shiqian return False 450e35fdd936d133bf8a48de140a3c666897588a05shiqian 451e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsDefinition(self): 452e35fdd936d133bf8a48de140a3c666897588a05shiqian return False 453e35fdd936d133bf8a48de140a3c666897588a05shiqian 454e35fdd936d133bf8a48de140a3c666897588a05shiqian def IsExportable(self): 455e35fdd936d133bf8a48de140a3c666897588a05shiqian return False 456e35fdd936d133bf8a48de140a3c666897588a05shiqian 457e35fdd936d133bf8a48de140a3c666897588a05shiqian 458e35fdd936d133bf8a48de140a3c666897588a05shiqianclass TypeConverter(object): 459e35fdd936d133bf8a48de140a3c666897588a05shiqian 460e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, namespace_stack): 461e35fdd936d133bf8a48de140a3c666897588a05shiqian self.namespace_stack = namespace_stack 462e35fdd936d133bf8a48de140a3c666897588a05shiqian 463e35fdd936d133bf8a48de140a3c666897588a05shiqian def _GetTemplateEnd(self, tokens, start): 464e35fdd936d133bf8a48de140a3c666897588a05shiqian count = 1 465e35fdd936d133bf8a48de140a3c666897588a05shiqian end = start 466e35fdd936d133bf8a48de140a3c666897588a05shiqian while 1: 467e35fdd936d133bf8a48de140a3c666897588a05shiqian token = tokens[end] 468e35fdd936d133bf8a48de140a3c666897588a05shiqian end += 1 469e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == '<': 470e35fdd936d133bf8a48de140a3c666897588a05shiqian count += 1 471e35fdd936d133bf8a48de140a3c666897588a05shiqian elif token.name == '>': 472e35fdd936d133bf8a48de140a3c666897588a05shiqian count -= 1 473e35fdd936d133bf8a48de140a3c666897588a05shiqian if count == 0: 474e35fdd936d133bf8a48de140a3c666897588a05shiqian break 475e35fdd936d133bf8a48de140a3c666897588a05shiqian return tokens[start:end-1], end 476e35fdd936d133bf8a48de140a3c666897588a05shiqian 477e35fdd936d133bf8a48de140a3c666897588a05shiqian def ToType(self, tokens): 478e35fdd936d133bf8a48de140a3c666897588a05shiqian """Convert [Token,...] to [Class(...), ] useful for base classes. 479e35fdd936d133bf8a48de140a3c666897588a05shiqian For example, code like class Foo : public Bar<x, y> { ... }; 480e35fdd936d133bf8a48de140a3c666897588a05shiqian the "Bar<x, y>" portion gets converted to an AST. 481e35fdd936d133bf8a48de140a3c666897588a05shiqian 482e35fdd936d133bf8a48de140a3c666897588a05shiqian Returns: 483e35fdd936d133bf8a48de140a3c666897588a05shiqian [Class(...), ...] 484e35fdd936d133bf8a48de140a3c666897588a05shiqian """ 485e35fdd936d133bf8a48de140a3c666897588a05shiqian result = [] 486e35fdd936d133bf8a48de140a3c666897588a05shiqian name_tokens = [] 487e35fdd936d133bf8a48de140a3c666897588a05shiqian reference = pointer = array = False 488e35fdd936d133bf8a48de140a3c666897588a05shiqian 489e35fdd936d133bf8a48de140a3c666897588a05shiqian def AddType(templated_types): 490e35fdd936d133bf8a48de140a3c666897588a05shiqian # Partition tokens into name and modifier tokens. 491e35fdd936d133bf8a48de140a3c666897588a05shiqian names = [] 492e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers = [] 493e35fdd936d133bf8a48de140a3c666897588a05shiqian for t in name_tokens: 494e35fdd936d133bf8a48de140a3c666897588a05shiqian if keywords.IsKeyword(t.name): 495e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers.append(t.name) 496e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 497e35fdd936d133bf8a48de140a3c666897588a05shiqian names.append(t.name) 498e35fdd936d133bf8a48de140a3c666897588a05shiqian name = ''.join(names) 4998e838ce0fd145431b433f534c71bdb7f5d6b11ackosak if name_tokens: 5008e838ce0fd145431b433f534c71bdb7f5d6b11ackosak result.append(Type(name_tokens[0].start, name_tokens[-1].end, 5018e838ce0fd145431b433f534c71bdb7f5d6b11ackosak name, templated_types, modifiers, 5028e838ce0fd145431b433f534c71bdb7f5d6b11ackosak reference, pointer, array)) 503e35fdd936d133bf8a48de140a3c666897588a05shiqian del name_tokens[:] 504e35fdd936d133bf8a48de140a3c666897588a05shiqian 505e35fdd936d133bf8a48de140a3c666897588a05shiqian i = 0 506e35fdd936d133bf8a48de140a3c666897588a05shiqian end = len(tokens) 507e35fdd936d133bf8a48de140a3c666897588a05shiqian while i < end: 508e35fdd936d133bf8a48de140a3c666897588a05shiqian token = tokens[i] 509e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == '<': 510e35fdd936d133bf8a48de140a3c666897588a05shiqian new_tokens, new_end = self._GetTemplateEnd(tokens, i+1) 511e35fdd936d133bf8a48de140a3c666897588a05shiqian AddType(self.ToType(new_tokens)) 512e35fdd936d133bf8a48de140a3c666897588a05shiqian # If there is a comma after the template, we need to consume 513e35fdd936d133bf8a48de140a3c666897588a05shiqian # that here otherwise it becomes part of the name. 514e35fdd936d133bf8a48de140a3c666897588a05shiqian i = new_end 515e35fdd936d133bf8a48de140a3c666897588a05shiqian reference = pointer = array = False 516e35fdd936d133bf8a48de140a3c666897588a05shiqian elif token.name == ',': 517e35fdd936d133bf8a48de140a3c666897588a05shiqian AddType([]) 518e35fdd936d133bf8a48de140a3c666897588a05shiqian reference = pointer = array = False 519e35fdd936d133bf8a48de140a3c666897588a05shiqian elif token.name == '*': 520e35fdd936d133bf8a48de140a3c666897588a05shiqian pointer = True 521e35fdd936d133bf8a48de140a3c666897588a05shiqian elif token.name == '&': 522e35fdd936d133bf8a48de140a3c666897588a05shiqian reference = True 523e35fdd936d133bf8a48de140a3c666897588a05shiqian elif token.name == '[': 524e35fdd936d133bf8a48de140a3c666897588a05shiqian pointer = True 525e35fdd936d133bf8a48de140a3c666897588a05shiqian elif token.name == ']': 526e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 527e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 528e35fdd936d133bf8a48de140a3c666897588a05shiqian name_tokens.append(token) 529e35fdd936d133bf8a48de140a3c666897588a05shiqian i += 1 530e35fdd936d133bf8a48de140a3c666897588a05shiqian 531e35fdd936d133bf8a48de140a3c666897588a05shiqian if name_tokens: 532e35fdd936d133bf8a48de140a3c666897588a05shiqian # No '<' in the tokens, just a simple name and no template. 533e35fdd936d133bf8a48de140a3c666897588a05shiqian AddType([]) 534e35fdd936d133bf8a48de140a3c666897588a05shiqian return result 535e35fdd936d133bf8a48de140a3c666897588a05shiqian 536e35fdd936d133bf8a48de140a3c666897588a05shiqian def DeclarationToParts(self, parts, needs_name_removed): 537e35fdd936d133bf8a48de140a3c666897588a05shiqian name = None 538e35fdd936d133bf8a48de140a3c666897588a05shiqian default = [] 539e35fdd936d133bf8a48de140a3c666897588a05shiqian if needs_name_removed: 540e35fdd936d133bf8a48de140a3c666897588a05shiqian # Handle default (initial) values properly. 541e35fdd936d133bf8a48de140a3c666897588a05shiqian for i, t in enumerate(parts): 542e35fdd936d133bf8a48de140a3c666897588a05shiqian if t.name == '=': 543e35fdd936d133bf8a48de140a3c666897588a05shiqian default = parts[i+1:] 544e35fdd936d133bf8a48de140a3c666897588a05shiqian name = parts[i-1].name 545e35fdd936d133bf8a48de140a3c666897588a05shiqian if name == ']' and parts[i-2].name == '[': 546e35fdd936d133bf8a48de140a3c666897588a05shiqian name = parts[i-3].name 547e35fdd936d133bf8a48de140a3c666897588a05shiqian i -= 1 548e35fdd936d133bf8a48de140a3c666897588a05shiqian parts = parts[:i-1] 549e35fdd936d133bf8a48de140a3c666897588a05shiqian break 550e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 551e35fdd936d133bf8a48de140a3c666897588a05shiqian if parts[-1].token_type == tokenize.NAME: 552e35fdd936d133bf8a48de140a3c666897588a05shiqian name = parts.pop().name 553e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 554e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): this is a hack that happens for code like 555e35fdd936d133bf8a48de140a3c666897588a05shiqian # Register(Foo<T>); where it thinks this is a function call 556e35fdd936d133bf8a48de140a3c666897588a05shiqian # but it's actually a declaration. 557e35fdd936d133bf8a48de140a3c666897588a05shiqian name = '???' 558e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers = [] 559e35fdd936d133bf8a48de140a3c666897588a05shiqian type_name = [] 560e35fdd936d133bf8a48de140a3c666897588a05shiqian other_tokens = [] 561e35fdd936d133bf8a48de140a3c666897588a05shiqian templated_types = [] 562e35fdd936d133bf8a48de140a3c666897588a05shiqian i = 0 563e35fdd936d133bf8a48de140a3c666897588a05shiqian end = len(parts) 564e35fdd936d133bf8a48de140a3c666897588a05shiqian while i < end: 565e35fdd936d133bf8a48de140a3c666897588a05shiqian p = parts[i] 566e35fdd936d133bf8a48de140a3c666897588a05shiqian if keywords.IsKeyword(p.name): 567e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers.append(p.name) 568e35fdd936d133bf8a48de140a3c666897588a05shiqian elif p.name == '<': 569e35fdd936d133bf8a48de140a3c666897588a05shiqian templated_tokens, new_end = self._GetTemplateEnd(parts, i+1) 570e35fdd936d133bf8a48de140a3c666897588a05shiqian templated_types = self.ToType(templated_tokens) 571e35fdd936d133bf8a48de140a3c666897588a05shiqian i = new_end - 1 572e35fdd936d133bf8a48de140a3c666897588a05shiqian # Don't add a spurious :: to data members being initialized. 573e35fdd936d133bf8a48de140a3c666897588a05shiqian next_index = i + 1 574e35fdd936d133bf8a48de140a3c666897588a05shiqian if next_index < end and parts[next_index].name == '::': 575e35fdd936d133bf8a48de140a3c666897588a05shiqian i += 1 576e35fdd936d133bf8a48de140a3c666897588a05shiqian elif p.name in ('[', ']', '='): 577e35fdd936d133bf8a48de140a3c666897588a05shiqian # These are handled elsewhere. 578e35fdd936d133bf8a48de140a3c666897588a05shiqian other_tokens.append(p) 579e35fdd936d133bf8a48de140a3c666897588a05shiqian elif p.name not in ('*', '&', '>'): 580e35fdd936d133bf8a48de140a3c666897588a05shiqian # Ensure that names have a space between them. 581e35fdd936d133bf8a48de140a3c666897588a05shiqian if (type_name and type_name[-1].token_type == tokenize.NAME and 582e35fdd936d133bf8a48de140a3c666897588a05shiqian p.token_type == tokenize.NAME): 583e35fdd936d133bf8a48de140a3c666897588a05shiqian type_name.append(tokenize.Token(tokenize.SYNTAX, ' ', 0, 0)) 584e35fdd936d133bf8a48de140a3c666897588a05shiqian type_name.append(p) 585e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 586e35fdd936d133bf8a48de140a3c666897588a05shiqian other_tokens.append(p) 587e35fdd936d133bf8a48de140a3c666897588a05shiqian i += 1 588e35fdd936d133bf8a48de140a3c666897588a05shiqian type_name = ''.join([t.name for t in type_name]) 589e35fdd936d133bf8a48de140a3c666897588a05shiqian return name, type_name, templated_types, modifiers, default, other_tokens 590e35fdd936d133bf8a48de140a3c666897588a05shiqian 591e35fdd936d133bf8a48de140a3c666897588a05shiqian def ToParameters(self, tokens): 592e35fdd936d133bf8a48de140a3c666897588a05shiqian if not tokens: 593e35fdd936d133bf8a48de140a3c666897588a05shiqian return [] 594e35fdd936d133bf8a48de140a3c666897588a05shiqian 595e35fdd936d133bf8a48de140a3c666897588a05shiqian result = [] 596e35fdd936d133bf8a48de140a3c666897588a05shiqian name = type_name = '' 597e35fdd936d133bf8a48de140a3c666897588a05shiqian type_modifiers = [] 598e35fdd936d133bf8a48de140a3c666897588a05shiqian pointer = reference = array = False 599e35fdd936d133bf8a48de140a3c666897588a05shiqian first_token = None 600e35fdd936d133bf8a48de140a3c666897588a05shiqian default = [] 601e35fdd936d133bf8a48de140a3c666897588a05shiqian 602f58b49a2b14f9903d3118ffdd1485cbbe7a230d7kosak def AddParameter(end): 603e35fdd936d133bf8a48de140a3c666897588a05shiqian if default: 604e35fdd936d133bf8a48de140a3c666897588a05shiqian del default[0] # Remove flag. 605e35fdd936d133bf8a48de140a3c666897588a05shiqian parts = self.DeclarationToParts(type_modifiers, True) 606e35fdd936d133bf8a48de140a3c666897588a05shiqian (name, type_name, templated_types, modifiers, 607e35fdd936d133bf8a48de140a3c666897588a05shiqian unused_default, unused_other_tokens) = parts 608e35fdd936d133bf8a48de140a3c666897588a05shiqian parameter_type = Type(first_token.start, first_token.end, 609e35fdd936d133bf8a48de140a3c666897588a05shiqian type_name, templated_types, modifiers, 610e35fdd936d133bf8a48de140a3c666897588a05shiqian reference, pointer, array) 611e35fdd936d133bf8a48de140a3c666897588a05shiqian p = Parameter(first_token.start, end, name, 612e35fdd936d133bf8a48de140a3c666897588a05shiqian parameter_type, default) 613e35fdd936d133bf8a48de140a3c666897588a05shiqian result.append(p) 614e35fdd936d133bf8a48de140a3c666897588a05shiqian 615e35fdd936d133bf8a48de140a3c666897588a05shiqian template_count = 0 616e35fdd936d133bf8a48de140a3c666897588a05shiqian for s in tokens: 617e35fdd936d133bf8a48de140a3c666897588a05shiqian if not first_token: 618e35fdd936d133bf8a48de140a3c666897588a05shiqian first_token = s 619e35fdd936d133bf8a48de140a3c666897588a05shiqian if s.name == '<': 620e35fdd936d133bf8a48de140a3c666897588a05shiqian template_count += 1 621e35fdd936d133bf8a48de140a3c666897588a05shiqian elif s.name == '>': 622e35fdd936d133bf8a48de140a3c666897588a05shiqian template_count -= 1 623e35fdd936d133bf8a48de140a3c666897588a05shiqian if template_count > 0: 624e35fdd936d133bf8a48de140a3c666897588a05shiqian type_modifiers.append(s) 625e35fdd936d133bf8a48de140a3c666897588a05shiqian continue 626e35fdd936d133bf8a48de140a3c666897588a05shiqian 627e35fdd936d133bf8a48de140a3c666897588a05shiqian if s.name == ',': 628f58b49a2b14f9903d3118ffdd1485cbbe7a230d7kosak AddParameter(s.start) 629e35fdd936d133bf8a48de140a3c666897588a05shiqian name = type_name = '' 630e35fdd936d133bf8a48de140a3c666897588a05shiqian type_modifiers = [] 631e35fdd936d133bf8a48de140a3c666897588a05shiqian pointer = reference = array = False 632e35fdd936d133bf8a48de140a3c666897588a05shiqian first_token = None 633e35fdd936d133bf8a48de140a3c666897588a05shiqian default = [] 634e35fdd936d133bf8a48de140a3c666897588a05shiqian elif s.name == '*': 635e35fdd936d133bf8a48de140a3c666897588a05shiqian pointer = True 636e35fdd936d133bf8a48de140a3c666897588a05shiqian elif s.name == '&': 637e35fdd936d133bf8a48de140a3c666897588a05shiqian reference = True 638e35fdd936d133bf8a48de140a3c666897588a05shiqian elif s.name == '[': 639e35fdd936d133bf8a48de140a3c666897588a05shiqian array = True 640e35fdd936d133bf8a48de140a3c666897588a05shiqian elif s.name == ']': 641e35fdd936d133bf8a48de140a3c666897588a05shiqian pass # Just don't add to type_modifiers. 642e35fdd936d133bf8a48de140a3c666897588a05shiqian elif s.name == '=': 643e35fdd936d133bf8a48de140a3c666897588a05shiqian # Got a default value. Add any value (None) as a flag. 644e35fdd936d133bf8a48de140a3c666897588a05shiqian default.append(None) 645e35fdd936d133bf8a48de140a3c666897588a05shiqian elif default: 646e35fdd936d133bf8a48de140a3c666897588a05shiqian default.append(s) 647e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 648e35fdd936d133bf8a48de140a3c666897588a05shiqian type_modifiers.append(s) 649f58b49a2b14f9903d3118ffdd1485cbbe7a230d7kosak AddParameter(tokens[-1].end) 650e35fdd936d133bf8a48de140a3c666897588a05shiqian return result 651e35fdd936d133bf8a48de140a3c666897588a05shiqian 652e35fdd936d133bf8a48de140a3c666897588a05shiqian def CreateReturnType(self, return_type_seq): 653e35fdd936d133bf8a48de140a3c666897588a05shiqian if not return_type_seq: 654e35fdd936d133bf8a48de140a3c666897588a05shiqian return None 655e35fdd936d133bf8a48de140a3c666897588a05shiqian start = return_type_seq[0].start 656e35fdd936d133bf8a48de140a3c666897588a05shiqian end = return_type_seq[-1].end 657e35fdd936d133bf8a48de140a3c666897588a05shiqian _, name, templated_types, modifiers, default, other_tokens = \ 658e35fdd936d133bf8a48de140a3c666897588a05shiqian self.DeclarationToParts(return_type_seq, False) 659e35fdd936d133bf8a48de140a3c666897588a05shiqian names = [n.name for n in other_tokens] 660e35fdd936d133bf8a48de140a3c666897588a05shiqian reference = '&' in names 661e35fdd936d133bf8a48de140a3c666897588a05shiqian pointer = '*' in names 662e35fdd936d133bf8a48de140a3c666897588a05shiqian array = '[' in names 663e35fdd936d133bf8a48de140a3c666897588a05shiqian return Type(start, end, name, templated_types, modifiers, 664e35fdd936d133bf8a48de140a3c666897588a05shiqian reference, pointer, array) 665e35fdd936d133bf8a48de140a3c666897588a05shiqian 666e35fdd936d133bf8a48de140a3c666897588a05shiqian def GetTemplateIndices(self, names): 667e35fdd936d133bf8a48de140a3c666897588a05shiqian # names is a list of strings. 668e35fdd936d133bf8a48de140a3c666897588a05shiqian start = names.index('<') 669e35fdd936d133bf8a48de140a3c666897588a05shiqian end = len(names) - 1 670e35fdd936d133bf8a48de140a3c666897588a05shiqian while end > 0: 671e35fdd936d133bf8a48de140a3c666897588a05shiqian if names[end] == '>': 672e35fdd936d133bf8a48de140a3c666897588a05shiqian break 673e35fdd936d133bf8a48de140a3c666897588a05shiqian end -= 1 674e35fdd936d133bf8a48de140a3c666897588a05shiqian return start, end+1 675e35fdd936d133bf8a48de140a3c666897588a05shiqian 676e35fdd936d133bf8a48de140a3c666897588a05shiqianclass AstBuilder(object): 677e35fdd936d133bf8a48de140a3c666897588a05shiqian def __init__(self, token_stream, filename, in_class='', visibility=None, 678e35fdd936d133bf8a48de140a3c666897588a05shiqian namespace_stack=[]): 679e35fdd936d133bf8a48de140a3c666897588a05shiqian self.tokens = token_stream 680e35fdd936d133bf8a48de140a3c666897588a05shiqian self.filename = filename 681e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): use a better data structure (deque) for the queue. 682e35fdd936d133bf8a48de140a3c666897588a05shiqian # Switching directions of the "queue" improved perf by about 25%. 683e35fdd936d133bf8a48de140a3c666897588a05shiqian # Using a deque should be even better since we access from both sides. 684e35fdd936d133bf8a48de140a3c666897588a05shiqian self.token_queue = [] 685e35fdd936d133bf8a48de140a3c666897588a05shiqian self.namespace_stack = namespace_stack[:] 686e35fdd936d133bf8a48de140a3c666897588a05shiqian self.in_class = in_class 687e35fdd936d133bf8a48de140a3c666897588a05shiqian if in_class is None: 688e35fdd936d133bf8a48de140a3c666897588a05shiqian self.in_class_name_only = None 689e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 690e35fdd936d133bf8a48de140a3c666897588a05shiqian self.in_class_name_only = in_class.split('::')[-1] 691e35fdd936d133bf8a48de140a3c666897588a05shiqian self.visibility = visibility 692e35fdd936d133bf8a48de140a3c666897588a05shiqian self.in_function = False 693e35fdd936d133bf8a48de140a3c666897588a05shiqian self.current_token = None 694e35fdd936d133bf8a48de140a3c666897588a05shiqian # Keep the state whether we are currently handling a typedef or not. 695e35fdd936d133bf8a48de140a3c666897588a05shiqian self._handling_typedef = False 696e35fdd936d133bf8a48de140a3c666897588a05shiqian 697e35fdd936d133bf8a48de140a3c666897588a05shiqian self.converter = TypeConverter(self.namespace_stack) 698e35fdd936d133bf8a48de140a3c666897588a05shiqian 699e35fdd936d133bf8a48de140a3c666897588a05shiqian def HandleError(self, msg, token): 700e35fdd936d133bf8a48de140a3c666897588a05shiqian printable_queue = list(reversed(self.token_queue[-20:])) 701e35fdd936d133bf8a48de140a3c666897588a05shiqian sys.stderr.write('Got %s in %s @ %s %s\n' % 702e35fdd936d133bf8a48de140a3c666897588a05shiqian (msg, self.filename, token, printable_queue)) 703e35fdd936d133bf8a48de140a3c666897588a05shiqian 704e35fdd936d133bf8a48de140a3c666897588a05shiqian def Generate(self): 705e35fdd936d133bf8a48de140a3c666897588a05shiqian while 1: 706e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 707e35fdd936d133bf8a48de140a3c666897588a05shiqian if not token: 708e35fdd936d133bf8a48de140a3c666897588a05shiqian break 709e35fdd936d133bf8a48de140a3c666897588a05shiqian 710e35fdd936d133bf8a48de140a3c666897588a05shiqian # Get the next token. 711e35fdd936d133bf8a48de140a3c666897588a05shiqian self.current_token = token 712e35fdd936d133bf8a48de140a3c666897588a05shiqian 713e35fdd936d133bf8a48de140a3c666897588a05shiqian # Dispatch on the next token type. 714e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.token_type == _INTERNAL_TOKEN: 715e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == _NAMESPACE_POP: 716e35fdd936d133bf8a48de140a3c666897588a05shiqian self.namespace_stack.pop() 717e35fdd936d133bf8a48de140a3c666897588a05shiqian continue 718e35fdd936d133bf8a48de140a3c666897588a05shiqian 719e35fdd936d133bf8a48de140a3c666897588a05shiqian try: 720e35fdd936d133bf8a48de140a3c666897588a05shiqian result = self._GenerateOne(token) 721e35fdd936d133bf8a48de140a3c666897588a05shiqian if result is not None: 722e35fdd936d133bf8a48de140a3c666897588a05shiqian yield result 723e35fdd936d133bf8a48de140a3c666897588a05shiqian except: 724e35fdd936d133bf8a48de140a3c666897588a05shiqian self.HandleError('exception', token) 725e35fdd936d133bf8a48de140a3c666897588a05shiqian raise 726e35fdd936d133bf8a48de140a3c666897588a05shiqian 727e35fdd936d133bf8a48de140a3c666897588a05shiqian def _CreateVariable(self, pos_token, name, type_name, type_modifiers, 728e35fdd936d133bf8a48de140a3c666897588a05shiqian ref_pointer_name_seq, templated_types, value=None): 729e35fdd936d133bf8a48de140a3c666897588a05shiqian reference = '&' in ref_pointer_name_seq 730e35fdd936d133bf8a48de140a3c666897588a05shiqian pointer = '*' in ref_pointer_name_seq 731e35fdd936d133bf8a48de140a3c666897588a05shiqian array = '[' in ref_pointer_name_seq 732e35fdd936d133bf8a48de140a3c666897588a05shiqian var_type = Type(pos_token.start, pos_token.end, type_name, 733e35fdd936d133bf8a48de140a3c666897588a05shiqian templated_types, type_modifiers, 734e35fdd936d133bf8a48de140a3c666897588a05shiqian reference, pointer, array) 735e35fdd936d133bf8a48de140a3c666897588a05shiqian return VariableDeclaration(pos_token.start, pos_token.end, 736e35fdd936d133bf8a48de140a3c666897588a05shiqian name, var_type, value, self.namespace_stack) 737e35fdd936d133bf8a48de140a3c666897588a05shiqian 738e35fdd936d133bf8a48de140a3c666897588a05shiqian def _GenerateOne(self, token): 739e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.token_type == tokenize.NAME: 740e35fdd936d133bf8a48de140a3c666897588a05shiqian if (keywords.IsKeyword(token.name) and 741e35fdd936d133bf8a48de140a3c666897588a05shiqian not keywords.IsBuiltinType(token.name)): 742e35fdd936d133bf8a48de140a3c666897588a05shiqian method = getattr(self, 'handle_' + token.name) 743e35fdd936d133bf8a48de140a3c666897588a05shiqian return method() 744e35fdd936d133bf8a48de140a3c666897588a05shiqian elif token.name == self.in_class_name_only: 745e35fdd936d133bf8a48de140a3c666897588a05shiqian # The token name is the same as the class, must be a ctor if 746e35fdd936d133bf8a48de140a3c666897588a05shiqian # there is a paren. Otherwise, it's the return type. 747e35fdd936d133bf8a48de140a3c666897588a05shiqian # Peek ahead to get the next token to figure out which. 748e35fdd936d133bf8a48de140a3c666897588a05shiqian next = self._GetNextToken() 749e35fdd936d133bf8a48de140a3c666897588a05shiqian self._AddBackToken(next) 750e35fdd936d133bf8a48de140a3c666897588a05shiqian if next.token_type == tokenize.SYNTAX and next.name == '(': 751e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._GetMethod([token], FUNCTION_CTOR, None, True) 752e35fdd936d133bf8a48de140a3c666897588a05shiqian # Fall through--handle like any other method. 753e35fdd936d133bf8a48de140a3c666897588a05shiqian 754e35fdd936d133bf8a48de140a3c666897588a05shiqian # Handle data or function declaration/definition. 755e35fdd936d133bf8a48de140a3c666897588a05shiqian syntax = tokenize.SYNTAX 756e35fdd936d133bf8a48de140a3c666897588a05shiqian temp_tokens, last_token = \ 757e35fdd936d133bf8a48de140a3c666897588a05shiqian self._GetVarTokensUpTo(syntax, '(', ';', '{', '[') 758e35fdd936d133bf8a48de140a3c666897588a05shiqian temp_tokens.insert(0, token) 759e35fdd936d133bf8a48de140a3c666897588a05shiqian if last_token.name == '(': 760e35fdd936d133bf8a48de140a3c666897588a05shiqian # If there is an assignment before the paren, 761e35fdd936d133bf8a48de140a3c666897588a05shiqian # this is an expression, not a method. 762e35fdd936d133bf8a48de140a3c666897588a05shiqian expr = bool([e for e in temp_tokens if e.name == '=']) 763e35fdd936d133bf8a48de140a3c666897588a05shiqian if expr: 764e35fdd936d133bf8a48de140a3c666897588a05shiqian new_temp = self._GetTokensUpTo(tokenize.SYNTAX, ';') 765e35fdd936d133bf8a48de140a3c666897588a05shiqian temp_tokens.append(last_token) 766e35fdd936d133bf8a48de140a3c666897588a05shiqian temp_tokens.extend(new_temp) 767e35fdd936d133bf8a48de140a3c666897588a05shiqian last_token = tokenize.Token(tokenize.SYNTAX, ';', 0, 0) 768e35fdd936d133bf8a48de140a3c666897588a05shiqian 769e35fdd936d133bf8a48de140a3c666897588a05shiqian if last_token.name == '[': 770e35fdd936d133bf8a48de140a3c666897588a05shiqian # Handle array, this isn't a method, unless it's an operator. 771e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): keep the size somewhere. 772e35fdd936d133bf8a48de140a3c666897588a05shiqian # unused_size = self._GetTokensUpTo(tokenize.SYNTAX, ']') 773e35fdd936d133bf8a48de140a3c666897588a05shiqian temp_tokens.append(last_token) 774e35fdd936d133bf8a48de140a3c666897588a05shiqian if temp_tokens[-2].name == 'operator': 775e35fdd936d133bf8a48de140a3c666897588a05shiqian temp_tokens.append(self._GetNextToken()) 776e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 777e35fdd936d133bf8a48de140a3c666897588a05shiqian temp_tokens2, last_token = \ 778e35fdd936d133bf8a48de140a3c666897588a05shiqian self._GetVarTokensUpTo(tokenize.SYNTAX, ';') 779e35fdd936d133bf8a48de140a3c666897588a05shiqian temp_tokens.extend(temp_tokens2) 780e35fdd936d133bf8a48de140a3c666897588a05shiqian 781e35fdd936d133bf8a48de140a3c666897588a05shiqian if last_token.name == ';': 782e35fdd936d133bf8a48de140a3c666897588a05shiqian # Handle data, this isn't a method. 783e35fdd936d133bf8a48de140a3c666897588a05shiqian parts = self.converter.DeclarationToParts(temp_tokens, True) 784e35fdd936d133bf8a48de140a3c666897588a05shiqian (name, type_name, templated_types, modifiers, default, 785e35fdd936d133bf8a48de140a3c666897588a05shiqian unused_other_tokens) = parts 786c2ad46a5df4414fc2b804c53525f4578f01a3dfezhanyong.wan 787e35fdd936d133bf8a48de140a3c666897588a05shiqian t0 = temp_tokens[0] 788e35fdd936d133bf8a48de140a3c666897588a05shiqian names = [t.name for t in temp_tokens] 789e35fdd936d133bf8a48de140a3c666897588a05shiqian if templated_types: 790e35fdd936d133bf8a48de140a3c666897588a05shiqian start, end = self.converter.GetTemplateIndices(names) 791e35fdd936d133bf8a48de140a3c666897588a05shiqian names = names[:start] + names[end:] 792e35fdd936d133bf8a48de140a3c666897588a05shiqian default = ''.join([t.name for t in default]) 793e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._CreateVariable(t0, name, type_name, modifiers, 794e35fdd936d133bf8a48de140a3c666897588a05shiqian names, templated_types, default) 795e35fdd936d133bf8a48de140a3c666897588a05shiqian if last_token.name == '{': 796e35fdd936d133bf8a48de140a3c666897588a05shiqian self._AddBackTokens(temp_tokens[1:]) 797e35fdd936d133bf8a48de140a3c666897588a05shiqian self._AddBackToken(last_token) 798e35fdd936d133bf8a48de140a3c666897588a05shiqian method_name = temp_tokens[0].name 799e35fdd936d133bf8a48de140a3c666897588a05shiqian method = getattr(self, 'handle_' + method_name, None) 800e35fdd936d133bf8a48de140a3c666897588a05shiqian if not method: 801e35fdd936d133bf8a48de140a3c666897588a05shiqian # Must be declaring a variable. 802e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): handle the declaration. 803e35fdd936d133bf8a48de140a3c666897588a05shiqian return None 804e35fdd936d133bf8a48de140a3c666897588a05shiqian return method() 805e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._GetMethod(temp_tokens, 0, None, False) 806e35fdd936d133bf8a48de140a3c666897588a05shiqian elif token.token_type == tokenize.SYNTAX: 807e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == '~' and self.in_class: 808e35fdd936d133bf8a48de140a3c666897588a05shiqian # Must be a dtor (probably not in method body). 809e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 810e35fdd936d133bf8a48de140a3c666897588a05shiqian # self.in_class can contain A::Name, but the dtor will only 811e35fdd936d133bf8a48de140a3c666897588a05shiqian # be Name. Make sure to compare against the right value. 812e35fdd936d133bf8a48de140a3c666897588a05shiqian if (token.token_type == tokenize.NAME and 813e35fdd936d133bf8a48de140a3c666897588a05shiqian token.name == self.in_class_name_only): 814e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._GetMethod([token], FUNCTION_DTOR, None, True) 815e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): handle a lot more syntax. 816e35fdd936d133bf8a48de140a3c666897588a05shiqian elif token.token_type == tokenize.PREPROCESSOR: 817e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): handle more preprocessor directives. 818e35fdd936d133bf8a48de140a3c666897588a05shiqian # token starts with a #, so remove it and strip whitespace. 819e35fdd936d133bf8a48de140a3c666897588a05shiqian name = token.name[1:].lstrip() 820e35fdd936d133bf8a48de140a3c666897588a05shiqian if name.startswith('include'): 821e35fdd936d133bf8a48de140a3c666897588a05shiqian # Remove "include". 822e35fdd936d133bf8a48de140a3c666897588a05shiqian name = name[7:].strip() 823e35fdd936d133bf8a48de140a3c666897588a05shiqian assert name 824e35fdd936d133bf8a48de140a3c666897588a05shiqian # Handle #include \<newline> "header-on-second-line.h". 825e35fdd936d133bf8a48de140a3c666897588a05shiqian if name.startswith('\\'): 826e35fdd936d133bf8a48de140a3c666897588a05shiqian name = name[1:].strip() 827e35fdd936d133bf8a48de140a3c666897588a05shiqian assert name[0] in '<"', token 828e35fdd936d133bf8a48de140a3c666897588a05shiqian assert name[-1] in '>"', token 829e35fdd936d133bf8a48de140a3c666897588a05shiqian system = name[0] == '<' 830e35fdd936d133bf8a48de140a3c666897588a05shiqian filename = name[1:-1] 831e35fdd936d133bf8a48de140a3c666897588a05shiqian return Include(token.start, token.end, filename, system) 832e35fdd936d133bf8a48de140a3c666897588a05shiqian if name.startswith('define'): 833e35fdd936d133bf8a48de140a3c666897588a05shiqian # Remove "define". 834e35fdd936d133bf8a48de140a3c666897588a05shiqian name = name[6:].strip() 835e35fdd936d133bf8a48de140a3c666897588a05shiqian assert name 836e35fdd936d133bf8a48de140a3c666897588a05shiqian value = '' 837e35fdd936d133bf8a48de140a3c666897588a05shiqian for i, c in enumerate(name): 838e35fdd936d133bf8a48de140a3c666897588a05shiqian if c.isspace(): 839e35fdd936d133bf8a48de140a3c666897588a05shiqian value = name[i:].lstrip() 840e35fdd936d133bf8a48de140a3c666897588a05shiqian name = name[:i] 841e35fdd936d133bf8a48de140a3c666897588a05shiqian break 842e35fdd936d133bf8a48de140a3c666897588a05shiqian return Define(token.start, token.end, name, value) 843e35fdd936d133bf8a48de140a3c666897588a05shiqian if name.startswith('if') and name[2:3].isspace(): 844e35fdd936d133bf8a48de140a3c666897588a05shiqian condition = name[3:].strip() 845e35fdd936d133bf8a48de140a3c666897588a05shiqian if condition.startswith('0') or condition.startswith('(0)'): 846e35fdd936d133bf8a48de140a3c666897588a05shiqian self._SkipIf0Blocks() 847e35fdd936d133bf8a48de140a3c666897588a05shiqian return None 848e35fdd936d133bf8a48de140a3c666897588a05shiqian 849e35fdd936d133bf8a48de140a3c666897588a05shiqian def _GetTokensUpTo(self, expected_token_type, expected_token): 850e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._GetVarTokensUpTo(expected_token_type, expected_token)[0] 851e35fdd936d133bf8a48de140a3c666897588a05shiqian 852e35fdd936d133bf8a48de140a3c666897588a05shiqian def _GetVarTokensUpTo(self, expected_token_type, *expected_tokens): 853e35fdd936d133bf8a48de140a3c666897588a05shiqian last_token = self._GetNextToken() 854e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens = [] 855e35fdd936d133bf8a48de140a3c666897588a05shiqian while (last_token.token_type != expected_token_type or 856e35fdd936d133bf8a48de140a3c666897588a05shiqian last_token.name not in expected_tokens): 857e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens.append(last_token) 858e35fdd936d133bf8a48de140a3c666897588a05shiqian last_token = self._GetNextToken() 859e35fdd936d133bf8a48de140a3c666897588a05shiqian return tokens, last_token 860e35fdd936d133bf8a48de140a3c666897588a05shiqian 861e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necesary. 862e35fdd936d133bf8a48de140a3c666897588a05shiqian def _IgnoreUpTo(self, token_type, token): 863e35fdd936d133bf8a48de140a3c666897588a05shiqian unused_tokens = self._GetTokensUpTo(token_type, token) 864e35fdd936d133bf8a48de140a3c666897588a05shiqian 865e35fdd936d133bf8a48de140a3c666897588a05shiqian def _SkipIf0Blocks(self): 866e35fdd936d133bf8a48de140a3c666897588a05shiqian count = 1 867e35fdd936d133bf8a48de140a3c666897588a05shiqian while 1: 868e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 869e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.token_type != tokenize.PREPROCESSOR: 870e35fdd936d133bf8a48de140a3c666897588a05shiqian continue 871e35fdd936d133bf8a48de140a3c666897588a05shiqian 872e35fdd936d133bf8a48de140a3c666897588a05shiqian name = token.name[1:].lstrip() 873e35fdd936d133bf8a48de140a3c666897588a05shiqian if name.startswith('endif'): 874e35fdd936d133bf8a48de140a3c666897588a05shiqian count -= 1 875e35fdd936d133bf8a48de140a3c666897588a05shiqian if count == 0: 876e35fdd936d133bf8a48de140a3c666897588a05shiqian break 877e35fdd936d133bf8a48de140a3c666897588a05shiqian elif name.startswith('if'): 878e35fdd936d133bf8a48de140a3c666897588a05shiqian count += 1 879e35fdd936d133bf8a48de140a3c666897588a05shiqian 880e35fdd936d133bf8a48de140a3c666897588a05shiqian def _GetMatchingChar(self, open_paren, close_paren, GetNextToken=None): 881e35fdd936d133bf8a48de140a3c666897588a05shiqian if GetNextToken is None: 882e35fdd936d133bf8a48de140a3c666897588a05shiqian GetNextToken = self._GetNextToken 883e35fdd936d133bf8a48de140a3c666897588a05shiqian # Assumes the current token is open_paren and we will consume 884e35fdd936d133bf8a48de140a3c666897588a05shiqian # and return up to the close_paren. 885e35fdd936d133bf8a48de140a3c666897588a05shiqian count = 1 886e35fdd936d133bf8a48de140a3c666897588a05shiqian token = GetNextToken() 887e35fdd936d133bf8a48de140a3c666897588a05shiqian while 1: 888e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.token_type == tokenize.SYNTAX: 889e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == open_paren: 890e35fdd936d133bf8a48de140a3c666897588a05shiqian count += 1 891e35fdd936d133bf8a48de140a3c666897588a05shiqian elif token.name == close_paren: 892e35fdd936d133bf8a48de140a3c666897588a05shiqian count -= 1 893e35fdd936d133bf8a48de140a3c666897588a05shiqian if count == 0: 894e35fdd936d133bf8a48de140a3c666897588a05shiqian break 895e35fdd936d133bf8a48de140a3c666897588a05shiqian yield token 896e35fdd936d133bf8a48de140a3c666897588a05shiqian token = GetNextToken() 897e35fdd936d133bf8a48de140a3c666897588a05shiqian yield token 898e35fdd936d133bf8a48de140a3c666897588a05shiqian 899e35fdd936d133bf8a48de140a3c666897588a05shiqian def _GetParameters(self): 900e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._GetMatchingChar('(', ')') 901e35fdd936d133bf8a48de140a3c666897588a05shiqian 902e35fdd936d133bf8a48de140a3c666897588a05shiqian def GetScope(self): 903e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._GetMatchingChar('{', '}') 904e35fdd936d133bf8a48de140a3c666897588a05shiqian 905e35fdd936d133bf8a48de140a3c666897588a05shiqian def _GetNextToken(self): 906e35fdd936d133bf8a48de140a3c666897588a05shiqian if self.token_queue: 907e35fdd936d133bf8a48de140a3c666897588a05shiqian return self.token_queue.pop() 908e35fdd936d133bf8a48de140a3c666897588a05shiqian return next(self.tokens) 909e35fdd936d133bf8a48de140a3c666897588a05shiqian 910e35fdd936d133bf8a48de140a3c666897588a05shiqian def _AddBackToken(self, token): 911e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.whence == tokenize.WHENCE_STREAM: 912e35fdd936d133bf8a48de140a3c666897588a05shiqian token.whence = tokenize.WHENCE_QUEUE 913e35fdd936d133bf8a48de140a3c666897588a05shiqian self.token_queue.insert(0, token) 914e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 915e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.whence == tokenize.WHENCE_QUEUE, token 916e35fdd936d133bf8a48de140a3c666897588a05shiqian self.token_queue.append(token) 917e35fdd936d133bf8a48de140a3c666897588a05shiqian 918e35fdd936d133bf8a48de140a3c666897588a05shiqian def _AddBackTokens(self, tokens): 919e35fdd936d133bf8a48de140a3c666897588a05shiqian if tokens: 920e35fdd936d133bf8a48de140a3c666897588a05shiqian if tokens[-1].whence == tokenize.WHENCE_STREAM: 921e35fdd936d133bf8a48de140a3c666897588a05shiqian for token in tokens: 922e35fdd936d133bf8a48de140a3c666897588a05shiqian token.whence = tokenize.WHENCE_QUEUE 923e35fdd936d133bf8a48de140a3c666897588a05shiqian self.token_queue[:0] = reversed(tokens) 924e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 925e35fdd936d133bf8a48de140a3c666897588a05shiqian assert tokens[-1].whence == tokenize.WHENCE_QUEUE, tokens 926e35fdd936d133bf8a48de140a3c666897588a05shiqian self.token_queue.extend(reversed(tokens)) 927e35fdd936d133bf8a48de140a3c666897588a05shiqian 928e35fdd936d133bf8a48de140a3c666897588a05shiqian def GetName(self, seq=None): 929e35fdd936d133bf8a48de140a3c666897588a05shiqian """Returns ([tokens], next_token_info).""" 930e35fdd936d133bf8a48de140a3c666897588a05shiqian GetNextToken = self._GetNextToken 931e35fdd936d133bf8a48de140a3c666897588a05shiqian if seq is not None: 932e35fdd936d133bf8a48de140a3c666897588a05shiqian it = iter(seq) 933e35fdd936d133bf8a48de140a3c666897588a05shiqian GetNextToken = lambda: next(it) 934e35fdd936d133bf8a48de140a3c666897588a05shiqian next_token = GetNextToken() 935e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens = [] 936e35fdd936d133bf8a48de140a3c666897588a05shiqian last_token_was_name = False 937e35fdd936d133bf8a48de140a3c666897588a05shiqian while (next_token.token_type == tokenize.NAME or 938e35fdd936d133bf8a48de140a3c666897588a05shiqian (next_token.token_type == tokenize.SYNTAX and 939e35fdd936d133bf8a48de140a3c666897588a05shiqian next_token.name in ('::', '<'))): 940e35fdd936d133bf8a48de140a3c666897588a05shiqian # Two NAMEs in a row means the identifier should terminate. 941e35fdd936d133bf8a48de140a3c666897588a05shiqian # It's probably some sort of variable declaration. 942e35fdd936d133bf8a48de140a3c666897588a05shiqian if last_token_was_name and next_token.token_type == tokenize.NAME: 943e35fdd936d133bf8a48de140a3c666897588a05shiqian break 944e35fdd936d133bf8a48de140a3c666897588a05shiqian last_token_was_name = next_token.token_type == tokenize.NAME 945e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens.append(next_token) 946e35fdd936d133bf8a48de140a3c666897588a05shiqian # Handle templated names. 947e35fdd936d133bf8a48de140a3c666897588a05shiqian if next_token.name == '<': 948e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens.extend(self._GetMatchingChar('<', '>', GetNextToken)) 949e35fdd936d133bf8a48de140a3c666897588a05shiqian last_token_was_name = True 950e35fdd936d133bf8a48de140a3c666897588a05shiqian next_token = GetNextToken() 951e35fdd936d133bf8a48de140a3c666897588a05shiqian return tokens, next_token 952e35fdd936d133bf8a48de140a3c666897588a05shiqian 953e35fdd936d133bf8a48de140a3c666897588a05shiqian def GetMethod(self, modifiers, templated_types): 954e35fdd936d133bf8a48de140a3c666897588a05shiqian return_type_and_name = self._GetTokensUpTo(tokenize.SYNTAX, '(') 955e35fdd936d133bf8a48de140a3c666897588a05shiqian assert len(return_type_and_name) >= 1 956e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._GetMethod(return_type_and_name, modifiers, templated_types, 957e35fdd936d133bf8a48de140a3c666897588a05shiqian False) 958e35fdd936d133bf8a48de140a3c666897588a05shiqian 959e35fdd936d133bf8a48de140a3c666897588a05shiqian def _GetMethod(self, return_type_and_name, modifiers, templated_types, 960e35fdd936d133bf8a48de140a3c666897588a05shiqian get_paren): 961e35fdd936d133bf8a48de140a3c666897588a05shiqian template_portion = None 962e35fdd936d133bf8a48de140a3c666897588a05shiqian if get_paren: 963e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 964e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.token_type == tokenize.SYNTAX, token 965e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == '<': 966e35fdd936d133bf8a48de140a3c666897588a05shiqian # Handle templatized dtors. 967e35fdd936d133bf8a48de140a3c666897588a05shiqian template_portion = [token] 968e35fdd936d133bf8a48de140a3c666897588a05shiqian template_portion.extend(self._GetMatchingChar('<', '>')) 969e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 970e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.token_type == tokenize.SYNTAX, token 971e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.name == '(', token 972e35fdd936d133bf8a48de140a3c666897588a05shiqian 973e35fdd936d133bf8a48de140a3c666897588a05shiqian name = return_type_and_name.pop() 974e35fdd936d133bf8a48de140a3c666897588a05shiqian # Handle templatized ctors. 975e35fdd936d133bf8a48de140a3c666897588a05shiqian if name.name == '>': 976e35fdd936d133bf8a48de140a3c666897588a05shiqian index = 1 977e35fdd936d133bf8a48de140a3c666897588a05shiqian while return_type_and_name[index].name != '<': 978e35fdd936d133bf8a48de140a3c666897588a05shiqian index += 1 979e35fdd936d133bf8a48de140a3c666897588a05shiqian template_portion = return_type_and_name[index:] + [name] 980e35fdd936d133bf8a48de140a3c666897588a05shiqian del return_type_and_name[index:] 981e35fdd936d133bf8a48de140a3c666897588a05shiqian name = return_type_and_name.pop() 982e35fdd936d133bf8a48de140a3c666897588a05shiqian elif name.name == ']': 983e35fdd936d133bf8a48de140a3c666897588a05shiqian rt = return_type_and_name 984e35fdd936d133bf8a48de140a3c666897588a05shiqian assert rt[-1].name == '[', return_type_and_name 985e35fdd936d133bf8a48de140a3c666897588a05shiqian assert rt[-2].name == 'operator', return_type_and_name 986e35fdd936d133bf8a48de140a3c666897588a05shiqian name_seq = return_type_and_name[-2:] 987e35fdd936d133bf8a48de140a3c666897588a05shiqian del return_type_and_name[-2:] 988e35fdd936d133bf8a48de140a3c666897588a05shiqian name = tokenize.Token(tokenize.NAME, 'operator[]', 989e35fdd936d133bf8a48de140a3c666897588a05shiqian name_seq[0].start, name.end) 990e35fdd936d133bf8a48de140a3c666897588a05shiqian # Get the open paren so _GetParameters() below works. 991e35fdd936d133bf8a48de140a3c666897588a05shiqian unused_open_paren = self._GetNextToken() 992e35fdd936d133bf8a48de140a3c666897588a05shiqian 993e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): store template_portion. 994e35fdd936d133bf8a48de140a3c666897588a05shiqian return_type = return_type_and_name 995e35fdd936d133bf8a48de140a3c666897588a05shiqian indices = name 996e35fdd936d133bf8a48de140a3c666897588a05shiqian if return_type: 997e35fdd936d133bf8a48de140a3c666897588a05shiqian indices = return_type[0] 998e35fdd936d133bf8a48de140a3c666897588a05shiqian 999e35fdd936d133bf8a48de140a3c666897588a05shiqian # Force ctor for templatized ctors. 1000e35fdd936d133bf8a48de140a3c666897588a05shiqian if name.name == self.in_class and not modifiers: 1001e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers |= FUNCTION_CTOR 1002e35fdd936d133bf8a48de140a3c666897588a05shiqian parameters = list(self._GetParameters()) 1003e35fdd936d133bf8a48de140a3c666897588a05shiqian del parameters[-1] # Remove trailing ')'. 1004e35fdd936d133bf8a48de140a3c666897588a05shiqian 1005e35fdd936d133bf8a48de140a3c666897588a05shiqian # Handling operator() is especially weird. 1006e35fdd936d133bf8a48de140a3c666897588a05shiqian if name.name == 'operator' and not parameters: 1007e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1008e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.name == '(', token 1009e35fdd936d133bf8a48de140a3c666897588a05shiqian parameters = list(self._GetParameters()) 1010e35fdd936d133bf8a48de140a3c666897588a05shiqian del parameters[-1] # Remove trailing ')'. 1011e35fdd936d133bf8a48de140a3c666897588a05shiqian 1012e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1013e35fdd936d133bf8a48de140a3c666897588a05shiqian while token.token_type == tokenize.NAME: 1014e35fdd936d133bf8a48de140a3c666897588a05shiqian modifier_token = token 1015e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1016e35fdd936d133bf8a48de140a3c666897588a05shiqian if modifier_token.name == 'const': 1017e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers |= FUNCTION_CONST 1018e35fdd936d133bf8a48de140a3c666897588a05shiqian elif modifier_token.name == '__attribute__': 1019e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): handle more __attribute__ details. 1020e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers |= FUNCTION_ATTRIBUTE 1021e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.name == '(', token 1022e35fdd936d133bf8a48de140a3c666897588a05shiqian # Consume everything between the (parens). 1023e35fdd936d133bf8a48de140a3c666897588a05shiqian unused_tokens = list(self._GetMatchingChar('(', ')')) 1024e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1025e35fdd936d133bf8a48de140a3c666897588a05shiqian elif modifier_token.name == 'throw': 1026e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers |= FUNCTION_THROW 1027e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.name == '(', token 1028e35fdd936d133bf8a48de140a3c666897588a05shiqian # Consume everything between the (parens). 1029e35fdd936d133bf8a48de140a3c666897588a05shiqian unused_tokens = list(self._GetMatchingChar('(', ')')) 1030e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1031c26f969579d62444ae7d422b37e0037ceca97a7akosak elif modifier_token.name == 'override': 1032c26f969579d62444ae7d422b37e0037ceca97a7akosak modifiers |= FUNCTION_OVERRIDE 1033e35fdd936d133bf8a48de140a3c666897588a05shiqian elif modifier_token.name == modifier_token.name.upper(): 1034e35fdd936d133bf8a48de140a3c666897588a05shiqian # HACK(nnorwitz): assume that all upper-case names 1035e35fdd936d133bf8a48de140a3c666897588a05shiqian # are some macro we aren't expanding. 1036e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers |= FUNCTION_UNKNOWN_ANNOTATION 1037e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 1038e35fdd936d133bf8a48de140a3c666897588a05shiqian self.HandleError('unexpected token', modifier_token) 1039e35fdd936d133bf8a48de140a3c666897588a05shiqian 1040e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.token_type == tokenize.SYNTAX, token 1041e35fdd936d133bf8a48de140a3c666897588a05shiqian # Handle ctor initializers. 1042e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == ':': 1043e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): anything else to handle for initializer list? 1044e35fdd936d133bf8a48de140a3c666897588a05shiqian while token.name != ';' and token.name != '{': 1045e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1046e35fdd936d133bf8a48de140a3c666897588a05shiqian 1047e35fdd936d133bf8a48de140a3c666897588a05shiqian # Handle pointer to functions that are really data but look 1048e35fdd936d133bf8a48de140a3c666897588a05shiqian # like method declarations. 1049e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == '(': 1050e35fdd936d133bf8a48de140a3c666897588a05shiqian if parameters[0].name == '*': 1051e35fdd936d133bf8a48de140a3c666897588a05shiqian # name contains the return type. 1052e35fdd936d133bf8a48de140a3c666897588a05shiqian name = parameters.pop() 1053e35fdd936d133bf8a48de140a3c666897588a05shiqian # parameters contains the name of the data. 1054e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers = [p.name for p in parameters] 1055e35fdd936d133bf8a48de140a3c666897588a05shiqian # Already at the ( to open the parameter list. 1056e35fdd936d133bf8a48de140a3c666897588a05shiqian function_parameters = list(self._GetMatchingChar('(', ')')) 1057e35fdd936d133bf8a48de140a3c666897588a05shiqian del function_parameters[-1] # Remove trailing ')'. 1058e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): store the function_parameters. 1059e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1060e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.token_type == tokenize.SYNTAX, token 1061e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.name == ';', token 1062e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._CreateVariable(indices, name.name, indices.name, 1063e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers, '', None) 1064e35fdd936d133bf8a48de140a3c666897588a05shiqian # At this point, we got something like: 1065e35fdd936d133bf8a48de140a3c666897588a05shiqian # return_type (type::*name_)(params); 1066e35fdd936d133bf8a48de140a3c666897588a05shiqian # This is a data member called name_ that is a function pointer. 1067e35fdd936d133bf8a48de140a3c666897588a05shiqian # With this code: void (sq_type::*field_)(string&); 1068e35fdd936d133bf8a48de140a3c666897588a05shiqian # We get: name=void return_type=[] parameters=sq_type ... field_ 1069e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): is return_type always empty? 1070e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): this isn't even close to being correct. 1071e35fdd936d133bf8a48de140a3c666897588a05shiqian # Just put in something so we don't crash and can move on. 1072e35fdd936d133bf8a48de140a3c666897588a05shiqian real_name = parameters[-1] 1073e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers = [p.name for p in self._GetParameters()] 1074e35fdd936d133bf8a48de140a3c666897588a05shiqian del modifiers[-1] # Remove trailing ')'. 1075e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._CreateVariable(indices, real_name.name, indices.name, 1076e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers, '', None) 1077e35fdd936d133bf8a48de140a3c666897588a05shiqian 1078e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == '{': 1079e35fdd936d133bf8a48de140a3c666897588a05shiqian body = list(self.GetScope()) 1080e35fdd936d133bf8a48de140a3c666897588a05shiqian del body[-1] # Remove trailing '}'. 1081e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 1082e35fdd936d133bf8a48de140a3c666897588a05shiqian body = None 1083e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == '=': 1084e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 108561adbcc5c6b8e0385e3e2bf4262771d20a375002kosak 108661adbcc5c6b8e0385e3e2bf4262771d20a375002kosak if token.name == 'default' or token.name == 'delete': 108761adbcc5c6b8e0385e3e2bf4262771d20a375002kosak # Ignore explicitly defaulted and deleted special members 108861adbcc5c6b8e0385e3e2bf4262771d20a375002kosak # in C++11. 108961adbcc5c6b8e0385e3e2bf4262771d20a375002kosak token = self._GetNextToken() 109061adbcc5c6b8e0385e3e2bf4262771d20a375002kosak else: 109161adbcc5c6b8e0385e3e2bf4262771d20a375002kosak # Handle pure-virtual declarations. 109261adbcc5c6b8e0385e3e2bf4262771d20a375002kosak assert token.token_type == tokenize.CONSTANT, token 109361adbcc5c6b8e0385e3e2bf4262771d20a375002kosak assert token.name == '0', token 109461adbcc5c6b8e0385e3e2bf4262771d20a375002kosak modifiers |= FUNCTION_PURE_VIRTUAL 109561adbcc5c6b8e0385e3e2bf4262771d20a375002kosak token = self._GetNextToken() 1096e35fdd936d133bf8a48de140a3c666897588a05shiqian 1097e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == '[': 1098e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): store tokens and improve parsing. 1099e35fdd936d133bf8a48de140a3c666897588a05shiqian # template <typename T, size_t N> char (&ASH(T (&seq)[N]))[N]; 1100e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens = list(self._GetMatchingChar('[', ']')) 1101e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1102e35fdd936d133bf8a48de140a3c666897588a05shiqian 1103e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.name == ';', (token, return_type_and_name, parameters) 1104e35fdd936d133bf8a48de140a3c666897588a05shiqian 1105e35fdd936d133bf8a48de140a3c666897588a05shiqian # Looks like we got a method, not a function. 1106e35fdd936d133bf8a48de140a3c666897588a05shiqian if len(return_type) > 2 and return_type[-1].name == '::': 1107e35fdd936d133bf8a48de140a3c666897588a05shiqian return_type, in_class = \ 1108e35fdd936d133bf8a48de140a3c666897588a05shiqian self._GetReturnTypeAndClassName(return_type) 1109e35fdd936d133bf8a48de140a3c666897588a05shiqian return Method(indices.start, indices.end, name.name, in_class, 1110e35fdd936d133bf8a48de140a3c666897588a05shiqian return_type, parameters, modifiers, templated_types, 1111e35fdd936d133bf8a48de140a3c666897588a05shiqian body, self.namespace_stack) 1112e35fdd936d133bf8a48de140a3c666897588a05shiqian return Function(indices.start, indices.end, name.name, return_type, 1113e35fdd936d133bf8a48de140a3c666897588a05shiqian parameters, modifiers, templated_types, body, 1114e35fdd936d133bf8a48de140a3c666897588a05shiqian self.namespace_stack) 1115e35fdd936d133bf8a48de140a3c666897588a05shiqian 1116e35fdd936d133bf8a48de140a3c666897588a05shiqian def _GetReturnTypeAndClassName(self, token_seq): 1117e35fdd936d133bf8a48de140a3c666897588a05shiqian # Splitting the return type from the class name in a method 1118e35fdd936d133bf8a48de140a3c666897588a05shiqian # can be tricky. For example, Return::Type::Is::Hard::To::Find(). 1119e35fdd936d133bf8a48de140a3c666897588a05shiqian # Where is the return type and where is the class name? 1120e35fdd936d133bf8a48de140a3c666897588a05shiqian # The heuristic used is to pull the last name as the class name. 1121e35fdd936d133bf8a48de140a3c666897588a05shiqian # This includes all the templated type info. 1122e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): if there is only One name like in the 1123e35fdd936d133bf8a48de140a3c666897588a05shiqian # example above, punt and assume the last bit is the class name. 1124e35fdd936d133bf8a48de140a3c666897588a05shiqian 1125e35fdd936d133bf8a48de140a3c666897588a05shiqian # Ignore a :: prefix, if exists so we can find the first real name. 1126e35fdd936d133bf8a48de140a3c666897588a05shiqian i = 0 1127e35fdd936d133bf8a48de140a3c666897588a05shiqian if token_seq[0].name == '::': 1128e35fdd936d133bf8a48de140a3c666897588a05shiqian i = 1 1129e35fdd936d133bf8a48de140a3c666897588a05shiqian # Ignore a :: suffix, if exists. 1130e35fdd936d133bf8a48de140a3c666897588a05shiqian end = len(token_seq) - 1 1131e35fdd936d133bf8a48de140a3c666897588a05shiqian if token_seq[end-1].name == '::': 1132e35fdd936d133bf8a48de140a3c666897588a05shiqian end -= 1 1133e35fdd936d133bf8a48de140a3c666897588a05shiqian 1134e35fdd936d133bf8a48de140a3c666897588a05shiqian # Make a copy of the sequence so we can append a sentinel 1135e35fdd936d133bf8a48de140a3c666897588a05shiqian # value. This is required for GetName will has to have some 1136e35fdd936d133bf8a48de140a3c666897588a05shiqian # terminating condition beyond the last name. 1137e35fdd936d133bf8a48de140a3c666897588a05shiqian seq_copy = token_seq[i:end] 1138e35fdd936d133bf8a48de140a3c666897588a05shiqian seq_copy.append(tokenize.Token(tokenize.SYNTAX, '', 0, 0)) 1139e35fdd936d133bf8a48de140a3c666897588a05shiqian names = [] 1140e35fdd936d133bf8a48de140a3c666897588a05shiqian while i < end: 1141e35fdd936d133bf8a48de140a3c666897588a05shiqian # Iterate through the sequence parsing out each name. 1142e35fdd936d133bf8a48de140a3c666897588a05shiqian new_name, next = self.GetName(seq_copy[i:]) 1143e35fdd936d133bf8a48de140a3c666897588a05shiqian assert new_name, 'Got empty new_name, next=%s' % next 1144e35fdd936d133bf8a48de140a3c666897588a05shiqian # We got a pointer or ref. Add it to the name. 1145e35fdd936d133bf8a48de140a3c666897588a05shiqian if next and next.token_type == tokenize.SYNTAX: 1146e35fdd936d133bf8a48de140a3c666897588a05shiqian new_name.append(next) 1147e35fdd936d133bf8a48de140a3c666897588a05shiqian names.append(new_name) 1148e35fdd936d133bf8a48de140a3c666897588a05shiqian i += len(new_name) 1149e35fdd936d133bf8a48de140a3c666897588a05shiqian 1150e35fdd936d133bf8a48de140a3c666897588a05shiqian # Now that we have the names, it's time to undo what we did. 1151e35fdd936d133bf8a48de140a3c666897588a05shiqian 1152e35fdd936d133bf8a48de140a3c666897588a05shiqian # Remove the sentinel value. 1153e35fdd936d133bf8a48de140a3c666897588a05shiqian names[-1].pop() 1154e35fdd936d133bf8a48de140a3c666897588a05shiqian # Flatten the token sequence for the return type. 1155e35fdd936d133bf8a48de140a3c666897588a05shiqian return_type = [e for seq in names[:-1] for e in seq] 1156e35fdd936d133bf8a48de140a3c666897588a05shiqian # The class name is the last name. 1157e35fdd936d133bf8a48de140a3c666897588a05shiqian class_name = names[-1] 1158e35fdd936d133bf8a48de140a3c666897588a05shiqian return return_type, class_name 1159e35fdd936d133bf8a48de140a3c666897588a05shiqian 1160e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_bool(self): 1161e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1162e35fdd936d133bf8a48de140a3c666897588a05shiqian 1163e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_char(self): 1164e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1165e35fdd936d133bf8a48de140a3c666897588a05shiqian 1166e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_int(self): 1167e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1168e35fdd936d133bf8a48de140a3c666897588a05shiqian 1169e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_long(self): 1170e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1171e35fdd936d133bf8a48de140a3c666897588a05shiqian 1172e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_short(self): 1173e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1174e35fdd936d133bf8a48de140a3c666897588a05shiqian 1175e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_double(self): 1176e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1177e35fdd936d133bf8a48de140a3c666897588a05shiqian 1178e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_float(self): 1179e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1180e35fdd936d133bf8a48de140a3c666897588a05shiqian 1181e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_void(self): 1182e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1183e35fdd936d133bf8a48de140a3c666897588a05shiqian 1184e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_wchar_t(self): 1185e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1186e35fdd936d133bf8a48de140a3c666897588a05shiqian 1187e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_unsigned(self): 1188e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1189e35fdd936d133bf8a48de140a3c666897588a05shiqian 1190e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_signed(self): 1191e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1192e35fdd936d133bf8a48de140a3c666897588a05shiqian 1193e35fdd936d133bf8a48de140a3c666897588a05shiqian def _GetNestedType(self, ctor): 1194e35fdd936d133bf8a48de140a3c666897588a05shiqian name = None 1195e35fdd936d133bf8a48de140a3c666897588a05shiqian name_tokens, token = self.GetName() 1196e35fdd936d133bf8a48de140a3c666897588a05shiqian if name_tokens: 1197e35fdd936d133bf8a48de140a3c666897588a05shiqian name = ''.join([t.name for t in name_tokens]) 1198e35fdd936d133bf8a48de140a3c666897588a05shiqian 1199e35fdd936d133bf8a48de140a3c666897588a05shiqian # Handle forward declarations. 1200e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.token_type == tokenize.SYNTAX and token.name == ';': 1201e35fdd936d133bf8a48de140a3c666897588a05shiqian return ctor(token.start, token.end, name, None, 1202e35fdd936d133bf8a48de140a3c666897588a05shiqian self.namespace_stack) 1203e35fdd936d133bf8a48de140a3c666897588a05shiqian 1204e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.token_type == tokenize.NAME and self._handling_typedef: 1205e35fdd936d133bf8a48de140a3c666897588a05shiqian self._AddBackToken(token) 1206e35fdd936d133bf8a48de140a3c666897588a05shiqian return ctor(token.start, token.end, name, None, 1207e35fdd936d133bf8a48de140a3c666897588a05shiqian self.namespace_stack) 1208e35fdd936d133bf8a48de140a3c666897588a05shiqian 1209e35fdd936d133bf8a48de140a3c666897588a05shiqian # Must be the type declaration. 1210e35fdd936d133bf8a48de140a3c666897588a05shiqian fields = list(self._GetMatchingChar('{', '}')) 1211e35fdd936d133bf8a48de140a3c666897588a05shiqian del fields[-1] # Remove trailing '}'. 1212e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.token_type == tokenize.SYNTAX and token.name == '{': 1213e35fdd936d133bf8a48de140a3c666897588a05shiqian next = self._GetNextToken() 1214e35fdd936d133bf8a48de140a3c666897588a05shiqian new_type = ctor(token.start, token.end, name, fields, 1215e35fdd936d133bf8a48de140a3c666897588a05shiqian self.namespace_stack) 1216e35fdd936d133bf8a48de140a3c666897588a05shiqian # A name means this is an anonymous type and the name 1217e35fdd936d133bf8a48de140a3c666897588a05shiqian # is the variable declaration. 1218e35fdd936d133bf8a48de140a3c666897588a05shiqian if next.token_type != tokenize.NAME: 1219e35fdd936d133bf8a48de140a3c666897588a05shiqian return new_type 1220e35fdd936d133bf8a48de140a3c666897588a05shiqian name = new_type 1221e35fdd936d133bf8a48de140a3c666897588a05shiqian token = next 1222e35fdd936d133bf8a48de140a3c666897588a05shiqian 1223e35fdd936d133bf8a48de140a3c666897588a05shiqian # Must be variable declaration using the type prefixed with keyword. 1224e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.token_type == tokenize.NAME, token 1225e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._CreateVariable(token, token.name, name, [], '', None) 1226e35fdd936d133bf8a48de140a3c666897588a05shiqian 1227e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_struct(self): 1228e35fdd936d133bf8a48de140a3c666897588a05shiqian # Special case the handling typedef/aliasing of structs here. 1229e35fdd936d133bf8a48de140a3c666897588a05shiqian # It would be a pain to handle in the class code. 1230e35fdd936d133bf8a48de140a3c666897588a05shiqian name_tokens, var_token = self.GetName() 1231e35fdd936d133bf8a48de140a3c666897588a05shiqian if name_tokens: 1232e35fdd936d133bf8a48de140a3c666897588a05shiqian next_token = self._GetNextToken() 1233e35fdd936d133bf8a48de140a3c666897588a05shiqian is_syntax = (var_token.token_type == tokenize.SYNTAX and 1234e35fdd936d133bf8a48de140a3c666897588a05shiqian var_token.name[0] in '*&') 1235e35fdd936d133bf8a48de140a3c666897588a05shiqian is_variable = (var_token.token_type == tokenize.NAME and 1236e35fdd936d133bf8a48de140a3c666897588a05shiqian next_token.name == ';') 1237e35fdd936d133bf8a48de140a3c666897588a05shiqian variable = var_token 1238e35fdd936d133bf8a48de140a3c666897588a05shiqian if is_syntax and not is_variable: 1239e35fdd936d133bf8a48de140a3c666897588a05shiqian variable = next_token 1240e35fdd936d133bf8a48de140a3c666897588a05shiqian temp = self._GetNextToken() 1241e35fdd936d133bf8a48de140a3c666897588a05shiqian if temp.token_type == tokenize.SYNTAX and temp.name == '(': 1242e35fdd936d133bf8a48de140a3c666897588a05shiqian # Handle methods declared to return a struct. 1243e35fdd936d133bf8a48de140a3c666897588a05shiqian t0 = name_tokens[0] 1244e35fdd936d133bf8a48de140a3c666897588a05shiqian struct = tokenize.Token(tokenize.NAME, 'struct', 1245e35fdd936d133bf8a48de140a3c666897588a05shiqian t0.start-7, t0.start-2) 1246e35fdd936d133bf8a48de140a3c666897588a05shiqian type_and_name = [struct] 1247e35fdd936d133bf8a48de140a3c666897588a05shiqian type_and_name.extend(name_tokens) 1248e35fdd936d133bf8a48de140a3c666897588a05shiqian type_and_name.extend((var_token, next_token)) 1249e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._GetMethod(type_and_name, 0, None, False) 1250e35fdd936d133bf8a48de140a3c666897588a05shiqian assert temp.name == ';', (temp, name_tokens, var_token) 1251e35fdd936d133bf8a48de140a3c666897588a05shiqian if is_syntax or (is_variable and not self._handling_typedef): 1252e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers = ['struct'] 1253e35fdd936d133bf8a48de140a3c666897588a05shiqian type_name = ''.join([t.name for t in name_tokens]) 1254e35fdd936d133bf8a48de140a3c666897588a05shiqian position = name_tokens[0] 1255e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._CreateVariable(position, variable.name, type_name, 1256e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers, var_token.name, None) 1257e35fdd936d133bf8a48de140a3c666897588a05shiqian name_tokens.extend((var_token, next_token)) 1258e35fdd936d133bf8a48de140a3c666897588a05shiqian self._AddBackTokens(name_tokens) 1259e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 1260e35fdd936d133bf8a48de140a3c666897588a05shiqian self._AddBackToken(var_token) 1261e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._GetClass(Struct, VISIBILITY_PUBLIC, None) 1262e35fdd936d133bf8a48de140a3c666897588a05shiqian 1263e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_union(self): 1264e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._GetNestedType(Union) 1265e35fdd936d133bf8a48de140a3c666897588a05shiqian 1266e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_enum(self): 1267e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._GetNestedType(Enum) 1268e35fdd936d133bf8a48de140a3c666897588a05shiqian 1269e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_auto(self): 1270e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): warn about using auto? Probably not since it 1271e35fdd936d133bf8a48de140a3c666897588a05shiqian # will be reclaimed and useful for C++0x. 1272e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1273e35fdd936d133bf8a48de140a3c666897588a05shiqian 1274e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_register(self): 1275e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1276e35fdd936d133bf8a48de140a3c666897588a05shiqian 1277e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_const(self): 1278e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1279e35fdd936d133bf8a48de140a3c666897588a05shiqian 1280e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_inline(self): 1281e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1282e35fdd936d133bf8a48de140a3c666897588a05shiqian 1283e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_extern(self): 1284e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1285e35fdd936d133bf8a48de140a3c666897588a05shiqian 1286e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_static(self): 1287e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1288e35fdd936d133bf8a48de140a3c666897588a05shiqian 1289e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_virtual(self): 1290e35fdd936d133bf8a48de140a3c666897588a05shiqian # What follows must be a method. 1291e35fdd936d133bf8a48de140a3c666897588a05shiqian token = token2 = self._GetNextToken() 1292e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == 'inline': 1293e35fdd936d133bf8a48de140a3c666897588a05shiqian # HACK(nnorwitz): handle inline dtors by ignoring 'inline'. 1294e35fdd936d133bf8a48de140a3c666897588a05shiqian token2 = self._GetNextToken() 1295e35fdd936d133bf8a48de140a3c666897588a05shiqian if token2.token_type == tokenize.SYNTAX and token2.name == '~': 1296e35fdd936d133bf8a48de140a3c666897588a05shiqian return self.GetMethod(FUNCTION_VIRTUAL + FUNCTION_DTOR, None) 1297e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.token_type == tokenize.NAME or token.name == '::', token 1298c26f969579d62444ae7d422b37e0037ceca97a7akosak return_type_and_name = self._GetTokensUpTo(tokenize.SYNTAX, '(') # ) 1299e35fdd936d133bf8a48de140a3c666897588a05shiqian return_type_and_name.insert(0, token) 1300e35fdd936d133bf8a48de140a3c666897588a05shiqian if token2 is not token: 1301e35fdd936d133bf8a48de140a3c666897588a05shiqian return_type_and_name.insert(1, token2) 1302e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._GetMethod(return_type_and_name, FUNCTION_VIRTUAL, 1303e35fdd936d133bf8a48de140a3c666897588a05shiqian None, False) 1304e35fdd936d133bf8a48de140a3c666897588a05shiqian 1305e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_volatile(self): 1306e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1307e35fdd936d133bf8a48de140a3c666897588a05shiqian 1308e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_mutable(self): 1309e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1310e35fdd936d133bf8a48de140a3c666897588a05shiqian 1311e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_public(self): 1312e35fdd936d133bf8a48de140a3c666897588a05shiqian assert self.in_class 1313e35fdd936d133bf8a48de140a3c666897588a05shiqian self.visibility = VISIBILITY_PUBLIC 1314e35fdd936d133bf8a48de140a3c666897588a05shiqian 1315e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_protected(self): 1316e35fdd936d133bf8a48de140a3c666897588a05shiqian assert self.in_class 1317e35fdd936d133bf8a48de140a3c666897588a05shiqian self.visibility = VISIBILITY_PROTECTED 1318e35fdd936d133bf8a48de140a3c666897588a05shiqian 1319e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_private(self): 1320e35fdd936d133bf8a48de140a3c666897588a05shiqian assert self.in_class 1321e35fdd936d133bf8a48de140a3c666897588a05shiqian self.visibility = VISIBILITY_PRIVATE 1322e35fdd936d133bf8a48de140a3c666897588a05shiqian 1323e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_friend(self): 1324e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') 1325e35fdd936d133bf8a48de140a3c666897588a05shiqian assert tokens 1326e35fdd936d133bf8a48de140a3c666897588a05shiqian t0 = tokens[0] 1327e35fdd936d133bf8a48de140a3c666897588a05shiqian return Friend(t0.start, t0.end, tokens, self.namespace_stack) 1328e35fdd936d133bf8a48de140a3c666897588a05shiqian 1329e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_static_cast(self): 1330e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1331e35fdd936d133bf8a48de140a3c666897588a05shiqian 1332e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_const_cast(self): 1333e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1334e35fdd936d133bf8a48de140a3c666897588a05shiqian 1335e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_dynamic_cast(self): 1336e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1337e35fdd936d133bf8a48de140a3c666897588a05shiqian 1338e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_reinterpret_cast(self): 1339e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1340e35fdd936d133bf8a48de140a3c666897588a05shiqian 1341e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_new(self): 1342e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1343e35fdd936d133bf8a48de140a3c666897588a05shiqian 1344e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_delete(self): 1345e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') 1346e35fdd936d133bf8a48de140a3c666897588a05shiqian assert tokens 1347e35fdd936d133bf8a48de140a3c666897588a05shiqian return Delete(tokens[0].start, tokens[0].end, tokens) 1348e35fdd936d133bf8a48de140a3c666897588a05shiqian 1349e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_typedef(self): 1350e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1351e35fdd936d133bf8a48de140a3c666897588a05shiqian if (token.token_type == tokenize.NAME and 1352e35fdd936d133bf8a48de140a3c666897588a05shiqian keywords.IsKeyword(token.name)): 1353e35fdd936d133bf8a48de140a3c666897588a05shiqian # Token must be struct/enum/union/class. 1354e35fdd936d133bf8a48de140a3c666897588a05shiqian method = getattr(self, 'handle_' + token.name) 1355e35fdd936d133bf8a48de140a3c666897588a05shiqian self._handling_typedef = True 1356e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens = [method()] 1357e35fdd936d133bf8a48de140a3c666897588a05shiqian self._handling_typedef = False 1358e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 1359e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens = [token] 1360e35fdd936d133bf8a48de140a3c666897588a05shiqian 1361e35fdd936d133bf8a48de140a3c666897588a05shiqian # Get the remainder of the typedef up to the semi-colon. 1362e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens.extend(self._GetTokensUpTo(tokenize.SYNTAX, ';')) 1363e35fdd936d133bf8a48de140a3c666897588a05shiqian 1364e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): clean all this up. 1365e35fdd936d133bf8a48de140a3c666897588a05shiqian assert tokens 1366e35fdd936d133bf8a48de140a3c666897588a05shiqian name = tokens.pop() 1367e35fdd936d133bf8a48de140a3c666897588a05shiqian indices = name 1368e35fdd936d133bf8a48de140a3c666897588a05shiqian if tokens: 1369e35fdd936d133bf8a48de140a3c666897588a05shiqian indices = tokens[0] 1370e35fdd936d133bf8a48de140a3c666897588a05shiqian if not indices: 1371e35fdd936d133bf8a48de140a3c666897588a05shiqian indices = token 1372e35fdd936d133bf8a48de140a3c666897588a05shiqian if name.name == ')': 1373e35fdd936d133bf8a48de140a3c666897588a05shiqian # HACK(nnorwitz): Handle pointers to functions "properly". 1374e35fdd936d133bf8a48de140a3c666897588a05shiqian if (len(tokens) >= 4 and 1375e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens[1].name == '(' and tokens[2].name == '*'): 1376e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens.append(name) 1377e35fdd936d133bf8a48de140a3c666897588a05shiqian name = tokens[3] 1378e35fdd936d133bf8a48de140a3c666897588a05shiqian elif name.name == ']': 1379e35fdd936d133bf8a48de140a3c666897588a05shiqian # HACK(nnorwitz): Handle arrays properly. 1380e35fdd936d133bf8a48de140a3c666897588a05shiqian if len(tokens) >= 2: 1381e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens.append(name) 1382e35fdd936d133bf8a48de140a3c666897588a05shiqian name = tokens[1] 1383e35fdd936d133bf8a48de140a3c666897588a05shiqian new_type = tokens 1384e35fdd936d133bf8a48de140a3c666897588a05shiqian if tokens and isinstance(tokens[0], tokenize.Token): 1385e35fdd936d133bf8a48de140a3c666897588a05shiqian new_type = self.converter.ToType(tokens)[0] 1386e35fdd936d133bf8a48de140a3c666897588a05shiqian return Typedef(indices.start, indices.end, name.name, 1387e35fdd936d133bf8a48de140a3c666897588a05shiqian new_type, self.namespace_stack) 1388e35fdd936d133bf8a48de140a3c666897588a05shiqian 1389e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_typeid(self): 1390e35fdd936d133bf8a48de140a3c666897588a05shiqian pass # Not needed yet. 1391e35fdd936d133bf8a48de140a3c666897588a05shiqian 1392e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_typename(self): 1393e35fdd936d133bf8a48de140a3c666897588a05shiqian pass # Not needed yet. 1394e35fdd936d133bf8a48de140a3c666897588a05shiqian 1395e35fdd936d133bf8a48de140a3c666897588a05shiqian def _GetTemplatedTypes(self): 1396e35fdd936d133bf8a48de140a3c666897588a05shiqian result = {} 1397e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens = list(self._GetMatchingChar('<', '>')) 1398e35fdd936d133bf8a48de140a3c666897588a05shiqian len_tokens = len(tokens) - 1 # Ignore trailing '>'. 1399e35fdd936d133bf8a48de140a3c666897588a05shiqian i = 0 1400e35fdd936d133bf8a48de140a3c666897588a05shiqian while i < len_tokens: 1401e35fdd936d133bf8a48de140a3c666897588a05shiqian key = tokens[i].name 1402e35fdd936d133bf8a48de140a3c666897588a05shiqian i += 1 1403e35fdd936d133bf8a48de140a3c666897588a05shiqian if keywords.IsKeyword(key) or key == ',': 1404e35fdd936d133bf8a48de140a3c666897588a05shiqian continue 1405e35fdd936d133bf8a48de140a3c666897588a05shiqian type_name = default = None 1406e35fdd936d133bf8a48de140a3c666897588a05shiqian if i < len_tokens: 1407e35fdd936d133bf8a48de140a3c666897588a05shiqian i += 1 1408e35fdd936d133bf8a48de140a3c666897588a05shiqian if tokens[i-1].name == '=': 1409e35fdd936d133bf8a48de140a3c666897588a05shiqian assert i < len_tokens, '%s %s' % (i, tokens) 1410e35fdd936d133bf8a48de140a3c666897588a05shiqian default, unused_next_token = self.GetName(tokens[i:]) 1411e35fdd936d133bf8a48de140a3c666897588a05shiqian i += len(default) 1412e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 1413e35fdd936d133bf8a48de140a3c666897588a05shiqian if tokens[i-1].name != ',': 1414e35fdd936d133bf8a48de140a3c666897588a05shiqian # We got something like: Type variable. 1415e35fdd936d133bf8a48de140a3c666897588a05shiqian # Re-adjust the key (variable) and type_name (Type). 1416e35fdd936d133bf8a48de140a3c666897588a05shiqian key = tokens[i-1].name 1417e35fdd936d133bf8a48de140a3c666897588a05shiqian type_name = tokens[i-2] 1418e35fdd936d133bf8a48de140a3c666897588a05shiqian 1419e35fdd936d133bf8a48de140a3c666897588a05shiqian result[key] = (type_name, default) 1420e35fdd936d133bf8a48de140a3c666897588a05shiqian return result 1421e35fdd936d133bf8a48de140a3c666897588a05shiqian 1422e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_template(self): 1423e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1424e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.token_type == tokenize.SYNTAX, token 1425e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.name == '<', token 1426e35fdd936d133bf8a48de140a3c666897588a05shiqian templated_types = self._GetTemplatedTypes() 1427e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): for now, just ignore the template params. 1428e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1429e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.token_type == tokenize.NAME: 1430e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == 'class': 1431e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._GetClass(Class, VISIBILITY_PRIVATE, templated_types) 1432e35fdd936d133bf8a48de140a3c666897588a05shiqian elif token.name == 'struct': 1433e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._GetClass(Struct, VISIBILITY_PUBLIC, templated_types) 1434e35fdd936d133bf8a48de140a3c666897588a05shiqian elif token.name == 'friend': 1435e35fdd936d133bf8a48de140a3c666897588a05shiqian return self.handle_friend() 1436e35fdd936d133bf8a48de140a3c666897588a05shiqian self._AddBackToken(token) 1437e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens, last = self._GetVarTokensUpTo(tokenize.SYNTAX, '(', ';') 1438e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens.append(last) 1439e35fdd936d133bf8a48de140a3c666897588a05shiqian self._AddBackTokens(tokens) 1440e35fdd936d133bf8a48de140a3c666897588a05shiqian if last.name == '(': 1441e35fdd936d133bf8a48de140a3c666897588a05shiqian return self.GetMethod(FUNCTION_NONE, templated_types) 1442e35fdd936d133bf8a48de140a3c666897588a05shiqian # Must be a variable definition. 1443e35fdd936d133bf8a48de140a3c666897588a05shiqian return None 1444e35fdd936d133bf8a48de140a3c666897588a05shiqian 1445e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_true(self): 1446e35fdd936d133bf8a48de140a3c666897588a05shiqian pass # Nothing to do. 1447e35fdd936d133bf8a48de140a3c666897588a05shiqian 1448e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_false(self): 1449e35fdd936d133bf8a48de140a3c666897588a05shiqian pass # Nothing to do. 1450e35fdd936d133bf8a48de140a3c666897588a05shiqian 1451e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_asm(self): 1452e35fdd936d133bf8a48de140a3c666897588a05shiqian pass # Not needed yet. 1453e35fdd936d133bf8a48de140a3c666897588a05shiqian 1454e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_class(self): 1455e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._GetClass(Class, VISIBILITY_PRIVATE, None) 1456e35fdd936d133bf8a48de140a3c666897588a05shiqian 1457e35fdd936d133bf8a48de140a3c666897588a05shiqian def _GetBases(self): 1458e35fdd936d133bf8a48de140a3c666897588a05shiqian # Get base classes. 1459e35fdd936d133bf8a48de140a3c666897588a05shiqian bases = [] 1460e35fdd936d133bf8a48de140a3c666897588a05shiqian while 1: 1461e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1462e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.token_type == tokenize.NAME, token 1463e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): store kind of inheritance...maybe. 1464e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name not in ('public', 'protected', 'private'): 1465e35fdd936d133bf8a48de140a3c666897588a05shiqian # If inheritance type is not specified, it is private. 1466e35fdd936d133bf8a48de140a3c666897588a05shiqian # Just put the token back so we can form a name. 1467e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): it would be good to warn about this. 1468e35fdd936d133bf8a48de140a3c666897588a05shiqian self._AddBackToken(token) 1469e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 1470e35fdd936d133bf8a48de140a3c666897588a05shiqian # Check for virtual inheritance. 1471e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1472e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name != 'virtual': 1473e35fdd936d133bf8a48de140a3c666897588a05shiqian self._AddBackToken(token) 1474e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 1475e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): store that we got virtual for this base. 1476e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1477e35fdd936d133bf8a48de140a3c666897588a05shiqian base, next_token = self.GetName() 1478e35fdd936d133bf8a48de140a3c666897588a05shiqian bases_ast = self.converter.ToType(base) 1479e35fdd936d133bf8a48de140a3c666897588a05shiqian assert len(bases_ast) == 1, bases_ast 1480e35fdd936d133bf8a48de140a3c666897588a05shiqian bases.append(bases_ast[0]) 1481e35fdd936d133bf8a48de140a3c666897588a05shiqian assert next_token.token_type == tokenize.SYNTAX, next_token 1482e35fdd936d133bf8a48de140a3c666897588a05shiqian if next_token.name == '{': 1483e35fdd936d133bf8a48de140a3c666897588a05shiqian token = next_token 1484e35fdd936d133bf8a48de140a3c666897588a05shiqian break 1485e35fdd936d133bf8a48de140a3c666897588a05shiqian # Support multiple inheritance. 1486e35fdd936d133bf8a48de140a3c666897588a05shiqian assert next_token.name == ',', next_token 1487e35fdd936d133bf8a48de140a3c666897588a05shiqian return bases, token 1488e35fdd936d133bf8a48de140a3c666897588a05shiqian 1489e35fdd936d133bf8a48de140a3c666897588a05shiqian def _GetClass(self, class_type, visibility, templated_types): 1490e35fdd936d133bf8a48de140a3c666897588a05shiqian class_name = None 1491e35fdd936d133bf8a48de140a3c666897588a05shiqian class_token = self._GetNextToken() 1492e35fdd936d133bf8a48de140a3c666897588a05shiqian if class_token.token_type != tokenize.NAME: 1493e35fdd936d133bf8a48de140a3c666897588a05shiqian assert class_token.token_type == tokenize.SYNTAX, class_token 1494e35fdd936d133bf8a48de140a3c666897588a05shiqian token = class_token 1495e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 14965b61ce3ee5b15e6356487dd97236bf663a96a391zhanyong.wan # Skip any macro (e.g. storage class specifiers) after the 14975b61ce3ee5b15e6356487dd97236bf663a96a391zhanyong.wan # 'class' keyword. 14985b61ce3ee5b15e6356487dd97236bf663a96a391zhanyong.wan next_token = self._GetNextToken() 14995b61ce3ee5b15e6356487dd97236bf663a96a391zhanyong.wan if next_token.token_type == tokenize.NAME: 15005b61ce3ee5b15e6356487dd97236bf663a96a391zhanyong.wan self._AddBackToken(next_token) 15015b61ce3ee5b15e6356487dd97236bf663a96a391zhanyong.wan else: 15025b61ce3ee5b15e6356487dd97236bf663a96a391zhanyong.wan self._AddBackTokens([class_token, next_token]) 1503e35fdd936d133bf8a48de140a3c666897588a05shiqian name_tokens, token = self.GetName() 1504e35fdd936d133bf8a48de140a3c666897588a05shiqian class_name = ''.join([t.name for t in name_tokens]) 1505e35fdd936d133bf8a48de140a3c666897588a05shiqian bases = None 1506e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.token_type == tokenize.SYNTAX: 1507e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == ';': 1508e35fdd936d133bf8a48de140a3c666897588a05shiqian # Forward declaration. 1509e35fdd936d133bf8a48de140a3c666897588a05shiqian return class_type(class_token.start, class_token.end, 1510e35fdd936d133bf8a48de140a3c666897588a05shiqian class_name, None, templated_types, None, 1511e35fdd936d133bf8a48de140a3c666897588a05shiqian self.namespace_stack) 1512e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name in '*&': 1513e35fdd936d133bf8a48de140a3c666897588a05shiqian # Inline forward declaration. Could be method or data. 1514e35fdd936d133bf8a48de140a3c666897588a05shiqian name_token = self._GetNextToken() 1515e35fdd936d133bf8a48de140a3c666897588a05shiqian next_token = self._GetNextToken() 1516e35fdd936d133bf8a48de140a3c666897588a05shiqian if next_token.name == ';': 1517e35fdd936d133bf8a48de140a3c666897588a05shiqian # Handle data 1518e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers = ['class'] 1519e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._CreateVariable(class_token, name_token.name, 1520e35fdd936d133bf8a48de140a3c666897588a05shiqian class_name, 1521e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers, token.name, None) 1522e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 1523e35fdd936d133bf8a48de140a3c666897588a05shiqian # Assume this is a method. 1524e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens = (class_token, token, name_token, next_token) 1525e35fdd936d133bf8a48de140a3c666897588a05shiqian self._AddBackTokens(tokens) 1526e35fdd936d133bf8a48de140a3c666897588a05shiqian return self.GetMethod(FUNCTION_NONE, None) 1527e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == ':': 1528e35fdd936d133bf8a48de140a3c666897588a05shiqian bases, token = self._GetBases() 1529e35fdd936d133bf8a48de140a3c666897588a05shiqian 1530e35fdd936d133bf8a48de140a3c666897588a05shiqian body = None 1531e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.token_type == tokenize.SYNTAX and token.name == '{': 1532e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.token_type == tokenize.SYNTAX, token 1533e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.name == '{', token 1534e35fdd936d133bf8a48de140a3c666897588a05shiqian 1535e35fdd936d133bf8a48de140a3c666897588a05shiqian ast = AstBuilder(self.GetScope(), self.filename, class_name, 1536e35fdd936d133bf8a48de140a3c666897588a05shiqian visibility, self.namespace_stack) 1537e35fdd936d133bf8a48de140a3c666897588a05shiqian body = list(ast.Generate()) 1538e35fdd936d133bf8a48de140a3c666897588a05shiqian 1539e35fdd936d133bf8a48de140a3c666897588a05shiqian if not self._handling_typedef: 1540e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1541e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.token_type != tokenize.NAME: 1542e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.token_type == tokenize.SYNTAX, token 1543e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.name == ';', token 1544e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 1545e35fdd936d133bf8a48de140a3c666897588a05shiqian new_class = class_type(class_token.start, class_token.end, 1546e35fdd936d133bf8a48de140a3c666897588a05shiqian class_name, bases, None, 1547e35fdd936d133bf8a48de140a3c666897588a05shiqian body, self.namespace_stack) 1548e35fdd936d133bf8a48de140a3c666897588a05shiqian 1549e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers = [] 1550e35fdd936d133bf8a48de140a3c666897588a05shiqian return self._CreateVariable(class_token, 1551e35fdd936d133bf8a48de140a3c666897588a05shiqian token.name, new_class, 1552e35fdd936d133bf8a48de140a3c666897588a05shiqian modifiers, token.name, None) 1553e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 1554e35fdd936d133bf8a48de140a3c666897588a05shiqian if not self._handling_typedef: 1555e35fdd936d133bf8a48de140a3c666897588a05shiqian self.HandleError('non-typedef token', token) 1556e35fdd936d133bf8a48de140a3c666897588a05shiqian self._AddBackToken(token) 1557e35fdd936d133bf8a48de140a3c666897588a05shiqian 1558e35fdd936d133bf8a48de140a3c666897588a05shiqian return class_type(class_token.start, class_token.end, class_name, 155945fef502fac471efa4bf25b3d4104943463912ebzhanyong.wan bases, templated_types, body, self.namespace_stack) 1560e35fdd936d133bf8a48de140a3c666897588a05shiqian 1561e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_namespace(self): 1562e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1563e35fdd936d133bf8a48de140a3c666897588a05shiqian # Support anonymous namespaces. 1564e35fdd936d133bf8a48de140a3c666897588a05shiqian name = None 1565e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.token_type == tokenize.NAME: 1566e35fdd936d133bf8a48de140a3c666897588a05shiqian name = token.name 1567e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1568e35fdd936d133bf8a48de140a3c666897588a05shiqian self.namespace_stack.append(name) 1569e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.token_type == tokenize.SYNTAX, token 1570c2ad46a5df4414fc2b804c53525f4578f01a3dfezhanyong.wan # Create an internal token that denotes when the namespace is complete. 1571c2ad46a5df4414fc2b804c53525f4578f01a3dfezhanyong.wan internal_token = tokenize.Token(_INTERNAL_TOKEN, _NAMESPACE_POP, 1572c2ad46a5df4414fc2b804c53525f4578f01a3dfezhanyong.wan None, None) 1573c2ad46a5df4414fc2b804c53525f4578f01a3dfezhanyong.wan internal_token.whence = token.whence 1574e35fdd936d133bf8a48de140a3c666897588a05shiqian if token.name == '=': 1575e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): handle aliasing namespaces. 1576e35fdd936d133bf8a48de140a3c666897588a05shiqian name, next_token = self.GetName() 1577e35fdd936d133bf8a48de140a3c666897588a05shiqian assert next_token.name == ';', next_token 1578c2ad46a5df4414fc2b804c53525f4578f01a3dfezhanyong.wan self._AddBackToken(internal_token) 1579e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 1580e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.name == '{', token 1581e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens = list(self.GetScope()) 1582c2ad46a5df4414fc2b804c53525f4578f01a3dfezhanyong.wan # Replace the trailing } with the internal namespace pop token. 1583c2ad46a5df4414fc2b804c53525f4578f01a3dfezhanyong.wan tokens[-1] = internal_token 1584e35fdd936d133bf8a48de140a3c666897588a05shiqian # Handle namespace with nothing in it. 1585e35fdd936d133bf8a48de140a3c666897588a05shiqian self._AddBackTokens(tokens) 1586e35fdd936d133bf8a48de140a3c666897588a05shiqian return None 1587e35fdd936d133bf8a48de140a3c666897588a05shiqian 1588e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_using(self): 1589e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') 1590e35fdd936d133bf8a48de140a3c666897588a05shiqian assert tokens 1591e35fdd936d133bf8a48de140a3c666897588a05shiqian return Using(tokens[0].start, tokens[0].end, tokens) 1592e35fdd936d133bf8a48de140a3c666897588a05shiqian 1593e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_explicit(self): 1594e35fdd936d133bf8a48de140a3c666897588a05shiqian assert self.in_class 1595e35fdd936d133bf8a48de140a3c666897588a05shiqian # Nothing much to do. 1596e35fdd936d133bf8a48de140a3c666897588a05shiqian # TODO(nnorwitz): maybe verify the method name == class name. 1597e35fdd936d133bf8a48de140a3c666897588a05shiqian # This must be a ctor. 1598e35fdd936d133bf8a48de140a3c666897588a05shiqian return self.GetMethod(FUNCTION_CTOR, None) 1599e35fdd936d133bf8a48de140a3c666897588a05shiqian 1600e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_this(self): 1601e35fdd936d133bf8a48de140a3c666897588a05shiqian pass # Nothing to do. 1602e35fdd936d133bf8a48de140a3c666897588a05shiqian 1603e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_operator(self): 1604e35fdd936d133bf8a48de140a3c666897588a05shiqian # Pull off the next token(s?) and make that part of the method name. 1605e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1606e35fdd936d133bf8a48de140a3c666897588a05shiqian 1607e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_sizeof(self): 1608e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1609e35fdd936d133bf8a48de140a3c666897588a05shiqian 1610e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_case(self): 1611e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1612e35fdd936d133bf8a48de140a3c666897588a05shiqian 1613e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_switch(self): 1614e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1615e35fdd936d133bf8a48de140a3c666897588a05shiqian 1616e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_default(self): 1617e35fdd936d133bf8a48de140a3c666897588a05shiqian token = self._GetNextToken() 1618e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.token_type == tokenize.SYNTAX 1619e35fdd936d133bf8a48de140a3c666897588a05shiqian assert token.name == ':' 1620e35fdd936d133bf8a48de140a3c666897588a05shiqian 1621e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_if(self): 1622e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1623e35fdd936d133bf8a48de140a3c666897588a05shiqian 1624e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_else(self): 1625e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1626e35fdd936d133bf8a48de140a3c666897588a05shiqian 1627e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_return(self): 1628e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') 1629e35fdd936d133bf8a48de140a3c666897588a05shiqian if not tokens: 1630e35fdd936d133bf8a48de140a3c666897588a05shiqian return Return(self.current_token.start, self.current_token.end, None) 1631e35fdd936d133bf8a48de140a3c666897588a05shiqian return Return(tokens[0].start, tokens[0].end, tokens) 1632e35fdd936d133bf8a48de140a3c666897588a05shiqian 1633e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_goto(self): 1634e35fdd936d133bf8a48de140a3c666897588a05shiqian tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') 1635e35fdd936d133bf8a48de140a3c666897588a05shiqian assert len(tokens) == 1, str(tokens) 1636e35fdd936d133bf8a48de140a3c666897588a05shiqian return Goto(tokens[0].start, tokens[0].end, tokens[0].name) 1637e35fdd936d133bf8a48de140a3c666897588a05shiqian 1638e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_try(self): 1639e35fdd936d133bf8a48de140a3c666897588a05shiqian pass # Not needed yet. 1640e35fdd936d133bf8a48de140a3c666897588a05shiqian 1641e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_catch(self): 1642e35fdd936d133bf8a48de140a3c666897588a05shiqian pass # Not needed yet. 1643e35fdd936d133bf8a48de140a3c666897588a05shiqian 1644e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_throw(self): 1645e35fdd936d133bf8a48de140a3c666897588a05shiqian pass # Not needed yet. 1646e35fdd936d133bf8a48de140a3c666897588a05shiqian 1647e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_while(self): 1648e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1649e35fdd936d133bf8a48de140a3c666897588a05shiqian 1650e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_do(self): 1651e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1652e35fdd936d133bf8a48de140a3c666897588a05shiqian 1653e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_for(self): 1654e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1655e35fdd936d133bf8a48de140a3c666897588a05shiqian 1656e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_break(self): 1657e35fdd936d133bf8a48de140a3c666897588a05shiqian self._IgnoreUpTo(tokenize.SYNTAX, ';') 1658e35fdd936d133bf8a48de140a3c666897588a05shiqian 1659e35fdd936d133bf8a48de140a3c666897588a05shiqian def handle_continue(self): 1660e35fdd936d133bf8a48de140a3c666897588a05shiqian self._IgnoreUpTo(tokenize.SYNTAX, ';') 1661e35fdd936d133bf8a48de140a3c666897588a05shiqian 1662e35fdd936d133bf8a48de140a3c666897588a05shiqian 1663e35fdd936d133bf8a48de140a3c666897588a05shiqiandef BuilderFromSource(source, filename): 1664e35fdd936d133bf8a48de140a3c666897588a05shiqian """Utility method that returns an AstBuilder from source code. 1665e35fdd936d133bf8a48de140a3c666897588a05shiqian 1666e35fdd936d133bf8a48de140a3c666897588a05shiqian Args: 1667e35fdd936d133bf8a48de140a3c666897588a05shiqian source: 'C++ source code' 1668e35fdd936d133bf8a48de140a3c666897588a05shiqian filename: 'file1' 1669e35fdd936d133bf8a48de140a3c666897588a05shiqian 1670e35fdd936d133bf8a48de140a3c666897588a05shiqian Returns: 1671e35fdd936d133bf8a48de140a3c666897588a05shiqian AstBuilder 1672e35fdd936d133bf8a48de140a3c666897588a05shiqian """ 1673e35fdd936d133bf8a48de140a3c666897588a05shiqian return AstBuilder(tokenize.GetTokens(source), filename) 1674e35fdd936d133bf8a48de140a3c666897588a05shiqian 1675e35fdd936d133bf8a48de140a3c666897588a05shiqian 1676e35fdd936d133bf8a48de140a3c666897588a05shiqiandef PrintIndentifiers(filename, should_print): 1677e35fdd936d133bf8a48de140a3c666897588a05shiqian """Prints all identifiers for a C++ source file. 1678e35fdd936d133bf8a48de140a3c666897588a05shiqian 1679e35fdd936d133bf8a48de140a3c666897588a05shiqian Args: 1680e35fdd936d133bf8a48de140a3c666897588a05shiqian filename: 'file1' 1681e35fdd936d133bf8a48de140a3c666897588a05shiqian should_print: predicate with signature: bool Function(token) 1682e35fdd936d133bf8a48de140a3c666897588a05shiqian """ 1683e35fdd936d133bf8a48de140a3c666897588a05shiqian source = utils.ReadFile(filename, False) 1684e35fdd936d133bf8a48de140a3c666897588a05shiqian if source is None: 1685e35fdd936d133bf8a48de140a3c666897588a05shiqian sys.stderr.write('Unable to find: %s\n' % filename) 1686e35fdd936d133bf8a48de140a3c666897588a05shiqian return 1687e35fdd936d133bf8a48de140a3c666897588a05shiqian 1688e35fdd936d133bf8a48de140a3c666897588a05shiqian #print('Processing %s' % actual_filename) 1689e35fdd936d133bf8a48de140a3c666897588a05shiqian builder = BuilderFromSource(source, filename) 1690e35fdd936d133bf8a48de140a3c666897588a05shiqian try: 1691e35fdd936d133bf8a48de140a3c666897588a05shiqian for node in builder.Generate(): 1692e35fdd936d133bf8a48de140a3c666897588a05shiqian if should_print(node): 1693e35fdd936d133bf8a48de140a3c666897588a05shiqian print(node.name) 1694e35fdd936d133bf8a48de140a3c666897588a05shiqian except KeyboardInterrupt: 1695c2ad46a5df4414fc2b804c53525f4578f01a3dfezhanyong.wan return 1696e35fdd936d133bf8a48de140a3c666897588a05shiqian except: 1697e35fdd936d133bf8a48de140a3c666897588a05shiqian pass 1698e35fdd936d133bf8a48de140a3c666897588a05shiqian 1699e35fdd936d133bf8a48de140a3c666897588a05shiqian 1700e35fdd936d133bf8a48de140a3c666897588a05shiqiandef PrintAllIndentifiers(filenames, should_print): 1701e35fdd936d133bf8a48de140a3c666897588a05shiqian """Prints all identifiers for each C++ source file in filenames. 1702e35fdd936d133bf8a48de140a3c666897588a05shiqian 1703e35fdd936d133bf8a48de140a3c666897588a05shiqian Args: 1704e35fdd936d133bf8a48de140a3c666897588a05shiqian filenames: ['file1', 'file2', ...] 1705e35fdd936d133bf8a48de140a3c666897588a05shiqian should_print: predicate with signature: bool Function(token) 1706e35fdd936d133bf8a48de140a3c666897588a05shiqian """ 1707e35fdd936d133bf8a48de140a3c666897588a05shiqian for path in filenames: 1708e35fdd936d133bf8a48de140a3c666897588a05shiqian PrintIndentifiers(path, should_print) 1709e35fdd936d133bf8a48de140a3c666897588a05shiqian 1710e35fdd936d133bf8a48de140a3c666897588a05shiqian 1711e35fdd936d133bf8a48de140a3c666897588a05shiqiandef main(argv): 1712e35fdd936d133bf8a48de140a3c666897588a05shiqian for filename in argv[1:]: 1713e35fdd936d133bf8a48de140a3c666897588a05shiqian source = utils.ReadFile(filename) 1714e35fdd936d133bf8a48de140a3c666897588a05shiqian if source is None: 1715e35fdd936d133bf8a48de140a3c666897588a05shiqian continue 1716e35fdd936d133bf8a48de140a3c666897588a05shiqian 1717e35fdd936d133bf8a48de140a3c666897588a05shiqian print('Processing %s' % filename) 1718e35fdd936d133bf8a48de140a3c666897588a05shiqian builder = BuilderFromSource(source, filename) 1719e35fdd936d133bf8a48de140a3c666897588a05shiqian try: 1720e35fdd936d133bf8a48de140a3c666897588a05shiqian entire_ast = filter(None, builder.Generate()) 1721e35fdd936d133bf8a48de140a3c666897588a05shiqian except KeyboardInterrupt: 1722e35fdd936d133bf8a48de140a3c666897588a05shiqian return 1723e35fdd936d133bf8a48de140a3c666897588a05shiqian except: 1724e35fdd936d133bf8a48de140a3c666897588a05shiqian # Already printed a warning, print the traceback and continue. 1725e35fdd936d133bf8a48de140a3c666897588a05shiqian traceback.print_exc() 1726e35fdd936d133bf8a48de140a3c666897588a05shiqian else: 1727e35fdd936d133bf8a48de140a3c666897588a05shiqian if utils.DEBUG: 1728e35fdd936d133bf8a48de140a3c666897588a05shiqian for ast in entire_ast: 1729e35fdd936d133bf8a48de140a3c666897588a05shiqian print(ast) 1730e35fdd936d133bf8a48de140a3c666897588a05shiqian 1731e35fdd936d133bf8a48de140a3c666897588a05shiqian 1732e35fdd936d133bf8a48de140a3c666897588a05shiqianif __name__ == '__main__': 1733e35fdd936d133bf8a48de140a3c666897588a05shiqian main(sys.argv) 1734