Skip to content

Commit dc051ab

Browse files
committed
移除泛型实例化过程中可变类型自动转换元组
1 parent 12b047f commit dc051ab

File tree

3 files changed

+109
-109
lines changed

3 files changed

+109
-109
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ mod test {
164164
let mut ws = VirtualWorkspace::new();
165165
ws.def(
166166
r#"
167-
---@alias Predicate<A: any[]> fun(...: A): boolean
167+
---@alias Predicate<A> fun(...: A...): boolean
168168
---@type Predicate<[string, integer, table]>
169169
pred = function() end
170170
"#,
@@ -269,7 +269,7 @@ mod test {
269269
270270
---@generic T
271271
---@param fn T
272-
---@param ... Parameters<T>
272+
---@param ... Parameters<T>...
273273
function f(fn, ...)
274274
end
275275
"#,
@@ -442,7 +442,7 @@ mod test {
442442
443443
---@generic T
444444
---@param name `T`|T
445-
---@param ... ConstructorParameters<T>
445+
---@param ... ConstructorParameters<T>...
446446
function f(name, ...)
447447
end
448448
"#,

crates/emmylua_code_analysis/src/semantic/generic/instantiate_special_generic.rs

Lines changed: 49 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use std::ops::Deref;
1+
use std::{ops::Deref, vec};
22

33
use crate::{
4-
DbIndex, LuaAliasCallKind, LuaAliasCallType, LuaMemberKey, LuaTupleStatus, LuaTupleType,
5-
LuaType, TypeOps, VariadicType, get_member_map,
4+
DbIndex, LuaAliasCallKind, LuaAliasCallType, LuaMemberInfo, LuaMemberKey, LuaTupleStatus,
5+
LuaTupleType, LuaType, TypeOps, VariadicType, get_member_map,
66
semantic::{
77
generic::instantiate_type_generic::key_type_to_member_key,
88
member::{find_members, infer_raw_member_type},
@@ -42,10 +42,9 @@ pub fn instantiate_alias_call(
4242
if operands.len() != 1 {
4343
return LuaType::Unknown;
4444
}
45-
let is_tuple = operands.len() == 1 && operands[0].is_tuple();
46-
// TODO: 根据`Typescript`的规则, 当为类型联合时, 应该返回共有字段, 但现在并不是
45+
// let is_tuple = operands.len() == 1 && operands[0].is_tuple();
4746

48-
let members = find_members(db, &operands[0]).unwrap_or_default();
47+
let members = get_keyof_members(db, &operands[0]).unwrap_or_default();
4948
let member_key_types = members
5049
.iter()
5150
.filter_map(|m| match &m.key {
@@ -54,13 +53,14 @@ pub fn instantiate_alias_call(
5453
_ => None,
5554
})
5655
.collect::<Vec<_>>();
57-
if is_tuple {
58-
LuaType::Tuple(
59-
LuaTupleType::new(member_key_types, LuaTupleStatus::InferResolve).into(),
60-
)
61-
} else {
62-
LuaType::from_vec(member_key_types)
63-
}
56+
LuaType::Tuple(LuaTupleType::new(member_key_types, LuaTupleStatus::InferResolve).into())
57+
// if is_tuple {
58+
// LuaType::Tuple(
59+
// LuaTupleType::new(member_key_types, LuaTupleStatus::InferResolve).into(),
60+
// )
61+
// } else {
62+
// LuaType::from_vec(member_key_types)
63+
// }
6464
}
6565
// 条件类型不在此处理
6666
LuaAliasCallKind::Extends => {
@@ -265,73 +265,51 @@ fn instantiate_rawget_call(db: &DbIndex, owner: &LuaType, key: &LuaType) -> LuaT
265265
}
266266

267267
fn instantiate_index_call(db: &DbIndex, owner: &LuaType, key: &LuaType) -> LuaType {
268-
match owner {
269-
LuaType::Union(union) => {
270-
let results = union
271-
.into_vec()
272-
.iter()
273-
.map(|member| instantiate_index_call(db, member, key))
274-
.collect::<Vec<_>>();
275-
return LuaType::from_vec(results);
276-
}
277-
LuaType::Intersection(intersection) => {
278-
let results = intersection
279-
.get_types()
280-
.iter()
281-
.map(|member| instantiate_index_call(db, member, key))
282-
.collect::<Vec<_>>();
283-
return LuaType::from_vec(results);
284-
}
285-
LuaType::Variadic(variadic) => match variadic.deref() {
268+
if let LuaType::Variadic(variadic) = owner {
269+
match variadic.deref() {
286270
VariadicType::Base(base) => {
287-
return instantiate_index_call(db, base, key);
271+
return base.clone();
288272
}
289273
VariadicType::Multi(types) => {
290-
let results = types
291-
.iter()
292-
.map(|member| instantiate_index_call(db, member, key))
293-
.collect::<Vec<_>>();
294-
return LuaType::from_vec(results);
274+
if let LuaType::IntegerConst(key) | LuaType::DocIntegerConst(key) = key {
275+
return types.get(*key as usize).cloned().unwrap_or(LuaType::Never);
276+
}
295277
}
296-
},
297-
_ => {}
278+
}
298279
}
299280

300-
match key {
301-
LuaType::Union(union) => {
302-
let results = union
303-
.into_vec()
304-
.iter()
305-
.map(|member| instantiate_index_call(db, owner, member))
306-
.collect::<Vec<_>>();
307-
return LuaType::from_vec(results);
308-
}
309-
LuaType::MultiLineUnion(multi) => {
310-
let results = multi
311-
.get_unions()
312-
.iter()
313-
.map(|(member, _)| instantiate_index_call(db, owner, member))
314-
.collect::<Vec<_>>();
315-
return LuaType::from_vec(results);
316-
}
281+
if let Some(member_key) = key_type_to_member_key(key) {
282+
infer_raw_member_type(db, owner, &member_key).unwrap_or(LuaType::Never)
283+
} else {
284+
LuaType::Never
285+
}
286+
}
287+
288+
fn get_keyof_members(db: &DbIndex, prefix_type: &LuaType) -> Option<Vec<LuaMemberInfo>> {
289+
match prefix_type {
317290
LuaType::Variadic(variadic) => match variadic.deref() {
318-
VariadicType::Base(base) => {
319-
return instantiate_index_call(db, owner, base);
320-
}
291+
VariadicType::Base(base) => Some(vec![LuaMemberInfo {
292+
property_owner_id: None,
293+
key: LuaMemberKey::Integer(0),
294+
typ: base.clone(),
295+
feature: None,
296+
overload_index: None,
297+
}]),
321298
VariadicType::Multi(types) => {
322-
let results = types
323-
.iter()
324-
.map(|member| instantiate_index_call(db, owner, member))
325-
.collect::<Vec<_>>();
326-
return LuaType::from_vec(results);
299+
let mut members = Vec::new();
300+
for (idx, typ) in types.iter().enumerate() {
301+
members.push(LuaMemberInfo {
302+
property_owner_id: None,
303+
key: LuaMemberKey::Integer(idx as i64),
304+
typ: typ.clone(),
305+
feature: None,
306+
overload_index: None,
307+
});
308+
}
309+
310+
Some(members)
327311
}
328312
},
329-
_ => {}
330-
}
331-
332-
if let Some(member_key) = key_type_to_member_key(key) {
333-
infer_raw_member_type(db, owner, &member_key).unwrap_or(LuaType::Unknown)
334-
} else {
335-
LuaType::Unknown
313+
_ => find_members(db, prefix_type),
336314
}
337315
}

crates/emmylua_code_analysis/src/semantic/generic/instantiate_type_generic.rs

Lines changed: 57 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,12 @@ pub fn instantiate_doc_function(
129129
};
130130
match origin_param_type {
131131
LuaType::Variadic(variadic) => match variadic.deref() {
132-
VariadicType::Base(base) => {
133-
if let LuaType::TplRef(tpl) = base {
132+
VariadicType::Base(base) => match base {
133+
LuaType::TplRef(tpl) => {
134134
if tpl.is_variadic() {
135135
if let Some(generics) = substitutor.get_variadic(tpl.get_tpl_id()) {
136136
for (j, typ) in generics.iter().enumerate() {
137-
let param_name = format!("args_{}", i + j);
137+
let param_name = format!("var{}", i + j);
138138
new_params.push((param_name, Some(typ.clone())));
139139
}
140140
}
@@ -149,7 +149,7 @@ pub fn instantiate_doc_function(
149149
}
150150
SubstitutorValue::MultiTypes(types) => {
151151
for (i, typ) in types.iter().enumerate() {
152-
let param_name = format!("args_{}", i);
152+
let param_name = format!("var{}", i);
153153
new_params.push((param_name, Some(typ.clone())));
154154
}
155155
}
@@ -164,22 +164,37 @@ pub fn instantiate_doc_function(
164164
}
165165
}
166166
}
167-
}
167+
LuaType::Generic(generic) => {
168+
let new_type = instantiate_generic(db, generic, substitutor);
169+
// 如果是 rest 参数且实例化后的类型是 tuple, 那么我们将展开 tuple
170+
if let LuaType::Tuple(tuple_type) = &new_type {
171+
let base_index = new_params.len();
172+
for (offset, tuple_element) in tuple_type.get_types().iter().enumerate()
173+
{
174+
let param_name = format!("var{}", base_index + offset);
175+
new_params.push((param_name, Some(tuple_element.clone())));
176+
}
177+
continue;
178+
}
179+
new_params.push((origin_param.0.clone(), Some(new_type)));
180+
}
181+
_ => {}
182+
},
168183
VariadicType::Multi(_) => (),
169184
},
170185
_ => {
171186
let new_type = instantiate_type_generic(db, origin_param_type, substitutor);
172187
// 如果是 rest 参数且实例化后的类型是 tuple, 那么我们将展开 tuple
173-
if origin_param.0 == "..." && tpl_func_params.len() == i + 1 {
174-
if let LuaType::Tuple(tuple_type) = &new_type {
175-
let base_index = new_params.len();
176-
for (offset, tuple_element) in tuple_type.get_types().iter().enumerate() {
177-
let param_name = format!("args_{}", base_index + offset);
178-
new_params.push((param_name, Some(tuple_element.clone())));
179-
}
180-
continue;
181-
}
182-
}
188+
// if origin_param.0 == "..." && tpl_func_params.len() == i + 1 {
189+
// if let LuaType::Tuple(tuple_type) = &new_type {
190+
// let base_index = new_params.len();
191+
// for (offset, tuple_element) in tuple_type.get_types().iter().enumerate() {
192+
// let param_name = format!("var{}", base_index + offset);
193+
// new_params.push((param_name, Some(tuple_element.clone())));
194+
// }
195+
// continue;
196+
// }
197+
// }
183198
new_params.push((origin_param.0.clone(), Some(new_type)));
184199
}
185200
}
@@ -202,6 +217,9 @@ pub fn instantiate_doc_function(
202217
}
203218
}
204219
}
220+
// dbg!(&new_params);
221+
// dbg!(&inst_ret_type);
222+
// dbg!(&modified_substitutor);
205223

206224
LuaType::DocFunction(
207225
LuaFunctionType::new(async_state, colon_define, new_params, inst_ret_type).into(),
@@ -267,17 +285,17 @@ fn instantiate_generic(
267285
let mut new_params = Vec::new();
268286
for param in generic_params {
269287
let new_param = instantiate_type_generic(db, param, substitutor);
270-
if let LuaType::Variadic(variadic) = &new_param {
271-
match variadic.deref() {
272-
VariadicType::Base(_) => {}
273-
VariadicType::Multi(types) => {
274-
for typ in types {
275-
new_params.push(typ.clone());
276-
}
277-
continue;
278-
}
279-
}
280-
}
288+
// if let LuaType::Variadic(variadic) = &new_param {
289+
// match variadic.deref() {
290+
// VariadicType::Base(_) => {}
291+
// VariadicType::Multi(types) => {
292+
// for typ in types {
293+
// new_params.push(typ.clone());
294+
// }
295+
// continue;
296+
// }
297+
// }
298+
// }
281299
new_params.push(new_param);
282300
}
283301

@@ -319,12 +337,14 @@ fn instantiate_tpl_ref(_: &DbIndex, tpl: &GenericTpl, substitutor: &TypeSubstitu
319337
// 泛型是否以`T...`定义(非使用), 以`T...`定义的泛型我们应该将其视为一个元组
320338
if tpl.is_variadic() {
321339
if let Some(generics) = substitutor.get_variadic(tpl.get_tpl_id()) {
322-
if generics.len() == 1 {
323-
return generics[0].clone();
324-
} else {
325-
return LuaType::Tuple(
326-
LuaTupleType::new(generics.clone(), LuaTupleStatus::DocResolve).into(),
327-
);
340+
match generics.len() {
341+
1 => return generics[0].clone(),
342+
_ => {
343+
return LuaType::Variadic(VariadicType::Multi(generics.clone()).into());
344+
// return LuaType::Tuple(
345+
// LuaTupleType::new(generics.clone(), LuaTupleStatus::DocResolve).into(),
346+
// );
347+
}
328348
}
329349
} else {
330350
return LuaType::Never;
@@ -466,6 +486,9 @@ fn instantiate_conditional(
466486
// 记录右侧出现的每个 infer 名称对应的具体类型
467487
let mut infer_assignments: HashMap<String, LuaType> = HashMap::new();
468488
let mut condition_result: Option<bool> = None;
489+
// dbg!(&conditional);
490+
// dbg!(&substitutor);
491+
// println!("substitutor: {:?}", substitutor);
469492

470493
// 仅当条件形如 T extends ... 时才尝试提前求值, 否则返回原始结构
471494
if let LuaType::Call(alias_call) = conditional.get_condition()
@@ -488,6 +511,8 @@ fn instantiate_conditional(
488511
}
489512
}
490513
}
514+
// dbg!(&left);
515+
// dbg!(&right);
491516

492517
// infer 必须位于条件语句中(right), 判断是否包含并收集
493518
if contains_conditional_infer(&right)
@@ -774,9 +799,6 @@ fn instantiate_mapped_type(
774799
.type_constraint
775800
.as_ref()
776801
.map(|ty| instantiate_type_generic(db, ty, substitutor));
777-
dbg!(&mapped);
778-
dbg!(&substitutor);
779-
dbg!(&constraint);
780802

781803
if let Some(constraint) = constraint {
782804
let mut key_types = Vec::new();

0 commit comments

Comments
 (0)