Skip to content

Commit cb88050

Browse files
authored
Merge pull request #762 from EmmyLuaLs/type_check
Improve type check performance
2 parents c9a4089 + 627ebeb commit cb88050

18 files changed

+501
-273
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ fn check_assign_type_mismatch(
391391
_ => {}
392392
}
393393

394-
let result = semantic_model.type_check(&source_type, &value_type);
394+
let result = semantic_model.type_check_detail(&source_type, &value_type);
395395
if !result.is_ok() {
396396
add_type_check_diagnostic(
397397
context,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ fn cast_type_check(
200200
}
201201
}
202202

203-
semantic_model.type_check(target_type, origin_type)
203+
semantic_model.type_check_detail(target_type, origin_type)
204204
}
205205
}
206206
}

crates/emmylua_code_analysis/src/diagnostic/checker/generic/generic_constraint_mismatch.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ fn check_doc_tag_type(
5454
.get_generic_params(&generic_type.get_base_type_id())?;
5555
for (i, param_type) in generic_type.get_params().iter().enumerate() {
5656
let extend_type = generic_params.get(i)?.type_constraint.clone()?;
57-
let result = semantic_model.type_check(&extend_type, &param_type);
57+
let result = semantic_model.type_check_detail(&extend_type, &param_type);
5858
if !result.is_ok() {
5959
add_type_check_diagnostic(
6060
context,
@@ -261,7 +261,7 @@ fn check_str_tpl_ref(
261261
if let Some(type_decl) = founded_type_decl {
262262
let type_id = type_decl.get_id();
263263
let ref_type = LuaType::Ref(type_id);
264-
let result = semantic_model.type_check(&extend_type, &ref_type);
264+
let result = semantic_model.type_check_detail(&extend_type, &ref_type);
265265
if result.is_err() {
266266
add_type_check_diagnostic(
267267
context,
@@ -296,7 +296,7 @@ fn check_tpl_ref(
296296
) -> Option<()> {
297297
let extend_type = extend_type.clone()?;
298298
let arg_info = arg_info?;
299-
let result = semantic_model.type_check(&extend_type, &arg_info.0);
299+
let result = semantic_model.type_check_detail(&extend_type, &arg_info.0);
300300
if !result.is_ok() {
301301
add_type_check_diagnostic(
302302
context,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ fn check_call_expr(
8787
check_type = result;
8888
}
8989
}
90-
let result = semantic_model.type_check(&check_type, arg_type);
90+
let result = semantic_model.type_check_detail(&check_type, arg_type);
9191
if !result.is_ok() {
9292
// 这里执行了`AssignTypeMismatch`的检查
9393
if arg_type.is_table() {
@@ -141,7 +141,7 @@ fn check_variadic_param_match_args(
141141
arg_ranges: &[TextRange],
142142
) {
143143
for (arg_type, arg_range) in arg_types.iter().zip(arg_ranges.iter()) {
144-
let result = semantic_model.type_check(variadic_type, arg_type);
144+
let result = semantic_model.type_check_detail(variadic_type, arg_type);
145145
if !result.is_ok() {
146146
try_add_diagnostic(
147147
context,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ fn check_return_stat(
8989
}
9090
}
9191

92-
let result = semantic_model.type_check(check_type, return_expr_type);
92+
let result = semantic_model.type_check_detail(check_type, return_expr_type);
9393
if !result.is_ok() {
9494
if return_expr_type.is_table() {
9595
if let Some(return_expr) = return_exprs.get(index) {
@@ -126,7 +126,7 @@ fn check_return_stat(
126126
}
127127
let return_expr_type = &return_expr_types[0];
128128
let return_expr_range = return_expr_ranges[0];
129-
let result = semantic_model.type_check(check_type, &return_expr_type);
129+
let result = semantic_model.type_check_detail(check_type, &return_expr_type);
130130
if !result.is_ok() {
131131
if return_expr_type.is_table() {
132132
if let Some(return_expr) = return_exprs.get(0) {

crates/emmylua_code_analysis/src/semantic/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub use visibility::check_export_visibility;
4040
use visibility::check_visibility;
4141

4242
use crate::semantic::member::find_members_with_key;
43+
use crate::semantic::type_check::check_type_compact_detail;
4344
use crate::{Emmyrc, LuaDocument, LuaSemanticDeclId, ModuleInfo, db_index::LuaTypeDeclId};
4445
use crate::{
4546
FileId,
@@ -148,6 +149,10 @@ impl<'a> SemanticModel<'a> {
148149
check_type_compact(self.db, source, compact_type)
149150
}
150151

152+
pub fn type_check_detail(&self, source: &LuaType, compact_type: &LuaType) -> TypeCheckResult {
153+
check_type_compact_detail(self.db, source, compact_type)
154+
}
155+
151156
pub fn infer_call_expr_func(
152157
&self,
153158
call_expr: LuaCallExpr,

crates/emmylua_code_analysis/src/semantic/type_check/complex_type/array_type_check.rs

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
use crate::{
2-
DbIndex, LuaMemberKey, LuaMemberOwner, LuaType, TypeCheckFailReason, TypeCheckResult, TypeOps,
2+
LuaMemberKey, LuaMemberOwner, LuaType, TypeCheckFailReason, TypeCheckResult, TypeOps,
33
find_index_operations,
4-
semantic::type_check::{check_general_type_compact, type_check_guard::TypeCheckGuard},
4+
semantic::type_check::{
5+
check_general_type_compact, type_check_context::TypeCheckContext,
6+
type_check_guard::TypeCheckGuard,
7+
},
58
};
69

710
pub fn check_array_type_compact(
8-
db: &DbIndex,
11+
context: &TypeCheckContext,
912
source_base: &LuaType,
1013
compact_type: &LuaType,
1114
check_guard: TypeCheckGuard,
1215
) -> TypeCheckResult {
13-
let source_base = TypeOps::Union.apply(db, source_base, &LuaType::Nil);
16+
let source_base = TypeOps::Union.apply(context.db, source_base, &LuaType::Nil);
1417

1518
match compact_type {
1619
LuaType::Array(compact_array_type) => {
1720
return check_general_type_compact(
18-
db,
21+
context,
1922
&source_base,
2023
compact_array_type.get_base(),
2124
check_guard.next_level()?,
@@ -24,7 +27,7 @@ pub fn check_array_type_compact(
2427
LuaType::Tuple(tuple_type) => {
2528
for element_type in tuple_type.get_types() {
2629
check_general_type_compact(
27-
db,
30+
context,
2831
&source_base,
2932
element_type,
3033
check_guard.next_level()?,
@@ -36,18 +39,18 @@ pub fn check_array_type_compact(
3639
LuaType::TableConst(inst) => {
3740
let table_member_owner = LuaMemberOwner::Element(inst.clone());
3841
return check_array_type_compact_table(
39-
db,
42+
context,
4043
&source_base,
4144
table_member_owner,
4245
check_guard.next_level()?,
4346
);
4447
}
4548
LuaType::Object(compact_object) => {
4649
let compact_base = compact_object
47-
.cast_down_array_base(db)
50+
.cast_down_array_base(context.db)
4851
.ok_or(TypeCheckFailReason::TypeNotMatch)?;
4952
return check_general_type_compact(
50-
db,
53+
context,
5154
&source_base,
5255
&compact_base,
5356
check_guard.next_level()?,
@@ -57,7 +60,12 @@ pub fn check_array_type_compact(
5760
LuaType::TableGeneric(compact_types) => {
5861
if compact_types.len() == 2 {
5962
for typ in compact_types.iter() {
60-
check_general_type_compact(db, &source_base, typ, check_guard.next_level()?)?;
63+
check_general_type_compact(
64+
context,
65+
&source_base,
66+
typ,
67+
check_guard.next_level()?,
68+
)?;
6169
}
6270

6371
return Ok(());
@@ -66,7 +74,7 @@ pub fn check_array_type_compact(
6674
LuaType::Any => return Ok(()),
6775
LuaType::Ref(_) | LuaType::Def(_) => {
6876
return check_array_type_compact_ref_def(
69-
db,
77+
context,
7078
&source_base,
7179
compact_type,
7280
check_guard.next_level()?,
@@ -79,20 +87,21 @@ pub fn check_array_type_compact(
7987
}
8088

8189
fn check_array_type_compact_ref_def(
82-
db: &DbIndex,
90+
context: &TypeCheckContext,
8391
source_base: &LuaType,
8492
compact_type: &LuaType,
8593
check_guard: TypeCheckGuard,
8694
) -> TypeCheckResult {
87-
let Some(members) = find_index_operations(db, compact_type) else {
95+
let Some(members) = find_index_operations(context.db, compact_type) else {
8896
return Err(TypeCheckFailReason::TypeNotMatch);
8997
};
9098

9199
for member in &members {
92100
match &member.key {
93101
LuaMemberKey::ExprType(key_type) => {
94102
if key_type.is_integer() {
95-
match check_general_type_compact(db, source_base, &member.typ, check_guard) {
103+
match check_general_type_compact(context, source_base, &member.typ, check_guard)
104+
{
96105
Ok(()) => return Ok(()),
97106
_ => {}
98107
}
@@ -106,21 +115,26 @@ fn check_array_type_compact_ref_def(
106115
}
107116

108117
fn check_array_type_compact_table(
109-
db: &DbIndex,
118+
context: &TypeCheckContext,
110119
source_base: &LuaType,
111120
table_owner: LuaMemberOwner,
112121
check_guard: TypeCheckGuard,
113122
) -> TypeCheckResult {
114-
let member_index = db.get_member_index();
123+
let member_index = context.db.get_member_index();
115124

116125
let member_len = member_index.get_member_len(&table_owner);
117126
for i in 0..member_len {
118127
let key = LuaMemberKey::Integer((i + 1) as i64);
119128
if let Some(member_item) = member_index.get_member_item(&table_owner, &key) {
120129
let member_type = member_item
121-
.resolve_type(db)
130+
.resolve_type(context.db)
122131
.map_err(|_| TypeCheckFailReason::TypeNotMatch)?;
123-
check_general_type_compact(db, source_base, &member_type, check_guard.next_level()?)?;
132+
check_general_type_compact(
133+
context,
134+
source_base,
135+
&member_type,
136+
check_guard.next_level()?,
137+
)?;
124138
} else {
125139
return Err(TypeCheckFailReason::TypeNotMatch);
126140
}

crates/emmylua_code_analysis/src/semantic/type_check/complex_type/intersection_type_check.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
use crate::{
2-
DbIndex, LuaIntersectionType, LuaMemberOwner, LuaType, TypeCheckFailReason, TypeCheckResult,
3-
semantic::type_check::{check_general_type_compact, type_check_guard::TypeCheckGuard},
2+
LuaIntersectionType, LuaMemberOwner, LuaType, TypeCheckFailReason, TypeCheckResult,
3+
semantic::type_check::{
4+
check_general_type_compact, type_check_context::TypeCheckContext,
5+
type_check_guard::TypeCheckGuard,
6+
},
47
};
58

69
pub fn check_intersection_type_compact(
7-
db: &DbIndex,
10+
context: &TypeCheckContext,
811
source_intersection: &LuaIntersectionType,
912
compact_type: &LuaType,
1013
check_guard: TypeCheckGuard,
1114
) -> TypeCheckResult {
1215
match compact_type {
1316
LuaType::TableConst(range) => check_intersection_type_compact_table(
14-
db,
17+
context,
1518
source_intersection,
1619
LuaMemberOwner::Element(range.clone()),
1720
check_guard.next_level()?,
@@ -20,7 +23,7 @@ pub fn check_intersection_type_compact(
2023
// 检查对象是否满足交叉类型的所有组成部分
2124
for intersection_component in source_intersection.get_types() {
2225
check_general_type_compact(
23-
db,
26+
context,
2427
intersection_component,
2528
compact_type,
2629
check_guard.next_level()?,
@@ -31,7 +34,7 @@ pub fn check_intersection_type_compact(
3134
LuaType::Intersection(compact_intersection) => {
3235
// 交叉类型对交叉类型:检查所有组成部分
3336
check_intersection_type_compact_intersection(
34-
db,
37+
context,
3538
source_intersection,
3639
compact_intersection,
3740
check_guard.next_level()?,
@@ -42,7 +45,7 @@ pub fn check_intersection_type_compact(
4245
// 对于其他类型,检查是否至少满足一个组成部分
4346
for intersection_component in source_intersection.get_types() {
4447
if check_general_type_compact(
45-
db,
48+
context,
4649
intersection_component,
4750
compact_type,
4851
check_guard.next_level()?,
@@ -58,15 +61,15 @@ pub fn check_intersection_type_compact(
5861
}
5962

6063
fn check_intersection_type_compact_table(
61-
db: &DbIndex,
64+
context: &TypeCheckContext,
6265
source_intersection: &LuaIntersectionType,
6366
table_owner: LuaMemberOwner,
6467
check_guard: TypeCheckGuard,
6568
) -> TypeCheckResult {
6669
// 交叉类型要求 TableConst 必须满足所有组成部分
6770
for intersection_component in source_intersection.get_types() {
6871
check_general_type_compact(
69-
db,
72+
context,
7073
intersection_component,
7174
&LuaType::TableConst(
7275
table_owner
@@ -82,7 +85,7 @@ fn check_intersection_type_compact_table(
8285
}
8386

8487
fn check_intersection_type_compact_intersection(
85-
db: &DbIndex,
88+
context: &TypeCheckContext,
8689
source_intersection: &LuaIntersectionType,
8790
compact_intersection: &LuaIntersectionType,
8891
check_guard: TypeCheckGuard,
@@ -93,7 +96,7 @@ fn check_intersection_type_compact_intersection(
9396

9497
for compact_component in compact_intersection.get_types() {
9598
if check_general_type_compact(
96-
db,
99+
context,
97100
source_component,
98101
compact_component,
99102
check_guard.next_level()?,

0 commit comments

Comments
 (0)