Skip to content

Commit d3fd56d

Browse files
committed
fix param-type-check and missing-parameter check
1 parent 1321d69 commit d3fd56d

File tree

2 files changed

+71
-29
lines changed

2 files changed

+71
-29
lines changed

crates/code_analysis/src/diagnostic/checker/missing_parameter.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use emmylua_parser::{LuaAstNode, LuaAstToken, LuaCallExpr, LuaGeneralToken, LuaLiteralExpr, LuaLiteralToken};
1+
use emmylua_parser::{
2+
LuaAstNode, LuaAstToken, LuaCallExpr, LuaGeneralToken, LuaLiteralExpr, LuaLiteralToken,
3+
};
24

35
use crate::{DiagnosticCode, SemanticModel};
46

@@ -22,19 +24,33 @@ fn check_call_expr(
2224
) -> Option<()> {
2325
let func = semantic_model.infer_call_expr_func(call_expr.clone(), None)?;
2426
let params = func.get_params();
25-
let args_count = call_expr.get_args_list()?.get_args().count();
27+
let mut args_count = call_expr.get_args_list()?.get_args().count();
28+
let colon_call = call_expr.is_colon_call();
29+
let colon_define = func.is_colon_define();
30+
match (colon_call, colon_define) {
31+
(true, true) | (false, false) => {}
32+
(false, true) => {
33+
if args_count > 0 {
34+
args_count -= 1;
35+
}
36+
}
37+
(true, false) => {
38+
args_count += 1;
39+
}
40+
}
41+
2642
if args_count < params.len() {
2743
// fix last arg is `...`
2844
if args_count != 0 {
29-
let last_arg = call_expr.get_args_list()?.child::<LuaLiteralExpr>()?;
30-
if let Some(literal_token) = last_arg.get_literal() {
31-
if let LuaLiteralToken::Dots(_) = literal_token {
32-
return Some(());
45+
if let Some(last_arg) = call_expr.get_args_list()?.child::<LuaLiteralExpr>() {
46+
if let Some(literal_token) = last_arg.get_literal() {
47+
if let LuaLiteralToken::Dots(_) = literal_token {
48+
return Some(());
49+
}
3350
}
3451
}
3552
}
3653

37-
3854
let mut miss_parameter_info = Vec::new();
3955
for i in args_count..params.len() {
4056
let param_info = params.get(i)?;
@@ -61,7 +77,8 @@ fn check_call_expr(
6177
num = params.len(),
6278
found_num = args_count,
6379
infos = miss_parameter_info.join("\n")
64-
).to_string(),
80+
)
81+
.to_string(),
6582
None,
6683
);
6784
}

crates/code_analysis/src/diagnostic/checker/param_type_check.rs

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,39 +28,65 @@ fn check_call_expr(
2828
) -> Option<()> {
2929
let func = semantic_model.infer_call_expr_func(call_expr.clone(), None)?;
3030
let params = func.get_params();
31-
let args = call_expr.get_args_list()?.get_args().collect::<Vec<_>>();
31+
let mut args = call_expr
32+
.get_args_list()?
33+
.get_args()
34+
.map(|arg| Some(arg))
35+
.collect::<Vec<_>>();
36+
let colon_call = call_expr.is_colon_call();
37+
let colon_define = func.is_colon_define();
38+
match (colon_call, colon_define) {
39+
(true, true) | (false, false) => {}
40+
(false, true) => {
41+
if args.len() > 0 {
42+
args.remove(0);
43+
}
44+
}
45+
(true, false) => {
46+
args.insert(0, None);
47+
}
48+
}
49+
3250
for (idx, param) in params.iter().enumerate() {
3351
if idx >= args.len() {
3452
break;
3553
}
3654

55+
let arg = &args[idx];
56+
if arg.is_none() {
57+
continue;
58+
}
59+
let arg = arg.clone().unwrap();
60+
3761
if param.0 == "..." {
3862
if param.1.is_none() {
3963
break;
4064
}
4165

4266
let param_type = param.1.clone().unwrap();
4367
for arg in args.iter().skip(idx) {
44-
let mut expr_type = semantic_model
45-
.infer_expr(arg.clone())
46-
.unwrap_or(LuaType::Any);
47-
// treat unknown type as any
48-
if expr_type.is_unknown() {
49-
expr_type = LuaType::Any;
50-
}
68+
if let Some(arg) = arg {
69+
let mut expr_type = semantic_model
70+
.infer_expr(arg.clone())
71+
.unwrap_or(LuaType::Any);
72+
// treat unknown type as any
73+
if expr_type.is_unknown() {
74+
expr_type = LuaType::Any;
75+
}
5176

52-
if !semantic_model.check_type_compact(&param_type, &expr_type) {
53-
let db = semantic_model.get_db();
54-
context.add_diagnostic(
55-
DiagnosticCode::ParamTypeNotMatch,
56-
arg.get_range(),
57-
format!(
58-
"expected {} but founded {}",
59-
humanize_type(db, &param_type),
60-
humanize_type(db, &expr_type)
61-
),
62-
None,
63-
);
77+
if !semantic_model.check_type_compact(&param_type, &expr_type) {
78+
let db = semantic_model.get_db();
79+
context.add_diagnostic(
80+
DiagnosticCode::ParamTypeNotMatch,
81+
arg.get_range(),
82+
format!(
83+
"expected {} but founded {}",
84+
humanize_type(db, &param_type),
85+
humanize_type(db, &expr_type)
86+
),
87+
None,
88+
);
89+
}
6490
}
6591
}
6692
} else {
@@ -69,7 +95,6 @@ fn check_call_expr(
6995
}
7096

7197
let param_type = param.1.clone().unwrap();
72-
let arg = &args[idx];
7398
let mut expr_type = semantic_model
7499
.infer_expr(arg.clone())
75100
.unwrap_or(LuaType::Any);

0 commit comments

Comments
 (0)