File indexing completed on 2024-07-14 15:05:10

0001 # -*- coding: utf-8 -*-
0002 #     Copyright 2007-8 Jim Bublitz <jbublitz@nwinternet.com>
0003 #     Copyright 2009 Simon Edwards <simon@simonzone.com>
0004 #
0005 # This program is free software; you can redistribute it and/or modify
0006 # it under the terms of the GNU General Public License as published by
0007 # the Free Software Foundation; either version 2 of the License, or
0008 # (at your option) any later version.
0009 #
0010 # This program is distributed in the hope that it will be useful,
0011 # but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 # GNU General Public License for more details.
0014 #
0015 # You should have received a copy of the GNU General Public License
0016 # along with this program; if not, write to the
0017 # Free Software Foundation, Inc.,
0018 # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0019 
0020 from .sealed import sealed
0021 #from argvalidate import accepts,returns,one_of
0022 import types
0023 
0024 RETURN_INDENT = 24
0025 
0026 class SymbolData(object):
0027     """Represent the contents of a C++ header file.
0028      
0029     This class and its nested classes can represent the contents of a C++
0030     header file. `topScope()` returns the top level scope. From here you can
0031     loop over the contents of the file.
0032     """
0033     ACCESS_PUBLIC = object()
0034     ACCESS_PRIVATE = object()
0035     ACCESS_PROTECTED = object()
0036     ACCESS_SIGNALS = object()
0037     ACCESS_TYPE_MAPPING_FROM_NAME = {
0038         'public': ACCESS_PUBLIC,
0039         'private': ACCESS_PRIVATE,
0040         'protected': ACCESS_PROTECTED,
0041         'signals': ACCESS_SIGNALS
0042     }
0043 
0044     ACCESS_TYPE_MAPPING_TO_NAME = {}
0045     for (key,value) in ACCESS_TYPE_MAPPING_FROM_NAME.items():
0046         ACCESS_TYPE_MAPPING_TO_NAME[value] = key
0047 
0048     @sealed
0049     def __init__(self):
0050         """Instantiate a new SymbolData."""
0051         self._scopes = []
0052         self._typeIndex = None
0053         self._nsIndex = None
0054 
0055     def lookupType(self,name,context):
0056         resolvedType = self._safeLookupType(name,context)
0057         if resolvedType is None:
0058             raise KeyError()
0059         return resolvedType
0060     
0061     def _safeLookupType(self,name,context):
0062         if self._typeIndex is None:
0063             self._buildTypeIndex()
0064             
0065         contextFqName = context.fqName() if context is not None else None
0066         if contextFqName is not None:
0067             pathParts = contextFqName.split("::")
0068             for i in range(len(pathParts)):
0069                 canidate = '::'.join(pathParts[:len(pathParts)-i]) + '::' + name
0070                 if canidate in self._typeIndex:
0071                     return self._typeIndex[canidate]
0072        
0073         resolvedType = self._typeIndex.get(name,None)
0074         if resolvedType is not None:
0075             return resolvedType
0076             
0077         if isinstance(context,SymbolData.CppClass):
0078             for base in context.bases():
0079                 resolvedBase = self._safeLookupType(base,context.parentScope())
0080                 if resolvedBase is not None:
0081                     result = self._safeLookupType(name,resolvedBase)
0082                     if result is not None:
0083                         return result
0084                     
0085         return None
0086             
0087     def _buildTypeIndex(self):
0088         self._typeIndex = {}
0089         
0090         def IndexScope(scope):
0091             for item in scope:
0092                 if isinstance(item,SymbolData.CppClass):
0093                     if item.fqName() in self._typeIndex:
0094                         if not self._typeIndex[item.fqName()].opaque():
0095                             continue
0096                     self._typeIndex[item.fqName()] = item
0097                     IndexScope(item)
0098                 elif isinstance(item,SymbolData.Enum) or isinstance(item,SymbolData.Typedef):
0099                     fqName = item.fqName()
0100                     if fqName is not None:
0101                         self._typeIndex[item.fqName()] = item
0102                 elif isinstance(item,SymbolData.Namespace):
0103                     self._typeIndex[item.fqName()] = item
0104                     IndexScope(item)
0105                 elif isinstance(item,SymbolData.Variable):
0106                     self._typeIndex[item.fqName()] = item
0107 
0108         for scope in self._scopes:
0109             IndexScope(scope)
0110         #print("index: " + repr(self._typeIndex.keys()))
0111 
0112     def lookupNamespace(self,nsName):
0113         if self._nsIndex is None:
0114             self._buildNSIndex()
0115 
0116         return self._nsIndex.setdefault(nsName,[])
0117 
0118     def _buildNSIndex(self):
0119         self._nsIndex = {}
0120 
0121         def IndexScope(scope):
0122             for item in scope:
0123                 if isinstance(item,SymbolData.Namespace):
0124                     entry = self._nsIndex.setdefault(item.fqName(), [])
0125                     entry.append(item)
0126                     IndexScope(item)
0127 
0128         for scope in self._scopes:
0129             IndexScope(scope)
0130 
0131     def _changed(self):
0132         self._typeIndex = None
0133         self._nsIndex = None
0134 
0135     def dumpKnownTypes(self):
0136         if self._typeIndex is None:
0137             self._buildTypeIndex()
0138         
0139         print("Known types (%i)---------------------------------" % (len(self._typeIndex.keys()),) )
0140         print("Top levels: %i" % (len(self._scopes),) )
0141         typesKeys = list(self._typeIndex.keys())
0142         typesKeys.sort()
0143         print(", ".join( (self._typeIndex[x].fqName()+":"+str(id(self._typeIndex[x])) for x in typesKeys) ))
0144 
0145     def lookupEnum(self,value,context):
0146         scope = context
0147         while scope is not None:
0148             for item in scope:
0149                 if isinstance(item,SymbolData.Enum):
0150                     for enum in item:
0151                         if enum.name()==value:
0152                             return item
0153             scope = scope.parentScope()
0154             
0155         if isinstance(context,self.SipClass):
0156             for base in context.bases():
0157                 resolvedBase = self._safeLookupType(base,context.parentScope())
0158                 if resolvedBase is not None:
0159                     enum = self.lookupEnum(value,resolvedBase)
0160                     if enum is not None:
0161                         return enum
0162         return None
0163 
0164     def newScope(self):
0165         scope = self.TopLevelScope(self)
0166         self._scopes.append(scope)
0167         return scope
0168         
0169     def removeScope(self,scope):
0170         if scope not in self._scopes:
0171             return
0172         self._scopes.remove(scope)
0173         self._changed()
0174 
0175     @classmethod
0176     def _indentString(cls, indent):
0177         return ' ' * (4*indent)
0178         
0179     # Query interface goes here.
0180     
0181     class Entity(object):
0182         """Represents an entity and a scope which can hold other entities.
0183         
0184         This class isn't meant to be used directly but is typically subclassed."""
0185         @sealed
0186         def __init__(self, parentScope, name, filename, lineno):
0187             self._scope = parentScope
0188             self._filename = filename
0189             self._lineno = lineno
0190             if self._scope is not None:
0191                 self._scope.insertIntoScope(None, self)
0192             self._items = []
0193             self._name = name
0194         
0195         def _fixScope(self):
0196             # A bit of an ugly hack to 
0197             for item in self:
0198                 if isinstance(item,SymbolData.Entity):
0199                     if item._scope is not self:
0200                         print("Fixing scope found an error!")
0201                         print("Fixing scope: " + repr(item._name))
0202                         print("Old scope: " + repr(item._scope._name) + " " + repr(id(item._scope)) + " "+repr(type(item._scope)))
0203                         print("Correct scope: " + repr(self._name) + " " + repr(id(self)) + " "+repr(type(item._scope)))
0204                     item._scope = self
0205                     item._fixScope()
0206         
0207         #@returns(one_of(str,types.NoneType))
0208         def name(self):
0209             return self._name
0210             
0211         #@returns(str)
0212         def fqName(self):
0213             parentFqn = self.parentScope().fqName()
0214             
0215             # FIXME name() should never be None. This only happens because the typedef parsing is broken with enums.
0216             if self.name() is None:
0217                 return ""
0218             
0219             if parentFqn is not None:
0220                 return parentFqn + "::" + self.name()
0221             else:
0222                 return self.name()
0223 
0224         def insertIntoScope(self, name, cppMember):
0225             if cppMember not in self._items:
0226                 self._items.append(cppMember)
0227             #if name is not None:
0228             #    self._names[name] = cppMember
0229             self._killCache(cppMember)
0230 
0231         def __str__(self):
0232             return '\n'.join( (str(item) for item in self._items) )
0233 
0234         def format(self,indent=0):
0235             return ''.join( (item.format(indent) for item in self._items) )
0236 
0237         def lastMember(self):
0238             return self._items[-1] if len(self._items)!=0 else None
0239             
0240         def __len__(self):
0241             return len(self._items)
0242         
0243         def __getitem__(self,key):
0244             return self._items[key]
0245             
0246         def __setitem__(self, key, value):
0247             oldValue = self._items.get(key,None)
0248             
0249             self._items[key] = value
0250             
0251             self._killCache(oldValue)
0252             self._killCache(value)
0253             
0254         def __iter__(self):
0255             return self._items.__iter__()
0256             
0257         def __delitem__(self,item):
0258             self._items.__delitem__(item)
0259             self._killCache(item)
0260             
0261         def index(self,item):
0262             return self._items.index(item)
0263             
0264         def append(self,item):
0265             self._items.append(item)
0266             self._killCache(item)
0267         
0268         def _killCache(self,targetItem):
0269             syms = self._symbolData()
0270             syms._changed()
0271             
0272         def parentScope(self):
0273             return self._scope
0274             
0275         def topScope(self):
0276             return self._scope.topScope()
0277         
0278         def _symbolData(self):
0279             return self._scope._symbolData()
0280         
0281         def sourceLocation(self):
0282             if self._filename is not None:
0283                 return "%s:%i" % (self._filename,self._lineno)
0284             else:
0285                 return "???:%i" % (self._lineno,)
0286         
0287     class TopLevelScope(Entity):
0288         @sealed
0289         def __init__(self,symbolData):
0290             SymbolData.Entity.__init__(self, None, None, None, -1)
0291             self._symbolDataPtr = symbolData
0292             self._headerFilename = None
0293 
0294         def _symbolData(self):
0295             return self._symbolDataPtr
0296             
0297         def topScope(self):
0298             return self
0299             
0300         def fqName(self):
0301             return None
0302             
0303         def setHeaderFilename(self,filename):
0304             self._headerFilename = filename
0305     
0306         def headerFilename(self):
0307             return self._headerFilename
0308     
0309         def sourceLocation(self):
0310             if self._headerFilename is not None:
0311                 return "%s:-1" % (self._headerFilename,)
0312             else:
0313                 return "???:-1" % (self._headerFilename,)
0314     
0315         def parentScope(self):
0316             return None
0317         
0318     class Namespace(Entity):
0319         """Represents a C++ style namespace."""
0320         @sealed
0321         def __init__(self, parentScope, name, filename, lineno):
0322             SymbolData.Entity.__init__(self, parentScope, name, filename, lineno)
0323 
0324         def format(self,indent=0):
0325             pre = SymbolData._indentString(indent)
0326             return pre + "namespace " + self._name + "\n"+pre+"{\n" + SymbolData.Entity.format(self,indent) + pre + "};\n"
0327 
0328     class _CppEntity(Entity):
0329         @sealed
0330         def __init__(self, parentScope, name, filename, lineno):
0331             SymbolData.Entity.__init__(self, parentScope, name, filename, lineno)
0332             self._access = SymbolData.ACCESS_PUBLIC
0333             if self._scope is not None:
0334                 self._scope.insertIntoScope(name, self)
0335 
0336         def setAccess(self,typeName):
0337             if typeName in SymbolData.ACCESS_TYPE_MAPPING_TO_NAME.keys():
0338                 self._access = typeName
0339             else:
0340                 self._access = SymbolData.ACCESS_TYPE_MAPPING_FROM_NAME[typeName]
0341 
0342         def access(self):
0343             return self._access
0344 
0345         def formatAccess(self):
0346             return SymbolData.ACCESS_TYPE_MAPPING_TO_NAME[self._access]
0347 
0348         def __str__(self):
0349             return self.format()
0350             
0351     class Enum(_CppEntity):
0352         @sealed
0353         def __init__(self, parentScope, name, filename, lineno):
0354             SymbolData._CppEntity.__init__(self, parentScope, name, filename, lineno)
0355             self._enumerators = []
0356             
0357         def fqName(self):
0358             if self.name() is None:
0359                 return None
0360                 
0361             parentFqn = self.parentScope().fqName() if self.parentScope() is not None else None
0362             if parentFqn is not None:
0363                 return parentFqn + "::" + self.name()
0364             else:
0365                 return self.name()
0366             
0367         def appendEnumerator(self,enumerator):
0368             self.append(enumerator)
0369             
0370         def append(self,enumerator):
0371             self._enumerators.append(enumerator)
0372             
0373         def __len__(self):
0374             return len(self._enumerators)
0375         
0376         def __getitem__(self,key):
0377             return self._enumerators[key]
0378             
0379         def __setitem__(self, key, value):
0380             self._enumerators[key] = value
0381             
0382         def __iter__(self):
0383             return self._enumerators.__iter__()
0384             
0385         def format(self,indent=0):
0386             pre = SymbolData._indentString(indent)
0387             accu = []
0388             accu.append(pre)
0389             accu.append("enum")
0390             if self._name is not None:
0391                     accu.append(" ")
0392                     accu.append(self._name)
0393             accu.append("\n")
0394             accu.append(pre)
0395             accu.append("{\n")
0396             
0397             pre2 = SymbolData._indentString(indent+1)
0398             accu.append(pre2)
0399             accu.append((",\n"+pre2).join((item.format() for item in self._enumerators)))
0400             accu.append("\n")
0401             accu.append(pre)
0402             accu.append("};\n")
0403             return ''.join(accu)
0404             
0405     class Enumerator(object):
0406         @sealed
0407         def __init__(self,name,value):
0408             self._name = name
0409             self._value = value
0410             
0411         def name(self):
0412             return self._name
0413             
0414         def value(self):
0415             return self._value
0416             
0417         def format(self):
0418             if self._value is None:
0419                 return self._name
0420             else:
0421                 return self._name + "=" + self._value
0422 
0423     class CppClass(_CppEntity):
0424         @sealed
0425         def __init__(self,parentScope, name, filename=None, lineno=-1):
0426             SymbolData._CppEntity.__init__(self, parentScope, name, filename, lineno)
0427             self._bases = []
0428             self._opaque = False
0429             self._macros = []
0430 
0431         #@accepts(str)
0432         def addBase(self, base):
0433             self._bases.append(base)
0434             
0435         #@accepts(list)
0436         def setBases(self,baseList):
0437             self._bases = baseList
0438         
0439         #@returns(list)
0440         def bases(self):
0441             """List of base class names
0442             
0443             Returns a list of string base class names."""
0444             return self._bases
0445         
0446         #@accepts(bool)
0447         def setOpaque(self,opaque):
0448             self._opaque = opaque
0449             
0450         #@returns(bool)
0451         def opaque(self):
0452             return self._opaque
0453             
0454         def addMacro(self,macro):
0455             self._macros.append(macro)
0456             
0457         #@returns(list)
0458         def macros(self):
0459             return self._macros
0460             
0461         #@accepts(indent=int)
0462         #@returns(str)
0463         def format(self,indent=0):
0464             pre = SymbolData._indentString(indent)
0465             accu = []
0466             accu.append(pre)
0467             accu.append("class ")
0468             
0469             for macro in self._macros:
0470                 accu.append(macro.name())
0471                 accu.append(" ")
0472             
0473             accu.append(self._name)
0474             if not self._opaque:
0475                 if len(self._bases):
0476                     accu.append(" : ")
0477                     accu.append(', '.join(self._bases))
0478                 accu.append(" {\n")
0479 
0480                 access = SymbolData.ACCESS_PRIVATE
0481                 pre2 = SymbolData._indentString(indent+1)
0482                 for item in self._items:
0483                     if isinstance(item,SymbolData._CppEntity) and item.access() is not access:
0484                         accu.append(pre2)
0485                         accu.append(item.formatAccess())
0486                         accu.append(":\n")
0487                         access = item.access()
0488                     accu.append(item.format(indent+2))
0489                 accu.append(pre)
0490                 accu.append("};\n")
0491             else:
0492                 accu.append(";\n")
0493             return ''.join(accu)
0494 
0495     class Argument(object):
0496         # Immutable.
0497         
0498         @sealed
0499         def __init__(self, argumentType, argumentName = None, argumentValue = None, template = None, defaultTypes = None):
0500             self._argumentType = argumentType
0501             self._argumentName = argumentName
0502             self._defaultValue = argumentValue  # string (no leading '=') of default value/expression
0503             self._defaultTypes = defaultTypes   # any types pulled out of the default value expression
0504             self._functionPtr = None
0505             #self._attributes = Attributes ()
0506             self._template = template           # the parsed info from any template-type argument
0507 
0508         #@returns(one_of(str,types.NoneType))
0509         def argumentType(self):
0510             return self._argumentType
0511             
0512         #@returns(one_of(str,types.NoneType))
0513         def name(self):
0514             return self._argumentName
0515             
0516         #@returns(one_of(str,types.NoneType))
0517         def defaultValue(self):
0518             return self._defaultValue
0519             
0520         def template(self):
0521             return self._template
0522             
0523         def defaultTypes(self):
0524             return self._defaultTypes
0525             
0526         def format(self):
0527             return self._argumentType + (" " + self._argumentName if self._argumentName is not None else "") + \
0528                 ("" if self._defaultValue is None else " = "+self._defaultValue)
0529             
0530     class FunctionArgument(Argument):
0531         # Immutable
0532         @sealed
0533         def __init__(self, argumentName, returnType, functionArguments):
0534             SymbolData.Argument.__init__(self,None, argumentName)
0535             self._returnType = returnType
0536             self._functionArguments = functionArguments
0537             
0538         def format(self):
0539             return self._returnType + " (*" + self._argumentName + ")("+self._functionArguments+")"
0540             
0541     class Variable(_CppEntity):
0542         """Represents a single variable declaration."""
0543         @sealed
0544         def __init__(self,parentScope, name, filename, lineno):
0545             SymbolData._CppEntity.__init__(self, parentScope, name, filename, lineno)
0546             self._storage = None
0547             self._argument = None
0548             self._bitfield = None
0549             
0550         #@accepts(SymbolData.Argument)
0551         def setArgument(self, argument):
0552             self._argument = argument
0553             
0554         #@returns(SymbolData.Argument)
0555         def argument(self):
0556             return self._argument
0557             
0558         #@accepts(one_of(str,types.NoneType))
0559         def setStorage(self,storage):
0560             self._storage = storage
0561             # "auto", "register", "static", "extern", "mutable"
0562             
0563         #@returns(one_of(str,types.NoneType))
0564         def storage(self):
0565             return self._storage
0566             
0567         def setBitfield(self,bitfield):
0568             self._bitfield = bitfield
0569             
0570         def bitfield(self):
0571             return self._bitfield
0572             
0573         #@accepts(indent=int)
0574         #@returns(str)
0575         def format(self,indent=0):
0576             pre = SymbolData._indentString(indent)
0577             storage = self._storage+" " if self._storage is not None else ""
0578             bitfield = " : " + self._bitfield if self._bitfield is not None else ""
0579             return pre + storage + self._argument.format() + bitfield + ";\n"
0580 
0581     class Function(_CppEntity):
0582         """Represents a C++ function or method if the parent scope is a class."""
0583         @sealed
0584         def __init__(self,parentScope, name, filename, lineno):
0585             SymbolData._CppEntity.__init__(self, parentScope, name, filename, lineno)
0586             self._return = None
0587             self._storage = None
0588             self._arguments = []
0589             self._qualifier = set()
0590             self._template = []
0591 
0592         def setStorage(self,storage):
0593             self._storage = storage
0594 
0595         def storage(self):
0596             return self._storage
0597             
0598         def setReturn(self,return_):
0599             self._return = return_
0600 
0601         def return_(self):
0602             return self._return
0603 
0604         def setArguments(self,arguments):
0605             self._arguments = tuple(arguments)
0606 
0607         def arguments(self):
0608             return self._arguments
0609 
0610         def addQualifier(self,qualifier):
0611             self._qualifier.add(qualifier)
0612 
0613         def qualifier(self):
0614             return self._qualifier
0615 
0616         def setTemplate(self, template):
0617             if template is None:
0618                 self._template = []
0619             else:
0620                 self._template = template
0621                 
0622         def template(self):
0623             return self._template
0624             
0625         def format(self,indent=0):
0626             accu = []
0627             indentstr = SymbolData._indentString(indent)
0628             if self._template:
0629                 accu.append(indentstr)
0630                 accu.append("template <")
0631                 accu.append(", ".join(self._template))
0632                 accu.append(">\n")
0633             
0634             accu.append(indentstr)
0635             chars = 0
0636             if 'virtual' in self._qualifier:
0637                 accu.append("virtual ")
0638                 chars += 8
0639             if self._storage is not None:
0640                 accu.append(self._storage)
0641                 accu.append(" ")
0642                 chars += len(self._storage) + 1
0643                 
0644             ret = self._return.format()
0645             accu.append(ret)
0646             if (len(ret)+chars) < (RETURN_INDENT-1):
0647                 accu.append(' ' * (RETURN_INDENT-len(ret)-chars))
0648             else:
0649                 accu.append("  ")
0650                 
0651             accu.append(self._name)
0652             accu.append(" (")
0653             accu.append(', '.join( (arg.format() for arg in self._arguments) ))
0654             accu.append(")")
0655             if 'const' in self._qualifier:
0656                 accu.append(" const")
0657             if 'pure' in self._qualifier:
0658                 accu.append("=0")
0659             accu.append(";\n")
0660             return ''.join(accu)
0661 
0662     class Constructor(Function):
0663         """Represents a constructor."""
0664         @sealed
0665         def __init__(self,parentScope, name, filename, lineno):
0666             SymbolData.Function.__init__(self, parentScope, name, filename, lineno)
0667 
0668         def format(self,indent=0):
0669             accu = []
0670             accu.append(SymbolData._indentString(indent))
0671             ret = (self._storage+" " if self._storage is not None else "") + \
0672                 ("explicit " if 'explicit' in self._qualifier else "")
0673             accu.append(ret)
0674             if len(ret) < (RETURN_INDENT-1):
0675                 accu.append(' ' * (RETURN_INDENT-len(ret)))
0676             else:
0677                 accu.append("  ")
0678             accu.append(self._name)
0679             accu.append(" (")
0680             accu.append(', '.join( (arg.format() for arg in self._arguments) ))
0681             accu.append(");\n")
0682             return ''.join(accu)
0683             
0684     class Destructor(Function):
0685         """Represents a destructor."""
0686         @sealed
0687         def __init__(self,parentScope, name, filename, lineno):
0688             SymbolData.Function.__init__(self, parentScope, name, filename, lineno)
0689 
0690         def format(self,indent=0):
0691             pre = SymbolData._indentString(indent)
0692             accu = []
0693             accu.append(pre)
0694             if 'virtual' in self._qualifier:
0695                 accu.append("virtual ")
0696             if self._storage is not None:
0697                 accu.append(self._storage)
0698                 accu.append(" ")
0699             accu.append("~")
0700             accu.append(self._name)
0701             accu.append(" ()")
0702             if 'const' in self._qualifier:
0703                 accu.append(" const")
0704             if 'pure' in self._qualifier:
0705                 accu.append("=0")
0706             accu.append(";\n")
0707             return ''.join(accu)
0708             
0709     class Typedef(_CppEntity):
0710         @sealed
0711         def __init__(self,parentScope, name, filename, lineno):
0712             SymbolData._CppEntity.__init__(self, parentScope, name, filename, lineno)
0713             self._argumentType = None
0714             
0715         def setArgumentType(self,argumentType):
0716             self._argumentType = argumentType
0717             
0718         def argumentType(self):
0719             return self._argumentType
0720             
0721         def format(self,indent=0):
0722             pre = SymbolData._indentString(indent)
0723             if self._argumentType is not None:
0724                 return pre + "typedef " + self._argumentType + " " + self._name + ";\n"
0725             else:
0726                 contents = ""
0727                 if len(self._items)!=0:
0728                     contents = self._items[0].format(indent+1)
0729                 return pre + "typedef\n" + " " + contents
0730                 
0731     class FunctionPointerTypedef(Typedef):
0732         @sealed
0733         def __init__(self,parentScope, functionArgument, filename, lineno):
0734             SymbolData.Typedef.__init__(self,parentScope, functionArgument.name(), filename, lineno)
0735             self._functionArgument = functionArgument
0736             
0737         def format(self,indent=0):
0738             pre = SymbolData._indentString(indent)
0739             return pre + "typedef "+ self._functionArgument.format() + ";\n"
0740                 
0741     class EnumTypedef(Typedef):
0742         @sealed
0743         def __init__(self,parentScope, name, enumDecl, filename, lineno):
0744             SymbolData.Typedef.__init__(self,parentScope, name, filename, lineno)
0745             self._enumDecl = enumDecl
0746             
0747         def enum(self):
0748             return self._enumDecl
0749             
0750         def format(self,indent=0):
0751             pre = SymbolData._indentString(indent)
0752             accu = []
0753             accu.append(pre)
0754             accu.append("typedef enum\n")
0755             accu.append(pre)
0756             accu.append("{\n")
0757             
0758             pre2 = SymbolData._indentString(indent+1)
0759             accu.append(pre2)
0760             accu.append((",\n"+pre2).join((item.format() for item in self._enumDecl)))
0761             accu.append("\n")
0762             accu.append(pre)
0763             accu.append("} ")
0764             accu.append(self.name())
0765             accu.append(";\n")
0766             return ''.join(accu)
0767                 
0768     class Macro(object):
0769         @sealed
0770         def __init__(self, name):
0771             self._name = name
0772             
0773         def name(self):
0774             return self._name
0775         
0776     class ScopedMacro(_CppEntity):
0777         @sealed
0778         def __init__(self,parentScope, name, filename, lineno):
0779             SymbolData._CppEntity.__init__(self, parentScope, name, filename, lineno)
0780             self._argument = None
0781             
0782         def setArgument(self,argument):
0783             self._argument = argument
0784             
0785         def format(self,indent=0):
0786             pre = SymbolData._indentString(indent)
0787             if self._argument is None:
0788                 return pre + self._name + "\n"
0789             else:
0790                 return pre + self._name + "(" + self._argument + ")\n"
0791                 
0792     class Comment(Entity):
0793         @sealed
0794         def __init__(self, parentScope, filename=None, lineno=-1):
0795             SymbolData.Entity.__init__(self, parentScope, None, filename, lineno)
0796             self._comment = None
0797             
0798         def setValue(self,comment):
0799             self._comment = comment
0800             
0801         def value(self):
0802             return self._comment
0803             
0804         def format(self,indent=0):
0805             return self._comment
0806