rust_analyzer_modules/
item.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5use ra_ap_hir::{self as hir};
6use ra_ap_ide::{self as ide};
7
8use crate::analyzer;
9
10pub(crate) use self::{
11    attr::{ItemAttrs, ItemCfgAttr, ItemTestAttr},
12    kind_display_name::ItemKindDisplayName,
13    visibility::ItemVisibility,
14};
15
16mod attr;
17mod kind_display_name;
18mod visibility;
19
20#[derive(Clone, PartialEq, Debug)]
21pub struct Item {
22    pub hir: hir::ModuleDef,
23}
24
25impl Item {
26    pub fn new(hir: hir::ModuleDef) -> Self {
27        Self { hir }
28    }
29
30    pub fn visibility(&self, db: &ide::RootDatabase, edition: ide::Edition) -> ItemVisibility {
31        ItemVisibility::new(self.hir, db, edition)
32    }
33
34    pub fn attrs(&self, db: &ide::RootDatabase, _edition: ide::Edition) -> ItemAttrs {
35        ItemAttrs::new(self, db)
36    }
37
38    pub fn kind_display_name(
39        &self,
40        db: &ide::RootDatabase,
41        _edition: ide::Edition,
42    ) -> ItemKindDisplayName {
43        ItemKindDisplayName::new(self, db)
44    }
45
46    pub fn display_name(&self, db: &ide::RootDatabase, edition: ide::Edition) -> String {
47        analyzer::display_name(self.hir, db, edition)
48    }
49
50    pub fn display_path(&self, db: &ide::RootDatabase, edition: ide::Edition) -> String {
51        analyzer::display_path(self.hir, db, edition)
52    }
53
54    pub fn kind_ordering(&self, _db: &ide::RootDatabase, _edition: ide::Edition) -> u8 {
55        // Return ordering based on item kind for sorting
56        // Lower numbers come first
57        match self.hir {
58            hir::ModuleDef::Module(_) => 0,
59            hir::ModuleDef::Trait(_) => 1,
60            hir::ModuleDef::TraitAlias(_) => 2,
61            hir::ModuleDef::Adt(adt) => match adt {
62                hir::Adt::Struct(_) => 3,
63                hir::Adt::Enum(_) => 4,
64                hir::Adt::Union(_) => 5,
65            },
66            hir::ModuleDef::Variant(_) => 6,
67            hir::ModuleDef::Const(_) => 7,
68            hir::ModuleDef::Static(_) => 8,
69            hir::ModuleDef::Function(_) => 9,
70            hir::ModuleDef::TypeAlias(_) => 10,
71            hir::ModuleDef::BuiltinType(_) => 11,
72            hir::ModuleDef::Macro(_) => 12,
73        }
74    }
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80
81    #[test]
82    fn test_item_creation() {
83        // We can't create a real ModuleDef without a database, but we can test the struct
84        // This is more of a compile-time test to ensure the API is correct
85        let _ = |hir: hir::ModuleDef| {
86            let item = Item::new(hir);
87            assert!(matches!(item.hir, _));
88        };
89    }
90
91    #[test]
92    fn test_kind_ordering() {
93        // Test that kind ordering returns expected values
94        let _ = |item: &Item, db: &ide::RootDatabase, edition: ide::Edition| {
95            let ordering = item.kind_ordering(db, edition);
96            match item.hir {
97                hir::ModuleDef::Module(_) => assert_eq!(ordering, 0),
98                hir::ModuleDef::Trait(_) => assert_eq!(ordering, 1),
99                hir::ModuleDef::TraitAlias(_) => assert_eq!(ordering, 2),
100                hir::ModuleDef::Adt(adt) => match adt {
101                    hir::Adt::Struct(_) => assert_eq!(ordering, 3),
102                    hir::Adt::Enum(_) => assert_eq!(ordering, 4),
103                    hir::Adt::Union(_) => assert_eq!(ordering, 5),
104                },
105                hir::ModuleDef::Variant(_) => assert_eq!(ordering, 6),
106                hir::ModuleDef::Const(_) => assert_eq!(ordering, 7),
107                hir::ModuleDef::Static(_) => assert_eq!(ordering, 8),
108                hir::ModuleDef::Function(_) => assert_eq!(ordering, 9),
109                hir::ModuleDef::TypeAlias(_) => assert_eq!(ordering, 10),
110                hir::ModuleDef::BuiltinType(_) => assert_eq!(ordering, 11),
111                hir::ModuleDef::Macro(_) => assert_eq!(ordering, 12),
112            }
113        };
114    }
115
116    #[test]
117    fn test_item_equality() {
118        // Items should be equal if they have the same HIR
119        let _ = |hir1: hir::ModuleDef, hir2: hir::ModuleDef| {
120            let item1 = Item::new(hir1);
121            let item2 = Item::new(hir2);
122
123            if hir1 == hir2 {
124                assert_eq!(item1, item2);
125            } else {
126                assert_ne!(item1, item2);
127            }
128        };
129    }
130}