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