2
2
3
3
use super :: derive:: { CanDeriveCopy , CanDeriveDebug , CanDeriveDefault } ;
4
4
use super :: int:: IntKind ;
5
- use super :: item:: { Item , ItemCanonicalPath } ;
5
+ use super :: item:: { Item , ItemCanonicalPath , ItemSet } ;
6
6
use super :: item_kind:: ItemKind ;
7
7
use super :: module:: { Module , ModuleKind } ;
8
+ use super :: traversal:: { self , Edge , ItemTraversal } ;
8
9
use super :: ty:: { FloatKind , TemplateDeclaration , Type , TypeKind } ;
9
- use super :: type_collector:: { ItemSet , TypeCollector } ;
10
10
use BindgenOptions ;
11
11
use cexpr;
12
12
use chooser:: TypeChooser ;
@@ -15,7 +15,7 @@ use clang_sys;
15
15
use parse:: ClangItemParser ;
16
16
use std:: borrow:: Cow ;
17
17
use std:: cell:: Cell ;
18
- use std:: collections:: { HashMap , VecDeque , hash_map} ;
18
+ use std:: collections:: { HashMap , hash_map} ;
19
19
use std:: collections:: btree_map:: { self , BTreeMap } ;
20
20
use std:: fmt;
21
21
use std:: iter:: IntoIterator ;
@@ -151,6 +151,13 @@ pub struct BindgenContext<'ctx> {
151
151
generated_bindegen_complex : Cell < bool > ,
152
152
}
153
153
154
+ /// A traversal of whitelisted items.
155
+ pub type WhitelistedItems < ' ctx , ' gen > = ItemTraversal < ' ctx ,
156
+ ' gen ,
157
+ ItemSet ,
158
+ Vec < ItemId > ,
159
+ fn ( Edge ) -> bool > ;
160
+
154
161
impl < ' ctx > BindgenContext < ' ctx > {
155
162
/// Construct the context for the given `options`.
156
163
pub fn new ( options : BindgenOptions ) -> Self {
@@ -538,23 +545,14 @@ impl<'ctx> BindgenContext<'ctx> {
538
545
539
546
fn assert_no_dangling_item_traversal < ' me >
540
547
( & ' me self )
541
- -> AssertNoDanglingItemIter < ' me , ' ctx > {
548
+ -> traversal :: AssertNoDanglingItemsTraversal < ' me , ' ctx > {
542
549
assert ! ( self . in_codegen_phase( ) ) ;
543
550
assert ! ( self . current_module == self . root_module) ;
544
551
545
- let mut roots = self . items ( ) . map ( |( & id, _) | id) ;
546
-
547
- let mut seen = BTreeMap :: < ItemId , ItemId > :: new ( ) ;
548
- let next_child = roots. next ( ) . map ( |id| id) . unwrap ( ) ;
549
- seen. insert ( next_child, next_child) ;
550
-
551
- let to_iterate = seen. iter ( ) . map ( |( & id, _) | id) . rev ( ) . collect ( ) ;
552
-
553
- AssertNoDanglingItemIter {
554
- ctx : self ,
555
- seen : seen,
556
- to_iterate : to_iterate,
557
- }
552
+ let roots = self . items ( ) . map ( |( & id, _) | id) ;
553
+ traversal:: AssertNoDanglingItemsTraversal :: new ( self ,
554
+ roots,
555
+ traversal:: all_edges)
558
556
}
559
557
560
558
// This deserves a comment. Builtin types don't get a valid declaration, so
@@ -1202,8 +1200,7 @@ impl<'ctx> BindgenContext<'ctx> {
1202
1200
///
1203
1201
/// If no items are explicitly whitelisted, then all items are considered
1204
1202
/// whitelisted.
1205
- pub fn whitelisted_items < ' me > ( & ' me self )
1206
- -> WhitelistedItemsIter < ' me , ' ctx > {
1203
+ pub fn whitelisted_items < ' me > ( & ' me self ) -> WhitelistedItems < ' me , ' ctx > {
1207
1204
assert ! ( self . in_codegen_phase( ) ) ;
1208
1205
assert ! ( self . current_module == self . root_module) ;
1209
1206
@@ -1268,18 +1265,19 @@ impl<'ctx> BindgenContext<'ctx> {
1268
1265
} )
1269
1266
. map ( |( & id, _) | id) ;
1270
1267
1271
- let seen: ItemSet = roots. collect ( ) ;
1272
-
1273
- // The .rev() preserves the expected ordering traversal, resulting in
1274
- // more stable-ish bindgen-generated names for anonymous types (like
1268
+ // The reversal preserves the expected ordering of traversal, resulting
1269
+ // in more stable-ish bindgen-generated names for anonymous types (like
1275
1270
// unions).
1276
- let to_iterate = seen. iter ( ) . cloned ( ) . rev ( ) . collect ( ) ;
1271
+ let mut roots: Vec < _ > = roots. collect ( ) ;
1272
+ roots. reverse ( ) ;
1277
1273
1278
- WhitelistedItemsIter {
1279
- ctx : self ,
1280
- seen : seen,
1281
- to_iterate : to_iterate,
1282
- }
1274
+ let predicate = if self . options ( ) . whitelist_recursively {
1275
+ traversal:: all_edges
1276
+ } else {
1277
+ traversal:: no_edges
1278
+ } ;
1279
+
1280
+ WhitelistedItems :: new ( self , roots, predicate)
1283
1281
}
1284
1282
1285
1283
/// Convenient method for getting the prefix to use for most traits in
@@ -1364,124 +1362,3 @@ impl TemplateDeclaration for PartialType {
1364
1362
}
1365
1363
}
1366
1364
}
1367
-
1368
- /// An iterator over whitelisted items.
1369
- ///
1370
- /// See `BindgenContext::whitelisted_items` for more information.
1371
- pub struct WhitelistedItemsIter < ' ctx , ' gen >
1372
- where ' gen : ' ctx ,
1373
- {
1374
- ctx : & ' ctx BindgenContext < ' gen > ,
1375
-
1376
- /// The set of whitelisted items we have seen. If you think of traversing
1377
- /// whitelisted items like GC tracing, this is the mark bits, and contains
1378
- /// both black and gray items.
1379
- seen : ItemSet ,
1380
-
1381
- /// The set of whitelisted items that we have seen but have yet to iterate
1382
- /// over and collect transitive references from. To return to the GC analogy,
1383
- /// this is the mark stack, containing the set of gray items which we have
1384
- /// not finished tracing yet.
1385
- to_iterate : Vec < ItemId > ,
1386
- }
1387
-
1388
- impl < ' ctx , ' gen > Iterator for WhitelistedItemsIter < ' ctx , ' gen >
1389
- where ' gen : ' ctx ,
1390
- {
1391
- type Item = ItemId ;
1392
-
1393
- fn next ( & mut self ) -> Option < Self :: Item > {
1394
- let id = match self . to_iterate . pop ( ) {
1395
- None => return None ,
1396
- Some ( id) => id,
1397
- } ;
1398
-
1399
- debug_assert ! ( self . seen. contains( & id) ) ;
1400
- debug_assert ! ( self . ctx. items. contains_key( & id) ) ;
1401
-
1402
- if self . ctx . options ( ) . whitelist_recursively {
1403
- let mut sub_types = ItemSet :: new ( ) ;
1404
- id. collect_types ( self . ctx , & mut sub_types, & ( ) ) ;
1405
-
1406
- for id in sub_types {
1407
- if self . seen . insert ( id) {
1408
- self . to_iterate . push ( id) ;
1409
- }
1410
- }
1411
- }
1412
-
1413
- Some ( id)
1414
- }
1415
- }
1416
-
1417
- /// An iterator to find any dangling items.
1418
- ///
1419
- /// See `BindgenContext::assert_no_dangling_item_traversal` for more
1420
- /// information.
1421
- pub struct AssertNoDanglingItemIter < ' ctx , ' gen >
1422
- where ' gen : ' ctx ,
1423
- {
1424
- ctx : & ' ctx BindgenContext < ' gen > ,
1425
- seen : BTreeMap < ItemId , ItemId > ,
1426
- to_iterate : VecDeque < ItemId > ,
1427
- }
1428
-
1429
- impl < ' ctx , ' gen > Iterator for AssertNoDanglingItemIter < ' ctx , ' gen >
1430
- where ' gen : ' ctx ,
1431
- {
1432
- type Item = ItemId ;
1433
-
1434
- fn next ( & mut self ) -> Option < Self :: Item > {
1435
- let id = match self . to_iterate . pop_front ( ) {
1436
- None => {
1437
- // We've traversed everything reachable from the previous
1438
- // root(s), see if we have any more roots.
1439
- match self . ctx
1440
- . items ( )
1441
- . filter ( |& ( id, _) | !self . seen . contains_key ( id) )
1442
- . next ( )
1443
- . map ( |( id, _) | * id) {
1444
- None => return None ,
1445
- Some ( id) => {
1446
- // This is a new root.
1447
- self . seen . insert ( id, id) ;
1448
- id
1449
- }
1450
- }
1451
- }
1452
- Some ( id) => id,
1453
- } ;
1454
-
1455
- let mut sub_types = ItemSet :: new ( ) ;
1456
- id. collect_types ( self . ctx , & mut sub_types, & ( ) ) ;
1457
-
1458
- if self . ctx . resolve_item_fallible ( id) . is_none ( ) {
1459
- let mut path = vec ! [ ] ;
1460
- let mut current = id;
1461
- loop {
1462
- let predecessor = * self . seen
1463
- . get ( & current)
1464
- . expect ( "We know we found this item id, so it must have a \
1465
- predecessor") ;
1466
- if predecessor == current {
1467
- break ;
1468
- }
1469
- path. push ( predecessor) ;
1470
- current = predecessor;
1471
- }
1472
- path. reverse ( ) ;
1473
- panic ! ( "Found reference to dangling id = {:?}\n via path = {:?}" ,
1474
- id,
1475
- path) ;
1476
- }
1477
-
1478
- for sub_id in sub_types {
1479
- if self . seen . insert ( sub_id, id) . is_none ( ) {
1480
- // We've never visited this sub item before.
1481
- self . to_iterate . push_back ( sub_id) ;
1482
- }
1483
- }
1484
-
1485
- Some ( id)
1486
- }
1487
- }
0 commit comments