Skip to content

Commit 3e2337f

Browse files
author
roman_yakovenko
committed
implement better algorithm for searching template instantiatd classes
1 parent b3ca273 commit 3e2337f

File tree

7 files changed

+113
-6
lines changed

7 files changed

+113
-6
lines changed

pygccxml/declarations/matchers.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ def _set_name( self, name ):
177177
else:
178178
self.__opt_is_full_name = False
179179
self.__decl_name_only = self.__opt_tmpl_name
180+
self.__name = templates.normalize( name )
180181
else:
181182
if '::' in self.__name:
182183
self.__opt_is_full_name = True
@@ -225,11 +226,12 @@ def check_name( self, decl ):
225226
assert not None is self.name
226227
if self.__opt_is_tmpl_inst:
227228
if not self.__opt_is_full_name:
228-
if self.name != decl.name and self.name != decl.partial_name:
229+
if self.name != templates.normalize( decl.name ) \
230+
and self.name != templates.normalize( decl.partial_name ):
229231
return False
230-
else:
231-
if self.name != algorithm.full_name( decl, with_defaults=True ) \
232-
and self.name != algorithm.full_name( decl, with_defaults=False ):
232+
else:
233+
if self.name != templates.normalize( algorithm.full_name( decl, with_defaults=True ) ) \
234+
and self.name != templates.normalize( algorithm.full_name( decl, with_defaults=False ) ):
233235
return False
234236
else:
235237
if not self.__opt_is_full_name:

pygccxml/declarations/pattern_parser.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def __init__( self
2424
def has_pattern( self, decl_string ):
2525
"""implementation details"""
2626
last_part = decl_string.split( '::' )[-1]
27-
return -1 != last_part.find( self.__end )
27+
return -1 != decl_string.find( self.__begin ) and -1 != last_part.find( self.__end )
2828

2929
def name( self, decl_string ):
3030
"""implementation details"""
@@ -127,3 +127,14 @@ def join( self, name, args, arg_separator=None ):
127127

128128
return ''.join( [ name, self.__begin, args_str, self.__end ] )
129129

130+
def normalize( self, decl_string, arg_separator=None ):
131+
"""implementation details"""
132+
if not self.has_pattern( decl_string ):
133+
return decl_string
134+
name, args = self.split( decl_string )
135+
for i, arg in enumerate( args ):
136+
args[i] = self.normalize( arg )
137+
return self.join( name, args, arg_separator )
138+
139+
140+

pygccxml/declarations/scopedef.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import time
1111
import algorithm
1212
import filtering
13+
import templates
1314
import declaration
1415
import mdecl_wrapper
1516
from pygccxml import utils
@@ -301,8 +302,15 @@ def __findout_range( self, name, decl_type, recursive ):
301302
decls = self.declarations
302303
if recursive:
303304
decls = algorithm.make_flatten( self.declarations )
305+
if decl_type:
306+
decls = filter( lambda d: isinstance( d, decl_type ), decls )
304307
return decls
305308

309+
if name and templates.is_instantiation( name ):
310+
#templates has tricky mode to compare them, so lets check the whole
311+
#range
312+
name = None
313+
306314
if name and decl_type:
307315
matcher = scopedef_t._impl_matchers[ scopedef_t.decl ]( name=name )
308316
if matcher.is_full_name():

pygccxml/declarations/templates.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,13 @@ def split_recursive( decl_string ):
6464
def join( name, args ):
6565
"""returns name< argument_1, argument_2, ..., argument_n >"""
6666
global __THE_PARSER
67-
return __THE_PARSER.join( name, args )
67+
return __THE_PARSER.join( name, args )
68+
69+
def normalize( decl_string ):
70+
"""returns decl_string, which contains "normalized" spaces
71+
72+
this functionality allows to implement comparison of 2 different string
73+
which are actually same: x::y< z > and x::y<z>
74+
"""
75+
global __THE_PARSER
76+
return __THE_PARSER.normalize( decl_string )
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright 2004 Roman Yakovenko.
2+
# Distributed under the Boost Software License, Version 1.0. (See
3+
# accompanying file LICENSE_1_0.txt or copy at
4+
# http://www.boost.org/LICENSE_1_0.txt)
5+
6+
import unittest
7+
import autoconfig
8+
import parser_test_case
9+
10+
from pygccxml import utils
11+
from pygccxml import parser
12+
from pygccxml import declarations
13+
14+
class tester_t( parser_test_case.parser_test_case_t ):
15+
16+
global_ns = None
17+
18+
def __init__(self, *args ):
19+
parser_test_case.parser_test_case_t.__init__( self, *args )
20+
self.header = 'better_templates_matcher_tester.hpp'
21+
22+
def setUp(self):
23+
if not tester_t.global_ns:
24+
decls = parser.parse( [self.header], self.config )
25+
tester_t.global_ns = declarations.get_global_namespace( decls )
26+
tester_t.global_ns.init_optimizer()
27+
28+
def test( self ):
29+
classes = [ '::std::vector<Ogre::PlaneBoundedVolume,std::allocator<Ogre::PlaneBoundedVolume>>'
30+
, '::std::vector<Ogre::Plane, std::allocator<Ogre::Plane>>'
31+
, '::Ogre::Singleton< Ogre::PCZoneFactoryManager>' ]
32+
for i in classes:
33+
c = self.global_ns.class_( i )
34+
35+
def create_suite():
36+
suite = unittest.TestSuite()
37+
suite.addTest( unittest.makeSuite(tester_t))
38+
return suite
39+
40+
def run_suite():
41+
unittest.TextTestRunner(verbosity=2).run( create_suite() )
42+
43+
if __name__ == "__main__":
44+
run_suite()
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2004 Roman Yakovenko.
2+
// Distributed under the Boost Software License, Version 1.0. (See
3+
// accompanying file LICENSE_1_0.txt or copy at
4+
// http://www.boost.org/LICENSE_1_0.txt)
5+
6+
#include <vector>
7+
#include <map>
8+
9+
namespace Ogre{
10+
struct PlaneBoundedVolume{};
11+
12+
struct Plane{};
13+
14+
std::vector<PlaneBoundedVolume> do_smth(){
15+
return std::vector<PlaneBoundedVolume>();
16+
}
17+
18+
std::vector<Plane> do_smth2(){
19+
return std::vector<Plane>();
20+
}
21+
22+
template< class X >
23+
struct Singleton{
24+
};
25+
26+
struct PCZoneFactoryManager{};
27+
28+
Singleton<PCZoneFactoryManager> do_smth3(){
29+
return Singleton<PCZoneFactoryManager>();
30+
}
31+
}

unittests/test_all.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import copy_constructor_tester
5151
import plain_c_tester
5252
import function_traits_tester
53+
import better_templates_matcher_tester
5354

5455
testers = [
5556
decl_string_tester
@@ -96,6 +97,7 @@
9697
, copy_constructor_tester
9798
, plain_c_tester
9899
, function_traits_tester
100+
, better_templates_matcher_tester
99101
]
100102

101103
def create_suite():

0 commit comments

Comments
 (0)