emmylua_code_analysis/db_index/property/
property.rs

1use std::sync::Arc;
2
3use emmylua_parser::{LuaVersionCondition, VisibilityKind};
4
5use crate::{
6    LuaType, LuaTypeDeclId,
7    db_index::property::decl_feature::{DeclFeatureFlag, PropertyDeclFeature},
8};
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct LuaCommonProperty {
12    pub visibility: VisibilityKind,
13    pub description: Option<Box<String>>,
14    pub source: Option<Box<String>>,
15    pub deprecated: Option<Box<LuaDeprecated>>,
16    pub version_conds: Option<Box<Vec<LuaVersionCondition>>>,
17    pub tag_content: Option<Box<LuaTagContent>>,
18    pub export: Option<LuaExport>,
19    pub decl_features: DeclFeatureFlag,
20    pub attribute_uses: Option<Arc<Vec<LuaAttributeUse>>>,
21}
22
23impl Default for LuaCommonProperty {
24    fn default() -> Self {
25        Self::new()
26    }
27}
28
29impl LuaCommonProperty {
30    pub fn new() -> Self {
31        Self {
32            visibility: VisibilityKind::Public,
33            description: None,
34            source: None,
35            deprecated: None,
36            version_conds: None,
37            tag_content: None,
38            export: None,
39            decl_features: DeclFeatureFlag::new(),
40            attribute_uses: None,
41        }
42    }
43
44    pub fn description(&self) -> Option<&String> {
45        self.description.as_deref()
46    }
47
48    pub fn version_conds(&self) -> Option<&Vec<LuaVersionCondition>> {
49        self.version_conds.as_deref()
50    }
51
52    pub fn export(&self) -> Option<&LuaExport> {
53        self.export.as_ref()
54    }
55
56    pub fn tag_content(&self) -> Option<&LuaTagContent> {
57        self.tag_content.as_deref()
58    }
59
60    pub fn deprecated(&self) -> Option<&LuaDeprecated> {
61        self.deprecated.as_deref()
62    }
63
64    pub fn source(&self) -> Option<&String> {
65        self.source.as_deref()
66    }
67
68    pub fn add_extra_description(&mut self, description: String) {
69        self.description = Some(Box::new(description));
70    }
71
72    pub fn add_extra_source(&mut self, source: String) {
73        self.source = Some(Box::new(source));
74    }
75
76    pub fn add_extra_deprecated(&mut self, message: Option<String>) {
77        self.deprecated = match message {
78            Some(msg) => Some(Box::new(LuaDeprecated::DeprecatedWithMessage(msg))),
79            None => Some(Box::new(LuaDeprecated::Deprecated)),
80        };
81    }
82
83    pub fn add_extra_version_cond(&mut self, conds: Vec<LuaVersionCondition>) {
84        self.version_conds = Some(Box::new(conds));
85    }
86
87    pub fn add_extra_tag(&mut self, tag: String, content: String) {
88        self.tag_content
89            .get_or_insert_with(|| Box::new(LuaTagContent::new()))
90            .add_tag(tag, content);
91    }
92
93    pub fn add_extra_export(&mut self, export: LuaExport) {
94        self.export = Some(export);
95    }
96
97    pub fn add_decl_feature(&mut self, feature: PropertyDeclFeature) {
98        self.decl_features.add_feature(feature);
99    }
100
101    pub fn add_attribute_use(&mut self, attribute_use: LuaAttributeUse) {
102        Arc::make_mut(
103            self.attribute_uses
104                .get_or_insert_with(|| Arc::new(Vec::new())),
105        )
106        .push(attribute_use);
107    }
108
109    pub fn attribute_uses(&self) -> Option<&Arc<Vec<LuaAttributeUse>>> {
110        self.attribute_uses.as_ref()
111    }
112
113    pub fn find_attribute_use(&self, id: &str) -> Option<&LuaAttributeUse> {
114        self.attribute_uses.as_ref().and_then(|attribute_uses| {
115            attribute_uses
116                .iter()
117                .find(|attribute_use| attribute_use.id.get_name() == id)
118        })
119    }
120}
121
122#[derive(Debug, Clone, PartialEq, Eq)]
123pub enum LuaDeprecated {
124    Deprecated,
125    DeprecatedWithMessage(String),
126}
127
128#[derive(Debug, Clone, PartialEq, Eq)]
129pub enum LuaExportScope {
130    Global,
131    Namespace,
132}
133
134#[derive(Debug, Clone, PartialEq, Eq)]
135pub struct LuaTagContent {
136    pub tags: Vec<(String, String)>,
137}
138
139impl Default for LuaTagContent {
140    fn default() -> Self {
141        Self::new()
142    }
143}
144
145impl LuaTagContent {
146    pub fn new() -> Self {
147        Self { tags: Vec::new() }
148    }
149
150    pub fn add_tag(&mut self, tag: String, content: String) {
151        self.tags.push((tag, content));
152    }
153
154    pub fn get_all_tags(&self) -> &[(String, String)] {
155        &self.tags
156    }
157}
158
159#[derive(Debug, Clone, PartialEq, Eq)]
160pub struct LuaExport {
161    pub scope: LuaExportScope,
162}
163
164#[derive(Debug, Clone, Hash, PartialEq, Eq, Copy)]
165pub struct LuaPropertyId {
166    id: u32,
167}
168
169impl LuaPropertyId {
170    pub fn new(id: u32) -> Self {
171        Self { id }
172    }
173}
174
175#[derive(Debug, Clone, Hash, PartialEq, Eq)]
176pub struct LuaAttributeUse {
177    pub id: LuaTypeDeclId,
178    pub args: Vec<(String, Option<LuaType>)>,
179}
180
181impl LuaAttributeUse {
182    pub fn new(id: LuaTypeDeclId, args: Vec<(String, Option<LuaType>)>) -> Self {
183        Self { id, args }
184    }
185
186    pub fn get_param_by_name(&self, name: &str) -> Option<&LuaType> {
187        self.args
188            .iter()
189            .find(|(n, _)| n == name)
190            .and_then(|(_, typ)| typ.as_ref())
191    }
192}