Skip to content

Commit e3b555e

Browse files
committed
make unpack support array
1 parent 7252f36 commit e3b555e

File tree

4 files changed

+60
-6
lines changed

4 files changed

+60
-6
lines changed

crates/emmylua_code_analysis/src/semantic/instantiate/instantiate_class_generic.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ fn instantiate_tuple(db: &DbIndex, tuple: &LuaTupleType, substitutor: &TypeSubst
6868
}
6969
}
7070
SubstitutorValue::Type(ty) => new_types.push(ty.clone()),
71+
SubstitutorValue::MultiBase(base) => new_types.push(base.clone()),
7172
}
7273
}
7374
}
@@ -135,7 +136,17 @@ pub fn instantiate_doc_function(
135136
new_returns.push(typ.clone());
136137
}
137138
}
138-
_ => {}
139+
SubstitutorValue::Params(params) => {
140+
for (_, ty) in params {
141+
new_returns.push(ty.clone().unwrap_or(LuaType::Unknown));
142+
}
143+
}
144+
SubstitutorValue::Type(ty) => new_returns.push(ty.clone()),
145+
SubstitutorValue::MultiBase(base) => {
146+
new_returns.push(LuaType::MuliReturn(
147+
LuaMultiReturn::Base(base.clone()).into(),
148+
));
149+
}
139150
}
140151
}
141152
}
@@ -264,6 +275,7 @@ fn instantiate_tpl_ref(_: &DbIndex, tpl: &GenericTpl, substitutor: &TypeSubstitu
264275
.clone()
265276
.unwrap_or(LuaType::Unknown);
266277
}
278+
SubstitutorValue::MultiBase(base) => return base.clone(),
267279
}
268280
}
269281

@@ -505,6 +517,9 @@ fn instantiate_variadic_type(
505517
.collect::<Vec<_>>();
506518
return LuaType::MuliReturn(LuaMultiReturn::Multi(types).into());
507519
}
520+
SubstitutorValue::MultiBase(base) => {
521+
return LuaType::MuliReturn(LuaMultiReturn::Base(base.clone()).into());
522+
}
508523
}
509524
}
510525
}

crates/emmylua_code_analysis/src/semantic/instantiate/test.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,24 @@ mod test {
6363
let expected = ws.expr_ty("2");
6464
assert_eq!(h, expected);
6565
}
66+
67+
#[test]
68+
fn test_unpack() {
69+
let mut ws = crate::VirtualWorkspace::new_with_init_std_lib();
70+
71+
ws.def(r#"
72+
local h ---@type number[]
73+
a, b, c = table.unpack(h)
74+
"#);
75+
76+
let a = ws.expr_ty("a");
77+
let expected = ws.ty("number");
78+
let b = ws.expr_ty("b");
79+
let expected_b = ws.ty("number");
80+
let c = ws.expr_ty("c");
81+
let expected_c = ws.ty("number");
82+
assert_eq!(a, expected);
83+
assert_eq!(b, expected_b);
84+
assert_eq!(c, expected_c);
85+
}
6686
}

crates/emmylua_code_analysis/src/semantic/instantiate/tpl_pattern.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use emmylua_parser::{LuaAstNode, LuaSyntaxId, LuaSyntaxNode, LuaTableExpr};
44
use smol_str::SmolStr;
55

66
use crate::{
7-
db_index::{DbIndex, LuaGenericType, LuaType}, semantic::{infer_expr, LuaInferConfig}, LuaFunctionType, LuaTupleType, LuaUnionType
7+
db_index::{DbIndex, LuaGenericType, LuaType},
8+
semantic::{infer_expr, LuaInferConfig},
9+
LuaFunctionType, LuaTupleType, LuaUnionType,
810
};
911

1012
use super::type_substitutor::TypeSubstitutor;
@@ -346,11 +348,18 @@ fn tuple_tpl_pattern_match(
346348
tpl_pattern_match(db, config, root, tpl_type, target_type, substitutor);
347349
}
348350
}
349-
// LuaType::Array(target_array_base) => {
350-
351-
// }
351+
LuaType::Array(target_array_base) => {
352+
let tupl_tuple_types = tpl_tuple.get_types();
353+
let last_type = tupl_tuple_types.last()?;
354+
if let LuaType::Variadic(inner) = last_type {
355+
if let LuaType::TplRef(tpl_ref) = inner.deref() {
356+
let tpl_id = tpl_ref.get_tpl_id();
357+
substitutor.insert_multi_base(tpl_id, target_array_base.deref().clone());
358+
}
359+
}
360+
}
352361
_ => {}
353362
}
354363

355364
Some(())
356-
}
365+
}

crates/emmylua_code_analysis/src/semantic/instantiate/type_substitutor.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ impl TypeSubstitutor {
6565
.insert(tpl_id, SubstitutorValue::MultiTypes(types));
6666
}
6767

68+
pub fn insert_multi_base(&mut self, tpl_id: GenericTplId, type_base: LuaType) {
69+
if self.tpl_replace_map.contains_key(&tpl_id) {
70+
return;
71+
}
72+
73+
self.tpl_replace_map
74+
.insert(tpl_id, SubstitutorValue::MultiBase(type_base));
75+
}
76+
6877
pub fn get(&self, tpl_id: GenericTplId) -> Option<&SubstitutorValue> {
6978
self.tpl_replace_map.get(&tpl_id)
7079
}
@@ -85,4 +94,5 @@ pub enum SubstitutorValue {
8594
Type(LuaType),
8695
Params(Vec<(String, Option<LuaType>)>),
8796
MultiTypes(Vec<LuaType>),
97+
MultiBase(LuaType),
8898
}

0 commit comments

Comments
 (0)