Skip to content

Commit 21aee41

Browse files
committed
add deprecated check
1 parent 2acb126 commit 21aee41

File tree

8 files changed

+171
-40
lines changed

8 files changed

+171
-40
lines changed

crates/code_analysis/src/compilation/analyzer/decl/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ impl<'a> DeclAnalyzer<'a> {
187187
.add_global_reference(name, file_id, range);
188188
}
189189

190+
self.db
191+
.get_reference_index_mut()
192+
.add_write_range(file_id, range);
193+
190194
id
191195
}
192196

crates/code_analysis/src/compilation/analyzer/decl/stats.rs

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ pub fn analyze_local_stat(analyzer: &mut DeclAnalyzer, stat: LuaLocalStat) -> Op
3030
None
3131
};
3232

33+
let file_id = analyzer.get_file_id();
34+
let range = local_name.get_range();
3335
let decl = LuaDecl::Local {
3436
name,
35-
file_id: analyzer.get_file_id(),
36-
range: local_name.get_range(),
37+
file_id,
38+
range,
3739
kind: local_name.syntax().kind().into(),
3840
attrib,
3941
decl_type: None,
@@ -52,15 +54,22 @@ pub fn analyze_assign_stat(analyzer: &mut DeclAnalyzer, stat: LuaAssignStat) ->
5254
let name_token = name.get_name_token()?;
5355
let position = name_token.get_position();
5456
let name = name_token.get_name_text().to_string();
57+
let file_id = analyzer.get_file_id();
58+
let range = name_token.get_range();
5559
if analyzer.find_decl(&name, position).is_none() {
5660
let decl = LuaDecl::Global {
5761
name,
58-
file_id: analyzer.get_file_id(),
59-
range: name_token.get_range(),
62+
file_id,
63+
range,
6064
decl_type: None,
6165
};
6266

6367
analyzer.add_decl(decl);
68+
} else {
69+
analyzer
70+
.db
71+
.get_reference_index_mut()
72+
.add_write_range(file_id, range);
6473
}
6574
}
6675
LuaVarExpr::IndexExpr(index_expr) => {
@@ -70,26 +79,6 @@ pub fn analyze_assign_stat(analyzer: &mut DeclAnalyzer, stat: LuaAssignStat) ->
7079
continue;
7180
}
7281

73-
// if let Some(LuaVarExpr::NameExpr(name_expr)) = index_expr.get_prefix_expr() {
74-
// let name_text = name_expr.get_name_text()?;
75-
// if name_text == "_G" || name_text == "_ENV" {
76-
// if analyzer
77-
// .find_decl(&name_text, index_expr.get_position())
78-
// .is_none()
79-
// {
80-
// let decl = LuaDecl::Global {
81-
// name: name_text.to_string(),
82-
// file_id: analyzer.get_file_id(),
83-
// range: name_expr.get_range(),
84-
// decl_type: None,
85-
// };
86-
87-
// analyzer.add_decl(decl);
88-
// }
89-
// continue;
90-
// }
91-
// }
92-
9382
let file_id = analyzer.get_file_id();
9483
let member = LuaMember::new(
9584
LuaMemberOwner::None,
@@ -100,6 +89,10 @@ pub fn analyze_assign_stat(analyzer: &mut DeclAnalyzer, stat: LuaAssignStat) ->
10089
);
10190

10291
analyzer.db.get_member_index_mut().add_member(member);
92+
analyzer
93+
.db
94+
.get_reference_index_mut()
95+
.add_write_range(file_id, index_expr.get_range());
10396
}
10497
}
10598
}
@@ -111,33 +104,40 @@ pub fn analyze_for_stat(analyzer: &mut DeclAnalyzer, stat: LuaForStat) -> Option
111104
let it_var = stat.get_var_name()?;
112105
let name = it_var.get_name_text().to_string();
113106
let pos = it_var.get_position();
114-
107+
let file_id = analyzer.get_file_id();
108+
let range = it_var.get_range();
115109
if analyzer.find_decl(&name, pos).is_none() {
116110
let decl = LuaDecl::Local {
117111
name,
118-
file_id: analyzer.get_file_id(),
112+
file_id,
119113
kind: it_var.syntax().kind(),
120-
range: it_var.get_range(),
114+
range,
121115
attrib: Some(LocalAttribute::IterConst),
122116
decl_type: Some(LuaType::Integer),
123117
};
124118

125119
analyzer.add_decl(decl);
120+
analyzer
121+
.db
122+
.get_reference_index_mut()
123+
.add_write_range(file_id, range);
126124
}
127125

128126
Some(())
129127
}
130128

131129
pub fn analyze_for_range_stat(analyzer: &mut DeclAnalyzer, stat: LuaForRangeStat) {
132130
let var_list = stat.get_var_name_list();
131+
let file_id = analyzer.get_file_id();
133132
for var in var_list {
134133
let name = var.get_name_text().to_string();
134+
let range = var.get_range();
135135

136136
let decl = LuaDecl::Local {
137137
name,
138-
file_id: analyzer.get_file_id(),
138+
file_id,
139139
kind: var.syntax().kind().into(),
140-
range: var.get_range(),
140+
range,
141141
attrib: Some(LocalAttribute::IterConst),
142142
decl_type: None,
143143
};
@@ -185,6 +185,10 @@ pub fn analyze_func_stat(analyzer: &mut DeclAnalyzer, stat: LuaFuncStat) -> Opti
185185
);
186186

187187
let member_id = analyzer.db.get_member_index_mut().add_member(member);
188+
analyzer
189+
.db
190+
.get_reference_index_mut()
191+
.add_write_range(file_id, index_name.get_range());
188192
LuaPropertyOwnerId::Member(member_id)
189193
}
190194
};
@@ -204,19 +208,19 @@ pub fn analyze_func_stat(analyzer: &mut DeclAnalyzer, stat: LuaFuncStat) -> Opti
204208
pub fn analyze_local_func_stat(analyzer: &mut DeclAnalyzer, stat: LuaLocalFuncStat) -> Option<()> {
205209
let local_name = stat.get_local_name()?;
206210
let name = local_name.get_name_token()?.get_name_text().to_string();
207-
211+
let range = local_name.get_range();
212+
let file_id = analyzer.get_file_id();
208213
let decl = LuaDecl::Local {
209214
name,
210-
file_id: analyzer.get_file_id(),
215+
file_id,
211216
kind: local_name.syntax().kind().into(),
212-
range: local_name.get_range(),
217+
range,
213218
attrib: None,
214219
decl_type: None,
215220
};
216221

217222
let decl_id = analyzer.add_decl(decl);
218223
let closure = stat.get_closure()?;
219-
let file_id = analyzer.get_file_id();
220224
let closure_owner_id = LuaPropertyOwnerId::Signature(LuaSignatureId::new(file_id, &closure));
221225
let property_decl_id = LuaPropertyOwnerId::LuaDecl(decl_id);
222226
analyzer

crates/code_analysis/src/db_index/reference/local_reference.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::HashMap;
1+
use std::collections::{HashMap, HashSet};
22
use rowan::TextRange;
33

44
use crate::db_index::LuaDeclId;
@@ -7,13 +7,15 @@ use crate::db_index::LuaDeclId;
77
pub struct LocalReference {
88
local_references: HashMap<LuaDeclId, Vec<TextRange>>,
99
references_to_decl: HashMap<TextRange, LuaDeclId>,
10+
write_ranges: HashSet<TextRange>
1011
}
1112

1213
impl LocalReference {
1314
pub fn new() -> Self {
1415
Self {
1516
local_references: HashMap::new(),
16-
references_to_decl: HashMap::new()
17+
references_to_decl: HashMap::new(),
18+
write_ranges: HashSet::new()
1719
}
1820
}
1921

@@ -22,6 +24,10 @@ impl LocalReference {
2224
self.references_to_decl.insert(range, decl_id);
2325
}
2426

27+
pub fn add_write_range(&mut self, range: TextRange) {
28+
self.write_ranges.insert(range);
29+
}
30+
2531
pub fn get_local_references(&self, decl_id: &LuaDeclId) -> Option<&Vec<TextRange>> {
2632
self.local_references.get(decl_id)
2733
}
@@ -33,4 +39,8 @@ impl LocalReference {
3339
pub fn get_decl_id(&self, range: &TextRange) -> Option<LuaDeclId> {
3440
self.references_to_decl.get(range).copied()
3541
}
42+
43+
pub fn is_write_range(&self, range: &TextRange) -> bool {
44+
self.write_ranges.contains(range)
45+
}
3646
}

crates/code_analysis/src/db_index/reference/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ impl LuaReferenceIndex {
7272
.add_string_reference(string, range);
7373
}
7474

75+
pub fn add_write_range(&mut self, file_id: FileId, range: TextRange) {
76+
self.local_references
77+
.entry(file_id)
78+
.or_insert_with(LocalReference::new)
79+
.add_write_range(range);
80+
}
81+
7582
pub fn get_local_reference(&self, file_id: &FileId) -> Option<&LocalReference> {
7683
self.local_references.get(file_id)
7784
}
@@ -175,6 +182,14 @@ impl LuaReferenceIndex {
175182

176183
results
177184
}
185+
186+
pub fn is_write_range(&self, file_id: FileId, range: TextRange) -> bool {
187+
self.local_references
188+
.get(&file_id)
189+
.map_or(false, |local_reference| {
190+
local_reference.is_write_range(&range)
191+
})
192+
}
178193
}
179194

180195
impl LuaIndex for LuaReferenceIndex {

crates/code_analysis/src/diagnostic/checker/depreacated.rs

Whitespace-only changes.
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
use emmylua_parser::{LuaAst, LuaAstNode, LuaIndexExpr, LuaNameExpr};
2+
3+
use crate::{DiagnosticCode, SemanticModel};
4+
5+
use super::DiagnosticContext;
6+
7+
pub const CODES: &[DiagnosticCode] = &[DiagnosticCode::Unused];
8+
9+
pub fn check(context: &mut DiagnosticContext, semantic_model: &mut SemanticModel) -> Option<()> {
10+
let file_id = semantic_model.get_file_id();
11+
let root = semantic_model.get_root().clone();
12+
for node in root.descendants::<LuaAst>() {
13+
match node {
14+
LuaAst::LuaNameExpr(name_expr) => {
15+
if semantic_model
16+
.get_db()
17+
.get_reference_index()
18+
.is_write_range(file_id, name_expr.get_range())
19+
{
20+
continue;
21+
}
22+
check_name_expr(context, semantic_model, name_expr);
23+
}
24+
LuaAst::LuaIndexExpr(index_expr) => {
25+
if semantic_model
26+
.get_db()
27+
.get_reference_index()
28+
.is_write_range(file_id, index_expr.get_range())
29+
{
30+
continue;
31+
}
32+
check_index_expr(context, semantic_model, index_expr);
33+
}
34+
_ => {}
35+
}
36+
}
37+
38+
Some(())
39+
}
40+
41+
fn check_name_expr(
42+
context: &mut DiagnosticContext,
43+
semantic_model: &mut SemanticModel,
44+
name_expr: LuaNameExpr,
45+
) -> Option<()> {
46+
let property_owner = semantic_model
47+
.get_property_owner_id(rowan::NodeOrToken::Node(name_expr.syntax().clone()))?;
48+
let property = semantic_model
49+
.get_db()
50+
.get_property_index()
51+
.get_property(property_owner)?;
52+
if property.is_deprecated {
53+
let depreacated_message = if let Some(message) = &property.deprecated_message {
54+
message.to_string()
55+
} else {
56+
"depreacated".to_string()
57+
};
58+
59+
context.add_diagnostic(
60+
DiagnosticCode::Deprecated,
61+
name_expr.get_range(),
62+
depreacated_message,
63+
None,
64+
);
65+
}
66+
Some(())
67+
}
68+
69+
fn check_index_expr(
70+
context: &mut DiagnosticContext,
71+
semantic_model: &mut SemanticModel,
72+
index_expr: LuaIndexExpr,
73+
) -> Option<()> {
74+
let property_owner = semantic_model
75+
.get_property_owner_id(rowan::NodeOrToken::Node(index_expr.syntax().clone()))?;
76+
let property = semantic_model
77+
.get_db()
78+
.get_property_index()
79+
.get_property(property_owner)?;
80+
if property.is_deprecated {
81+
let depreacated_message = if let Some(message) = &property.deprecated_message {
82+
message.to_string()
83+
} else {
84+
"deprecated".to_string()
85+
};
86+
87+
let index_name_range = index_expr.get_index_name_token()?.text_range();
88+
89+
context.add_diagnostic(
90+
DiagnosticCode::Deprecated,
91+
index_name_range,
92+
depreacated_message,
93+
None,
94+
);
95+
}
96+
Some(())
97+
}

crates/code_analysis/src/diagnostic/checker/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
mod analyze_error;
22
mod syntax_error;
33
mod unused;
4-
mod depreacated;
4+
mod deprecated;
55

66
use lsp_types::{Diagnostic, DiagnosticSeverity, DiagnosticTag, NumberOrString};
77
use rowan::TextRange;
@@ -29,6 +29,7 @@ pub fn check_file(context: &mut DiagnosticContext, semantic_model:&mut SemanticM
2929
check!(syntax_error);
3030
check!(analyze_error);
3131
check!(unused);
32+
check!(deprecated);
3233

3334
Some(())
3435
}

crates/code_analysis/src/diagnostic/checker/unused.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ pub fn check(context: &mut DiagnosticContext, semantic_model: &SemanticModel) ->
2121
context.add_diagnostic(
2222
DiagnosticCode::Unused,
2323
decl.get_range(),
24-
format!(
25-
"{0} is never used, if this is intentional, prefix it with an underscore: _{0}",
26-
name
27-
),
24+
t!(
25+
"%{name} is never used, if this is intentional, prefix it with an underscore: _%{name}",
26+
name = name
27+
).to_string(),
2828
None,
2929
);
3030
}

0 commit comments

Comments
 (0)