Skip to content

Commit daf8fa7

Browse files
committed
support overload global function in meta file
1 parent 5beeadd commit daf8fa7

File tree

9 files changed

+124
-49
lines changed

9 files changed

+124
-49
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ pub fn analyze_func_stat(analyzer: &mut DeclAnalyzer, stat: LuaFuncStat) -> Opti
234234
let position = name_token.get_position();
235235
let name = name_token.get_name_text();
236236
let range = name_token.get_range();
237-
if analyzer.find_decl(name, position).is_none() {
237+
if analyzer.find_decl(name, position).is_none() || analyzer.is_meta {
238238
let decl = LuaDecl::new(
239239
name,
240240
file_id,

crates/emmylua_code_analysis/src/db_index/global/mod.rs

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub use global_id::GlobalId;
66

77
use crate::FileId;
88

9-
use super::{DbIndex, LuaDeclId, LuaIndex};
9+
use super::{LuaDeclId, LuaIndex};
1010

1111
#[derive(Debug)]
1212
pub struct LuaGlobalIndex {
@@ -49,34 +49,6 @@ impl LuaGlobalIndex {
4949
let id = GlobalId::new(name);
5050
self.global_decl.contains_key(&id)
5151
}
52-
53-
pub fn resolve_global_decl_id(&self, db: &DbIndex, name: &str) -> Option<LuaDeclId> {
54-
let decl_ids = self.get_global_decl_ids(name)?;
55-
if decl_ids.len() == 1 {
56-
return Some(decl_ids[0]);
57-
}
58-
59-
let mut last_valid_decl_id = None;
60-
for decl_id in decl_ids {
61-
let decl_type_cache = db.get_type_index().get_type_cache(&(*decl_id).into());
62-
if let Some(type_cache) = decl_type_cache {
63-
let typ = type_cache.as_type();
64-
if typ.is_def() || typ.is_ref() || typ.is_function() {
65-
return Some(*decl_id);
66-
}
67-
68-
if type_cache.is_table() {
69-
last_valid_decl_id = Some(decl_id)
70-
}
71-
}
72-
}
73-
74-
if last_valid_decl_id.is_none() && !decl_ids.is_empty() {
75-
return Some(decl_ids[0]);
76-
}
77-
78-
last_valid_decl_id.cloned()
79-
}
8052
}
8153

8254
impl LuaIndex for LuaGlobalIndex {

crates/emmylua_code_analysis/src/diagnostic/checker/global_in_non_module.rs renamed to crates/emmylua_code_analysis/src/diagnostic/checker/global_non_module.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use emmylua_parser::{LuaAssignStat, LuaAst, LuaAstNode, LuaBlock, LuaVarExpr};
22

3-
use crate::{DiagnosticCode, LuaDeclId, SemanticModel};
3+
use crate::{DiagnosticCode, LuaDeclId, SemanticModel, resolve_global_decl_id};
44

55
use super::{Checker, DiagnosticContext};
66

@@ -62,11 +62,12 @@ fn is_global_define_in_non_module_scope(
6262
}
6363

6464
let name = var.get_text();
65-
let Some(global_id) = semantic_model
66-
.get_db()
67-
.get_global_index()
68-
.resolve_global_decl_id(semantic_model.get_db(), &name)
69-
else {
65+
let Some(global_id) = resolve_global_decl_id(
66+
semantic_model.get_db(),
67+
&mut semantic_model.get_cache().borrow_mut(),
68+
&name,
69+
None,
70+
) else {
7071
return true;
7172
};
7273

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ mod duplicate_require;
1717
mod duplicate_type;
1818
mod enum_value_mismatch;
1919
mod generic;
20-
mod global_in_non_module;
20+
mod global_non_module;
2121
mod incomplete_signature_doc;
2222
mod local_const_reassign;
2323
mod missing_fields;
@@ -121,7 +121,7 @@ pub fn check_file(context: &mut DiagnosticContext, semantic_model: &SemanticMode
121121
semantic_model,
122122
);
123123
run_check::<readonly_check::ReadOnlyChecker>(context, semantic_model);
124-
run_check::<global_in_non_module::GlobalInNonModuleChecker>(context, semantic_model);
124+
run_check::<global_non_module::GlobalInNonModuleChecker>(context, semantic_model);
125125
Some(())
126126
}
127127

crates/emmylua_code_analysis/src/semantic/infer/infer_name.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ use crate::{
66
SemanticDeclLevel, TypeOps,
77
db_index::{DbIndex, LuaDeclOrMemberId},
88
infer_node_semantic_decl,
9-
semantic::infer::narrow::{VarRefId, infer_expr_narrow_type},
9+
semantic::{
10+
infer::narrow::{VarRefId, infer_expr_narrow_type},
11+
semantic_info::resolve_global_decl_id,
12+
},
1013
};
1114

1215
pub fn infer_name_expr(
@@ -74,7 +77,7 @@ pub fn get_name_expr_var_ref_id(
7477
return Some(VarRefId::VarRef(decl_id));
7578
}
7679

77-
let global_decl_id = db.get_global_index().resolve_global_decl_id(db, name)?;
80+
let global_decl_id = resolve_global_decl_id(db, cache, name, Some(name_expr))?;
7881
Some(VarRefId::VarRef(global_decl_id))
7982
}
8083
}
@@ -373,10 +376,14 @@ pub fn infer_global_type(db: &DbIndex, name: &str) -> InferResult {
373376
continue;
374377
}
375378

376-
if typ.is_def() || typ.is_ref() || typ.is_function() {
379+
if typ.is_def() || typ.is_ref() {
377380
return Ok(typ.clone());
378381
}
379382

383+
if typ.is_function() {
384+
valid_type = TypeOps::Union.apply(db, &valid_type, typ);
385+
}
386+
380387
if type_cache.is_table() {
381388
valid_type = typ.clone();
382389
}
@@ -421,7 +428,7 @@ pub fn find_self_decl_or_member_id(
421428
return Some(LuaDeclOrMemberId::Decl(decl.get_id()));
422429
}
423430

424-
let id = db.get_global_index().resolve_global_decl_id(db, &name)?;
431+
let id = resolve_global_decl_id(db, cache, &name, Some(&prefix_name))?;
425432
Some(LuaDeclOrMemberId::Decl(id))
426433
}
427434
LuaExpr::IndexExpr(prefix_index) => {

crates/emmylua_code_analysis/src/semantic/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use member::{find_member_origin_owner, find_members};
3131
use reference::is_reference_to;
3232
use rowan::{NodeOrToken, TextRange};
3333
pub use semantic_info::SemanticInfo;
34-
pub(crate) use semantic_info::infer_node_semantic_decl;
34+
pub(crate) use semantic_info::{infer_node_semantic_decl, resolve_global_decl_id};
3535
use semantic_info::{
3636
infer_node_semantic_info, infer_token_semantic_decl, infer_token_semantic_info,
3737
};

crates/emmylua_code_analysis/src/semantic/semantic_info/infer_expr_semantic_decl.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ use crate::{
77
DbIndex, LuaDeclId, LuaDeclOrMemberId, LuaInferCache, LuaInstanceType, LuaMemberId,
88
LuaMemberKey, LuaMemberOwner, LuaSemanticDeclId, LuaType, LuaTypeCache, LuaTypeDeclId,
99
LuaUnionType,
10-
semantic::{infer::find_self_decl_or_member_id, member::get_buildin_type_map_type_id},
10+
semantic::{
11+
infer::find_self_decl_or_member_id, member::get_buildin_type_map_type_id,
12+
semantic_info::resolve_global_decl_id,
13+
},
1114
};
1215

1316
use super::{
@@ -160,7 +163,7 @@ fn get_name_decl_id(
160163
}
161164
}
162165

163-
db.get_global_index().resolve_global_decl_id(db, name)
166+
resolve_global_decl_id(db, cache, name, Some(&name_expr))
164167
}
165168

166169
fn infer_self_semantic_decl(
@@ -279,7 +282,7 @@ fn infer_member_semantic_decl_by_member_key(
279282
member_key,
280283
semantic_guard.next_level()?,
281284
),
282-
LuaType::Global => infer_global_member_semantic_decl_by_member_key(db, member_key),
285+
LuaType::Global => infer_global_member_semantic_decl_by_member_key(db, cache, member_key),
283286
_ => None,
284287
}
285288
}
@@ -393,10 +396,9 @@ fn infer_instance_member_semantic_decl_by_member_key(
393396

394397
fn infer_global_member_semantic_decl_by_member_key(
395398
db: &DbIndex,
399+
cache: &mut LuaInferCache,
396400
member_key: &LuaMemberKey,
397401
) -> Option<LuaSemanticDeclId> {
398402
let name = member_key.get_name()?;
399-
db.get_global_index()
400-
.resolve_global_decl_id(db, name)
401-
.map(LuaSemanticDeclId::LuaDecl)
403+
resolve_global_decl_id(db, cache, name, None).map(LuaSemanticDeclId::LuaDecl)
402404
}

crates/emmylua_code_analysis/src/semantic/semantic_info/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod infer_expr_semantic_decl;
2+
mod resolve_global_decl;
23
mod semantic_decl_level;
34
mod semantic_guard;
45

@@ -11,6 +12,7 @@ use emmylua_parser::{
1112
LuaSyntaxKind, LuaSyntaxNode, LuaSyntaxToken, LuaTableField,
1213
};
1314
pub use infer_expr_semantic_decl::infer_expr_semantic_decl;
15+
pub use resolve_global_decl::resolve_global_decl_id;
1416
pub use semantic_decl_level::SemanticDeclLevel;
1517
pub use semantic_guard::SemanticDeclGuard;
1618

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
use std::sync::Arc;
2+
3+
use emmylua_parser::{LuaAstNode, LuaCallExpr, LuaNameExpr};
4+
5+
use crate::{
6+
DbIndex, LuaDeclId, LuaInferCache, LuaType, semantic::overload_resolve::resolve_signature,
7+
};
8+
9+
pub fn resolve_global_decl_id(
10+
db: &DbIndex,
11+
cache: &mut LuaInferCache,
12+
name: &str,
13+
name_expr: Option<&LuaNameExpr>,
14+
) -> Option<LuaDeclId> {
15+
let decl_ids = db.get_global_index().get_global_decl_ids(name)?;
16+
if decl_ids.len() == 1 {
17+
return Some(decl_ids[0]);
18+
}
19+
20+
if let Some(name_expr) = name_expr
21+
&& let Some(call_expr) = name_expr.get_parent::<LuaCallExpr>()
22+
{
23+
return resolve_global_func_decl_id(db, cache, name, call_expr);
24+
}
25+
26+
let mut last_valid_decl_id = None;
27+
for decl_id in decl_ids {
28+
let decl_type_cache = db.get_type_index().get_type_cache(&(*decl_id).into());
29+
if let Some(type_cache) = decl_type_cache {
30+
let typ = type_cache.as_type();
31+
if typ.is_def() || typ.is_ref() || typ.is_function() {
32+
return Some(*decl_id);
33+
}
34+
35+
if type_cache.is_table() {
36+
last_valid_decl_id = Some(decl_id)
37+
}
38+
}
39+
}
40+
if last_valid_decl_id.is_none() && !decl_ids.is_empty() {
41+
return Some(decl_ids[0]);
42+
}
43+
44+
last_valid_decl_id.cloned()
45+
}
46+
47+
fn resolve_global_func_decl_id(
48+
db: &DbIndex,
49+
cache: &mut LuaInferCache,
50+
name: &str,
51+
call_expr: LuaCallExpr,
52+
) -> Option<LuaDeclId> {
53+
let decl_ids = db.get_global_index().get_global_decl_ids(name)?;
54+
let mut overload_signature = vec![];
55+
for decl_id in decl_ids {
56+
let decl_type_cache = db.get_type_index().get_type_cache(&(*decl_id).into());
57+
if let Some(type_cache) = decl_type_cache {
58+
let typ = type_cache.as_type();
59+
if typ.is_def() || typ.is_ref() || typ.is_table() {
60+
return Some(*decl_id);
61+
}
62+
63+
if let LuaType::Signature(signature) = typ {
64+
let signature = db.get_signature_index().get(signature)?;
65+
overload_signature.push((decl_id.clone(), signature.to_doc_func_type()));
66+
}
67+
}
68+
}
69+
70+
let signature = resolve_signature(
71+
db,
72+
cache,
73+
overload_signature
74+
.iter()
75+
.map(|(_, doc_func)| doc_func.clone())
76+
.collect(),
77+
call_expr,
78+
false,
79+
None,
80+
);
81+
82+
if let Ok(signature) = signature {
83+
for (decl_id, doc_func) in &overload_signature {
84+
if Arc::ptr_eq(&signature, doc_func) {
85+
return Some(decl_id.clone());
86+
}
87+
}
88+
}
89+
90+
overload_signature.first().map(|(id, _)| id.clone())
91+
}

0 commit comments

Comments
 (0)