@@ -51,15 +51,18 @@ impl RawAttrs {
51
51
) -> Self {
52
52
let entries: Vec < _ > = collect_attrs ( owner)
53
53
. filter_map ( |( id, attr) | match attr {
54
- Either :: Left ( attr) => {
55
- attr. meta ( ) . and_then ( |meta| Attr :: from_src ( db, meta, span_map, id) )
56
- }
54
+ Either :: Left ( attr) => Attr :: from_src ( db, attr, span_map, id) ,
57
55
Either :: Right ( comment) => comment. doc_comment ( ) . map ( |doc| {
58
56
let span = span_map. span_for_range ( comment. syntax ( ) . text_range ( ) ) ;
59
57
let ( text, kind) =
60
58
desugar_doc_comment_text ( doc, DocCommentDesugarMode :: ProcMacro ) ;
61
59
Attr {
62
60
id,
61
+ place : if comment. is_inner ( ) {
62
+ AttrPlacement :: Inner
63
+ } else {
64
+ AttrPlacement :: Outer
65
+ } ,
63
66
input : Some ( Box :: new ( AttrInput :: Literal ( tt:: Literal {
64
67
symbol : text,
65
68
span,
@@ -147,8 +150,9 @@ impl RawAttrs {
147
150
None => return smallvec ! [ attr. clone( ) ] ,
148
151
} ;
149
152
let index = attr. id ;
153
+ let place = attr. place ;
150
154
let attrs = parts. enumerate ( ) . take ( 1 << AttrId :: CFG_ATTR_BITS ) . filter_map (
151
- |( idx, attr) | Attr :: from_tt ( db, attr, index. with_cfg_attr ( idx) ) ,
155
+ |( idx, attr) | Attr :: from_tt ( db, attr, index. with_cfg_attr ( idx) , place ) ,
152
156
) ;
153
157
154
158
let cfg = TopSubtree :: from_token_trees ( subtree. top_subtree ( ) . delimiter , cfg) ;
@@ -211,6 +215,15 @@ pub struct Attr {
211
215
pub path : Interned < ModPath > ,
212
216
pub input : Option < Box < AttrInput > > ,
213
217
pub ctxt : SyntaxContext ,
218
+ pub place : AttrPlacement ,
219
+ }
220
+
221
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
222
+ pub enum AttrPlacement {
223
+ /// `#![attr]`
224
+ Inner ,
225
+ /// `#[attr]`
226
+ Outer ,
214
227
}
215
228
216
229
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
@@ -233,10 +246,16 @@ impl fmt::Display for AttrInput {
233
246
impl Attr {
234
247
fn from_src (
235
248
db : & dyn ExpandDatabase ,
236
- ast : ast:: Meta ,
249
+ ast_attr : ast:: Attr ,
237
250
span_map : SpanMapRef < ' _ > ,
238
251
id : AttrId ,
239
252
) -> Option < Attr > {
253
+ let ast = ast_attr. meta ( ) ?;
254
+ let place = if ast_attr. excl_token ( ) . is_some ( ) {
255
+ AttrPlacement :: Inner
256
+ } else {
257
+ AttrPlacement :: Outer
258
+ } ;
240
259
let path = ast. path ( ) ?;
241
260
let range = path. syntax ( ) . text_range ( ) ;
242
261
let path = Interned :: new ( ModPath :: from_src ( db, path, & mut |range| {
@@ -257,13 +276,14 @@ impl Attr {
257
276
} else {
258
277
None
259
278
} ;
260
- Some ( Attr { id, path, input, ctxt : span. ctx } )
279
+ Some ( Attr { id, path, input, ctxt : span. ctx , place } )
261
280
}
262
281
263
282
fn from_tt (
264
283
db : & dyn ExpandDatabase ,
265
284
mut tt : tt:: TokenTreesView < ' _ > ,
266
285
id : AttrId ,
286
+ place : AttrPlacement ,
267
287
) -> Option < Attr > {
268
288
if matches ! ( tt. flat_tokens( ) ,
269
289
[ tt:: TokenTree :: Leaf ( tt:: Leaf :: Ident ( tt:: Ident { sym, .. } ) ) , ..]
@@ -314,7 +334,7 @@ impl Attr {
314
334
}
315
335
_ => None ,
316
336
} ;
317
- Some ( Attr { id, path, input, ctxt } )
337
+ Some ( Attr { id, path, input, ctxt, place } )
318
338
}
319
339
320
340
pub fn path ( & self ) -> & ModPath {
0 commit comments