Skip to content

Commit 8a840cc

Browse files
committed
update resolve signature
fix #633
1 parent 25f61a4 commit 8a840cc

File tree

2 files changed

+87
-8
lines changed

2 files changed

+87
-8
lines changed

crates/emmylua_code_analysis/src/diagnostic/test/missing_parameter_test.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,4 +195,35 @@ mod test {
195195
"#
196196
));
197197
}
198+
199+
#[test]
200+
fn test_issue_633() {
201+
let mut ws = VirtualWorkspace::new();
202+
ws.def_file(
203+
"test.lua",
204+
r#"
205+
---@param mode number
206+
---@param a number
207+
---@param b number
208+
---@param c number
209+
---@param d number?
210+
---@return string
211+
---@overload fun(mode:number, a:number, b:number):number
212+
function test(mode, a, b, c, d)
213+
end
214+
215+
---@return number, number
216+
function getNumbers()
217+
return 1, 2
218+
end
219+
"#,
220+
);
221+
222+
assert!(ws.check_code_for_namespace(
223+
DiagnosticCode::MissingParameter,
224+
r#"
225+
test(1, getNumbers())
226+
"#
227+
));
228+
}
198229
}

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

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
use std::sync::Arc;
1+
use std::{ops::Deref, sync::Arc};
22

3-
use emmylua_parser::LuaCallExpr;
3+
use emmylua_parser::{LuaCallExpr, LuaExpr};
44

5-
use crate::db_index::{DbIndex, LuaFunctionType, LuaType};
5+
use crate::{
6+
VariadicType,
7+
db_index::{DbIndex, LuaFunctionType, LuaType},
8+
infer_expr,
9+
};
610

711
use super::{
812
LuaInferCache,
913
generic::instantiate_func_generic,
1014
infer::{InferCallFuncResult, InferFailReason},
11-
infer_expr,
1215
type_check::check_type_compact,
1316
};
1417

@@ -21,10 +24,12 @@ pub fn resolve_signature(
2124
arg_count: Option<usize>,
2225
) -> InferCallFuncResult {
2326
let args = call_expr.get_args_list().ok_or(InferFailReason::None)?;
24-
let mut expr_types = Vec::new();
25-
for arg in args.get_args() {
26-
expr_types.push(infer_expr(db, cache, arg)?);
27-
}
27+
let expr_types = infer_expr_list_types(
28+
db,
29+
cache,
30+
args.get_args().collect::<Vec<_>>().as_slice(),
31+
arg_count,
32+
);
2833
if is_generic {
2934
resolve_signature_by_generic(db, cache, overloads, call_expr, expr_types, arg_count)
3035
} else {
@@ -139,3 +144,46 @@ fn resolve_signature_by_args(
139144
.or_else(|| overloads.last().cloned())
140145
.ok_or(InferFailReason::None)
141146
}
147+
148+
fn infer_expr_list_types(
149+
db: &DbIndex,
150+
cache: &mut LuaInferCache,
151+
exprs: &[LuaExpr],
152+
var_count: Option<usize>,
153+
) -> Vec<LuaType> {
154+
let mut value_types = Vec::new();
155+
for (idx, expr) in exprs.iter().enumerate() {
156+
let expr_type = infer_expr(db, cache, expr.clone()).unwrap_or(LuaType::Unknown);
157+
match expr_type {
158+
LuaType::Variadic(variadic) => {
159+
if let Some(var_count) = var_count {
160+
if idx < var_count {
161+
for i in idx..var_count {
162+
if let Some(typ) = variadic.get_type(i - idx) {
163+
value_types.push(typ.clone());
164+
} else {
165+
break;
166+
}
167+
}
168+
}
169+
} else {
170+
match variadic.deref() {
171+
VariadicType::Base(base) => {
172+
value_types.push(base.clone());
173+
}
174+
VariadicType::Multi(vecs) => {
175+
for typ in vecs {
176+
value_types.push(typ.clone());
177+
}
178+
}
179+
}
180+
}
181+
182+
break;
183+
}
184+
_ => value_types.push(expr_type.clone()),
185+
}
186+
}
187+
188+
value_types
189+
}

0 commit comments

Comments
 (0)