mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 00:32:57 -04:00
*** empty log message ***
This commit is contained in:
parent
aeb400fc59
commit
0084b86283
@ -137,11 +137,7 @@ class GlobalFunctionSpecification(FunctionSpecification):
|
||||
self.outputMethodHeader(methodClass, file, nesting)
|
||||
self.outputMethodBody(methodClass, file, nesting)
|
||||
self.outputMethodFooter(methodClass, file, nesting)
|
||||
def generateInheritedMethodCode(self, methodClass, parentClass, file, nesting, needsDowncast):
|
||||
self.outputInheritedMethodHeader(methodClass, parentClass, file, nesting, needsDowncast)
|
||||
self.outputInheritedMethodBody(methodClass, parentClass, file, nesting, needsDowncast)
|
||||
self.outputInheritedMethodFooter(methodClass, parentClass, file, nesting, needsDowncast)
|
||||
|
||||
|
||||
##################################################
|
||||
## Global Function Code Generation
|
||||
##################################################
|
||||
@ -217,52 +213,6 @@ class GlobalFunctionSpecification(FunctionSpecification):
|
||||
def outputMethodFooter(self, methodClass, file, nesting):
|
||||
indent(file, nesting+1, '\n')
|
||||
|
||||
##################################################
|
||||
## Upcast Class Method Code Generation
|
||||
##################################################
|
||||
def outputInheritedMethodHeader(self, methodClass, parentClass, file, nesting, needsDowncast):
|
||||
argTypes = self.typeDescriptor.argumentTypes
|
||||
thislessArgTypes = self.typeDescriptor.thislessArgTypes()
|
||||
indent(file, nesting+1, 'def ' + self.getFinalName() + '(self')
|
||||
if (len(thislessArgTypes) > 0):
|
||||
file.write(', ')
|
||||
for i in range(len(thislessArgTypes)):
|
||||
file.write(thislessArgTypes[i].name)
|
||||
if (i < (len(thislessArgTypes)-1)):
|
||||
file.write(', ')
|
||||
file.write('):\n')
|
||||
|
||||
def outputInheritedMethodBody(self, methodClass, parentClass, file, nesting, needsDowncast):
|
||||
# The method body will look something like
|
||||
# upcastSelf = self.upcastToParentClass()
|
||||
# returnValue = ParentClass.method(upcastSelf, arg)
|
||||
# returnValue.userManagesMemory = 1 (optional)
|
||||
# return returnValue
|
||||
self.outputCFunctionComment(file, nesting+2)
|
||||
argTypes = self.typeDescriptor.argumentTypes
|
||||
thislessArgTypes = self.typeDescriptor.thislessArgTypes()
|
||||
self.outputTypeChecking(methodClass, thislessArgTypes, file, nesting+2)
|
||||
if self.typeDescriptor.userManagesMemory:
|
||||
indent(file, nesting+2, 'self.userManagesMemory = 1\n')
|
||||
indent(file, nesting+2, 'upcastSelf = self.upcast' + 'To'
|
||||
+ parentClass.foreignTypeName + '()\n')
|
||||
indent(file, nesting+2, 'returnValue = ' + parentClass.foreignTypeName
|
||||
+ '.' + self.typeDescriptor.wrapperName + '(upcastSelf.this')
|
||||
if (len(thislessArgTypes) > 0):
|
||||
file.write(', ')
|
||||
for i in range(len(thislessArgTypes)):
|
||||
file.write(thislessArgTypes[i].passName())
|
||||
if (i < (len(thislessArgTypes)-1)):
|
||||
file.write(', ')
|
||||
file.write(')\n')
|
||||
returnType = self.typeDescriptor.returnType.recursiveTypeDescriptor()
|
||||
# Generate the return value code with no downcast instructions
|
||||
returnType.generateReturnValueWrapper(file, self.typeDescriptor.userManagesMemory,
|
||||
needsDowncast, nesting+2)
|
||||
|
||||
def outputInheritedMethodFooter(self, methodClass, parentClass, file, nesting, needsDowncast):
|
||||
pass
|
||||
|
||||
|
||||
class MethodSpecification(FunctionSpecification):
|
||||
def __init__(self):
|
||||
@ -288,10 +238,10 @@ class MethodSpecification(FunctionSpecification):
|
||||
self.outputStaticBody(methodClass, file, nesting)
|
||||
self.outputStaticFooter(methodClass, file, nesting)
|
||||
|
||||
def generateInheritedMethodCode(self, methodClass, parentClass, file, nesting, needsDowncast):
|
||||
self.outputInheritedMethodHeader(methodClass, parentClass, file, nesting, needsDowncast)
|
||||
self.outputInheritedMethodBody(methodClass, parentClass, file, nesting, needsDowncast)
|
||||
self.outputInheritedMethodFooter(methodClass, parentClass, file, nesting, needsDowncast)
|
||||
def generateInheritedMethodCode(self, methodClass, parentList, file, nesting, needsDowncast):
|
||||
self.outputInheritedMethodHeader(methodClass, parentList, file, nesting, needsDowncast)
|
||||
self.outputInheritedMethodBody(methodClass, parentList, file, nesting, needsDowncast)
|
||||
self.outputInheritedMethodFooter(methodClass, parentList, file, nesting, needsDowncast)
|
||||
|
||||
def generateDowncastMethodCode(self, methodClass, file, nesting):
|
||||
# The downcast method code is just like regular code, but the
|
||||
@ -342,6 +292,7 @@ class MethodSpecification(FunctionSpecification):
|
||||
indent(file, nesting+2, 'assert(self.this != 0)\n')
|
||||
if self.typeDescriptor.userManagesMemory:
|
||||
indent(file, nesting+2, 'self.userManagesMemory = 1\n')
|
||||
|
||||
def outputConstructorFooter(self, methodClass, file, nesting):
|
||||
indent(file, nesting+1, '\n')
|
||||
|
||||
@ -443,20 +394,19 @@ class MethodSpecification(FunctionSpecification):
|
||||
file.write(', ')
|
||||
file.write(')\n')
|
||||
returnType = self.typeDescriptor.returnType.recursiveTypeDescriptor()
|
||||
returnType.generateReturnValueWrapper(file, self.typeDescriptor.userManagesMemory, 1, nesting+2)
|
||||
returnType.generateReturnValueWrapper(file, self.typeDescriptor.userManagesMemory,
|
||||
1, nesting+2)
|
||||
|
||||
def outputStaticFooter(self, methodClass, file, nesting):
|
||||
indent(file, nesting+1, self.getFinalName() + ' = '
|
||||
+ FFIConstants.staticModuleName + '.' + FFIConstants.staticModuleName
|
||||
+ '(' + self.getFinalName() + ')\n')
|
||||
indent(file, nesting+1, '\n')
|
||||
|
||||
|
||||
indent(file, nesting+1, '\n')
|
||||
|
||||
##################################################
|
||||
## Upcast Method Code Generation
|
||||
##################################################
|
||||
def outputInheritedMethodHeader(self, methodClass, parentClass, file, nesting, needsDowncast):
|
||||
def outputInheritedMethodHeader(self, methodClass, parentList, file, nesting, needsDowncast):
|
||||
argTypes = self.typeDescriptor.argumentTypes
|
||||
thislessArgTypes = self.typeDescriptor.thislessArgTypes()
|
||||
indent(file, nesting+1, 'def ' + self.getFinalName() + '(self')
|
||||
@ -468,7 +418,7 @@ class MethodSpecification(FunctionSpecification):
|
||||
file.write(', ')
|
||||
file.write('):\n')
|
||||
|
||||
def outputInheritedMethodBody(self, methodClass, parentClass, file, nesting, needsDowncast):
|
||||
def outputInheritedMethodBody(self, methodClass, parentList, file, nesting, needsDowncast):
|
||||
# The method body will look something like
|
||||
# upcastSelf = self.upcastToParentClass()
|
||||
# returnValue = libpanda.method(upcastSelf.this, arg)
|
||||
@ -478,10 +428,19 @@ class MethodSpecification(FunctionSpecification):
|
||||
argTypes = self.typeDescriptor.argumentTypes
|
||||
thislessArgTypes = self.typeDescriptor.thislessArgTypes()
|
||||
self.outputTypeChecking(methodClass, thislessArgTypes, file, nesting+2)
|
||||
indent(file, nesting+2, 'upcastSelf = self.upcast' + 'To'
|
||||
+ parentClass.foreignTypeName + '()\n')
|
||||
for i in range(len(parentList)):
|
||||
# Only output the upcast call if that parent class defines it
|
||||
parentClass = parentList[i]
|
||||
methodName = 'upcastTo' + parentClass.foreignTypeName
|
||||
if (i != 0):
|
||||
childClass = parentList[i-1]
|
||||
if childClass.hasMethodNamed(methodName):
|
||||
indent(file, nesting+2, 'upcastSelf = self.' + methodName + '()\n')
|
||||
else:
|
||||
if methodClass.hasMethodNamed(methodName):
|
||||
indent(file, nesting+2, 'upcastSelf = self.' + methodName + '()\n')
|
||||
indent(file, nesting+2, 'returnValue = ' + self.typeDescriptor.moduleName
|
||||
+ '.' + self.typeDescriptor.wrapperName + '(upcastSelf.this')
|
||||
+ '.' + self.typeDescriptor.wrapperName + '(upcastSelf.this')
|
||||
if (len(thislessArgTypes) > 0):
|
||||
file.write(', ')
|
||||
for i in range(len(thislessArgTypes)):
|
||||
@ -494,8 +453,8 @@ class MethodSpecification(FunctionSpecification):
|
||||
returnType.generateReturnValueWrapper(file, self.typeDescriptor.userManagesMemory,
|
||||
needsDowncast, nesting+2)
|
||||
|
||||
def outputInheritedMethodFooter(self, methodClass, parentClass, file, nesting, needsDowncast):
|
||||
indent(file, nesting+1, '\n')
|
||||
def outputInheritedMethodFooter(self, methodClass, parentList, file, nesting, needsDowncast):
|
||||
indent(file, nesting+1, '\n')
|
||||
|
||||
|
||||
class GlobalValueSpecification:
|
||||
|
@ -212,10 +212,6 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
# Instance methods that had no this pointer are moved into here
|
||||
self.staticMethods = []
|
||||
|
||||
# Global methods that take this class as the first parameter are just
|
||||
# stored with the class because it is more useable that way
|
||||
self.globalMethods = []
|
||||
|
||||
# These are dictionaries used to temporarily hold methods for
|
||||
# overloading while generating code
|
||||
self.overloadedClassMethods = {}
|
||||
@ -224,6 +220,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
# Nested typeDescriptors inside this class
|
||||
self.nestedTypes = []
|
||||
|
||||
|
||||
def getExtensionModuleName(self):
|
||||
"""
|
||||
Return a filename for the extensions for this class
|
||||
@ -243,12 +240,10 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
# Otherwise, it must be our first time through, do the real work
|
||||
self.CModules = []
|
||||
for method in (self.constructors + [self.destructor] + self.instanceMethods
|
||||
+ self.upcastMethods + self.downcastMethods
|
||||
+ self.staticMethods + self.globalMethods):
|
||||
+ self.upcastMethods + self.downcastMethods + self.staticMethods):
|
||||
if method:
|
||||
if (not (method.typeDescriptor.moduleName in self.CModules)):
|
||||
self.CModules.append(method.typeDescriptor.moduleName)
|
||||
|
||||
# Now look at all the methods that we might inherit if we are at
|
||||
# a multiple inheritance node and get their C modules
|
||||
if (len(self.parentTypes) >= 2):
|
||||
@ -259,10 +254,6 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
for method in parentType.upcastMethods:
|
||||
if (not (method.typeDescriptor.moduleName in self.CModules)):
|
||||
self.CModules.append(method.typeDescriptor.moduleName)
|
||||
for method in parentType.globalMethods:
|
||||
if (not (method.typeDescriptor.moduleName in self.CModules)):
|
||||
self.CModules.append(method.typeDescriptor.moduleName)
|
||||
|
||||
return self.CModules
|
||||
|
||||
|
||||
@ -272,51 +263,52 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
class references.
|
||||
Be careful about nested types
|
||||
"""
|
||||
moduleList = []
|
||||
|
||||
upcastMethods = []
|
||||
if (len(self.parentTypes) >= 2):
|
||||
for parentType in self.parentTypes:
|
||||
for method in parentType.instanceMethods:
|
||||
upcastMethods.append(method)
|
||||
for method in parentType.upcastMethods:
|
||||
upcastMethods.append(method)
|
||||
for method in parentType.globalMethods:
|
||||
upcastMethods.append(method)
|
||||
|
||||
for method in (self.constructors + [self.destructor] + self.instanceMethods
|
||||
+ self.upcastMethods + self.downcastMethods
|
||||
+ self.staticMethods + self.globalMethods + upcastMethods):
|
||||
if method:
|
||||
# Get the real return type (not derived)
|
||||
returnType = method.typeDescriptor.returnType.recursiveTypeDescriptor()
|
||||
if (not returnType.isNested):
|
||||
returnTypeName = returnType.foreignTypeName
|
||||
# Do not put our own module in the import list
|
||||
if ((returnTypeName != self.foreignTypeName) and
|
||||
# Do not put modules already in the list (like a set)
|
||||
(not (returnTypeName in moduleList))):
|
||||
# If this is a class (not a primitive), put it on the list
|
||||
if (returnType.__class__ == ClassTypeDescriptor):
|
||||
moduleList.append(returnTypeName)
|
||||
|
||||
# Now look at all the arguments
|
||||
argTypes = method.typeDescriptor.argumentTypes
|
||||
for argType in argTypes:
|
||||
# Return type modules are cached once they are calculated so we
|
||||
# do not have to calculate them again
|
||||
try:
|
||||
return self.returnTypeModules
|
||||
except:
|
||||
moduleList = []
|
||||
upcastMethods = []
|
||||
if (len(self.parentTypes) >= 2):
|
||||
for parentType in self.parentTypes:
|
||||
for method in parentType.instanceMethods:
|
||||
upcastMethods.append(method)
|
||||
for method in parentType.upcastMethods:
|
||||
upcastMethods.append(method)
|
||||
for method in (self.constructors + [self.destructor] + self.instanceMethods
|
||||
+ self.upcastMethods + self.downcastMethods
|
||||
+ self.staticMethods + upcastMethods):
|
||||
if method:
|
||||
# Get the real return type (not derived)
|
||||
argType = argType.typeDescriptor.recursiveTypeDescriptor()
|
||||
if (not argType.isNested):
|
||||
argTypeName = argType.foreignTypeName
|
||||
returnType = method.typeDescriptor.returnType.recursiveTypeDescriptor()
|
||||
if (not returnType.isNested):
|
||||
returnTypeName = returnType.foreignTypeName
|
||||
# Do not put our own module in the import list
|
||||
if ((argTypeName != self.foreignTypeName) and
|
||||
if ((returnTypeName != self.foreignTypeName) and
|
||||
# Do not put modules already in the list (like a set)
|
||||
(not (argTypeName in moduleList))):
|
||||
(not (returnTypeName in moduleList))):
|
||||
# If this is a class (not a primitive), put it on the list
|
||||
if (argType.__class__ == ClassTypeDescriptor):
|
||||
moduleList.append(argTypeName)
|
||||
|
||||
return moduleList
|
||||
|
||||
if (returnType.__class__ == ClassTypeDescriptor):
|
||||
moduleList.append(returnTypeName)
|
||||
# Now look at all the arguments
|
||||
argTypes = method.typeDescriptor.argumentTypes
|
||||
for argType in argTypes:
|
||||
# Get the real return type (not derived)
|
||||
argType = argType.typeDescriptor.recursiveTypeDescriptor()
|
||||
if (not argType.isNested):
|
||||
argTypeName = argType.foreignTypeName
|
||||
# Do not put our own module in the import list
|
||||
if ((argTypeName != self.foreignTypeName) and
|
||||
# Do not put modules already in the list (like a set)
|
||||
(not (argTypeName in moduleList))):
|
||||
# If this is a class (not a primitive), put it on the list
|
||||
if (argType.__class__ == ClassTypeDescriptor):
|
||||
moduleList.append(argTypeName)
|
||||
self.returnTypeModules = moduleList
|
||||
return self.returnTypeModules
|
||||
|
||||
|
||||
def recordClassMethod(self, methodSpec):
|
||||
"""
|
||||
Record all class methods in a 2 level dictionary so we can go
|
||||
@ -326,6 +318,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
methodList = ifAbsentPut(self.overloadedClassMethods, methodSpec.name, [])
|
||||
methodList.append(methodSpec)
|
||||
|
||||
|
||||
def recordInstanceMethod(self, methodSpec):
|
||||
"""
|
||||
Record all instance methods in a 2 level dictionary so we can go
|
||||
@ -335,6 +328,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
methodList = ifAbsentPut(self.overloadedInstanceMethods, methodSpec.name, [])
|
||||
methodList.append(methodSpec)
|
||||
|
||||
|
||||
def cullOverloadedMethods(self):
|
||||
"""
|
||||
Find all the entries that have multiple indexes for the same method name
|
||||
@ -343,6 +337,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
self.overloadedClassMethods = FFIOverload.cullOverloadedMethods(self.overloadedClassMethods)
|
||||
self.overloadedInstanceMethods = FFIOverload.cullOverloadedMethods(self.overloadedInstanceMethods)
|
||||
|
||||
|
||||
def filterOutStaticMethods(self):
|
||||
"""
|
||||
Run through the list of instance methods and filter out the
|
||||
@ -361,6 +356,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
newInstanceMethods.append(method)
|
||||
self.instanceMethods = newInstanceMethods
|
||||
|
||||
|
||||
def recordOverloadedMethods(self):
|
||||
"""
|
||||
Record all the methods in dictionaries based on method name
|
||||
@ -372,16 +368,75 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
for method in classMethods:
|
||||
self.recordClassMethod(method)
|
||||
|
||||
instanceMethods = (self.instanceMethods + self.globalMethods
|
||||
+ self.upcastMethods + self.downcastMethods)
|
||||
instanceMethods = (self.instanceMethods + self.upcastMethods + self.downcastMethods)
|
||||
for method in instanceMethods:
|
||||
self.recordInstanceMethod(method)
|
||||
|
||||
|
||||
def hasMethodNamed(self, methodName):
|
||||
for method in (self.constructors + [self.destructor] + self.instanceMethods
|
||||
+ self.upcastMethods + self.downcastMethods + self.staticMethods):
|
||||
if (method and (method.name == methodName)):
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
def copyParentMethods(self, file, nesting):
|
||||
"""
|
||||
At multiple inheritance nodes, copy all the parent methods into
|
||||
this class and call them after upcasting us to that class
|
||||
"""
|
||||
if (len(self.parentTypes) >= 2):
|
||||
indent(file, nesting+1, '\n')
|
||||
indent(file, nesting+1, '##################################################\n')
|
||||
indent(file, nesting+1, '# Upcast inherited instance method wrappers #\n')
|
||||
indent(file, nesting+1, '##################################################\n')
|
||||
indent(file, nesting+1, '\n')
|
||||
for parentType in self.parentTypes:
|
||||
parentList = [parentType]
|
||||
self.copyParentMethodsRecursively(parentList, file, nesting)
|
||||
|
||||
|
||||
def copyParentMethodsRecursively(self, parentList, file, nesting):
|
||||
"""
|
||||
Copy all the parents instance methods
|
||||
Do not copy functions if this class already has a function with that name
|
||||
We need to recurse up the hierarchy copying all our parents nodes all
|
||||
the way up the tree stopping either at the top, or at another MI node
|
||||
that has already copied his parent's methods in
|
||||
Note: Do not copy the downcast methods
|
||||
"""
|
||||
parent = parentList[-1]
|
||||
if (len(parent.parentTypes) > 0):
|
||||
recurse = 1
|
||||
else:
|
||||
recurse = 0
|
||||
|
||||
for method in parent.instanceMethods:
|
||||
if not self.hasMethodNamed(method.name):
|
||||
# with downcast for all instance methods that are not themselves upcasts
|
||||
method.generateInheritedMethodCode(self, parentList, file, nesting, 1)
|
||||
# Copy all the parents upcast methods so we transitively pick them up
|
||||
for method in parent.upcastMethods:
|
||||
if not self.hasMethodNamed(method.name):
|
||||
# no downcast for all instance methods that are themselves upcasts
|
||||
# that would cause an infinite loop
|
||||
method.generateInheritedMethodCode(self, parentList, file, nesting, 0)
|
||||
|
||||
# Now recurse up the heirarchy until we get to a node that is itself
|
||||
# a multiple inheritance node and stop there because he will have already
|
||||
# copied all his parent functions in
|
||||
if recurse:
|
||||
for parentType in parent.parentTypes:
|
||||
newParentList = parentList[:]
|
||||
newParentList.append(parentType)
|
||||
self.copyParentMethodsRecursively(newParentList, file, nesting)
|
||||
|
||||
|
||||
def generateOverloadedMethods(self, file, nesting):
|
||||
"""
|
||||
Generate code for all the overloaded methods of this class
|
||||
"""
|
||||
|
||||
if (len(self.overloadedClassMethods.values()) or
|
||||
len(self.overloadedInstanceMethods.values())):
|
||||
indent(file, nesting+1, '\n')
|
||||
@ -389,14 +444,13 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
indent(file, nesting+1, '# Overloaded methods #\n')
|
||||
indent(file, nesting+1, '##################################################\n')
|
||||
indent(file, nesting+1, '\n')
|
||||
|
||||
for methodSpecList in self.overloadedClassMethods.values():
|
||||
treeColl = FFIOverload.FFIMethodArgumentTreeCollection(self, methodSpecList)
|
||||
treeColl.generateCode(file, nesting)
|
||||
for methodSpecList in self.overloadedInstanceMethods.values():
|
||||
# Overload all the class and instance methods
|
||||
for methodSpecList in (self.overloadedClassMethods.values() +
|
||||
self.overloadedInstanceMethods.values()):
|
||||
treeColl = FFIOverload.FFIMethodArgumentTreeCollection(self, methodSpecList)
|
||||
treeColl.generateCode(file, nesting)
|
||||
|
||||
|
||||
def generateGlobalCode(self, dir, extensionsDir):
|
||||
"""
|
||||
Generate shadow class code for this type.
|
||||
@ -414,6 +468,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
self.outputClassFooter(file)
|
||||
file.close()
|
||||
|
||||
|
||||
def generateCode(self, file, nesting):
|
||||
self.recordOverloadedMethods()
|
||||
self.cullOverloadedMethods()
|
||||
@ -482,46 +537,12 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
for method in self.downcastMethods:
|
||||
method.generateDowncastMethodCode(self, file, nesting)
|
||||
|
||||
if len(self.globalMethods):
|
||||
indent(file, nesting+1, '\n')
|
||||
indent(file, nesting+1, '##################################################\n')
|
||||
indent(file, nesting+1, '# Global methods #\n')
|
||||
indent(file, nesting+1, '##################################################\n')
|
||||
indent(file, nesting+1, '\n')
|
||||
for method in self.globalMethods:
|
||||
method.generateMethodCode(self, file, nesting)
|
||||
|
||||
# At multiple inheritance nodes, copy all the parent methods into
|
||||
# this class and call them after upcasting us to that class
|
||||
if (len(self.parentTypes) >= 2):
|
||||
indent(file, nesting+1, '\n')
|
||||
indent(file, nesting+1, '##################################################\n')
|
||||
indent(file, nesting+1, '# Upcast inherited instance method wrappers #\n')
|
||||
indent(file, nesting+1, '##################################################\n')
|
||||
indent(file, nesting+1, '\n')
|
||||
for parentType in self.parentTypes:
|
||||
# Copy all the parents instance methods
|
||||
for method in parentType.instanceMethods:
|
||||
method.generateInheritedMethodCode(self, parentType, file, nesting, 1) # with downcast
|
||||
# Copy all the parents upcast methods so we transitively pick them up
|
||||
for method in parentType.upcastMethods:
|
||||
method.generateInheritedMethodCode(self, parentType, file, nesting, 0) # no downcast
|
||||
# Do not copy the downcast methods
|
||||
|
||||
# At multiple inheritance nodes, copy all the parent methods into
|
||||
# this class and call them after upcasting us to that class
|
||||
if (len(self.parentTypes) >= 2):
|
||||
indent(file, nesting+1, '\n')
|
||||
indent(file, nesting+1, '##################################################\n')
|
||||
indent(file, nesting+1, '# Upcast global method wrappers #\n')
|
||||
indent(file, nesting+1, '##################################################\n')
|
||||
indent(file, nesting+1, '\n')
|
||||
for parentType in self.parentTypes:
|
||||
for method in parentType.globalMethods:
|
||||
method.generateInheritedMethodCode(self, parentType, file, nesting, 1) # with downcast
|
||||
|
||||
# Copy in all our parent nodes (only does work if we are an MI node)
|
||||
self.copyParentMethods(file, nesting)
|
||||
|
||||
self.generateOverloadedMethods(file, nesting)
|
||||
|
||||
|
||||
def outputNestedTypes(self, file, nesting):
|
||||
if (len(self.nestedTypes) > 0):
|
||||
indent(file, nesting+1, '\n')
|
||||
@ -533,6 +554,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
for nestedType in self.nestedTypes:
|
||||
nestedType.generateCode(file, nesting+1)
|
||||
|
||||
|
||||
def copyExtensions(self, extensionsDir, file, nesting):
|
||||
"""
|
||||
Copy in the extension file for this class if one exists
|
||||
@ -568,28 +590,37 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
indent(file, 0, 'import ' + moduleName + 'Downcasts\n')
|
||||
indent(file, 0, '\n')
|
||||
indent(file, 0, 'import FFIExternalObject\n')
|
||||
|
||||
|
||||
def outputImportsRecursively(self, parent, file, nesting):
|
||||
for parentType in parent.parentTypes:
|
||||
self.outputImportsRecursively(parentType, file, nesting)
|
||||
indent(file, nesting, 'import ' + parent.foreignTypeName + '\n')
|
||||
|
||||
returnTypeModules = parent.getReturnTypeModules()
|
||||
if len(returnTypeModules):
|
||||
for moduleName in returnTypeModules:
|
||||
indent(file, nesting, 'import ' + moduleName + '\n')
|
||||
|
||||
|
||||
def outputImports(self, file, nesting):
|
||||
"""
|
||||
Generate code that imports the modules we need for this class
|
||||
"""
|
||||
indent(file, nesting, '# Import everybody we inherit from\n')
|
||||
indent(file, nesting, '# and all the shadow class modules this class uses\n')
|
||||
|
||||
if len(self.parentTypes):
|
||||
indent(file, nesting, '# Import everybody we inherit from\n')
|
||||
for parent in self.parentTypes:
|
||||
indent(file, nesting, 'import ' + parent.foreignTypeName + '\n')
|
||||
indent(file, nesting, '\n')
|
||||
|
||||
# Output all of our return types
|
||||
returnTypeModules = self.getReturnTypeModules()
|
||||
if len(returnTypeModules):
|
||||
indent(file, nesting, '# Import all the shadow class modules this class uses\n')
|
||||
for moduleName in returnTypeModules:
|
||||
indent(file, nesting, 'import ' + moduleName + '\n')
|
||||
|
||||
# an extra line just for spacing
|
||||
|
||||
for parentType in self.parentTypes:
|
||||
self.outputImportsRecursively(parentType, file, nesting)
|
||||
indent(file, nesting, '\n')
|
||||
|
||||
|
||||
def outputClassComment(self, file, nesting):
|
||||
"""
|
||||
Output the class comment to the file
|
||||
@ -660,6 +691,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
def outputClassFooter(self, file):
|
||||
indent(file, 0, " # When this class gets defined, put it in this module's namespace\n")
|
||||
indent(file, 0, " globals()['" + self.foreignTypeName + "'] = " + self.foreignTypeName + '\n')
|
||||
|
||||
|
||||
def outputBaseConstructor(self, file, nesting):
|
||||
"""
|
||||
@ -681,6 +713,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
indent(file, nesting+2, 'apply(self.constructor, _args)\n')
|
||||
indent(file, nesting+2, '\n')
|
||||
|
||||
|
||||
def outputEmptyConstructor(self, file, nesting):
|
||||
"""
|
||||
If there is no C++ constructor, we output code for a runtime error
|
||||
@ -689,6 +722,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
indent(file, nesting+1, 'def constructor(self):\n')
|
||||
indent(file, nesting+2, "raise RuntimeError, 'No C++ constructor defined for class: ' + self.__class__.__name__\n")
|
||||
|
||||
|
||||
def outputBaseDestructor(self, file, nesting):
|
||||
"""
|
||||
This destructor overwrites the builtin Python destructor
|
||||
@ -711,6 +745,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
indent(file, nesting+2, 'if (self.userManagesMemory and (self.this != 0)):\n')
|
||||
indent(file, nesting+3, 'self.destructor()\n')
|
||||
|
||||
|
||||
def outputEmptyDestructor(self, file, nesting):
|
||||
"""
|
||||
If there is no C++ destructor, we just output this
|
||||
@ -719,8 +754,8 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
||||
indent(file, nesting+1, 'def destructor(self):\n')
|
||||
indent(file, nesting+2, 'pass\n')
|
||||
|
||||
def generateReturnValueWrapper(self, file, userManagesMemory,
|
||||
needsDowncast, nesting):
|
||||
|
||||
def generateReturnValueWrapper(self, file, userManagesMemory, needsDowncast, nesting):
|
||||
"""
|
||||
Generate code that creates a shadow object of this type
|
||||
then sets the this pointer and returns the object. We call the
|
||||
|
Loading…
x
Reference in New Issue
Block a user