File indexing completed on 2025-02-16 04:24:40
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)