@@ -1164,6 +1164,23 @@ impl AttrPath {
1164
1164
span : path. span ,
1165
1165
}
1166
1166
}
1167
+
1168
+ /// For a single-segment attribute (i.e., `#[attr]` and not `#[path::atrr]`),
1169
+ /// return the name of the attribute; otherwise, returns `None`.
1170
+ pub fn name ( & self ) -> Option < Symbol > {
1171
+ self . ident ( ) . map ( |ident| ident. name )
1172
+ }
1173
+
1174
+ /// For a single-segment attribute, returns its ident; otherwise, returns `None`.
1175
+
1176
+ pub fn ident ( & self ) -> Option < Ident > {
1177
+ if let [ ident] = self . segments . as_ref ( ) { Some ( * ident) } else { None }
1178
+ }
1179
+
1180
+ #[ inline]
1181
+ pub fn has_name ( & self , name : Symbol ) -> bool {
1182
+ self . name ( ) == Some ( name)
1183
+ }
1167
1184
}
1168
1185
1169
1186
impl fmt:: Display for AttrPath {
@@ -1206,27 +1223,48 @@ pub enum Attribute {
1206
1223
Unparsed ( Box < AttrItem > ) ,
1207
1224
}
1208
1225
1226
+ pub fn find_attritems_by_name (
1227
+ attrs : & [ Attribute ] ,
1228
+ name : Symbol ,
1229
+ ) -> impl Iterator < Item = & AttrItem > {
1230
+ attrs. iter ( ) . filter_map ( move |attr| match attr {
1231
+ Attribute :: Unparsed ( attr_item) if attr_item. has_name ( name) => Some ( & * * attr_item) ,
1232
+ _ => None ,
1233
+ } )
1234
+ }
1235
+
1209
1236
impl Attribute {
1210
- pub fn get_normal_item ( & self ) -> & AttrItem {
1237
+ pub fn attritem ( self ) -> Option < AttrItem > {
1238
+ match self {
1239
+ Attribute :: Parsed ( _) => None ,
1240
+ Attribute :: Unparsed ( attr_item) => Some ( * attr_item) ,
1241
+ }
1242
+ }
1243
+ pub fn attritem_ref ( & self ) -> Option < & AttrItem > {
1244
+ match self {
1245
+ Attribute :: Parsed ( _) => None ,
1246
+ Attribute :: Unparsed ( attr_item) => Some ( attr_item) ,
1247
+ }
1248
+ }
1249
+
1250
+ pub fn unwrap_attritem_ref ( & self ) -> & AttrItem {
1211
1251
match & self {
1212
1252
Attribute :: Unparsed ( normal) => & normal,
1213
1253
_ => panic ! ( "unexpected parsed attribute" ) ,
1214
1254
}
1215
1255
}
1216
1256
1217
- pub fn unwrap_normal_item ( self ) -> AttrItem {
1257
+ pub fn unwrap_attritem ( self ) -> AttrItem {
1218
1258
match self {
1219
1259
Attribute :: Unparsed ( normal) => * normal,
1220
1260
_ => panic ! ( "unexpected parsed attribute" ) ,
1221
1261
}
1222
1262
}
1223
-
1263
+ }
1264
+ impl AttrItem {
1224
1265
pub fn value_lit ( & self ) -> Option < & MetaItemLit > {
1225
1266
match & self {
1226
- Attribute :: Unparsed ( n) => match n. as_ref ( ) {
1227
- AttrItem { args : AttrArgs :: Eq { eq_span : _, expr } , .. } => Some ( expr) ,
1228
- _ => None ,
1229
- } ,
1267
+ AttrItem { args : AttrArgs :: Eq { eq_span : _, expr } , .. } => Some ( expr) ,
1230
1268
_ => None ,
1231
1269
}
1232
1270
}
@@ -1256,12 +1294,18 @@ impl AttributeExt for Attribute {
1256
1294
1257
1295
#[ inline]
1258
1296
fn value_str ( & self ) -> Option < Symbol > {
1259
- self . value_lit ( ) . and_then ( |x| x. value_str ( ) )
1297
+ match self {
1298
+ Attribute :: Parsed ( _) => None ,
1299
+ Attribute :: Unparsed ( attr_item) => attr_item. value_lit ( ) . and_then ( |x| x. value_str ( ) ) ,
1300
+ }
1260
1301
}
1261
1302
1262
1303
#[ inline]
1263
1304
fn value_span ( & self ) -> Option < Span > {
1264
- self . value_lit ( ) . map ( |i| i. span )
1305
+ match self {
1306
+ Attribute :: Parsed ( _) => None ,
1307
+ Attribute :: Unparsed ( attr_item) => attr_item. value_lit ( ) . map ( |i| i. span ) ,
1308
+ }
1265
1309
}
1266
1310
1267
1311
/// For a single-segment attribute, returns its name; otherwise, returns `None`.
@@ -1355,6 +1399,239 @@ impl AttributeExt for Attribute {
1355
1399
}
1356
1400
}
1357
1401
1402
+ impl AttributeExt for AttrItem {
1403
+ #[ inline]
1404
+ fn id ( & self ) -> AttrId {
1405
+ self . id . attr_id
1406
+ }
1407
+
1408
+ #[ inline]
1409
+ fn meta_item_list ( & self ) -> Option < ThinVec < ast:: MetaItemInner > > {
1410
+ match & self {
1411
+ AttrItem { args : AttrArgs :: Delimited ( d) , .. } => {
1412
+ ast:: MetaItemKind :: list_from_tokens ( d. tokens . clone ( ) )
1413
+ }
1414
+ _ => None ,
1415
+ }
1416
+ }
1417
+
1418
+ #[ inline]
1419
+ fn value_str ( & self ) -> Option < Symbol > {
1420
+ self . value_lit ( ) . and_then ( |x| x. value_str ( ) )
1421
+ }
1422
+
1423
+ #[ inline]
1424
+ fn value_span ( & self ) -> Option < Span > {
1425
+ self . value_lit ( ) . map ( |i| i. span )
1426
+ }
1427
+
1428
+ /// For a single-segment attribute, returns its name; otherwise, returns `None`.
1429
+ #[ inline]
1430
+ fn ident ( & self ) -> Option < Ident > {
1431
+ self . path . ident ( )
1432
+ }
1433
+
1434
+ #[ inline]
1435
+ fn path_matches ( & self , name : & [ Symbol ] ) -> bool {
1436
+ self . path . segments . len ( ) == name. len ( )
1437
+ && self . path . segments . iter ( ) . zip ( name) . all ( |( s, n) | s. name == * n)
1438
+ }
1439
+
1440
+ #[ inline]
1441
+ fn is_doc_comment ( & self ) -> bool {
1442
+ false
1443
+ }
1444
+
1445
+ #[ inline]
1446
+ fn span ( & self ) -> Span {
1447
+ self . span
1448
+ }
1449
+
1450
+ #[ inline]
1451
+ fn is_word ( & self ) -> bool {
1452
+ matches ! ( self . args, AttrArgs :: Empty )
1453
+ }
1454
+
1455
+ #[ inline]
1456
+ fn ident_path ( & self ) -> Option < SmallVec < [ Ident ; 1 ] > > {
1457
+ Some ( self . path . segments . iter ( ) . copied ( ) . collect ( ) )
1458
+ }
1459
+
1460
+ #[ inline]
1461
+ fn doc_str ( & self ) -> Option < Symbol > {
1462
+ if self . has_name ( sym:: doc) { self . value_str ( ) } else { None }
1463
+ }
1464
+ #[ inline]
1465
+ fn doc_str_and_comment_kind ( & self ) -> Option < ( Symbol , CommentKind ) > {
1466
+ if self . has_name ( sym:: doc) {
1467
+ self . value_str ( ) . map ( |s| ( s, CommentKind :: Line ) )
1468
+ } else {
1469
+ None
1470
+ }
1471
+ }
1472
+
1473
+ #[ inline]
1474
+ fn style ( & self ) -> AttrStyle {
1475
+ self . style
1476
+ }
1477
+ }
1478
+
1479
+ // FIXME(fn_delegation): use function delegation instead of manually forwarding
1480
+ impl AttributeExt for & ' _ AttrItem {
1481
+ #[ inline]
1482
+ fn id ( & self ) -> AttrId {
1483
+ <AttrItem as AttributeExt >:: id ( self )
1484
+ }
1485
+
1486
+ #[ inline]
1487
+ fn meta_item_list ( & self ) -> Option < ThinVec < MetaItemInner > > {
1488
+ <AttrItem as AttributeExt >:: meta_item_list ( self )
1489
+ }
1490
+
1491
+ #[ inline]
1492
+ fn value_str ( & self ) -> Option < Symbol > {
1493
+ <AttrItem as AttributeExt >:: value_str ( self )
1494
+ }
1495
+
1496
+ #[ inline]
1497
+ fn value_span ( & self ) -> Option < Span > {
1498
+ <AttrItem as AttributeExt >:: value_span ( self )
1499
+ }
1500
+
1501
+ #[ inline]
1502
+ fn ident ( & self ) -> Option < Ident > {
1503
+ <AttrItem as AttributeExt >:: ident ( self )
1504
+ }
1505
+
1506
+ #[ inline]
1507
+ fn path_matches ( & self , name : & [ Symbol ] ) -> bool {
1508
+ <AttrItem as AttributeExt >:: path_matches ( self , name)
1509
+ }
1510
+
1511
+ #[ inline]
1512
+ fn is_doc_comment ( & self ) -> bool {
1513
+ <AttrItem as AttributeExt >:: is_doc_comment ( self )
1514
+ }
1515
+
1516
+ #[ inline]
1517
+ fn span ( & self ) -> Span {
1518
+ <AttrItem as AttributeExt >:: span ( self )
1519
+ }
1520
+
1521
+ #[ inline]
1522
+ fn is_word ( & self ) -> bool {
1523
+ <AttrItem as AttributeExt >:: is_word ( self )
1524
+ }
1525
+
1526
+ #[ inline]
1527
+ fn ident_path ( & self ) -> Option < SmallVec < [ Ident ; 1 ] > > {
1528
+ <AttrItem as AttributeExt >:: ident_path ( self )
1529
+ }
1530
+
1531
+ #[ inline]
1532
+ fn doc_str ( & self ) -> Option < Symbol > {
1533
+ <AttrItem as AttributeExt >:: doc_str ( self )
1534
+ }
1535
+
1536
+ #[ inline]
1537
+ fn doc_str_and_comment_kind ( & self ) -> Option < ( Symbol , CommentKind ) > {
1538
+ <AttrItem as AttributeExt >:: doc_str_and_comment_kind ( self )
1539
+ }
1540
+
1541
+ #[ inline]
1542
+ fn style ( & self ) -> AttrStyle {
1543
+ <AttrItem as AttributeExt >:: style ( self )
1544
+ }
1545
+ }
1546
+
1547
+ // FIXME(fn_delegation): use function delegation instead of manually forwarding
1548
+ impl AttrItem {
1549
+ #[ inline]
1550
+ pub fn id ( & self ) -> AttrId {
1551
+ <AttrItem as AttributeExt >:: id ( self )
1552
+ }
1553
+
1554
+ #[ inline]
1555
+ pub fn path ( & self ) -> SmallVec < [ Symbol ; 1 ] > {
1556
+ <AttrItem as AttributeExt >:: path ( self )
1557
+ }
1558
+
1559
+ #[ inline]
1560
+ pub fn name ( & self ) -> Option < Symbol > {
1561
+ <AttrItem as AttributeExt >:: name ( self )
1562
+ }
1563
+
1564
+ #[ inline]
1565
+ pub fn has_name ( & self , name : Symbol ) -> bool {
1566
+ <AttrItem as AttributeExt >:: has_name ( self , name)
1567
+ }
1568
+
1569
+ #[ inline]
1570
+ pub fn has_any_name ( & self , names : & [ Symbol ] ) -> bool {
1571
+ <AttrItem as AttributeExt >:: has_any_name ( self , names)
1572
+ }
1573
+
1574
+ #[ inline]
1575
+ pub fn meta_item_list ( & self ) -> Option < ThinVec < MetaItemInner > > {
1576
+ <AttrItem as AttributeExt >:: meta_item_list ( self )
1577
+ }
1578
+
1579
+ #[ inline]
1580
+ pub fn value_str ( & self ) -> Option < Symbol > {
1581
+ <AttrItem as AttributeExt >:: value_str ( self )
1582
+ }
1583
+
1584
+ #[ inline]
1585
+ pub fn value_span ( & self ) -> Option < Span > {
1586
+ <AttrItem as AttributeExt >:: value_span ( self )
1587
+ }
1588
+
1589
+ #[ inline]
1590
+ pub fn ident ( & self ) -> Option < Ident > {
1591
+ <AttrItem as AttributeExt >:: ident ( self )
1592
+ }
1593
+
1594
+ #[ inline]
1595
+ pub fn path_matches ( & self , name : & [ Symbol ] ) -> bool {
1596
+ <AttrItem as AttributeExt >:: path_matches ( self , name)
1597
+ }
1598
+
1599
+ #[ inline]
1600
+ pub fn is_doc_comment ( & self ) -> bool {
1601
+ <AttrItem as AttributeExt >:: is_doc_comment ( self )
1602
+ }
1603
+
1604
+ #[ inline]
1605
+ pub fn span ( & self ) -> Span {
1606
+ <AttrItem as AttributeExt >:: span ( self )
1607
+ }
1608
+
1609
+ #[ inline]
1610
+ pub fn is_word ( & self ) -> bool {
1611
+ <AttrItem as AttributeExt >:: is_word ( self )
1612
+ }
1613
+
1614
+ #[ inline]
1615
+ pub fn ident_path ( & self ) -> Option < SmallVec < [ Ident ; 1 ] > > {
1616
+ <AttrItem as AttributeExt >:: ident_path ( self )
1617
+ }
1618
+
1619
+ #[ inline]
1620
+ pub fn doc_str ( & self ) -> Option < Symbol > {
1621
+ <AttrItem as AttributeExt >:: doc_str ( self )
1622
+ }
1623
+
1624
+ #[ inline]
1625
+ pub fn doc_str_and_comment_kind ( & self ) -> Option < ( Symbol , CommentKind ) > {
1626
+ <AttrItem as AttributeExt >:: doc_str_and_comment_kind ( self )
1627
+ }
1628
+
1629
+ #[ inline]
1630
+ pub fn style ( & self ) -> AttrStyle {
1631
+ <AttrItem as AttributeExt >:: style ( self )
1632
+ }
1633
+ }
1634
+
1358
1635
// FIXME(fn_delegation): use function delegation instead of manually forwarding
1359
1636
impl Attribute {
1360
1637
#[ inline]
0 commit comments