@@ -21,7 +21,7 @@ use crate::{
21
21
item_tree:: { ItemTreeId , ItemTreeNode } ,
22
22
nameres:: ModuleSource ,
23
23
path:: { ModPath , PathKind } ,
24
- src:: HasChildSource ,
24
+ src:: { HasChildSource , HasSource } ,
25
25
AdtId , AttrDefId , EnumId , GenericParamId , HasModule , LocalEnumVariantId , LocalFieldId , Lookup ,
26
26
VariantId ,
27
27
} ;
@@ -51,6 +51,12 @@ pub(crate) struct RawAttrs {
51
51
#[ derive( Default , Debug , Clone , PartialEq , Eq ) ]
52
52
pub struct Attrs ( RawAttrs ) ;
53
53
54
+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
55
+ pub struct AttrsWithOwner {
56
+ attrs : Attrs ,
57
+ owner : AttrDefId ,
58
+ }
59
+
54
60
impl ops:: Deref for RawAttrs {
55
61
type Target = [ Attr ] ;
56
62
@@ -73,6 +79,14 @@ impl ops::Deref for Attrs {
73
79
}
74
80
}
75
81
82
+ impl ops:: Deref for AttrsWithOwner {
83
+ type Target = Attrs ;
84
+
85
+ fn deref ( & self ) -> & Attrs {
86
+ & self . attrs
87
+ }
88
+ }
89
+
76
90
impl RawAttrs {
77
91
pub ( crate ) const EMPTY : Self = Self { entries : None } ;
78
92
@@ -169,78 +183,6 @@ impl RawAttrs {
169
183
impl Attrs {
170
184
pub const EMPTY : Self = Self ( RawAttrs :: EMPTY ) ;
171
185
172
- pub ( crate ) fn attrs_query ( db : & dyn DefDatabase , def : AttrDefId ) -> Attrs {
173
- let raw_attrs = match def {
174
- AttrDefId :: ModuleId ( module) => {
175
- let def_map = module. def_map ( db) ;
176
- let mod_data = & def_map[ module. local_id ] ;
177
- match mod_data. declaration_source ( db) {
178
- Some ( it) => {
179
- let raw_attrs = RawAttrs :: from_attrs_owner (
180
- db,
181
- it. as_ref ( ) . map ( |it| it as & dyn ast:: AttrsOwner ) ,
182
- ) ;
183
- match mod_data. definition_source ( db) {
184
- InFile { file_id, value : ModuleSource :: SourceFile ( file) } => raw_attrs
185
- . merge ( RawAttrs :: from_attrs_owner ( db, InFile :: new ( file_id, & file) ) ) ,
186
- _ => raw_attrs,
187
- }
188
- }
189
- None => RawAttrs :: from_attrs_owner (
190
- db,
191
- mod_data. definition_source ( db) . as_ref ( ) . map ( |src| match src {
192
- ModuleSource :: SourceFile ( file) => file as & dyn ast:: AttrsOwner ,
193
- ModuleSource :: Module ( module) => module as & dyn ast:: AttrsOwner ,
194
- ModuleSource :: BlockExpr ( block) => block as & dyn ast:: AttrsOwner ,
195
- } ) ,
196
- ) ,
197
- }
198
- }
199
- AttrDefId :: FieldId ( it) => {
200
- return db. fields_attrs ( it. parent ) [ it. local_id ] . clone ( ) ;
201
- }
202
- AttrDefId :: EnumVariantId ( it) => {
203
- return db. variants_attrs ( it. parent ) [ it. local_id ] . clone ( ) ;
204
- }
205
- AttrDefId :: AdtId ( it) => match it {
206
- AdtId :: StructId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
207
- AdtId :: EnumId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
208
- AdtId :: UnionId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
209
- } ,
210
- AttrDefId :: TraitId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
211
- AttrDefId :: MacroDefId ( it) => it
212
- . ast_id ( )
213
- . left ( )
214
- . map_or_else ( Default :: default, |ast_id| attrs_from_ast ( ast_id, db) ) ,
215
- AttrDefId :: ImplId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
216
- AttrDefId :: ConstId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
217
- AttrDefId :: StaticId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
218
- AttrDefId :: FunctionId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
219
- AttrDefId :: TypeAliasId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
220
- AttrDefId :: GenericParamId ( it) => match it {
221
- GenericParamId :: TypeParamId ( it) => {
222
- let src = it. parent . child_source ( db) ;
223
- RawAttrs :: from_attrs_owner (
224
- db,
225
- src. with_value (
226
- src. value [ it. local_id ] . as_ref ( ) . either ( |it| it as _ , |it| it as _ ) ,
227
- ) ,
228
- )
229
- }
230
- GenericParamId :: LifetimeParamId ( it) => {
231
- let src = it. parent . child_source ( db) ;
232
- RawAttrs :: from_attrs_owner ( db, src. with_value ( & src. value [ it. local_id ] ) )
233
- }
234
- GenericParamId :: ConstParamId ( it) => {
235
- let src = it. parent . child_source ( db) ;
236
- RawAttrs :: from_attrs_owner ( db, src. with_value ( & src. value [ it. local_id ] ) )
237
- }
238
- } ,
239
- } ;
240
-
241
- raw_attrs. filter ( db, def. krate ( db) )
242
- }
243
-
244
186
pub ( crate ) fn variants_attrs_query (
245
187
db : & dyn DefDatabase ,
246
188
e : EnumId ,
@@ -281,56 +223,6 @@ impl Attrs {
281
223
Arc :: new ( res)
282
224
}
283
225
284
- /// Constructs a map that maps the lowered `Attr`s in this `Attrs` back to its original syntax nodes.
285
- ///
286
- /// `owner` must be the original owner of the attributes.
287
- // FIXME: figure out a better api that doesnt require the for_module hack
288
- pub fn source_map ( & self , owner : InFile < & dyn ast:: AttrsOwner > ) -> AttrSourceMap {
289
- // FIXME: This doesn't work correctly for modules, as the attributes there can have up to
290
- // two different owners
291
- AttrSourceMap {
292
- attrs : collect_attrs ( owner. value )
293
- . map ( |attr| InFile :: new ( owner. file_id , attr) )
294
- . collect ( ) ,
295
- }
296
- }
297
-
298
- pub fn source_map_for_module (
299
- & self ,
300
- db : & dyn DefDatabase ,
301
- module : crate :: ModuleId ,
302
- ) -> AttrSourceMap {
303
- let def_map = module. def_map ( db) ;
304
- let mod_data = & def_map[ module. local_id ] ;
305
- let attrs = match mod_data. declaration_source ( db) {
306
- Some ( it) => {
307
- let mut attrs: Vec < _ > = collect_attrs ( & it. value as & dyn ast:: AttrsOwner )
308
- . map ( |attr| InFile :: new ( it. file_id , attr) )
309
- . collect ( ) ;
310
- if let InFile { file_id, value : ModuleSource :: SourceFile ( file) } =
311
- mod_data. definition_source ( db)
312
- {
313
- attrs. extend (
314
- collect_attrs ( & file as & dyn ast:: AttrsOwner )
315
- . map ( |attr| InFile :: new ( file_id, attr) ) ,
316
- )
317
- }
318
- attrs
319
- }
320
- None => {
321
- let InFile { file_id, value } = mod_data. definition_source ( db) ;
322
- match & value {
323
- ModuleSource :: SourceFile ( file) => collect_attrs ( file as & dyn ast:: AttrsOwner ) ,
324
- ModuleSource :: Module ( module) => collect_attrs ( module as & dyn ast:: AttrsOwner ) ,
325
- ModuleSource :: BlockExpr ( block) => collect_attrs ( block as & dyn ast:: AttrsOwner ) ,
326
- }
327
- . map ( |attr| InFile :: new ( file_id, attr) )
328
- . collect ( )
329
- }
330
- } ;
331
- AttrSourceMap { attrs }
332
- }
333
-
334
226
pub fn by_key ( & self , key : & ' static str ) -> AttrQuery < ' _ > {
335
227
AttrQuery { attrs : self , key }
336
228
}
@@ -387,6 +279,180 @@ impl Attrs {
387
279
}
388
280
}
389
281
282
+ impl AttrsWithOwner {
283
+ pub ( crate ) fn attrs_query ( db : & dyn DefDatabase , def : AttrDefId ) -> Self {
284
+ // FIXME: this should use `Trace` to avoid duplication in `source_map` below
285
+ let raw_attrs = match def {
286
+ AttrDefId :: ModuleId ( module) => {
287
+ let def_map = module. def_map ( db) ;
288
+ let mod_data = & def_map[ module. local_id ] ;
289
+ match mod_data. declaration_source ( db) {
290
+ Some ( it) => {
291
+ let raw_attrs = RawAttrs :: from_attrs_owner (
292
+ db,
293
+ it. as_ref ( ) . map ( |it| it as & dyn ast:: AttrsOwner ) ,
294
+ ) ;
295
+ match mod_data. definition_source ( db) {
296
+ InFile { file_id, value : ModuleSource :: SourceFile ( file) } => raw_attrs
297
+ . merge ( RawAttrs :: from_attrs_owner ( db, InFile :: new ( file_id, & file) ) ) ,
298
+ _ => raw_attrs,
299
+ }
300
+ }
301
+ None => RawAttrs :: from_attrs_owner (
302
+ db,
303
+ mod_data. definition_source ( db) . as_ref ( ) . map ( |src| match src {
304
+ ModuleSource :: SourceFile ( file) => file as & dyn ast:: AttrsOwner ,
305
+ ModuleSource :: Module ( module) => module as & dyn ast:: AttrsOwner ,
306
+ ModuleSource :: BlockExpr ( block) => block as & dyn ast:: AttrsOwner ,
307
+ } ) ,
308
+ ) ,
309
+ }
310
+ }
311
+ AttrDefId :: FieldId ( it) => {
312
+ return Self { attrs : db. fields_attrs ( it. parent ) [ it. local_id ] . clone ( ) , owner : def } ;
313
+ }
314
+ AttrDefId :: EnumVariantId ( it) => {
315
+ return Self {
316
+ attrs : db. variants_attrs ( it. parent ) [ it. local_id ] . clone ( ) ,
317
+ owner : def,
318
+ } ;
319
+ }
320
+ AttrDefId :: AdtId ( it) => match it {
321
+ AdtId :: StructId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
322
+ AdtId :: EnumId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
323
+ AdtId :: UnionId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
324
+ } ,
325
+ AttrDefId :: TraitId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
326
+ AttrDefId :: MacroDefId ( it) => it
327
+ . ast_id ( )
328
+ . left ( )
329
+ . map_or_else ( Default :: default, |ast_id| attrs_from_ast ( ast_id, db) ) ,
330
+ AttrDefId :: ImplId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
331
+ AttrDefId :: ConstId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
332
+ AttrDefId :: StaticId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
333
+ AttrDefId :: FunctionId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
334
+ AttrDefId :: TypeAliasId ( it) => attrs_from_item_tree ( it. lookup ( db) . id , db) ,
335
+ AttrDefId :: GenericParamId ( it) => match it {
336
+ GenericParamId :: TypeParamId ( it) => {
337
+ let src = it. parent . child_source ( db) ;
338
+ RawAttrs :: from_attrs_owner (
339
+ db,
340
+ src. with_value (
341
+ src. value [ it. local_id ] . as_ref ( ) . either ( |it| it as _ , |it| it as _ ) ,
342
+ ) ,
343
+ )
344
+ }
345
+ GenericParamId :: LifetimeParamId ( it) => {
346
+ let src = it. parent . child_source ( db) ;
347
+ RawAttrs :: from_attrs_owner ( db, src. with_value ( & src. value [ it. local_id ] ) )
348
+ }
349
+ GenericParamId :: ConstParamId ( it) => {
350
+ let src = it. parent . child_source ( db) ;
351
+ RawAttrs :: from_attrs_owner ( db, src. with_value ( & src. value [ it. local_id ] ) )
352
+ }
353
+ } ,
354
+ } ;
355
+
356
+ let attrs = raw_attrs. filter ( db, def. krate ( db) ) ;
357
+ Self { attrs, owner : def }
358
+ }
359
+
360
+ pub fn source_map ( & self , db : & dyn DefDatabase ) -> AttrSourceMap {
361
+ let owner = match self . owner {
362
+ AttrDefId :: ModuleId ( module) => {
363
+ // Modules can have 2 attribute owners (the `mod x;` item, and the module file itself).
364
+
365
+ let def_map = module. def_map ( db) ;
366
+ let mod_data = & def_map[ module. local_id ] ;
367
+ let attrs = match mod_data. declaration_source ( db) {
368
+ Some ( it) => {
369
+ let mut attrs: Vec < _ > = collect_attrs ( & it. value as & dyn ast:: AttrsOwner )
370
+ . map ( |attr| InFile :: new ( it. file_id , attr) )
371
+ . collect ( ) ;
372
+ if let InFile { file_id, value : ModuleSource :: SourceFile ( file) } =
373
+ mod_data. definition_source ( db)
374
+ {
375
+ attrs. extend (
376
+ collect_attrs ( & file as & dyn ast:: AttrsOwner )
377
+ . map ( |attr| InFile :: new ( file_id, attr) ) ,
378
+ )
379
+ }
380
+ attrs
381
+ }
382
+ None => {
383
+ let InFile { file_id, value } = mod_data. definition_source ( db) ;
384
+ match & value {
385
+ ModuleSource :: SourceFile ( file) => {
386
+ collect_attrs ( file as & dyn ast:: AttrsOwner )
387
+ }
388
+ ModuleSource :: Module ( module) => {
389
+ collect_attrs ( module as & dyn ast:: AttrsOwner )
390
+ }
391
+ ModuleSource :: BlockExpr ( block) => {
392
+ collect_attrs ( block as & dyn ast:: AttrsOwner )
393
+ }
394
+ }
395
+ . map ( |attr| InFile :: new ( file_id, attr) )
396
+ . collect ( )
397
+ }
398
+ } ;
399
+ return AttrSourceMap { attrs } ;
400
+ }
401
+ AttrDefId :: FieldId ( id) => {
402
+ id. parent . child_source ( db) . map ( |source| match & source[ id. local_id ] {
403
+ Either :: Left ( field) => ast:: AttrsOwnerNode :: new ( field. clone ( ) ) ,
404
+ Either :: Right ( field) => ast:: AttrsOwnerNode :: new ( field. clone ( ) ) ,
405
+ } )
406
+ }
407
+ AttrDefId :: AdtId ( adt) => match adt {
408
+ AdtId :: StructId ( id) => id. lookup ( db) . source ( db) . map ( ast:: AttrsOwnerNode :: new) ,
409
+ AdtId :: UnionId ( id) => id. lookup ( db) . source ( db) . map ( ast:: AttrsOwnerNode :: new) ,
410
+ AdtId :: EnumId ( id) => id. lookup ( db) . source ( db) . map ( ast:: AttrsOwnerNode :: new) ,
411
+ } ,
412
+ AttrDefId :: FunctionId ( id) => id. lookup ( db) . source ( db) . map ( ast:: AttrsOwnerNode :: new) ,
413
+ AttrDefId :: EnumVariantId ( id) => id
414
+ . parent
415
+ . child_source ( db)
416
+ . map ( |source| ast:: AttrsOwnerNode :: new ( source[ id. local_id ] . clone ( ) ) ) ,
417
+ AttrDefId :: StaticId ( id) => id. lookup ( db) . source ( db) . map ( ast:: AttrsOwnerNode :: new) ,
418
+ AttrDefId :: ConstId ( id) => id. lookup ( db) . source ( db) . map ( ast:: AttrsOwnerNode :: new) ,
419
+ AttrDefId :: TraitId ( id) => id. lookup ( db) . source ( db) . map ( ast:: AttrsOwnerNode :: new) ,
420
+ AttrDefId :: TypeAliasId ( id) => id. lookup ( db) . source ( db) . map ( ast:: AttrsOwnerNode :: new) ,
421
+ AttrDefId :: MacroDefId ( id) => match id. ast_id ( ) {
422
+ Either :: Left ( it) => {
423
+ it. with_value ( ast:: AttrsOwnerNode :: new ( it. to_node ( db. upcast ( ) ) ) )
424
+ }
425
+ Either :: Right ( it) => {
426
+ it. with_value ( ast:: AttrsOwnerNode :: new ( it. to_node ( db. upcast ( ) ) ) )
427
+ }
428
+ } ,
429
+ AttrDefId :: ImplId ( id) => id. lookup ( db) . source ( db) . map ( ast:: AttrsOwnerNode :: new) ,
430
+ AttrDefId :: GenericParamId ( id) => match id {
431
+ GenericParamId :: TypeParamId ( id) => {
432
+ id. parent . child_source ( db) . map ( |source| match & source[ id. local_id ] {
433
+ Either :: Left ( id) => ast:: AttrsOwnerNode :: new ( id. clone ( ) ) ,
434
+ Either :: Right ( id) => ast:: AttrsOwnerNode :: new ( id. clone ( ) ) ,
435
+ } )
436
+ }
437
+ GenericParamId :: LifetimeParamId ( id) => id
438
+ . parent
439
+ . child_source ( db)
440
+ . map ( |source| ast:: AttrsOwnerNode :: new ( source[ id. local_id ] . clone ( ) ) ) ,
441
+ GenericParamId :: ConstParamId ( id) => id
442
+ . parent
443
+ . child_source ( db)
444
+ . map ( |source| ast:: AttrsOwnerNode :: new ( source[ id. local_id ] . clone ( ) ) ) ,
445
+ } ,
446
+ } ;
447
+
448
+ AttrSourceMap {
449
+ attrs : collect_attrs ( & owner. value )
450
+ . map ( |attr| InFile :: new ( owner. file_id , attr) )
451
+ . collect ( ) ,
452
+ }
453
+ }
454
+ }
455
+
390
456
fn inner_attributes (
391
457
syntax : & SyntaxNode ,
392
458
) -> Option < ( impl Iterator < Item = ast:: Attr > , impl Iterator < Item = ast:: Comment > ) > {
0 commit comments