Skip to content

Commit 86ae47e

Browse files
committed
Better support for the @module feature
Fix #842
1 parent 40da8e3 commit 86ae47e

File tree

13 files changed

+128
-36
lines changed

13 files changed

+128
-36
lines changed

crates/emmylua_code_analysis/src/compilation/analyzer/doc/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ impl AnalysisPipeline for DocAnalysisPipeline {
3434
&mut generic_index,
3535
comment,
3636
root.syntax().clone(),
37-
context,
3837
);
3938
analyze_comment(&mut analyzer);
4039
}
@@ -71,7 +70,6 @@ pub struct DocAnalyzer<'a> {
7170
comment: LuaComment,
7271
root: LuaSyntaxNode,
7372
is_meta: bool,
74-
context: &'a mut AnalyzeContext,
7573
}
7674

7775
impl<'a> DocAnalyzer<'a> {
@@ -81,7 +79,6 @@ impl<'a> DocAnalyzer<'a> {
8179
generic_index: &'a mut FileGenericIndex,
8280
comment: LuaComment,
8381
root: LuaSyntaxNode,
84-
context: &'a mut AnalyzeContext,
8582
) -> DocAnalyzer<'a> {
8683
let is_meta = db.get_module_index().is_meta_file(&file_id);
8784
DocAnalyzer {
@@ -92,7 +89,6 @@ impl<'a> DocAnalyzer<'a> {
9289
comment,
9390
root,
9491
is_meta,
95-
context,
9692
}
9793
}
9894
}

crates/emmylua_code_analysis/src/compilation/analyzer/doc/type_ref_tags.rs

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ use super::{
1212
tags::{find_owner_closure, get_owner_id_or_report},
1313
};
1414
use crate::{
15-
InFiled, InferFailReason, LuaOperatorMetaMethod, LuaTypeCache, LuaTypeOwner, OperatorFunction,
15+
InFiled, LuaOperatorMetaMethod, LuaTypeCache, LuaTypeOwner, OperatorFunction,
1616
SignatureReturnStatus, TypeOps,
17-
compilation::analyzer::{common::bind_type, unresolve::UnResolveModuleRef},
17+
compilation::analyzer::common::bind_type,
1818
db_index::{
1919
LuaDeclId, LuaDocParamInfo, LuaDocReturnInfo, LuaMemberId, LuaOperator, LuaSemanticDeclId,
2020
LuaSignatureId, LuaType,
@@ -335,34 +335,23 @@ pub fn analyze_overload(analyzer: &mut DocAnalyzer, tag: LuaDocTagOverload) -> O
335335
pub fn analyze_module(analyzer: &mut DocAnalyzer, tag: LuaDocTagModule) -> Option<()> {
336336
let module_path = tag.get_string_token()?.get_value();
337337
let module_info = analyzer.db.get_module_index().find_module(&module_path)?;
338-
let export_type = module_info.export_type.clone();
339338
let module_file_id = module_info.file_id;
340339
let owner_id = get_owner_id_or_report(analyzer, &tag)?;
341-
if let Some(export_type) = export_type {
342-
match &owner_id {
343-
LuaSemanticDeclId::LuaDecl(decl_id) => {
344-
analyzer.db.get_type_index_mut().bind_type(
345-
(*decl_id).into(),
346-
LuaTypeCache::DocType(export_type.clone()),
347-
);
348-
}
349-
LuaSemanticDeclId::Member(member_id) => {
350-
analyzer.db.get_type_index_mut().bind_type(
351-
(*member_id).into(),
352-
LuaTypeCache::DocType(export_type.clone()),
353-
);
354-
}
355-
_ => {}
340+
let module_ref = LuaType::ModuleRef(module_file_id);
341+
match &owner_id {
342+
LuaSemanticDeclId::LuaDecl(decl_id) => {
343+
analyzer
344+
.db
345+
.get_type_index_mut()
346+
.bind_type((*decl_id).into(), LuaTypeCache::DocType(module_ref));
356347
}
357-
} else {
358-
let unresolve = UnResolveModuleRef {
359-
module_file_id,
360-
owner_id,
361-
};
362-
363-
analyzer
364-
.context
365-
.add_unresolve(unresolve.into(), InferFailReason::None);
348+
LuaSemanticDeclId::Member(member_id) => {
349+
analyzer
350+
.db
351+
.get_type_index_mut()
352+
.bind_type((*member_id).into(), LuaTypeCache::DocType(module_ref));
353+
}
354+
_ => {}
366355
}
367356

368357
Some(())

crates/emmylua_code_analysis/src/compilation/analyzer/unresolve/check_reason.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ pub fn check_reach_reason(
4444
let signature = db.get_signature_index().get(signature_id)?;
4545
Some(signature.is_resolve_return())
4646
}
47+
InferFailReason::UnResolveModuleExport(file_id) => {
48+
let module = db.get_module_index().get_module(*file_id)?;
49+
Some(module.export_type.is_some())
50+
}
4751
}
4852
}
4953

@@ -104,6 +108,12 @@ pub fn resolve_as_any(db: &mut DbIndex, reason: &InferFailReason, loop_count: us
104108
signature.resolve_return = SignatureReturnStatus::InferResolve;
105109
}
106110
}
111+
InferFailReason::UnResolveModuleExport(file_id) => {
112+
let module = db.get_module_index_mut().get_module_mut(*file_id)?;
113+
if module.export_type.is_none() {
114+
module.export_type = Some(LuaType::Any);
115+
}
116+
}
107117
}
108118

109119
Some(())

crates/emmylua_code_analysis/src/compilation/test/module_annotation.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ mod test {
2323
);
2424

2525
let aaa_ty = ws.expr_ty("aaa");
26-
let expected = ws.expr_ty("require('a')");
27-
assert_eq!(aaa_ty, expected);
26+
assert!(aaa_ty.is_module_ref());
2827
}
2928
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,17 @@ pub fn humanize_type(db: &DbIndex, ty: &LuaType, level: RenderLevel) -> String {
110110
LuaType::Conditional(c) => humanize_conditional_type(db, c, level),
111111
LuaType::ConditionalInfer(s) => s.to_string(),
112112
LuaType::Never => "never".to_string(),
113+
LuaType::ModuleRef(file_id) => {
114+
if let Some(module_info) = db.get_module_index().get_module(*file_id) {
115+
humanize_type(
116+
db,
117+
&module_info.export_type.clone().unwrap_or(LuaType::Any),
118+
level,
119+
)
120+
} else {
121+
"module 'unknown'".to_string()
122+
}
123+
}
113124
_ => "unknown".to_string(),
114125
}
115126
}

crates/emmylua_code_analysis/src/db_index/type/types.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,10 @@ impl LuaType {
493493
}
494494
}
495495
}
496+
497+
pub fn is_module_ref(&self) -> bool {
498+
matches!(self, LuaType::ModuleRef(_))
499+
}
496500
}
497501

498502
impl TypeVisitTrait for LuaType {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use emmylua_parser::LuaExpr;
22

3-
use crate::{InFiled, LuaDeclId, LuaMemberId, LuaSignatureId};
3+
use crate::{FileId, InFiled, LuaDeclId, LuaMemberId, LuaSignatureId};
44

55
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
66
pub enum InferFailReason {
@@ -12,6 +12,7 @@ pub enum InferFailReason {
1212
UnResolveDeclType(LuaDeclId),
1313
UnResolveMemberType(LuaMemberId),
1414
UnResolveOperatorCall,
15+
UnResolveModuleExport(FileId),
1516
}
1617

1718
impl InferFailReason {
@@ -24,6 +25,7 @@ impl InferFailReason {
2425
| InferFailReason::UnResolveDeclType(_)
2526
| InferFailReason::UnResolveMemberType(_)
2627
| InferFailReason::UnResolveOperatorCall
28+
| InferFailReason::UnResolveModuleExport(_)
2729
)
2830
}
2931
}

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,24 @@ pub fn infer_member_by_member_key(
189189
LuaType::Namespace(ns) => infer_namespace_member(db, cache, ns, index_expr),
190190
LuaType::Array(array_type) => infer_array_member(db, cache, array_type, index_expr),
191191
LuaType::TplRef(tpl) => infer_tpl_ref_member(db, cache, tpl, index_expr, infer_guard),
192+
LuaType::ModuleRef(file_id) => {
193+
let module_info = db.get_module_index().get_module(*file_id);
194+
if let Some(module_info) = module_info {
195+
if let Some(export_type) = &module_info.export_type {
196+
return infer_member_by_member_key(
197+
db,
198+
cache,
199+
export_type,
200+
index_expr,
201+
infer_guard,
202+
);
203+
} else {
204+
return Err(InferFailReason::UnResolveModuleExport(*file_id));
205+
}
206+
}
207+
208+
Err(InferFailReason::FieldNotFound)
209+
}
192210
_ => Err(InferFailReason::FieldNotFound),
193211
}
194212
}
@@ -818,6 +836,24 @@ pub fn infer_member_by_operator(
818836
let base = inst.get_base();
819837
infer_member_by_operator(db, cache, base, index_expr, infer_guard)
820838
}
839+
LuaType::ModuleRef(file_id) => {
840+
let module_info = db.get_module_index().get_module(*file_id);
841+
if let Some(module_info) = module_info {
842+
if let Some(export_type) = &module_info.export_type {
843+
return infer_member_by_operator(
844+
db,
845+
cache,
846+
export_type,
847+
index_expr,
848+
infer_guard,
849+
);
850+
} else {
851+
return Err(InferFailReason::UnResolveModuleExport(*file_id));
852+
}
853+
}
854+
855+
Err(InferFailReason::FieldNotFound)
856+
}
821857
_ => Err(InferFailReason::FieldNotFound),
822858
}
823859
}

crates/emmylua_code_analysis/src/semantic/member/find_index.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ pub fn find_index_operations_guard(
3838
let base = inst.get_base();
3939
find_index_operations_guard(db, base, infer_guard)
4040
}
41+
LuaType::ModuleRef(file_id) => {
42+
let module_info = db.get_module_index().get_module(*file_id);
43+
if let Some(module_info) = module_info
44+
&& let Some(export_type) = &module_info.export_type
45+
{
46+
return find_index_operations_guard(db, export_type, infer_guard);
47+
}
48+
49+
None
50+
}
4151
_ => None,
4252
}
4353
}

crates/emmylua_code_analysis/src/semantic/member/find_members.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,16 @@ fn find_members_guard(
9595
LuaType::Global => find_global_members(db, filter),
9696
LuaType::Instance(inst) => find_instance_members(db, inst, infer_guard, filter),
9797
LuaType::Namespace(ns) => find_namespace_members(db, ns, filter),
98+
LuaType::ModuleRef(file_id) => {
99+
let module_info = db.get_module_index().get_module(*file_id);
100+
if let Some(module_info) = module_info
101+
&& let Some(export_type) = &module_info.export_type
102+
{
103+
return find_members_guard(db, export_type, infer_guard, filter);
104+
}
105+
106+
None
107+
}
98108
_ => None,
99109
}
100110
}

0 commit comments

Comments
 (0)