Skip to content

Commit 83599ed

Browse files
committed
refactor support use _G define global
1 parent c93109f commit 83599ed

File tree

11 files changed

+145
-61
lines changed

11 files changed

+145
-61
lines changed

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

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use emmylua_parser::{
22
LuaAstNode, LuaAstToken, LuaClosureExpr, LuaIndexExpr, LuaIndexKey, LuaLiteralExpr,
3-
LuaLiteralToken, LuaNameExpr, LuaTableExpr,
3+
LuaLiteralToken, LuaNameExpr, LuaTableExpr, LuaVarExpr,
44
};
55

66
use crate::{
@@ -46,14 +46,14 @@ pub fn analyze_name_expr(analyzer: &mut DeclAnalyzer, expr: LuaNameExpr) -> Opti
4646
}
4747

4848
if !is_local {
49-
reference_index.add_global_reference(name, file_id, range);
49+
reference_index.add_global_reference(name, file_id, expr.get_syntax_id());
5050
}
5151

5252
Some(())
5353
}
5454

55-
pub fn analyze_index_expr(analyzer: &mut DeclAnalyzer, expr: LuaIndexExpr) -> Option<()> {
56-
let index_key = expr.get_index_key()?;
55+
pub fn analyze_index_expr(analyzer: &mut DeclAnalyzer, index_expr: LuaIndexExpr) -> Option<()> {
56+
let index_key = index_expr.get_index_key()?;
5757
let key = match index_key {
5858
LuaIndexKey::Name(name) => LuaMemberKey::Name(name.get_name_text().to_string().into()),
5959
LuaIndexKey::Integer(int) => {
@@ -68,11 +68,28 @@ pub fn analyze_index_expr(analyzer: &mut DeclAnalyzer, expr: LuaIndexExpr) -> Op
6868
};
6969

7070
let file_id = analyzer.get_file_id();
71-
let syntax_id = expr.get_syntax_id();
71+
let syntax_id = index_expr.get_syntax_id();
72+
let prefix = index_expr.get_prefix_expr()?;
73+
if let LuaVarExpr::NameExpr(name_expr) = prefix {
74+
let name_token = name_expr.get_name_token()?;
75+
let name_token_text = name_token.get_name_text();
76+
if name_token_text == "_G" || name_token_text == "_ENV" {
77+
if let LuaMemberKey::Name(name) = &key {
78+
analyzer
79+
.db
80+
.get_reference_index_mut()
81+
.add_global_reference(name, file_id, syntax_id);
82+
}
83+
84+
return Some(());
85+
}
86+
}
87+
7288
analyzer
7389
.db
7490
.get_reference_index_mut()
7591
.add_index_reference(key, file_id, syntax_id);
92+
7693
Some(())
7794
}
7895

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,17 +178,16 @@ impl<'a> DeclAnalyzer<'a> {
178178
let range = decl.get_range();
179179
let file_id = decl.get_file_id();
180180
let name = decl.get_name().to_string();
181+
let syntax_id = decl.get_syntax_id();
181182
let id = self.decl.add_decl(decl);
182183
self.add_decl_to_current_scope(id);
183184

184185
if is_global {
185-
self.db
186-
.get_decl_index_mut()
187-
.add_global_decl(&name, id);
186+
self.db.get_decl_index_mut().add_global_decl(&name, id);
188187

189188
self.db
190189
.get_reference_index_mut()
191-
.add_global_reference(&name, file_id, range);
190+
.add_global_reference(&name, file_id, syntax_id);
192191
}
193192

194193
self.db

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

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use emmylua_parser::{
2-
LuaAssignStat, LuaAstNode, LuaAstToken, LuaForRangeStat, LuaForStat, LuaFuncStat,
3-
LuaLocalFuncStat, LuaLocalStat, LuaVarExpr,
2+
LuaAssignStat, LuaAstNode, LuaAstToken, LuaForRangeStat, LuaForStat, LuaFuncStat, LuaIndexExpr,
3+
LuaLocalFuncStat, LuaLocalStat, LuaSyntaxKind, LuaVarExpr,
44
};
55

66
use crate::{
@@ -63,7 +63,10 @@ pub fn analyze_assign_stat(analyzer: &mut DeclAnalyzer, stat: LuaAssignStat) ->
6363
name,
6464
file_id,
6565
range,
66-
LuaDeclExtra::Global { decl_type: None },
66+
LuaDeclExtra::Global {
67+
kind: LuaSyntaxKind::NameExpr.into(),
68+
decl_type: None,
69+
},
6770
);
6871

6972
analyzer.add_decl(decl);
@@ -84,7 +87,7 @@ pub fn analyze_assign_stat(analyzer: &mut DeclAnalyzer, stat: LuaAssignStat) ->
8487
let file_id = analyzer.get_file_id();
8588
let member = LuaMember::new(
8689
LuaMemberOwner::None,
87-
key,
90+
key.clone(),
8891
file_id,
8992
index_expr.get_syntax_id(),
9093
None,
@@ -95,6 +98,49 @@ pub fn analyze_assign_stat(analyzer: &mut DeclAnalyzer, stat: LuaAssignStat) ->
9598
.db
9699
.get_reference_index_mut()
97100
.add_write_range(file_id, index_expr.get_range());
101+
102+
if let LuaMemberKey::Name(name) = &key {
103+
analyze_maybe_global_index_expr(analyzer, index_expr, &name, None);
104+
}
105+
}
106+
}
107+
}
108+
109+
Some(())
110+
}
111+
112+
fn analyze_maybe_global_index_expr(
113+
analyzer: &mut DeclAnalyzer,
114+
index_expr: &LuaIndexExpr,
115+
index_name: &str,
116+
typ: Option<LuaType>,
117+
) -> Option<()> {
118+
let file_id = analyzer.get_file_id();
119+
let prefix = index_expr.get_prefix_expr()?;
120+
if let LuaVarExpr::NameExpr(name_expr) = prefix {
121+
let name_token = name_expr.get_name_token()?;
122+
let name_token_text = name_token.get_name_text();
123+
if name_token_text == "_G" || name_token_text == "_ENV" {
124+
let position = index_expr.get_position();
125+
let name = name_token.get_name_text();
126+
let range = index_expr.get_range();
127+
if analyzer.find_decl(&name, position).is_none() {
128+
let decl = LuaDecl::new(
129+
index_name,
130+
file_id,
131+
range,
132+
LuaDeclExtra::Global {
133+
kind: LuaSyntaxKind::IndexExpr.into(),
134+
decl_type: typ,
135+
},
136+
);
137+
138+
analyzer.add_decl(decl);
139+
} else {
140+
analyzer
141+
.db
142+
.get_reference_index_mut()
143+
.add_write_range(file_id, range);
98144
}
99145
}
100146
}
@@ -167,7 +213,10 @@ pub fn analyze_func_stat(analyzer: &mut DeclAnalyzer, stat: LuaFuncStat) -> Opti
167213
name,
168214
file_id,
169215
range,
170-
LuaDeclExtra::Global { decl_type: None },
216+
LuaDeclExtra::Global {
217+
kind: LuaSyntaxKind::NameExpr.into(),
218+
decl_type: None,
219+
},
171220
);
172221

173222
let decl_id = analyzer.add_decl(decl);
@@ -176,8 +225,8 @@ pub fn analyze_func_stat(analyzer: &mut DeclAnalyzer, stat: LuaFuncStat) -> Opti
176225
return Some(());
177226
}
178227
}
179-
LuaVarExpr::IndexExpr(index_name) => {
180-
let index_key = index_name.get_index_key()?;
228+
LuaVarExpr::IndexExpr(index_expr) => {
229+
let index_key = index_expr.get_index_key()?;
181230
let key: LuaMemberKey = index_key.into();
182231
if key.is_none() {
183232
return None;
@@ -186,17 +235,21 @@ pub fn analyze_func_stat(analyzer: &mut DeclAnalyzer, stat: LuaFuncStat) -> Opti
186235
let file_id = analyzer.get_file_id();
187236
let member = LuaMember::new(
188237
LuaMemberOwner::None,
189-
key,
238+
key.clone(),
190239
file_id,
191-
index_name.get_syntax_id(),
240+
index_expr.get_syntax_id(),
192241
None,
193242
);
194243

195244
let member_id = analyzer.db.get_member_index_mut().add_member(member);
196245
analyzer
197246
.db
198247
.get_reference_index_mut()
199-
.add_write_range(file_id, index_name.get_range());
248+
.add_write_range(file_id, index_expr.get_range());
249+
250+
if let LuaMemberKey::Name(name) = &key {
251+
analyze_maybe_global_index_expr(analyzer, &index_expr, &name, None);
252+
}
200253
LuaPropertyOwnerId::Member(member_id)
201254
}
202255
};

crates/code_analysis/src/compilation/analyzer/doc/type_def_tags.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -325,12 +325,11 @@ fn get_global_reference_ranges(
325325
let name = name_token.get_name_text().to_string();
326326
let mut ranges = Vec::new();
327327

328-
let refs = analyzer
328+
let ref_syntax_ids = analyzer
329329
.db
330330
.get_reference_index_mut()
331331
.get_global_file_references(&name, file_id)?;
332-
for reference_range in refs {
333-
let syntax_id = LuaSyntaxId::new(LuaSyntaxKind::NameExpr.into(), reference_range.clone());
332+
for syntax_id in ref_syntax_ids {
334333
let name_node = syntax_id.to_node_from_root(&analyzer.root)?;
335334
if let Some(parent1) = name_node.parent() {
336335
if parent1.kind() == LuaSyntaxKind::IndexExpr.into() {
@@ -344,7 +343,7 @@ fn get_global_reference_ranges(
344343
} else if parent2.kind() == LuaSyntaxKind::AssignStat.into() {
345344
let stat = LuaAssignStat::cast(parent2)?;
346345
if let Some(assign_token) = stat.token_by_kind(LuaTokenKind::TkAssign) {
347-
if assign_token.get_position() > reference_range.start() {
346+
if assign_token.get_position() > syntax_id.get_range().start() {
348347
ranges.push(stat.get_range());
349348
for comment in stat.get_comments() {
350349
ranges.push(comment.get_range());

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,13 @@ fn get_var_type_owner(
155155
}
156156
LuaMemberOwner::Type(def_id)
157157
}
158-
LuaType::Instance(instance) => LuaMemberOwner::Element(instance.get_range().clone()),
158+
LuaType::Instance(instance) => {
159+
LuaMemberOwner::Element(instance.get_range().clone())
160+
}
161+
LuaType::Global => {
162+
let decl_id = LuaDeclId::new(file_id, prefix_expr.get_position());
163+
return Some(TypeOwner::Decl(decl_id));
164+
}
159165
// is ref need extend field?
160166
_ => {
161167
return None;

crates/code_analysis/src/db_index/declaration/decl.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub enum LuaDeclExtra {
2828
signature_id: LuaSignatureId,
2929
},
3030
Global {
31+
kind: LuaKind,
3132
decl_type: Option<LuaType>,
3233
},
3334
}
@@ -84,8 +85,8 @@ impl LuaDecl {
8485
LuaDeclExtra::Param { .. } => {
8586
LuaSyntaxId::new(LuaSyntaxKind::ParamName.into(), self.range)
8687
}
87-
LuaDeclExtra::Global { .. } => {
88-
LuaSyntaxId::new(LuaSyntaxKind::NameExpr.into(), self.range)
88+
LuaDeclExtra::Global { kind, .. } => {
89+
LuaSyntaxId::new(kind, self.range)
8990
}
9091
}
9192
}

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

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ mod string_reference;
33

44
use std::collections::{HashMap, HashSet};
55

6-
use emmylua_parser::{LuaSyntaxId, LuaSyntaxKind};
6+
use emmylua_parser::LuaSyntaxId;
77
use local_reference::LocalReference;
88
use rowan::TextRange;
99
use smol_str::SmolStr;
@@ -17,6 +17,7 @@ use super::{traits::LuaIndex, LuaDeclId, LuaMemberKey};
1717
pub struct LuaReferenceIndex {
1818
local_references: HashMap<FileId, LocalReference>,
1919
index_reference: HashMap<LuaMemberKey, HashMap<FileId, HashSet<LuaSyntaxId>>>,
20+
global_references: HashMap<SmolStr, HashMap<FileId, HashSet<LuaSyntaxId>>>,
2021
string_references: HashMap<FileId, StringReference>,
2122
}
2223

@@ -25,6 +26,7 @@ impl LuaReferenceIndex {
2526
Self {
2627
local_references: HashMap::new(),
2728
index_reference: HashMap::new(),
29+
global_references: HashMap::new(),
2830
string_references: HashMap::new(),
2931
}
3032
}
@@ -36,14 +38,14 @@ impl LuaReferenceIndex {
3638
.add_local_reference(decl_id, range);
3739
}
3840

39-
pub fn add_global_reference(&mut self, name: &str, file_id: FileId, range: TextRange) {
41+
pub fn add_global_reference(&mut self, name: &str, file_id: FileId, syntax_id: LuaSyntaxId) {
4042
let key = SmolStr::new(name);
41-
self.index_reference
42-
.entry(LuaMemberKey::Name(key))
43+
self.global_references
44+
.entry(key)
4345
.or_insert_with(HashMap::new)
4446
.entry(file_id)
4547
.or_insert_with(HashSet::new)
46-
.insert(LuaSyntaxId::new(LuaSyntaxKind::NameExpr.into(), range));
48+
.insert(syntax_id);
4749
}
4850

4951
pub fn add_index_reference(
@@ -107,38 +109,32 @@ impl LuaReferenceIndex {
107109
&self,
108110
name: &str,
109111
file_id: FileId,
110-
) -> Option<Vec<TextRange>> {
111-
let key = SmolStr::new(name);
112+
) -> Option<Vec<LuaSyntaxId>> {
112113
let results = self
113-
.index_reference
114-
.get(&LuaMemberKey::Name(key))?
114+
.global_references
115+
.get(name)?
115116
.iter()
116-
.filter_map(|(key_file_id, syntax_ids)| {
117-
if *key_file_id == file_id {
118-
Some(syntax_ids.iter().map(|syntax_id| syntax_id.get_range()))
117+
.filter_map(|(source_file_id, syntax_ids)| {
118+
if file_id == *source_file_id {
119+
Some(syntax_ids.iter())
119120
} else {
120121
None
121122
}
122123
})
123124
.flatten()
125+
.copied()
124126
.collect();
125127

126128
Some(results)
127129
}
128130

129-
pub fn get_global_references(&self, key: &LuaMemberKey) -> Option<Vec<InFiled<TextRange>>> {
131+
pub fn get_global_references(&self, name: &str) -> Option<Vec<InFiled<LuaSyntaxId>>> {
130132
let results = self
131-
.index_reference
132-
.get(&key)?
133+
.global_references
134+
.get(name)?
133135
.iter()
134136
.map(|(file_id, syntax_ids)| {
135-
syntax_ids.iter().filter_map(|syntax_id| {
136-
if syntax_id.get_kind() == LuaSyntaxKind::NameExpr {
137-
Some(InFiled::new(*file_id, syntax_id.get_range()))
138-
} else {
139-
None
140-
}
141-
})
137+
syntax_ids.iter().map(|syntax_id| InFiled::new(*file_id, *syntax_id))
142138
})
143139
.flatten()
144140
.collect();
@@ -202,5 +198,17 @@ impl LuaIndex for LuaReferenceIndex {
202198
for key in to_be_remove {
203199
self.index_reference.remove(&key);
204200
}
201+
202+
let mut to_be_remove = Vec::new();
203+
for (key, references) in self.global_references.iter_mut() {
204+
references.remove(&file_id);
205+
if references.is_empty() {
206+
to_be_remove.push(key.clone());
207+
}
208+
}
209+
210+
for key in to_be_remove {
211+
self.global_references.remove(&key);
212+
}
205213
}
206214
}

crates/code_analysis/src/db_index/type/humanize_type.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub fn humanize_type(db: &DbIndex, ty: &LuaType) -> String {
1919
LuaType::IntegerConst(i) => i.to_string(),
2020
LuaType::FloatConst(f) => f.to_string(),
2121
LuaType::TableConst(_) => "table".to_string(),
22+
LuaType::Global => "global".to_string(),
2223
LuaType::Def(id) => humanize_def_type(db, id),
2324
LuaType::Union(union) => humanize_union_type(db, union),
2425
LuaType::Tuple(tuple) => humanize_tuple_type(db, tuple),

crates/emmylua_ls/src/handlers/references/reference_seacher.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ pub fn search_decl_references(
5757
let global_references = semantic_model
5858
.get_db()
5959
.get_reference_index()
60-
.get_global_references(&LuaMemberKey::Name(name.to_string().into()))?;
61-
for in_filed_reference_range in global_references {
60+
.get_global_references(name)?;
61+
for in_filed_syntax_id in global_references {
6262
let document =
63-
semantic_model.get_document_by_file_id(in_filed_reference_range.file_id)?;
64-
let location = document.to_lsp_location(in_filed_reference_range.value.clone())?;
63+
semantic_model.get_document_by_file_id(in_filed_syntax_id.file_id)?;
64+
let location = document.to_lsp_location(in_filed_syntax_id.value.get_range())?;
6565
result.push(location);
6666
}
6767
}

0 commit comments

Comments
 (0)