Skip to content

Commit 68c245a

Browse files
committed
diagnostic: 增强表检查
1 parent 0b5ae74 commit 68c245a

4 files changed

Lines changed: 94 additions & 13 deletions

File tree

crates/emmylua_code_analysis/src/diagnostic/checker/assign_type_mismatch.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ fn check_name_expr(
113113
check_table_expr(
114114
context,
115115
semantic_model,
116+
&expr,
116117
source_type.as_ref(),
117118
Some(&value_type),
118-
&expr,
119119
);
120120
}
121121

@@ -149,9 +149,9 @@ fn check_index_expr(
149149
check_table_expr(
150150
context,
151151
semantic_model,
152+
&expr,
152153
source_type.as_ref(),
153154
Some(&value_type),
154-
&expr,
155155
);
156156
}
157157
Some(())
@@ -192,21 +192,21 @@ fn check_local_stat(
192192
check_table_expr(
193193
context,
194194
semantic_model,
195+
&expr,
195196
Some(&var_type),
196197
Some(&value_type),
197-
&expr,
198198
);
199199
}
200200
}
201201
Some(())
202202
}
203203

204-
fn check_table_expr(
204+
pub fn check_table_expr(
205205
context: &mut DiagnosticContext,
206206
semantic_model: &SemanticModel,
207+
table_expr: &LuaExpr,
207208
table_type: Option<&LuaType>, // 记录的类型
208209
expr_type: Option<&LuaType>, // 实际表达式推导出的类型
209-
table_expr: &LuaExpr,
210210
) -> Option<()> {
211211
// 需要进行一些过滤
212212
if table_type == expr_type {

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

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,20 @@ use emmylua_parser::{LuaAst, LuaAstNode, LuaAstToken, LuaCallExpr, LuaExpr, LuaI
22
use rowan::TextRange;
33

44
use crate::{
5-
humanize_type, DiagnosticCode, LuaSemanticDeclId, LuaType, RenderLevel, SemanticDeclLevel,
6-
SemanticModel, TypeCheckFailReason, TypeCheckResult,
5+
diagnostic::checker::assign_type_mismatch::check_table_expr, humanize_type, DiagnosticCode,
6+
LuaSemanticDeclId, LuaType, RenderLevel, SemanticDeclLevel, SemanticModel, TypeCheckFailReason,
7+
TypeCheckResult,
78
};
89

910
use super::{Checker, DiagnosticContext};
1011

1112
pub struct ParamTypeCheckChecker;
1213

1314
impl Checker for ParamTypeCheckChecker {
14-
const CODES: &[DiagnosticCode] = &[DiagnosticCode::ParamTypeNotMatch];
15+
const CODES: &[DiagnosticCode] = &[
16+
DiagnosticCode::ParamTypeNotMatch,
17+
DiagnosticCode::AssignTypeMismatch,
18+
];
1519

1620
/// a simple implementation of param type check, later we will do better
1721
fn check(context: &mut DiagnosticContext, semantic_model: &SemanticModel) {
@@ -85,6 +89,30 @@ fn check_call_expr(
8589
}
8690
let result = semantic_model.type_check(&check_type, arg_type);
8791
if !result.is_ok() {
92+
// 这里执行了`AssignTypeMismatch`的检查
93+
if arg_type.is_table() {
94+
let arg_expr_idx = match (colon_call, colon_define) {
95+
(true, false) => {
96+
if idx == 0 {
97+
continue;
98+
} else {
99+
idx - 1
100+
}
101+
}
102+
_ => idx,
103+
};
104+
105+
if let Some(arg_expr) = arg_exprs.get(arg_expr_idx) {
106+
check_table_expr(
107+
context,
108+
semantic_model,
109+
arg_expr,
110+
Some(&param_type),
111+
Some(arg_type),
112+
);
113+
}
114+
}
115+
88116
try_add_diagnostic(
89117
context,
90118
semantic_model,

crates/emmylua_code_analysis/src/diagnostic/checker/return_type_mismatch.rs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,20 @@ use emmylua_parser::{
44
use rowan::{NodeOrToken, TextRange};
55

66
use crate::{
7-
humanize_type, DiagnosticCode, LuaSemanticDeclId, LuaSignatureId, LuaType, RenderLevel,
8-
SemanticDeclLevel, SemanticModel, SignatureReturnStatus, TypeCheckFailReason, TypeCheckResult,
7+
diagnostic::checker::assign_type_mismatch::check_table_expr, humanize_type, DiagnosticCode,
8+
LuaSemanticDeclId, LuaSignatureId, LuaType, RenderLevel, SemanticDeclLevel, SemanticModel,
9+
SignatureReturnStatus, TypeCheckFailReason, TypeCheckResult,
910
};
1011

1112
use super::{get_return_stats, Checker, DiagnosticContext};
1213

1314
pub struct ReturnTypeMismatch;
1415

1516
impl Checker for ReturnTypeMismatch {
16-
const CODES: &[DiagnosticCode] = &[DiagnosticCode::ReturnTypeMismatch];
17+
const CODES: &[DiagnosticCode] = &[
18+
DiagnosticCode::ReturnTypeMismatch,
19+
DiagnosticCode::AssignTypeMismatch,
20+
];
1721

1822
fn check(context: &mut DiagnosticContext, semantic_model: &SemanticModel) {
1923
let root = semantic_model.get_root().clone();
@@ -54,9 +58,9 @@ fn check_return_stat(
5458
return_type: &LuaType,
5559
return_stat: &LuaReturnStat,
5660
) -> Option<()> {
61+
let return_exprs = return_stat.get_expr_list().collect::<Vec<_>>();
5762
let (return_expr_types, return_expr_ranges) = {
58-
let infos = semantic_model
59-
.infer_expr_list_types(&return_stat.get_expr_list().collect::<Vec<_>>(), None);
63+
let infos = semantic_model.infer_expr_list_types(&return_exprs, None);
6064
let mut return_expr_types = infos.iter().map(|(typ, _)| typ.clone()).collect::<Vec<_>>();
6165
// 解决 setmetatable 的返回值类型问题
6266
let setmetatable_index = has_setmetatable(semantic_model, return_stat);
@@ -87,6 +91,18 @@ fn check_return_stat(
8791

8892
let result = semantic_model.type_check(check_type, return_expr_type);
8993
if !result.is_ok() {
94+
if return_expr_type.is_table() {
95+
if let Some(return_expr) = return_exprs.get(index) {
96+
check_table_expr(
97+
context,
98+
semantic_model,
99+
return_expr,
100+
Some(check_type),
101+
Some(return_expr_type),
102+
);
103+
}
104+
}
105+
90106
add_type_check_diagnostic(
91107
context,
92108
semantic_model,
@@ -112,6 +128,17 @@ fn check_return_stat(
112128
let return_expr_range = return_expr_ranges[0];
113129
let result = semantic_model.type_check(check_type, &return_expr_type);
114130
if !result.is_ok() {
131+
if return_expr_type.is_table() {
132+
if let Some(return_expr) = return_exprs.get(0) {
133+
check_table_expr(
134+
context,
135+
semantic_model,
136+
return_expr,
137+
Some(return_type),
138+
Some(return_expr_type),
139+
);
140+
}
141+
}
115142
add_type_check_diagnostic(
116143
context,
117144
semantic_model,

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,4 +922,30 @@ return t
922922
"#
923923
));
924924
}
925+
926+
#[test]
927+
fn test_param_tbale() {
928+
let mut ws = VirtualWorkspace::new();
929+
assert!(!ws.check_code_for(
930+
DiagnosticCode::AssignTypeMismatch,
931+
r#"
932+
---@class ability
933+
---@field t abilityType
934+
935+
---@enum (key) abilityType
936+
local abilityType = {
937+
passive = 1,
938+
}
939+
940+
---@param a ability
941+
function test(a)
942+
943+
end
944+
945+
test({
946+
t = ""
947+
})
948+
"#
949+
));
950+
}
925951
}

0 commit comments

Comments
 (0)