mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
*** empty log message ***
This commit is contained in:
parent
aeb400fc59
commit
0084b86283
@ -137,10 +137,6 @@ class GlobalFunctionSpecification(FunctionSpecification):
|
|||||||
self.outputMethodHeader(methodClass, file, nesting)
|
self.outputMethodHeader(methodClass, file, nesting)
|
||||||
self.outputMethodBody(methodClass, file, nesting)
|
self.outputMethodBody(methodClass, file, nesting)
|
||||||
self.outputMethodFooter(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
|
## Global Function Code Generation
|
||||||
@ -217,52 +213,6 @@ class GlobalFunctionSpecification(FunctionSpecification):
|
|||||||
def outputMethodFooter(self, methodClass, file, nesting):
|
def outputMethodFooter(self, methodClass, file, nesting):
|
||||||
indent(file, nesting+1, '\n')
|
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):
|
class MethodSpecification(FunctionSpecification):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -288,10 +238,10 @@ class MethodSpecification(FunctionSpecification):
|
|||||||
self.outputStaticBody(methodClass, file, nesting)
|
self.outputStaticBody(methodClass, file, nesting)
|
||||||
self.outputStaticFooter(methodClass, file, nesting)
|
self.outputStaticFooter(methodClass, file, nesting)
|
||||||
|
|
||||||
def generateInheritedMethodCode(self, methodClass, parentClass, file, nesting, needsDowncast):
|
def generateInheritedMethodCode(self, methodClass, parentList, file, nesting, needsDowncast):
|
||||||
self.outputInheritedMethodHeader(methodClass, parentClass, file, nesting, needsDowncast)
|
self.outputInheritedMethodHeader(methodClass, parentList, file, nesting, needsDowncast)
|
||||||
self.outputInheritedMethodBody(methodClass, parentClass, file, nesting, needsDowncast)
|
self.outputInheritedMethodBody(methodClass, parentList, file, nesting, needsDowncast)
|
||||||
self.outputInheritedMethodFooter(methodClass, parentClass, file, nesting, needsDowncast)
|
self.outputInheritedMethodFooter(methodClass, parentList, file, nesting, needsDowncast)
|
||||||
|
|
||||||
def generateDowncastMethodCode(self, methodClass, file, nesting):
|
def generateDowncastMethodCode(self, methodClass, file, nesting):
|
||||||
# The downcast method code is just like regular code, but the
|
# 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')
|
indent(file, nesting+2, 'assert(self.this != 0)\n')
|
||||||
if self.typeDescriptor.userManagesMemory:
|
if self.typeDescriptor.userManagesMemory:
|
||||||
indent(file, nesting+2, 'self.userManagesMemory = 1\n')
|
indent(file, nesting+2, 'self.userManagesMemory = 1\n')
|
||||||
|
|
||||||
def outputConstructorFooter(self, methodClass, file, nesting):
|
def outputConstructorFooter(self, methodClass, file, nesting):
|
||||||
indent(file, nesting+1, '\n')
|
indent(file, nesting+1, '\n')
|
||||||
|
|
||||||
@ -443,7 +394,8 @@ class MethodSpecification(FunctionSpecification):
|
|||||||
file.write(', ')
|
file.write(', ')
|
||||||
file.write(')\n')
|
file.write(')\n')
|
||||||
returnType = self.typeDescriptor.returnType.recursiveTypeDescriptor()
|
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):
|
def outputStaticFooter(self, methodClass, file, nesting):
|
||||||
indent(file, nesting+1, self.getFinalName() + ' = '
|
indent(file, nesting+1, self.getFinalName() + ' = '
|
||||||
@ -451,12 +403,10 @@ class MethodSpecification(FunctionSpecification):
|
|||||||
+ '(' + self.getFinalName() + ')\n')
|
+ '(' + self.getFinalName() + ')\n')
|
||||||
indent(file, nesting+1, '\n')
|
indent(file, nesting+1, '\n')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
## Upcast Method Code Generation
|
## Upcast Method Code Generation
|
||||||
##################################################
|
##################################################
|
||||||
def outputInheritedMethodHeader(self, methodClass, parentClass, file, nesting, needsDowncast):
|
def outputInheritedMethodHeader(self, methodClass, parentList, file, nesting, needsDowncast):
|
||||||
argTypes = self.typeDescriptor.argumentTypes
|
argTypes = self.typeDescriptor.argumentTypes
|
||||||
thislessArgTypes = self.typeDescriptor.thislessArgTypes()
|
thislessArgTypes = self.typeDescriptor.thislessArgTypes()
|
||||||
indent(file, nesting+1, 'def ' + self.getFinalName() + '(self')
|
indent(file, nesting+1, 'def ' + self.getFinalName() + '(self')
|
||||||
@ -468,7 +418,7 @@ class MethodSpecification(FunctionSpecification):
|
|||||||
file.write(', ')
|
file.write(', ')
|
||||||
file.write('):\n')
|
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
|
# The method body will look something like
|
||||||
# upcastSelf = self.upcastToParentClass()
|
# upcastSelf = self.upcastToParentClass()
|
||||||
# returnValue = libpanda.method(upcastSelf.this, arg)
|
# returnValue = libpanda.method(upcastSelf.this, arg)
|
||||||
@ -478,8 +428,17 @@ class MethodSpecification(FunctionSpecification):
|
|||||||
argTypes = self.typeDescriptor.argumentTypes
|
argTypes = self.typeDescriptor.argumentTypes
|
||||||
thislessArgTypes = self.typeDescriptor.thislessArgTypes()
|
thislessArgTypes = self.typeDescriptor.thislessArgTypes()
|
||||||
self.outputTypeChecking(methodClass, thislessArgTypes, file, nesting+2)
|
self.outputTypeChecking(methodClass, thislessArgTypes, file, nesting+2)
|
||||||
indent(file, nesting+2, 'upcastSelf = self.upcast' + 'To'
|
for i in range(len(parentList)):
|
||||||
+ parentClass.foreignTypeName + '()\n')
|
# 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
|
indent(file, nesting+2, 'returnValue = ' + self.typeDescriptor.moduleName
|
||||||
+ '.' + self.typeDescriptor.wrapperName + '(upcastSelf.this')
|
+ '.' + self.typeDescriptor.wrapperName + '(upcastSelf.this')
|
||||||
if (len(thislessArgTypes) > 0):
|
if (len(thislessArgTypes) > 0):
|
||||||
@ -494,7 +453,7 @@ class MethodSpecification(FunctionSpecification):
|
|||||||
returnType.generateReturnValueWrapper(file, self.typeDescriptor.userManagesMemory,
|
returnType.generateReturnValueWrapper(file, self.typeDescriptor.userManagesMemory,
|
||||||
needsDowncast, nesting+2)
|
needsDowncast, nesting+2)
|
||||||
|
|
||||||
def outputInheritedMethodFooter(self, methodClass, parentClass, file, nesting, needsDowncast):
|
def outputInheritedMethodFooter(self, methodClass, parentList, file, nesting, needsDowncast):
|
||||||
indent(file, nesting+1, '\n')
|
indent(file, nesting+1, '\n')
|
||||||
|
|
||||||
|
|
||||||
|
@ -212,10 +212,6 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
# Instance methods that had no this pointer are moved into here
|
# Instance methods that had no this pointer are moved into here
|
||||||
self.staticMethods = []
|
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
|
# These are dictionaries used to temporarily hold methods for
|
||||||
# overloading while generating code
|
# overloading while generating code
|
||||||
self.overloadedClassMethods = {}
|
self.overloadedClassMethods = {}
|
||||||
@ -224,6 +220,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
# Nested typeDescriptors inside this class
|
# Nested typeDescriptors inside this class
|
||||||
self.nestedTypes = []
|
self.nestedTypes = []
|
||||||
|
|
||||||
|
|
||||||
def getExtensionModuleName(self):
|
def getExtensionModuleName(self):
|
||||||
"""
|
"""
|
||||||
Return a filename for the extensions for this class
|
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
|
# Otherwise, it must be our first time through, do the real work
|
||||||
self.CModules = []
|
self.CModules = []
|
||||||
for method in (self.constructors + [self.destructor] + self.instanceMethods
|
for method in (self.constructors + [self.destructor] + self.instanceMethods
|
||||||
+ self.upcastMethods + self.downcastMethods
|
+ self.upcastMethods + self.downcastMethods + self.staticMethods):
|
||||||
+ self.staticMethods + self.globalMethods):
|
|
||||||
if method:
|
if method:
|
||||||
if (not (method.typeDescriptor.moduleName in self.CModules)):
|
if (not (method.typeDescriptor.moduleName in self.CModules)):
|
||||||
self.CModules.append(method.typeDescriptor.moduleName)
|
self.CModules.append(method.typeDescriptor.moduleName)
|
||||||
|
|
||||||
# Now look at all the methods that we might inherit if we are at
|
# Now look at all the methods that we might inherit if we are at
|
||||||
# a multiple inheritance node and get their C modules
|
# a multiple inheritance node and get their C modules
|
||||||
if (len(self.parentTypes) >= 2):
|
if (len(self.parentTypes) >= 2):
|
||||||
@ -259,10 +254,6 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
for method in parentType.upcastMethods:
|
for method in parentType.upcastMethods:
|
||||||
if (not (method.typeDescriptor.moduleName in self.CModules)):
|
if (not (method.typeDescriptor.moduleName in self.CModules)):
|
||||||
self.CModules.append(method.typeDescriptor.moduleName)
|
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
|
return self.CModules
|
||||||
|
|
||||||
|
|
||||||
@ -272,8 +263,12 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
class references.
|
class references.
|
||||||
Be careful about nested types
|
Be careful about nested types
|
||||||
"""
|
"""
|
||||||
|
# Return type modules are cached once they are calculated so we
|
||||||
|
# do not have to calculate them again
|
||||||
|
try:
|
||||||
|
return self.returnTypeModules
|
||||||
|
except:
|
||||||
moduleList = []
|
moduleList = []
|
||||||
|
|
||||||
upcastMethods = []
|
upcastMethods = []
|
||||||
if (len(self.parentTypes) >= 2):
|
if (len(self.parentTypes) >= 2):
|
||||||
for parentType in self.parentTypes:
|
for parentType in self.parentTypes:
|
||||||
@ -281,12 +276,9 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
upcastMethods.append(method)
|
upcastMethods.append(method)
|
||||||
for method in parentType.upcastMethods:
|
for method in parentType.upcastMethods:
|
||||||
upcastMethods.append(method)
|
upcastMethods.append(method)
|
||||||
for method in parentType.globalMethods:
|
|
||||||
upcastMethods.append(method)
|
|
||||||
|
|
||||||
for method in (self.constructors + [self.destructor] + self.instanceMethods
|
for method in (self.constructors + [self.destructor] + self.instanceMethods
|
||||||
+ self.upcastMethods + self.downcastMethods
|
+ self.upcastMethods + self.downcastMethods
|
||||||
+ self.staticMethods + self.globalMethods + upcastMethods):
|
+ self.staticMethods + upcastMethods):
|
||||||
if method:
|
if method:
|
||||||
# Get the real return type (not derived)
|
# Get the real return type (not derived)
|
||||||
returnType = method.typeDescriptor.returnType.recursiveTypeDescriptor()
|
returnType = method.typeDescriptor.returnType.recursiveTypeDescriptor()
|
||||||
@ -299,7 +291,6 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
# If this is a class (not a primitive), put it on the list
|
# If this is a class (not a primitive), put it on the list
|
||||||
if (returnType.__class__ == ClassTypeDescriptor):
|
if (returnType.__class__ == ClassTypeDescriptor):
|
||||||
moduleList.append(returnTypeName)
|
moduleList.append(returnTypeName)
|
||||||
|
|
||||||
# Now look at all the arguments
|
# Now look at all the arguments
|
||||||
argTypes = method.typeDescriptor.argumentTypes
|
argTypes = method.typeDescriptor.argumentTypes
|
||||||
for argType in argTypes:
|
for argType in argTypes:
|
||||||
@ -314,8 +305,9 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
# If this is a class (not a primitive), put it on the list
|
# If this is a class (not a primitive), put it on the list
|
||||||
if (argType.__class__ == ClassTypeDescriptor):
|
if (argType.__class__ == ClassTypeDescriptor):
|
||||||
moduleList.append(argTypeName)
|
moduleList.append(argTypeName)
|
||||||
|
self.returnTypeModules = moduleList
|
||||||
|
return self.returnTypeModules
|
||||||
|
|
||||||
return moduleList
|
|
||||||
|
|
||||||
def recordClassMethod(self, methodSpec):
|
def recordClassMethod(self, methodSpec):
|
||||||
"""
|
"""
|
||||||
@ -326,6 +318,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
methodList = ifAbsentPut(self.overloadedClassMethods, methodSpec.name, [])
|
methodList = ifAbsentPut(self.overloadedClassMethods, methodSpec.name, [])
|
||||||
methodList.append(methodSpec)
|
methodList.append(methodSpec)
|
||||||
|
|
||||||
|
|
||||||
def recordInstanceMethod(self, methodSpec):
|
def recordInstanceMethod(self, methodSpec):
|
||||||
"""
|
"""
|
||||||
Record all instance methods in a 2 level dictionary so we can go
|
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 = ifAbsentPut(self.overloadedInstanceMethods, methodSpec.name, [])
|
||||||
methodList.append(methodSpec)
|
methodList.append(methodSpec)
|
||||||
|
|
||||||
|
|
||||||
def cullOverloadedMethods(self):
|
def cullOverloadedMethods(self):
|
||||||
"""
|
"""
|
||||||
Find all the entries that have multiple indexes for the same method name
|
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.overloadedClassMethods = FFIOverload.cullOverloadedMethods(self.overloadedClassMethods)
|
||||||
self.overloadedInstanceMethods = FFIOverload.cullOverloadedMethods(self.overloadedInstanceMethods)
|
self.overloadedInstanceMethods = FFIOverload.cullOverloadedMethods(self.overloadedInstanceMethods)
|
||||||
|
|
||||||
|
|
||||||
def filterOutStaticMethods(self):
|
def filterOutStaticMethods(self):
|
||||||
"""
|
"""
|
||||||
Run through the list of instance methods and filter out the
|
Run through the list of instance methods and filter out the
|
||||||
@ -361,6 +356,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
newInstanceMethods.append(method)
|
newInstanceMethods.append(method)
|
||||||
self.instanceMethods = newInstanceMethods
|
self.instanceMethods = newInstanceMethods
|
||||||
|
|
||||||
|
|
||||||
def recordOverloadedMethods(self):
|
def recordOverloadedMethods(self):
|
||||||
"""
|
"""
|
||||||
Record all the methods in dictionaries based on method name
|
Record all the methods in dictionaries based on method name
|
||||||
@ -372,16 +368,75 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
for method in classMethods:
|
for method in classMethods:
|
||||||
self.recordClassMethod(method)
|
self.recordClassMethod(method)
|
||||||
|
|
||||||
instanceMethods = (self.instanceMethods + self.globalMethods
|
instanceMethods = (self.instanceMethods + self.upcastMethods + self.downcastMethods)
|
||||||
+ self.upcastMethods + self.downcastMethods)
|
|
||||||
for method in instanceMethods:
|
for method in instanceMethods:
|
||||||
self.recordInstanceMethod(method)
|
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):
|
def generateOverloadedMethods(self, file, nesting):
|
||||||
"""
|
"""
|
||||||
Generate code for all the overloaded methods of this class
|
Generate code for all the overloaded methods of this class
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if (len(self.overloadedClassMethods.values()) or
|
if (len(self.overloadedClassMethods.values()) or
|
||||||
len(self.overloadedInstanceMethods.values())):
|
len(self.overloadedInstanceMethods.values())):
|
||||||
indent(file, nesting+1, '\n')
|
indent(file, nesting+1, '\n')
|
||||||
@ -389,13 +444,12 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
indent(file, nesting+1, '# Overloaded methods #\n')
|
indent(file, nesting+1, '# Overloaded methods #\n')
|
||||||
indent(file, nesting+1, '##################################################\n')
|
indent(file, nesting+1, '##################################################\n')
|
||||||
indent(file, nesting+1, '\n')
|
indent(file, nesting+1, '\n')
|
||||||
|
# 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)
|
||||||
|
|
||||||
for methodSpecList in self.overloadedClassMethods.values():
|
|
||||||
treeColl = FFIOverload.FFIMethodArgumentTreeCollection(self, methodSpecList)
|
|
||||||
treeColl.generateCode(file, nesting)
|
|
||||||
for methodSpecList in self.overloadedInstanceMethods.values():
|
|
||||||
treeColl = FFIOverload.FFIMethodArgumentTreeCollection(self, methodSpecList)
|
|
||||||
treeColl.generateCode(file, nesting)
|
|
||||||
|
|
||||||
def generateGlobalCode(self, dir, extensionsDir):
|
def generateGlobalCode(self, dir, extensionsDir):
|
||||||
"""
|
"""
|
||||||
@ -414,6 +468,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
self.outputClassFooter(file)
|
self.outputClassFooter(file)
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
|
|
||||||
def generateCode(self, file, nesting):
|
def generateCode(self, file, nesting):
|
||||||
self.recordOverloadedMethods()
|
self.recordOverloadedMethods()
|
||||||
self.cullOverloadedMethods()
|
self.cullOverloadedMethods()
|
||||||
@ -482,46 +537,12 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
for method in self.downcastMethods:
|
for method in self.downcastMethods:
|
||||||
method.generateDowncastMethodCode(self, file, nesting)
|
method.generateDowncastMethodCode(self, file, nesting)
|
||||||
|
|
||||||
if len(self.globalMethods):
|
# Copy in all our parent nodes (only does work if we are an MI node)
|
||||||
indent(file, nesting+1, '\n')
|
self.copyParentMethods(file, nesting)
|
||||||
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
|
|
||||||
|
|
||||||
self.generateOverloadedMethods(file, nesting)
|
self.generateOverloadedMethods(file, nesting)
|
||||||
|
|
||||||
|
|
||||||
def outputNestedTypes(self, file, nesting):
|
def outputNestedTypes(self, file, nesting):
|
||||||
if (len(self.nestedTypes) > 0):
|
if (len(self.nestedTypes) > 0):
|
||||||
indent(file, nesting+1, '\n')
|
indent(file, nesting+1, '\n')
|
||||||
@ -533,6 +554,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
for nestedType in self.nestedTypes:
|
for nestedType in self.nestedTypes:
|
||||||
nestedType.generateCode(file, nesting+1)
|
nestedType.generateCode(file, nesting+1)
|
||||||
|
|
||||||
|
|
||||||
def copyExtensions(self, extensionsDir, file, nesting):
|
def copyExtensions(self, extensionsDir, file, nesting):
|
||||||
"""
|
"""
|
||||||
Copy in the extension file for this class if one exists
|
Copy in the extension file for this class if one exists
|
||||||
@ -570,26 +592,35 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
indent(file, 0, 'import FFIExternalObject\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):
|
def outputImports(self, file, nesting):
|
||||||
"""
|
"""
|
||||||
Generate code that imports the modules we need for this class
|
Generate code that imports the modules we need for this class
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if len(self.parentTypes):
|
|
||||||
indent(file, nesting, '# Import everybody we inherit from\n')
|
indent(file, nesting, '# Import everybody we inherit from\n')
|
||||||
for parent in self.parentTypes:
|
indent(file, nesting, '# and all the shadow class modules this class uses\n')
|
||||||
indent(file, nesting, 'import ' + parent.foreignTypeName + '\n')
|
|
||||||
indent(file, nesting, '\n')
|
|
||||||
|
|
||||||
|
# Output all of our return types
|
||||||
returnTypeModules = self.getReturnTypeModules()
|
returnTypeModules = self.getReturnTypeModules()
|
||||||
if len(returnTypeModules):
|
if len(returnTypeModules):
|
||||||
indent(file, nesting, '# Import all the shadow class modules this class uses\n')
|
|
||||||
for moduleName in returnTypeModules:
|
for moduleName in returnTypeModules:
|
||||||
indent(file, nesting, 'import ' + moduleName + '\n')
|
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')
|
indent(file, nesting, '\n')
|
||||||
|
|
||||||
|
|
||||||
def outputClassComment(self, file, nesting):
|
def outputClassComment(self, file, nesting):
|
||||||
"""
|
"""
|
||||||
Output the class comment to the file
|
Output the class comment to the file
|
||||||
@ -661,6 +692,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
indent(file, 0, " # When this class gets defined, put it in this module's namespace\n")
|
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')
|
indent(file, 0, " globals()['" + self.foreignTypeName + "'] = " + self.foreignTypeName + '\n')
|
||||||
|
|
||||||
|
|
||||||
def outputBaseConstructor(self, file, nesting):
|
def outputBaseConstructor(self, file, nesting):
|
||||||
"""
|
"""
|
||||||
Output the __init__ constructor for this class.
|
Output the __init__ constructor for this class.
|
||||||
@ -681,6 +713,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
indent(file, nesting+2, 'apply(self.constructor, _args)\n')
|
indent(file, nesting+2, 'apply(self.constructor, _args)\n')
|
||||||
indent(file, nesting+2, '\n')
|
indent(file, nesting+2, '\n')
|
||||||
|
|
||||||
|
|
||||||
def outputEmptyConstructor(self, file, nesting):
|
def outputEmptyConstructor(self, file, nesting):
|
||||||
"""
|
"""
|
||||||
If there is no C++ constructor, we output code for a runtime error
|
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+1, 'def constructor(self):\n')
|
||||||
indent(file, nesting+2, "raise RuntimeError, 'No C++ constructor defined for class: ' + self.__class__.__name__\n")
|
indent(file, nesting+2, "raise RuntimeError, 'No C++ constructor defined for class: ' + self.__class__.__name__\n")
|
||||||
|
|
||||||
|
|
||||||
def outputBaseDestructor(self, file, nesting):
|
def outputBaseDestructor(self, file, nesting):
|
||||||
"""
|
"""
|
||||||
This destructor overwrites the builtin Python destructor
|
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+2, 'if (self.userManagesMemory and (self.this != 0)):\n')
|
||||||
indent(file, nesting+3, 'self.destructor()\n')
|
indent(file, nesting+3, 'self.destructor()\n')
|
||||||
|
|
||||||
|
|
||||||
def outputEmptyDestructor(self, file, nesting):
|
def outputEmptyDestructor(self, file, nesting):
|
||||||
"""
|
"""
|
||||||
If there is no C++ destructor, we just output this
|
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+1, 'def destructor(self):\n')
|
||||||
indent(file, nesting+2, 'pass\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
|
Generate code that creates a shadow object of this type
|
||||||
then sets the this pointer and returns the object. We call the
|
then sets the this pointer and returns the object. We call the
|
||||||
|
Loading…
x
Reference in New Issue
Block a user