@@ -117,14 +117,10 @@ impl RawAttrs {
117
117
None => return smallvec ! [ attr. clone( ) ] ,
118
118
} ;
119
119
let index = attr. id ;
120
- let attrs =
121
- parts. enumerate ( ) . take ( 1 << AttrId :: CFG_ATTR_BITS ) . filter_map ( |( idx, attr) | {
122
- let tree = Subtree {
123
- delimiter : tt:: Delimiter :: invisible_spanned ( attr. first ( ) ?. first_span ( ) ) ,
124
- token_trees : attr. to_vec ( ) ,
125
- } ;
126
- Attr :: from_tt ( db, & tree, index. with_cfg_attr ( idx) )
127
- } ) ;
120
+ let attrs = parts
121
+ . enumerate ( )
122
+ . take ( 1 << AttrId :: CFG_ATTR_BITS )
123
+ . filter_map ( |( idx, attr) | Attr :: from_tt ( db, attr, index. with_cfg_attr ( idx) ) ) ;
128
124
129
125
let cfg_options = & crate_graph[ krate] . cfg_options ;
130
126
let cfg = Subtree { delimiter : subtree. delimiter , token_trees : cfg. to_vec ( ) } ;
@@ -222,12 +218,41 @@ impl Attr {
222
218
Some ( Attr { id, path, input, span } )
223
219
}
224
220
225
- fn from_tt ( db : & dyn ExpandDatabase , tt : & tt:: Subtree , id : AttrId ) -> Option < Attr > {
226
- // FIXME: Unecessary roundtrip tt -> ast -> tt
227
- let ( parse, map) = mbe:: token_tree_to_syntax_node ( tt, mbe:: TopEntryPoint :: MetaItem ) ;
228
- let ast = ast:: Meta :: cast ( parse. syntax_node ( ) ) ?;
229
-
230
- Self :: from_src ( db, ast, SpanMapRef :: ExpansionSpanMap ( & map) , id)
221
+ fn from_tt ( db : & dyn ExpandDatabase , tt : & [ tt:: TokenTree ] , id : AttrId ) -> Option < Attr > {
222
+ dbg ! ( tt) ;
223
+ let span = tt. first ( ) ?. first_span ( ) ;
224
+ let path_end = tt
225
+ . iter ( )
226
+ . position ( |tt| {
227
+ !matches ! (
228
+ tt,
229
+ tt:: TokenTree :: Leaf (
230
+ tt:: Leaf :: Punct ( tt:: Punct { char : ':' | '$' , .. } ) | tt:: Leaf :: Ident ( _) ,
231
+ )
232
+ )
233
+ } )
234
+ . unwrap_or_else ( || tt. len ( ) ) ;
235
+
236
+ let ( path, input) = tt. split_at ( path_end) ;
237
+ let path = Interned :: new ( ModPath :: from_tt ( db, path) ?) ;
238
+
239
+ let input = match input. get ( 0 ) {
240
+ Some ( tt:: TokenTree :: Subtree ( tree) ) => {
241
+ Some ( Interned :: new ( AttrInput :: TokenTree ( Box :: new ( tree. clone ( ) ) ) ) )
242
+ }
243
+ Some ( tt:: TokenTree :: Leaf ( tt:: Leaf :: Punct ( tt:: Punct { char : '=' , .. } ) ) ) => {
244
+ let input = match input. get ( 1 ) {
245
+ Some ( tt:: TokenTree :: Leaf ( tt:: Leaf :: Literal ( tt:: Literal { text, .. } ) ) ) => {
246
+ //FIXME the trimming here isn't quite right, raw strings are not handled
247
+ Some ( Interned :: new ( AttrInput :: Literal ( text. trim_matches ( '"' ) . into ( ) ) ) )
248
+ }
249
+ _ => None ,
250
+ } ;
251
+ input
252
+ }
253
+ _ => None ,
254
+ } ;
255
+ Some ( Attr { id, path, input, span } )
231
256
}
232
257
233
258
pub fn path ( & self ) -> & ModPath {
@@ -277,29 +302,8 @@ impl Attr {
277
302
. token_trees
278
303
. split ( |tt| matches ! ( tt, tt:: TokenTree :: Leaf ( tt:: Leaf :: Punct ( Punct { char : ',' , .. } ) ) ) )
279
304
. filter_map ( move |tts| {
280
- if tts. is_empty ( ) {
281
- return None ;
282
- }
283
- // FIXME: This is necessarily a hack. It'd be nice if we could avoid allocation
284
- // here or maybe just parse a mod path from a token tree directly
285
- let subtree = tt:: Subtree {
286
- delimiter : tt:: Delimiter :: invisible_spanned ( tts. first ( ) ?. first_span ( ) ) ,
287
- token_trees : tts. to_vec ( ) ,
288
- } ;
289
- let ( parse, span_map) =
290
- mbe:: token_tree_to_syntax_node ( & subtree, mbe:: TopEntryPoint :: MetaItem ) ;
291
- let meta = ast:: Meta :: cast ( parse. syntax_node ( ) ) ?;
292
- // Only simple paths are allowed.
293
- if meta. eq_token ( ) . is_some ( ) || meta. expr ( ) . is_some ( ) || meta. token_tree ( ) . is_some ( )
294
- {
295
- return None ;
296
- }
297
- let path = meta. path ( ) ?;
298
- let call_site = span_map. span_at ( path. syntax ( ) . text_range ( ) . start ( ) ) ;
299
- Some ( (
300
- ModPath :: from_src ( db, path, SpanMapRef :: ExpansionSpanMap ( & span_map) ) ?,
301
- call_site,
302
- ) )
305
+ let span = tts. first ( ) ?. first_span ( ) ;
306
+ Some ( ( ModPath :: from_tt ( db, tts) ?, span) )
303
307
} ) ;
304
308
305
309
Some ( paths)
0 commit comments