Add more helper functions to the exgractor classes.

Make it possible to distinguish between virtual and pure-virtual methods.
Switch to %AutoPyName and don't automatically use /PyName/ just to drop the leading 'wx'
Write %ModuleHeaderCode items before %Include items

git-svn-id: https://svn.wxwidgets.org/svn/wx/sandbox/trunk/Phoenix@66195 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2010-11-18 08:25:38 +00:00
parent 548d52253c
commit 5d686a914f
3 changed files with 145 additions and 21 deletions

View File

@@ -4,7 +4,7 @@
#
# Created: 3-Nov-2010
# Copyright: (c) 2010 by Total Control Software
# Licence: wxWindows license
# License: wxWindows License
#---------------------------------------------------------------------------
"""
@@ -107,6 +107,9 @@ class BaseDef(object):
def addItem(self, item):
self.items.append(item)
def insertItem(self, index, item):
self.items.insert(index, item)
@@ -343,7 +346,8 @@ class MethodDef(FunctionDef):
def extract(self, element, className):
super(MethodDef, self).extract(element)
self.isStatic = element.get('static') == 'yes'
self.isVirtual = element.get('virt') == 'virtual'
self.isVirtual = element.get('virt') in ['virtual', 'pure-virtual']
self.isPureVirtual = element.get('virt') == 'pure-virtual'
self.isCtor = self.name == className
self.isDtor = self.name == '~' + className
self.protection = element.get('prot')
@@ -515,7 +519,10 @@ class ClassDef(BaseDef):
def addCppMethod(self, type, name, argsString, body, doc=None, **kw):
"""
Add a new C++ method to a class.
Add a new C++ method to a class. This method doesn't have to actually
exist in the real C++ class. Instead it will be grafted on by the
back-end wrapper generator such that it is visible in the class in the
target language.
"""
md = CppMethodDef(type, name, argsString, body, doc, **kw)
self.items.append(md)
@@ -549,6 +556,65 @@ class ClassDef(BaseDef):
return pc
def addPublic(self, code=''):
"""
Adds a 'public:' protection keyword to the class, optionally followed
by some additional code.
"""
text = 'public:'
if code:
text = text + '\n' + code
self.addItem(WigCode(text))
def addProtected(self, code=''):
"""
Adds a 'protected:' protection keyword to the class, optionally followed
by some additional code.
"""
text = 'protected:'
if code:
text = text + '\n' + code
self.addItem(WigCode(text))
def addPrivate(self, code=''):
"""
Adds a 'private:' protection keyword to the class, optionally followed
by some additional code.
"""
text = 'private:'
if code:
text = text + '\n' + code
self.addItem(WigCode(text))
def addCopyCtor(self, prot='protected'):
# add declaration of a copy constructor to this class
wig = WigCode("""
{PROT}:
{CLASS}(const {CLASS}&);
""".format(CLASS=self.name, PROT=prot))
self.addItem(wig)
def addPrivateCopyCtor(self):
self.addCopyCtor('private')
def addPrivateAssignOp(self):
# add declaration of an assignment opperator to this class
wig = WigCode("""
private:
{CLASS}& operator=(const {CLASS}&);
""".format(CLASS=self.name))
self.addItem(wig)
def addDtor(self, prot='protected'):
# add declaration of a destructor to this class
wig = WigCode("""
{PROT}:
~{CLASS}();
""".format(CLASS=self.name, PROT=prot))
self.addItem(wig)
#---------------------------------------------------------------------------
class EnumDef(BaseDef):

View File

@@ -4,7 +4,7 @@
#
# Created: 3-Nov-2010
# Copyright: (c) 2010 by Total Control Software
# Licence: wxWindows license
# License: wxWindows License
#---------------------------------------------------------------------------
"""
@@ -46,15 +46,18 @@ class SipWrapperGenerator(generators.WrapperGeneratorBase):
// This file is generated by wxPython's SIP generator. Do not edit by hand.
//
// Copyright: (c) 2010 by Total Control Software
// Licence: wxWindows license
// License: wxWindows License
""")
if module.name == module.module:
stream.write("""
%%Module(name=%s.%s, use_argument_names=True, language="C++")
{
%%AutoPyName(remove_leading="wx")
}
%%Copying
Copyright: (c) 2010 by Total Control Software
Licence: wxWindows license
License: wxWindows License
%%End
""" % (module.package, module.name))
@@ -68,7 +71,7 @@ class SipWrapperGenerator(generators.WrapperGeneratorBase):
# This file is generated by wxPython's SIP generator. Do not edit by hand.
#
# Copyright: (c) 2010 by Total Control Software
# Licence: wxWindows license
# License: wxWindows License
%s
from %s import *
@@ -80,7 +83,14 @@ from %s import *
stream.write("//\n// This file will be included by %s.sip\n//\n" % module.module)
stream.write(divider)
# C++ code to be written to the module's header
if module.headerCode:
stream.write("\n%ModuleHeaderCode\n")
for c in module.headerCode:
stream.write('%s\n' % c)
stream.write("%End\n\n")
# %Imports and %Includes
for i in module.imports:
stream.write("%%Import %s.sip\n" % i)
@@ -89,12 +99,6 @@ from %s import *
stream.write("%%Include %s.sip\n" % i)
# C++ code to be written out to the generated module
if module.headerCode:
stream.write("\n%ModuleHeaderCode\n")
for c in module.headerCode:
stream.write('%s\n' % c)
stream.write("%End\n\n")
if module.cppCode:
stream.write("%ModuleCode\n")
for c in module.cppCode:
@@ -181,14 +185,14 @@ from %s import *
name = enum.name
if name.startswith('@'):
name = ''
stream.write('%senum %s%s\n{\n' % (indent, name, self.annotate(enum)))
stream.write('%senum %s%s\n%s{\n' % (indent, name, self.annotate(enum), indent))
values = []
for v in enum.items:
if v.ignored:
continue
values.append("%s %s%s" % (indent, v.name, self.annotate(v)))
stream.write(',\n'.join(values))
stream.write('%s\n};\n\n' % (indent, ))
stream.write('%s\n%s};\n\n' % (indent, indent))
#-----------------------------------------------------------------------
@@ -344,7 +348,10 @@ from %s import *
stream.write('\n')
self.generateParameters(method.items, stream, indent+' '*4)
stream.write(indent)
stream.write(')%s;\n\n' % self.annotate(method))
stream.write(')')
if method.isPureVirtual:
stream.write(' = 0')
stream.write('%s;\n\n' % self.annotate(method))
if method.overloads:
for m in method.overloads:
self.generateMethod(m, stream, indent)
@@ -385,7 +392,8 @@ from %s import *
def annotate(self, item):
annotations = []
if item.pyName:
annotations.append('PyName=%s' % item.pyName)
if not getattr(item, 'wxDropped', False):
annotations.append('PyName=%s' % item.pyName)
if isinstance(item, extractors.ParamDef):
if item.out:

View File

@@ -4,7 +4,7 @@
#
# Created: 3-Nov-2010
# Copyright: (c) 2010 by Total Control Software
# Licence: wxWindows license
# License: wxWindows License
#---------------------------------------------------------------------------
"""
@@ -18,7 +18,10 @@ import extractors
def removeWxPrefixes(node):
"""
Rename items with a 'wx' prefix to not have the prefix.
Rename items with a 'wx' prefix to not have the prefix. If the back-end
generator supports auto-renaming then it can ignore the pyName value for
those that are changed here. We'll still change them all incase the
pyNames are needed elsewhere.
"""
for item in node.allItems():
if not item.pyName \
@@ -27,9 +30,13 @@ def removeWxPrefixes(node):
and not isinstance(item, (extractors.TypedefDef,
extractors.MethodDef )): # TODO: Any others?
item.pyName = item.name[2:]
item.wxDropped = True
if item.name.startswith('wxEVT_'):
# give these theire actual name so the auto-renamer won't touch them
item.pyName = item.name
def ignoreAssignmentOperators(node):
"""
Set the ignored flag for all class methods that are assignment operators
@@ -169,3 +176,46 @@ def convertTwoDoublesTemplate(CLASS):
""".format(**locals())
def convertFourDoublesTemplate(CLASS):
return """\
// is it just a typecheck?
if (!sipIsErr) {{
if (sipCanConvertToType(sipPy, sipType_{CLASS}, SIP_NO_CONVERTORS))
return 1;
if (PySequence_Check(sipPy) && PySequence_Size(sipPy) == 4) {{
int rval = 1;
PyObject* o1 = PySequence_ITEM(sipPy, 0);
PyObject* o2 = PySequence_ITEM(sipPy, 1);
PyObject* o3 = PySequence_ITEM(sipPy, 2);
PyObject* o4 = PySequence_ITEM(sipPy, 3);
if (!PyNumber_Check(o1) || !PyNumber_Check(o2) || !PyNumber_Check(o3) || !PyNumber_Check(o4))
rval = 0;
Py_DECREF(o1);
Py_DECREF(o2);
Py_DECREF(o3);
Py_DECREF(o4);
return rval;
}}
return 0;
}}
// otherwise do the conversion
if (PySequence_Check(sipPy)) {{
PyObject* o1 = PySequence_ITEM(sipPy, 0);
PyObject* o2 = PySequence_ITEM(sipPy, 1);
PyObject* o3 = PySequence_ITEM(sipPy, 2);
PyObject* o4 = PySequence_ITEM(sipPy, 3);
*sipCppPtr = new {CLASS}(PyFloat_AsDouble(o1), PyFloat_AsDouble(o2),
PyFloat_AsDouble(o3), PyFloat_AsDouble(o4));
Py_DECREF(o1);
Py_DECREF(o2);
return sipGetState(sipTransferObj);
}}
*sipCppPtr = reinterpret_cast<{CLASS}*>(sipConvertToType(
sipPy, sipType_{CLASS}, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr));
return 0;
""".format(**locals())