Skip to content

Commit a3a27a6

Browse files
authored
Merge pull request #857 from xuhuanzy/fix
update
2 parents 4d6f7da + 120d3c7 commit a3a27a6

File tree

24 files changed

+1129
-463
lines changed

24 files changed

+1129
-463
lines changed

crates/emmylua_code_analysis/resources/std/builtin.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@
100100

101101
---@class void
102102

103+
---@class unknown
104+
105+
---@class never
106+
103107
---@class self
104108

105109
---@alias int integer
@@ -145,6 +149,8 @@
145149
--- Get the parameters of a constructor as a tuple
146150
---@alias ConstructorParameters<T> T extends new (fun(...: infer P): any) and P or never
147151

152+
---@alias ReturnType<T extends function> T extends (fun(...: any): infer R) and R or any
153+
148154
--- Make all properties in T optional
149155
---@alias Partial<T> { [P in keyof T]?: T[P]; }
150156

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

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::collections::HashMap;
22

33
use rowan::{TextRange, TextSize};
44

5-
use crate::{GenericParam, GenericTplId};
5+
use crate::{GenericParam, GenericTplId, LuaType};
66

77
#[derive(Debug, Clone)]
88
pub struct FileGenericIndex {
@@ -20,18 +20,12 @@ impl FileGenericIndex {
2020
}
2121
}
2222

23-
pub fn add_generic_scope(
24-
&mut self,
25-
ranges: Vec<TextRange>,
26-
params: Vec<GenericParam>,
27-
is_func: bool,
28-
) {
29-
let params_id = self.generic_params.len();
30-
// 由于我们允许 infer 推断出一个虚拟泛型, 因此需要计算已声明的泛型数量确定其位置
23+
pub fn add_generic_scope(&mut self, ranges: Vec<TextRange>, is_func: bool) -> GenericParamId {
24+
let params_index = self.generic_params.len();
3125
let start = self.get_start(&ranges).unwrap_or(0);
3226
self.generic_params
33-
.push(TagGenericParams::new(params, is_func, start));
34-
let params_id = GenericParamId::new(params_id);
27+
.push(TagGenericParams::new(is_func, start));
28+
let params_id = GenericParamId::new(params_index);
3529
let root_node_ids: Vec<_> = self.root_node_ids.clone();
3630
for range in ranges {
3731
let mut added = false;
@@ -53,6 +47,33 @@ impl FileGenericIndex {
5347
self.root_node_ids.push(GenericEffectId::new(child_node_id));
5448
}
5549
}
50+
51+
params_id
52+
}
53+
54+
pub fn append_generic_param(&mut self, scope_id: GenericParamId, param: GenericParam) {
55+
if let Some(scope) = self.generic_params.get_mut(scope_id.id) {
56+
scope.insert_param(param);
57+
}
58+
}
59+
60+
pub fn append_generic_params(&mut self, scope_id: GenericParamId, params: Vec<GenericParam>) {
61+
for param in params {
62+
self.append_generic_param(scope_id, param);
63+
}
64+
}
65+
66+
pub fn set_param_constraint(
67+
&mut self,
68+
scope_id: GenericParamId,
69+
name: &str,
70+
constraint: Option<LuaType>,
71+
) {
72+
if let Some(scope) = self.generic_params.get_mut(scope_id.id)
73+
&& let Some((_idx, stored_param)) = scope.params.get_mut(name)
74+
{
75+
stored_param.type_constraint = constraint;
76+
}
5677
}
5778

5879
fn get_start(&self, ranges: &[TextRange]) -> Option<usize> {
@@ -107,19 +128,24 @@ impl FileGenericIndex {
107128
}
108129

109130
/// Find generic parameter by position and name.
110-
/// return (GenericTplId, is_variadic)
111-
pub fn find_generic(&self, position: TextSize, name: &str) -> Option<GenericTplId> {
131+
/// return (GenericTplId, constraint)
132+
pub fn find_generic(
133+
&self,
134+
position: TextSize,
135+
name: &str,
136+
) -> Option<(GenericTplId, Option<LuaType>)> {
112137
let params_ids = self.find_generic_params(position)?;
113138

114139
for params_id in params_ids.iter().rev() {
115140
if let Some(params) = self.generic_params.get(*params_id)
116-
&& let Some(id) = params.params.get(name)
141+
&& let Some((id, param)) = params.params.get(name)
117142
{
118-
if params.is_func {
119-
return Some(GenericTplId::Func(*id as u32));
143+
let tpl_id = if params.is_func {
144+
GenericTplId::Func(*id as u32)
120145
} else {
121-
return Some(GenericTplId::Type(*id as u32));
122-
}
146+
GenericTplId::Type(*id as u32)
147+
};
148+
return Some((tpl_id, param.type_constraint.clone()));
123149
}
124150
}
125151

@@ -193,16 +219,24 @@ impl GenericEffectId {
193219

194220
#[derive(Debug, Clone, PartialEq, Eq)]
195221
pub struct TagGenericParams {
196-
params: HashMap<String, usize>,
222+
params: HashMap<String, (usize, GenericParam)>,
197223
is_func: bool,
224+
next_index: usize,
198225
}
199226

200227
impl TagGenericParams {
201-
pub fn new(generic_params: Vec<GenericParam>, is_func: bool, start: usize) -> Self {
202-
let mut params = HashMap::new();
203-
for (i, param) in generic_params.into_iter().enumerate() {
204-
params.insert(param.name.to_string(), start + i);
228+
pub fn new(is_func: bool, start: usize) -> Self {
229+
Self {
230+
params: HashMap::new(),
231+
is_func,
232+
next_index: start,
205233
}
206-
Self { params, is_func }
234+
}
235+
236+
fn insert_param(&mut self, param: GenericParam) {
237+
let current_index = self.next_index;
238+
self.next_index += 1;
239+
self.params
240+
.insert(param.name.to_string(), (current_index, param));
207241
}
208242
}

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

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,12 @@ fn infer_buildin_or_ref_type(
164164
LuaType::Table
165165
}
166166
_ => {
167-
if let Some(tpl_id) = analyzer.generic_index.find_generic(position, name) {
167+
if let Some((tpl_id, constraint)) = analyzer.generic_index.find_generic(position, name)
168+
{
168169
return LuaType::TplRef(Arc::new(GenericTpl::new(
169170
tpl_id,
170171
SmolStr::new(name).into(),
172+
constraint,
171173
)));
172174
}
173175

@@ -570,9 +572,12 @@ fn register_inline_func_generics(
570572
return;
571573
}
572574

575+
let scope_id = analyzer
576+
.generic_index
577+
.add_generic_scope(vec![func.get_range()], true);
573578
analyzer
574579
.generic_index
575-
.add_generic_scope(vec![func.get_range()], generics, true);
580+
.append_generic_params(scope_id, generics);
576581
}
577582

578583
fn get_colon_define(analyzer: &mut DocAnalyzer) -> Option<bool> {
@@ -633,10 +638,16 @@ fn infer_str_tpl(
633638
let typ = infer_buildin_or_ref_type(analyzer, &tpl, str_tpl.get_range(), node);
634639
if let LuaType::TplRef(tpl) = typ {
635640
let tpl_id = tpl.get_tpl_id();
636-
let prefix = prefix.unwrap_or("".to_string());
637-
let suffix = suffix.unwrap_or("".to_string());
641+
let prefix = prefix.unwrap_or_default();
642+
let suffix = suffix.unwrap_or_default();
638643
if tpl_id.is_func() {
639-
let str_tpl_type = LuaStringTplType::new(&prefix, tpl.get_name(), tpl_id, &suffix);
644+
let str_tpl_type = LuaStringTplType::new(
645+
&prefix,
646+
tpl.get_name(),
647+
tpl_id,
648+
&suffix,
649+
tpl.get_constraint().cloned(),
650+
);
640651
return LuaType::StrTplRef(str_tpl_type.into());
641652
}
642653
}
@@ -731,9 +742,12 @@ fn infer_conditional_type(
731742
if !infer_params.is_empty() {
732743
// 条件表达式中 infer 声明的类型参数只允许在`true`分支中使用
733744
let true_range = when_true.get_range();
745+
let scope_id = analyzer
746+
.generic_index
747+
.add_generic_scope(vec![true_range], false);
734748
analyzer
735749
.generic_index
736-
.add_generic_scope(vec![true_range], infer_params.clone(), false);
750+
.append_generic_params(scope_id, infer_params.clone());
737751
}
738752

739753
// 处理条件和分支类型
@@ -780,13 +794,14 @@ fn infer_mapped_type(
780794
.map(|constraint| infer_type(analyzer, constraint));
781795
let param = GenericParam::new(SmolStr::new(name), constraint, None);
782796

783-
analyzer.generic_index.add_generic_scope(
784-
vec![mapped_type.get_range()],
785-
vec![param.clone()],
786-
false,
787-
);
797+
let scope_id = analyzer
798+
.generic_index
799+
.add_generic_scope(vec![mapped_type.get_range()], false);
800+
analyzer
801+
.generic_index
802+
.append_generic_param(scope_id, param.clone());
788803
let position = mapped_type.get_range().start();
789-
let id = analyzer.generic_index.find_generic(position, name)?;
804+
let (id, _) = analyzer.generic_index.find_generic(position, name)?;
790805

791806
let doc_type = mapped_type.get_value_type()?;
792807
let value_type = infer_type(analyzer, doc_type);

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

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::{
2020
},
2121
};
2222
use std::sync::Arc;
23+
use std::vec;
2324

2425
pub fn analyze_class(analyzer: &mut DocAnalyzer, tag: LuaDocTagClass) -> Option<()> {
2526
let file_id = analyzer.file_id;
@@ -149,9 +150,10 @@ pub fn analyze_alias(analyzer: &mut DocAnalyzer, tag: LuaDocTagAlias) -> Option<
149150
.get_type_index_mut()
150151
.add_generic_params(alias_decl_id.clone(), generic_params.clone());
151152
let range = analyzer.comment.get_range();
153+
let scope_id = analyzer.generic_index.add_generic_scope(vec![range], false);
152154
analyzer
153155
.generic_index
154-
.add_generic_scope(vec![range], generic_params, false);
156+
.append_generic_params(scope_id, generic_params);
155157
}
156158

157159
let origin_type = infer_type(analyzer, tag.get_type()?);
@@ -240,9 +242,10 @@ fn add_generic_index(
240242
}
241243
}
242244

245+
let scope_id = analyzer.generic_index.add_generic_scope(ranges, false);
243246
analyzer
244247
.generic_index
245-
.add_generic_scope(ranges, generic_params, false);
248+
.append_generic_params(scope_id, generic_params);
246249
}
247250

248251
fn get_local_stat_reference_ranges(
@@ -334,37 +337,40 @@ pub fn analyze_func_generic(analyzer: &mut DocAnalyzer, tag: LuaDocTagGeneric) -
334337
report_orphan_tag(analyzer, &tag);
335338
return None;
336339
};
337-
let mut params_result = vec![];
340+
341+
let scope_id = analyzer.generic_index.add_generic_scope(
342+
vec![analyzer.comment.get_range(), comment_owner.get_range()],
343+
true,
344+
);
345+
338346
let mut param_info = Vec::new();
339347
if let Some(params_list) = tag.get_generic_decl_list() {
340348
for param in params_list.get_generic_decl() {
341-
let name = if let Some(param) = param.get_name_token() {
342-
param.get_name_text().to_string()
343-
} else {
349+
let Some(name_token) = param.get_name_token() else {
344350
continue;
345351
};
352+
let name_text = name_token.get_name_text().to_string();
353+
let smol_name = SmolStr::new(name_text.as_str());
354+
analyzer
355+
.generic_index
356+
.append_generic_param(scope_id, GenericParam::new(smol_name.clone(), None, None));
357+
346358
let type_ref = param
347359
.get_type()
348360
.map(|type_ref| infer_type(analyzer, type_ref));
349361

350-
params_result.push(GenericParam::new(
351-
SmolStr::new(name.as_str()),
362+
analyzer.generic_index.set_param_constraint(
363+
scope_id,
364+
name_text.as_str(),
352365
type_ref.clone(),
353-
None,
354-
));
355-
param_info.push(Arc::new(LuaGenericParamInfo::new(name, type_ref, None)));
366+
);
367+
368+
param_info.push(Arc::new(LuaGenericParamInfo::new(
369+
name_text, type_ref, None,
370+
)));
356371
}
357372
}
358373

359-
let mut ranges = Vec::new();
360-
let range = analyzer.comment.get_range();
361-
ranges.push(range);
362-
let range = comment_owner.get_range();
363-
ranges.push(range);
364-
analyzer
365-
.generic_index
366-
.add_generic_scope(ranges, params_result, true);
367-
368374
let closure = find_owner_closure(analyzer)?;
369375
let signature_id = LuaSignatureId::from_closure(analyzer.file_id, &closure);
370376
let signature = analyzer

0 commit comments

Comments
 (0)