@@ -9,7 +9,7 @@ use mbe::{syntax_node_to_token_tree, DelimiterKind, Punct};
9
9
use smallvec:: { smallvec, SmallVec } ;
10
10
use span:: { Span , SyntaxContextId } ;
11
11
use syntax:: { ast, format_smolstr, match_ast, AstNode , AstToken , SmolStr , SyntaxNode } ;
12
- use triomphe:: Arc ;
12
+ use triomphe:: ThinArc ;
13
13
14
14
use crate :: {
15
15
db:: ExpandDatabase ,
@@ -22,16 +22,15 @@ use crate::{
22
22
/// Syntactical attributes, without filtering of `cfg_attr`s.
23
23
#[ derive( Default , Debug , Clone , PartialEq , Eq ) ]
24
24
pub struct RawAttrs {
25
- // FIXME: Make this a ThinArc
26
- entries : Option < Arc < [ Attr ] > > ,
25
+ entries : Option < ThinArc < ( ) , Attr > > ,
27
26
}
28
27
29
28
impl ops:: Deref for RawAttrs {
30
29
type Target = [ Attr ] ;
31
30
32
31
fn deref ( & self ) -> & [ Attr ] {
33
32
match & self . entries {
34
- Some ( it) => it ,
33
+ Some ( it) => & it . slice ,
35
34
None => & [ ] ,
36
35
}
37
36
}
@@ -45,27 +44,34 @@ impl RawAttrs {
45
44
owner : & dyn ast:: HasAttrs ,
46
45
span_map : SpanMapRef < ' _ > ,
47
46
) -> Self {
48
- let entries = collect_attrs ( owner) . filter_map ( |( id, attr) | match attr {
49
- Either :: Left ( attr) => {
50
- attr. meta ( ) . and_then ( |meta| Attr :: from_src ( db, meta, span_map, id) )
51
- }
52
- Either :: Right ( comment) => comment. doc_comment ( ) . map ( |doc| {
53
- let span = span_map. span_for_range ( comment. syntax ( ) . text_range ( ) ) ;
54
- Attr {
55
- id,
56
- input : Some ( Interned :: new ( AttrInput :: Literal ( tt:: Literal {
57
- // FIXME: Escape quotes from comment content
58
- text : SmolStr :: new ( format_smolstr ! ( "\" {doc}\" " , ) ) ,
59
- span,
60
- } ) ) ) ,
61
- path : Interned :: new ( ModPath :: from ( crate :: name!( doc) ) ) ,
62
- ctxt : span. ctx ,
47
+ let entries: Vec < _ > = collect_attrs ( owner)
48
+ . filter_map ( |( id, attr) | match attr {
49
+ Either :: Left ( attr) => {
50
+ attr. meta ( ) . and_then ( |meta| Attr :: from_src ( db, meta, span_map, id) )
63
51
}
64
- } ) ,
65
- } ) ;
66
- let entries: Arc < [ Attr ] > = Arc :: from_iter ( entries) ;
52
+ Either :: Right ( comment) => comment. doc_comment ( ) . map ( |doc| {
53
+ let span = span_map. span_for_range ( comment. syntax ( ) . text_range ( ) ) ;
54
+ Attr {
55
+ id,
56
+ input : Some ( Interned :: new ( AttrInput :: Literal ( tt:: Literal {
57
+ // FIXME: Escape quotes from comment content
58
+ text : SmolStr :: new ( format_smolstr ! ( "\" {doc}\" " , ) ) ,
59
+ span,
60
+ } ) ) ) ,
61
+ path : Interned :: new ( ModPath :: from ( crate :: name!( doc) ) ) ,
62
+ ctxt : span. ctx ,
63
+ }
64
+ } ) ,
65
+ } )
66
+ . collect ( ) ;
67
67
68
- Self { entries : if entries. is_empty ( ) { None } else { Some ( entries) } }
68
+ let entries = if entries. is_empty ( ) {
69
+ None
70
+ } else {
71
+ Some ( ThinArc :: from_header_and_iter ( ( ) , entries. into_iter ( ) ) )
72
+ } ;
73
+
74
+ RawAttrs { entries }
69
75
}
70
76
71
77
pub fn from_attrs_owner (
@@ -82,16 +88,20 @@ impl RawAttrs {
82
88
( None , entries @ Some ( _) ) => Self { entries } ,
83
89
( Some ( entries) , None ) => Self { entries : Some ( entries. clone ( ) ) } ,
84
90
( Some ( a) , Some ( b) ) => {
85
- let last_ast_index = a. last ( ) . map_or ( 0 , |it| it. id . ast_index ( ) + 1 ) as u32 ;
86
- Self {
87
- entries : Some ( Arc :: from_iter ( a. iter ( ) . cloned ( ) . chain ( b. iter ( ) . map ( |it| {
91
+ let last_ast_index = a. slice . last ( ) . map_or ( 0 , |it| it. id . ast_index ( ) + 1 ) as u32 ;
92
+ let items = a
93
+ . slice
94
+ . iter ( )
95
+ . cloned ( )
96
+ . chain ( b. slice . iter ( ) . map ( |it| {
88
97
let mut it = it. clone ( ) ;
89
98
it. id . id = ( it. id . ast_index ( ) as u32 + last_ast_index)
90
99
| ( it. id . cfg_attr_index ( ) . unwrap_or ( 0 ) as u32 )
91
100
<< AttrId :: AST_INDEX_BITS ;
92
101
it
93
- } ) ) ) ) ,
94
- }
102
+ } ) )
103
+ . collect :: < Vec < _ > > ( ) ;
104
+ Self { entries : Some ( ThinArc :: from_header_and_iter ( ( ) , items. into_iter ( ) ) ) }
95
105
}
96
106
}
97
107
}
@@ -107,41 +117,47 @@ impl RawAttrs {
107
117
}
108
118
109
119
let crate_graph = db. crate_graph ( ) ;
110
- let new_attrs = Arc :: from_iter ( self . iter ( ) . flat_map ( |attr| -> SmallVec < [ _ ; 1 ] > {
111
- let is_cfg_attr =
112
- attr. path . as_ident ( ) . map_or ( false , |name| * name == crate :: name![ cfg_attr] ) ;
113
- if !is_cfg_attr {
114
- return smallvec ! [ attr. clone( ) ] ;
115
- }
116
-
117
- let subtree = match attr. token_tree_value ( ) {
118
- Some ( it) => it,
119
- _ => return smallvec ! [ attr. clone( ) ] ,
120
- } ;
121
-
122
- let ( cfg, parts) = match parse_cfg_attr_input ( subtree) {
123
- Some ( it) => it,
124
- None => return smallvec ! [ attr. clone( ) ] ,
125
- } ;
126
- let index = attr. id ;
127
- let attrs = parts
128
- . enumerate ( )
129
- . take ( 1 << AttrId :: CFG_ATTR_BITS )
130
- . filter_map ( |( idx, attr) | Attr :: from_tt ( db, attr, index. with_cfg_attr ( idx) ) ) ;
131
-
132
- let cfg_options = & crate_graph[ krate] . cfg_options ;
133
- let cfg = Subtree { delimiter : subtree. delimiter , token_trees : Box :: from ( cfg) } ;
134
- let cfg = CfgExpr :: parse ( & cfg) ;
135
- if cfg_options. check ( & cfg) == Some ( false ) {
136
- smallvec ! [ ]
137
- } else {
138
- cov_mark:: hit!( cfg_attr_active) ;
139
-
140
- attrs. collect ( )
141
- }
142
- } ) ) ;
120
+ let new_attrs =
121
+ self . iter ( )
122
+ . flat_map ( |attr| -> SmallVec < [ _ ; 1 ] > {
123
+ let is_cfg_attr =
124
+ attr. path . as_ident ( ) . map_or ( false , |name| * name == crate :: name![ cfg_attr] ) ;
125
+ if !is_cfg_attr {
126
+ return smallvec ! [ attr. clone( ) ] ;
127
+ }
143
128
144
- RawAttrs { entries : Some ( new_attrs) }
129
+ let subtree = match attr. token_tree_value ( ) {
130
+ Some ( it) => it,
131
+ _ => return smallvec ! [ attr. clone( ) ] ,
132
+ } ;
133
+
134
+ let ( cfg, parts) = match parse_cfg_attr_input ( subtree) {
135
+ Some ( it) => it,
136
+ None => return smallvec ! [ attr. clone( ) ] ,
137
+ } ;
138
+ let index = attr. id ;
139
+ let attrs = parts. enumerate ( ) . take ( 1 << AttrId :: CFG_ATTR_BITS ) . filter_map (
140
+ |( idx, attr) | Attr :: from_tt ( db, attr, index. with_cfg_attr ( idx) ) ,
141
+ ) ;
142
+
143
+ let cfg_options = & crate_graph[ krate] . cfg_options ;
144
+ let cfg = Subtree { delimiter : subtree. delimiter , token_trees : Box :: from ( cfg) } ;
145
+ let cfg = CfgExpr :: parse ( & cfg) ;
146
+ if cfg_options. check ( & cfg) == Some ( false ) {
147
+ smallvec ! [ ]
148
+ } else {
149
+ cov_mark:: hit!( cfg_attr_active) ;
150
+
151
+ attrs. collect ( )
152
+ }
153
+ } )
154
+ . collect :: < Vec < _ > > ( ) ;
155
+ let entries = if new_attrs. is_empty ( ) {
156
+ None
157
+ } else {
158
+ Some ( ThinArc :: from_header_and_iter ( ( ) , new_attrs. into_iter ( ) ) )
159
+ } ;
160
+ RawAttrs { entries }
145
161
}
146
162
}
147
163
0 commit comments