File indexing completed on 2024-04-21 04:44:11

0001 # -*- coding: utf-8 -*-
0002 #     Copyright 2009 Simon Edwards <simon@simonzone.com>
0003 #
0004 # This program is free software; you can redistribute it and/or modify
0005 # it under the terms of the GNU General Public License as published by
0006 # the Free Software Foundation; either version 2 of the License, or
0007 # (at your option) any later version.
0008 #
0009 # This program is distributed in the hope that it will be useful,
0010 # but WITHOUT ANY WARRANTY; without even the implied warranty of
0011 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012 # GNU General Public License for more details.
0013 #
0014 # You should have received a copy of the GNU General Public License
0015 # along with this program; if not, write to the
0016 # Free Software Foundation, Inc.,
0017 # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0018 from .sealed import sealed
0019 # from argvalidate import accepts,returns,one_of
0020 import types
0021 import kbindinggenerator.cppsymboldata as cppsymboldata
0022 
0023 class SymbolData(cppsymboldata.SymbolData):
0024     @sealed
0025     def __init__(self):
0026         cppsymboldata.SymbolData.__init__(self)
0027         
0028     class _SipEntityExtra(object):
0029         @sealed
0030         def __init__(self):
0031             self._annotations = []
0032             self._blocks = []
0033             self._ignore = False
0034             self._cppargs = None
0035             self._cppreturn = None
0036             self._force = False
0037             
0038         # @returns(str)
0039         def fqPythonName(self):
0040             parentFqn = self.parentScope().fqPythonName()
0041             
0042             if self.name() is None:
0043                 return ""
0044             
0045             if parentFqn is not None:
0046                 return parentFqn + "." + self.name()
0047             else:
0048                 return self.name()
0049                 
0050         def ignore(self):
0051             return self._ignore
0052             
0053         def setIgnore(self,ignore):
0054             self._ignore = ignore
0055             
0056         def setForce(self,force):
0057             self._force = force
0058             
0059         def force(self):
0060             return self._force
0061             
0062         def setAnnotations(self,annotations):
0063             self._annotations = annotations
0064             
0065         def annotations(self):
0066             return self._annotations
0067             
0068         def setCppArgs(self,cppArgs):
0069             self._cppargs = cppArgs
0070             
0071         def setCppReturn(self,cppreturn):
0072             self._cppreturn = cppreturn
0073             
0074         def addBlock(self, block):
0075             self._blocks.append(block)
0076             
0077         def blocks(self):
0078             return self._blocks
0079         
0080         def setBlocks(self,blocks):
0081             self._blocks = blocks[:]
0082         
0083         def _formatIgnore(self,indent):
0084             if self._ignore:
0085                 return "//ig" + (" " if indent==0 else "")
0086             else:
0087                 return ""
0088                 
0089         def _formatCppArgs(self):
0090             if self._cppargs is not None:
0091                 return (" [(" if self._cppreturn is None else " [" + self._cppreturn + " (") + \
0092                     ", ".join(item.format() for item in self._cppargs) + ")]"
0093             else:
0094                 return ""
0095                 
0096     class TopLevelScope(cppsymboldata.SymbolData.TopLevelScope):
0097         @sealed
0098         def __init__(self,symbolData):
0099             cppsymboldata.SymbolData.TopLevelScope.__init__(self,symbolData)
0100             self._module = None
0101             
0102         def format(self,indent=0):
0103             accu = []
0104             force = False
0105             for item in self:
0106                 if isinstance(item,cppsymboldata.SymbolData._CppEntity) or isinstance(item,SymbolData.SipDirective):
0107                     if item.force()!=force:
0108                         if not force:
0109                             accu.append("//force\n")
0110                         else:
0111                             accu.append("//end\n")
0112                         force = not force
0113                 accu.append(item.format(indent))
0114             if force:
0115                 accu.append("//end\n")
0116                 
0117             return ''.join(accu)
0118             
0119         def setModule(self,module):
0120             self._module = module
0121             
0122         def module(self):
0123             return self._module
0124 
0125         def fqPythonName(self):
0126             return None
0127 
0128     class SipClass(_SipEntityExtra, cppsymboldata.SymbolData.CppClass):
0129         @sealed
0130         def __init__(self,parentScope, name, filename=None, lineno=-1):
0131             cppsymboldata.SymbolData.CppClass.__init__(self, parentScope, name, filename, lineno)
0132             SymbolData._SipEntityExtra.__init__(self)
0133 
0134         def allSuperClassNames(self):
0135             """Get all super class names
0136             
0137             A set of super class names."""
0138             symbolData = self._symbolData()
0139             allBases = set()
0140             for name in self._bases:
0141                 allBases.add(name)
0142                 
0143                 class_ = symbolData.lookupType(name,self)
0144                 if class_ is not None:
0145                     allBases.update(class_.allSuperClassNames())
0146                     
0147             return allBases
0148             
0149         def classHierarchy(self):
0150             symbolData = self._symbolData()
0151             if len(self._bases)==0:
0152                 return [self]
0153             base = symbolData.lookupType(self._bases[0],self)
0154             if base is not None:
0155                 return [self] + base.classHierarchy()
0156             else:
0157                 return [self]
0158         
0159         def format(self,indent=0):
0160             pre = SymbolData._indentString(indent)
0161             accu = []
0162             
0163             if self._ignore:
0164                 accu.append(self._formatIgnore(indent))
0165             accu.append(pre)
0166             accu.append("class ")
0167             
0168             accu.append(self._name)
0169             if not self._opaque:
0170                 if len(self._bases):
0171                     accu.append(" : ")
0172                     accu.append(', '.join(self._bases))
0173                     
0174                 if self._annotations is not None and len(self._annotations)!=0:
0175                     accu.append(' /')
0176                     accu.append(','.join(self._annotations))
0177                     accu.append('/')
0178                 accu.append("\n")
0179                 accu.append(pre)
0180                 accu.append("{\n")
0181 
0182                 access = SymbolData.ACCESS_PRIVATE
0183                 force = False
0184                 for item in self._items:
0185                     if isinstance(item,cppsymboldata.SymbolData._CppEntity) or isinstance(item,SymbolData.SipDirective):
0186                         if item.force()!=force and force:
0187                             accu.append("//end\n")
0188                             force = not force
0189                             
0190                     if isinstance(item,cppsymboldata.SymbolData._CppEntity):
0191                         if item.access() is not access:
0192                             accu.append(pre)
0193                             accu.append(item.formatAccess())
0194                             accu.append(":\n")
0195                             access = item.access()
0196                             
0197                     if isinstance(item,cppsymboldata.SymbolData._CppEntity) or isinstance(item,SymbolData.SipDirective):
0198                         if item.force()!=force and not force:
0199                             accu.append("//force\n")
0200                             force = not force
0201                             
0202                     accu.append(item.format(indent+1))
0203                 if force:
0204                     accu.append("//end\n")
0205                 
0206                 accu.append(pre)
0207                 accu.append("};\n")
0208             else:
0209                 accu.append(";\n")
0210             return ''.join(accu)
0211 
0212         def __str__(self):
0213             return "<SipClass '%s'>" % (self.name(),)
0214 
0215     class Argument(cppsymboldata.SymbolData.Argument):
0216         # FIXME Make this immutable.
0217     
0218         @sealed
0219         def __init__(self, argumentType, argumentName = None, argumentValue = None, template = None, defaultTypes = None):
0220             cppsymboldata.SymbolData.Argument.__init__(self, argumentType, argumentName, argumentValue, template, defaultTypes)
0221             self._annotations = []
0222 
0223         def setAnnotations(self,annotations):
0224             self._annotations = annotations
0225             
0226         def annotations(self):
0227             return self._annotations
0228         
0229         def format(self):
0230             annos = ""
0231             if self._annotations is not None and len(self._annotations)!=0:
0232                 annos = " /" + ",".join(self._annotations) + "/"
0233             return self._argumentType + (" " + self._argumentName if self._argumentName is not None else "") + \
0234                 annos + \
0235                 ("" if self._defaultValue is None else " = "+self._defaultValue)
0236 
0237     class FunctionArgument(Argument):
0238         @sealed
0239         def __init__(self, argumentName, returnType, functionArguments):
0240             SymbolData.Argument.__init__(self,None, argumentName)
0241             self._returnType = returnType
0242             self._functionArguments = functionArguments
0243             
0244         def format(self):
0245             return self._returnType + " (*" + self._argumentName + ")("+self._functionArguments+")"
0246 
0247     class Function(_SipEntityExtra, cppsymboldata.SymbolData.Function):
0248         @sealed
0249         def __init__(self, parentScope, name, filename=None, lineno=-1):
0250             cppsymboldata.SymbolData.Function.__init__(self,parentScope,name,filename,lineno)
0251             SymbolData._SipEntityExtra.__init__(self)
0252 
0253         def format(self,indent=0):
0254             accu = []
0255             
0256             annotations = ""
0257             if self._annotations is not None and len(self._annotations)!=0:
0258                 annotations = ' /' + ', '.join(self._annotations) + '/'
0259             
0260             accu.append(self._formatIgnore(indent))
0261             accu.append(cppsymboldata.SymbolData.Function.format(self,indent)[:-2])
0262             accu.append(annotations)
0263             accu.append(self._formatCppArgs())
0264             accu.append(";\n")
0265             for block in self._blocks:
0266                 accu.append(block.format(indent))
0267             
0268             return ''.join(accu)
0269 
0270 
0271     class Constructor(_SipEntityExtra, cppsymboldata.SymbolData.Constructor):
0272         @sealed
0273         def __init__(self, parentScope, name, filename=None, lineno=-1):
0274             cppsymboldata.SymbolData.Constructor.__init__(self,parentScope,name,filename,lineno)
0275             SymbolData._SipEntityExtra.__init__(self)
0276             
0277         def format(self,indent=0):
0278             annotations = ""
0279             if self._annotations is not None and len(self._annotations)!=0:
0280                 annotations = ' /' + ', '.join(self._annotations) + '/'
0281             
0282             return self._formatIgnore(indent) + cppsymboldata.SymbolData.Constructor.format(self,indent)[:-2] + \
0283                 annotations + self._formatCppArgs() + ";\n" + \
0284                 ''.join( (block.format(indent) for block in self._blocks))
0285 
0286     class Destructor(_SipEntityExtra, cppsymboldata.SymbolData.Destructor):
0287         @sealed
0288         def __init__(self, parentScope, name, filename=None, lineno=-1):
0289             cppsymboldata.SymbolData.Destructor.__init__(self,parentScope,name,filename,lineno)
0290             SymbolData._SipEntityExtra.__init__(self)
0291             
0292         def format(self,indent=0):
0293             annotations = ""
0294             if self._annotations is not None and len(self._annotations)!=0:
0295                 annotations = ' /' + ', '.join(self._annotations) + '/'
0296             
0297             return self._formatIgnore(indent) + cppsymboldata.SymbolData.Destructor.format(self,indent)[:-2] + \
0298                 annotations + self._formatCppArgs() + ";\n" + \
0299                 ''.join( (block.format(indent) for block in self._blocks))
0300             
0301     class Variable(_SipEntityExtra, cppsymboldata.SymbolData.Variable):
0302         @sealed
0303         def __init__(self, parentScope, name, filename=None, lineno=-1):
0304             cppsymboldata.SymbolData.Variable.__init__(self,parentScope,name,filename,lineno)
0305             SymbolData._SipEntityExtra.__init__(self)
0306             
0307         def format(self,indent=0):
0308             return self._formatIgnore(indent) + cppsymboldata.SymbolData.Variable.format(self,indent)
0309 
0310     class SipBlock(object):
0311         @sealed
0312         def __init__(self, name):
0313             self._name = name
0314             self._body = None
0315             
0316         def name(self):
0317             return self._name
0318         
0319         def setBody(self, body):
0320             self._body = body
0321             
0322         def body(self):
0323             return self._body
0324             
0325         def format(self,indent=0):
0326             pre = SymbolData._indentString(indent)
0327             return self._body + '\n'
0328 
0329     class SipDirective(cppsymboldata.SymbolData.Entity, SipBlock):
0330         @sealed
0331         def __init__(self, parentScope, name, filename=None, lineno=-1):
0332             cppsymboldata.SymbolData.Entity.__init__(self, parentScope, name, filename, lineno)
0333             SymbolData.SipBlock.__init__(self, name)
0334             self._force = False
0335             self._keypairs = None
0336             
0337         def setForce(self,force):
0338             self._force = force
0339             
0340         def force(self):
0341             return self._force
0342             
0343         def setKeypairs(self, pairlist):
0344             self._keypairs = pairlist   # A list of key-value tuples.
0345             
0346         def format(self,indent=0):
0347             return SymbolData.SipBlock.format(self,indent)
0348         
0349     class Comment(cppsymboldata.SymbolData.Comment):
0350         @sealed
0351         def __init__(self, parentScope, filename=None, lineno=-1):
0352             cppsymboldata.SymbolData.Comment.__init__(self, parentScope, filename, lineno)
0353 
0354     class Template(_SipEntityExtra, cppsymboldata.SymbolData._CppEntity):
0355         @sealed
0356         def __init__(self, parentScope, filename, lineno):
0357             cppsymboldata.SymbolData._CppEntity.__init__(self, parentScope, None, filename, lineno)
0358             SymbolData._SipEntityExtra.__init__(self)
0359             self._parameters = None
0360             
0361         def setParameters(self,parameters):
0362             self._parameters = parameters
0363             
0364         def insertIntoScope(self, name, cppMember):
0365             cppsymboldata.SymbolData.Entity.insertIntoScope(self,name,cppMember)
0366             self._scope.insertIntoScope(name, self)
0367             
0368         def format(self,indent=0):
0369             pre = SymbolData._indentString(indent)
0370             return pre + 'template <' + self._parameters + '>\n' + cppsymboldata.SymbolData.Entity.format(self,indent)
0371             
0372     class SipType(cppsymboldata.SymbolData.Entity, SipBlock):
0373         @sealed
0374         def __init__(self, parentScope, filename, lineno):
0375             cppsymboldata.SymbolData.Entity.__init__(self, parentScope, None, filename, lineno)
0376             SymbolData.SipBlock.__init__(self, None)
0377 
0378         def format(self,indent=0):
0379             return SymbolData.SipBlock.format(self,indent)
0380 
0381     class Enum(_SipEntityExtra, cppsymboldata.SymbolData.Enum):
0382         @sealed
0383         # @accepts(cppsymboldata.SymbolData.Entity,one_of(str,types.NoneType),filename=one_of(str,types.NoneType),lineno=int)
0384         def __init__(self, parentScope, name, filename=None, lineno=-1):
0385             cppsymboldata.SymbolData.Enum.__init__(self, parentScope, name, filename, lineno)
0386             SymbolData._SipEntityExtra.__init__(self)
0387             
0388         def format(self,indent=0):
0389             pre = SymbolData._indentString(indent)
0390             accu = []
0391             accu.append(pre)
0392             accu.append("enum")
0393             if self._name is not None:
0394                     accu.append(" ")
0395                     accu.append(self._name)
0396             accu.append("\n")
0397             accu.append(pre)
0398             accu.append("{\n")
0399             
0400             pre2 = SymbolData._indentString(indent+1)
0401             num_enums = sum( (1 for e in self._enumerators if isinstance(e,cppsymboldata.SymbolData.Enumerator)) )
0402             enum_count = 0
0403             for item in self._enumerators:
0404                 accu.append(pre2)
0405                 if isinstance(item,cppsymboldata.SymbolData.Enumerator):
0406                     accu.append(item.format())
0407                     enum_count += 1
0408                     if enum_count!=num_enums:
0409                         accu.append(",")
0410                     accu.append("\n")
0411                 else:
0412                     accu.append(item.format())
0413             accu.append(pre)
0414             accu.append("};\n")
0415             return ''.join(accu)
0416         
0417     class Enumerator(cppsymboldata.SymbolData.Enumerator):
0418         @sealed
0419         def __init__(self,name,value):
0420             cppsymboldata.SymbolData.Enumerator.__init__(self,name,value)
0421 
0422         def format(self):
0423             return self._name
0424                 
0425     class EnumeratorComment(object):
0426         @sealed
0427         def __init__(self,body):
0428             self._body = body
0429             
0430         def format(self):
0431             return self._body
0432 
0433     class Typedef(_SipEntityExtra, cppsymboldata.SymbolData.Typedef):
0434         @sealed
0435         def __init__(self,parentScope, name, filename=None, lineno=-1):
0436             cppsymboldata.SymbolData.Typedef.__init__(self,parentScope, name, filename, lineno)
0437             SymbolData._SipEntityExtra.__init__(self)
0438             
0439         def classHierarchy(self):
0440             symbolData = self._symbolData()
0441             base = symbolData.lookupType(self.argumentType(),self)
0442             if base is not None:
0443                 return base.classHierarchy()
0444             else:
0445                 return []
0446           
0447         def format(self,indent=0):
0448             return self._formatIgnore(indent) + cppsymboldata.SymbolData.Typedef.format(self,indent)
0449             
0450     class FunctionPointerTypedef(Typedef):
0451         @sealed
0452         def __init__(self,parentScope, functionArgument, filename, lineno):
0453             SymbolData.Typedef.__init__(self,parentScope, functionArgument.name(), filename, lineno)
0454             self._functionArgument = functionArgument
0455             
0456         def format(self,indent=0):
0457             pre = SymbolData._indentString(indent)
0458             return self._formatIgnore(indent) + pre + "typedef "+ self._functionArgument.format() + ";\n"
0459             
0460     class Namespace(_SipEntityExtra, cppsymboldata.SymbolData.Namespace):
0461         @sealed
0462         def __init__(self, parentScope, name, filename=None, lineno=-1):
0463             cppsymboldata.SymbolData.Namespace.__init__(self, parentScope, name, filename, lineno)
0464             SymbolData._SipEntityExtra.__init__(self)
0465             
0466         def format(self,indent=0):
0467             pre = SymbolData._indentString(indent)
0468             accu = []
0469             accu.append(self._formatIgnore(indent))
0470             accu.append(pre)
0471             accu.append("namespace ")
0472             accu.append(self._name)
0473             if self.ignore():
0474                 accu.append(";\n")
0475             else:
0476                 accu.append("\n")
0477                 accu.append(pre)
0478                 accu.append("{\n")
0479             
0480                 force = False
0481                 for item in self._items:
0482                     if isinstance(item,cppsymboldata.SymbolData._CppEntity) or isinstance(item,SymbolData.SipDirective):
0483                         if item.force()!=force:
0484                             if not force:
0485                                 accu.append("//force\n")
0486                             else:
0487                                 accu.append("//end\n")
0488                             force = not force
0489                     accu.append(item.format(indent))
0490                 if force:
0491                     accu.append("//end\n")
0492                 
0493                 accu.append(pre)
0494                 accu.append("};\n")
0495             return "".join(accu)