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    Default, // 默认声明, 会根据配置文件作不同的处理.
131    Global,
132    Namespace,
133}
134
135#[derive(Debug, Clone, PartialEq, Eq)]
136pub struct LuaTagContent {
137    pub tags: Vec<(String, String)>,
138}
139
140impl Default for LuaTagContent {
141    fn default() -> Self {
142        Self::new()
143    }
144}
145
146impl LuaTagContent {
147    pub fn new() -> Self {
148        Self { tags: Vec::new() }
149    }
150
151    pub fn add_tag(&mut self, tag: String, content: String) {
152        self.tags.push((tag, content));
153    }
154
155    pub fn get_all_tags(&self) -> &[(String, String)] {
156        &self.tags
157    }
158}
159
160#[derive(Debug, Clone, PartialEq, Eq)]
161pub struct LuaExport {
162    pub scope: LuaExportScope,
163}
164
165#[derive(Debug, Clone, Hash, PartialEq, Eq, Copy)]
166pub struct LuaPropertyId {
167    id: u32,
168}
169
170impl LuaPropertyId {
171    pub fn new(id: u32) -> Self {
172        Self { id }
173    }
174}
175
176#[derive(Debug, Clone, Hash, PartialEq, Eq)]
177pub struct LuaAttributeUse {
178    pub id: LuaTypeDeclId,
179    pub args: Vec<(String, Option<LuaType>)>,
180}
181
182impl LuaAttributeUse {
183    pub fn new(id: LuaTypeDeclId, args: Vec<(String, Option<LuaType>)>) -> Self {
184        Self { id, args }
185    }
186
187    pub fn get_param_by_name(&self, name: &str) -> Option<&LuaType> {
188        self.args
189            .iter()
190            .find(|(n, _)| n == name)
191            .and_then(|(_, typ)| typ.as_ref())
192    }
193}