Skip to content

Commit 918636f

Browse files
author
Bruno da Silva de Oliveira
committed
- Fixed a bug where in some classes the virtual methods were being definied incorrectly
[SVN r19525]
1 parent 83a6adb commit 918636f

10 files changed

Lines changed: 61 additions & 29 deletions

File tree

pyste/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ solution.
77
Automatically convert \ to / in Windows systems before passing the paths to
88
gccxml.
99

10+
Fixed a bug reported by Prabhu Ramachandran, where in some classes the virtual
11+
methods were being definied incorrectly. Thanks a lot Prabhu!
12+
1013
7 July 2003
1114
Applied 2 patches by Prabhu Ramachandran: a fix in the new --multiple method,
1215
and two new functions "hold_with_shared_ptr" and its counterpart for auto_ptr.

pyste/src/Pyste/ClassExporter.py

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ def InheritMethods(self, exported_names):
113113
valid_members = (Method, ClassVariable, NestedClass, ClassEnumeration)
114114
# these don't work INVESTIGATE!: (ClassOperator, ConverterOperator)
115115
fullnames = [x.FullName() for x in self.class_]
116+
pointers = [x.PointerDeclaration(True) for x in self.class_ if isinstance(x, Method)]
117+
fullnames = dict([(x, None) for x in fullnames])
118+
pointers = dict([(x, None) for x in pointers])
116119
for level in self.class_.hierarchy:
117120
level_exported = False
118121
for base in level:
@@ -122,7 +125,12 @@ def InheritMethods(self, exported_names):
122125
if type(member) in valid_members:
123126
member_copy = copy.deepcopy(member)
124127
member_copy.class_ = self.class_.FullName()
125-
if member_copy.FullName() not in fullnames:
128+
if isinstance(member_copy, Method):
129+
pointer = member_copy.PointerDeclaration(True)
130+
if pointer not in pointers:
131+
self.class_.AddMember(member)
132+
pointers[pointer] = None
133+
elif member_copy.FullName() not in fullnames:
126134
self.class_.AddMember(member)
127135
else:
128136
level_exported = True
@@ -646,7 +654,7 @@ class _VirtualWrapperGenerator(object):
646654
'Generates code to export the virtual methods of the given class'
647655

648656
def __init__(self, class_, bases, info):
649-
self.class_ = class_
657+
self.class_ = copy.deepcopy(class_)
650658
self.bases = bases[:]
651659
self.info = info
652660
self.wrapper_name = makeid(class_.FullName()) + '_Wrapper'
@@ -703,7 +711,7 @@ def DefaultImpl(method, param_names):
703711
if not wrapper:
704712
# return the default implementation of the class
705713
if method.abstract:
706-
s = indent2 + 'PyErr_SetString(PyExc_RuntimeError, "abstract function called");\n' +\
714+
s = indent2 + 'PyErr_SetString(PyExc_RuntimeError, "pure virtual function called");\n' +\
707715
indent2 + 'throw_error_already_set();\n'
708716
if method.result.FullName() != 'void':
709717
s += indent2 + 'return %s();\n' % method.result.FullName()
@@ -789,14 +797,7 @@ def IsVirtual(m):
789797
return type(m) is Method and \
790798
m.virtual and \
791799
m.visibility != Scope.private
792-
793-
all_methods = [x for x in self.class_ if IsVirtual(x)]
794-
for base in self.bases:
795-
base_methods = [copy.deepcopy(x) for x in base if IsVirtual(x)]
796-
for base_method in base_methods:
797-
base_method.class_ = self.class_.FullName()
798-
all_methods.append(base_method)
799-
800+
800801
# extract the virtual methods, avoiding duplications. The duplication
801802
# must take in account the full signature without the class name, so
802803
# that inherited members are correctly excluded if the subclass overrides
@@ -811,10 +812,22 @@ def MethodSig(method):
811812
else:
812813
result = ''
813814
params = ', '.join([x.FullName() for x in method.parameters])
814-
return '%s %s(%s) %s' % (result, method.name, params, const)
815-
816-
self.virtual_methods = []
815+
return '%s %s(%s) %s' % (result, method.name, params, const)
816+
817817
already_added = {}
818+
self.virtual_methods = []
819+
for member in self.class_:
820+
if IsVirtual(member):
821+
already_added[MethodSig(member)] = None
822+
self.virtual_methods.append(member)
823+
824+
for base in self.bases:
825+
base_methods = [copy.deepcopy(x) for x in base if IsVirtual(x)]
826+
for base_method in base_methods:
827+
self.class_.AddMember(base_method)
828+
829+
all_methods = [x for x in self.class_ if IsVirtual(x)]
830+
818831
for member in all_methods:
819832
sig = MethodSig(member)
820833
if IsVirtual(member) and not sig in already_added:

pyste/src/Pyste/CppParser.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ def CacheFileName(self, interface):
152152
cache_file = os.path.splitext(interface_name)[0] + '.pystec'
153153
cache_file = os.path.join(self.cache_dir, cache_file)
154154
return cache_file
155-
156155

157156

158157
def GetCache(self, header, interface, tail):

pyste/src/Pyste/declarations.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def AddMember(self, member):
123123
m.is_unique = False
124124
else:
125125
member.is_unique = True
126-
self.__member_names[member.name] = 1
126+
self.__member_names[member.name] = 1
127127
self.__members.append(member)
128128
if isinstance(member, ClassOperator):
129129
self.operator[member.name] = member
@@ -329,6 +329,10 @@ def IsCopy(self):
329329
return param_reference and class_as_param and param.const and is_public
330330

331331

332+
def PointerDeclaration(self, force=False):
333+
return ''
334+
335+
332336
#==============================================================================
333337
# Destructor
334338
#==============================================================================
@@ -342,6 +346,10 @@ def FullName(self):
342346
return self.class_ + '::~' + self.name
343347

344348

349+
def PointerDeclaration(self, force=False):
350+
return ''
351+
352+
345353

346354
#==============================================================================
347355
# ClassOperator

pyste/src/Pyste/pyste.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
import time
4444
from declarations import Typedef
4545

46-
__VERSION__ = '0.9.11'
46+
__VERSION__ = '0.9.12'
4747

4848
def RecursiveIncludes(include):
4949
'Return a list containg the include dir and all its subdirectories'

pyste/tests/inherit2.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@ struct A
44
{
55
int x;
66
int getx() { return x; }
7+
int foo() { return 0; }
8+
int foo(int x) { return x; }
79
};
810

911
struct B : A
1012
{
1113
int y;
1214
int gety() { return y; }
15+
int foo() { return 1; }
1316
};
1417

1518
struct C : B

pyste/tests/inherit2.pyste

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
header = AllFromHeader('inherit2.h')
2-
exclude(header.A)
3-
exclude(header.C)
1+
Class('inherit2::B', 'inherit2.h')
2+
Class('inherit2::D', 'inherit2.h')

pyste/tests/inherit2UT.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ def testIt(self):
1616
self.assertEqual(d.gety(), 15)
1717
self.assertEqual(d.getz(), 10)
1818
self.assertEqual(d.getw(), 5)
19+
self.assertEqual(b.foo(), 1)
20+
self.assertEqual(b.foo(3), 3)
1921

2022
def wrong():
2123
return b.getw()

pyste/tests/inherit3.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ struct A
55
{
66
struct X { int y; };
77
int x;
8-
int foo() { return 1; }
8+
virtual int foo() { return 0; }
9+
virtual int foo(int x) { return x; }
910
A operator+(A o) const
1011
{
1112
A r;

pyste/tests/inherit3UT.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,20 @@
44
class testInherit3(unittest.TestCase):
55

66
def testIt(self):
7-
def testClass(class_):
8-
c = class_()
7+
def testInst(c):
98
self.assertEqual(c.x, 0)
10-
self.assertEqual(c.foo(), 1)
11-
x = class_.X()
9+
self.assertEqual(c.foo(3), 3)
10+
x = c.X()
1211
self.assertEqual(x.y, 0)
13-
self.assertEqual(class_.E.i, 0)
14-
self.assertEqual(class_.E.j, 1)
15-
testClass(B)
16-
testClass(C)
12+
self.assertEqual(c.E.i, 0)
13+
self.assertEqual(c.E.j, 1)
14+
b = B()
15+
c = C()
16+
testInst(b)
17+
testInst(c)
18+
self.assertEqual(b.foo(), 1)
19+
self.assertEqual(c.foo(), 0)
20+
1721

1822
if __name__ == '__main__':
1923
unittest.main()

0 commit comments

Comments
 (0)