Skip to content

Commit 959328a

Browse files
committed
optimize is_sub_type_of
1 parent 0089cad commit 959328a

File tree

1 file changed

+36
-69
lines changed
  • crates/emmylua_code_analysis/src/semantic/type_check

1 file changed

+36
-69
lines changed
Lines changed: 36 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
use std::collections::HashSet;
22

3-
use crate::{DbIndex, InferGuard, LuaType, LuaTypeDeclId};
3+
use crate::{DbIndex, LuaType, LuaTypeDeclId};
44

55
pub fn is_sub_type_of(
66
db: &DbIndex,
77
sub_type_ref_id: &LuaTypeDeclId,
88
super_type_ref_id: &LuaTypeDeclId,
99
) -> bool {
10-
// let mut infer_guard = InferGuard::new();
11-
// check_sub_type_of(db, sub_type_ref_id, super_type_ref_id, &mut infer_guard).unwrap_or(false)
1210
check_sub_type_of_iterative(db, sub_type_ref_id, super_type_ref_id).unwrap_or(false)
1311
}
1412

@@ -22,34 +20,33 @@ fn check_sub_type_of_iterative(
2220
}
2321

2422
let type_index = db.get_type_index();
25-
let mut stack = Vec::new();
26-
let mut visited = HashSet::new();
27-
28-
stack.push(sub_type_ref_id.clone());
23+
let mut stack = Vec::with_capacity(4);
24+
let mut visited = HashSet::with_capacity(4);
2925

26+
stack.push(sub_type_ref_id);
3027
while let Some(current_id) = stack.pop() {
31-
if !visited.insert(current_id.clone()) {
28+
if !visited.insert(current_id) {
3229
continue;
3330
}
3431

35-
let supers = match type_index.get_super_types(&current_id) {
36-
Some(s) => s,
32+
let supers_iter = match type_index.get_super_types_iter(&current_id) {
33+
Some(iter) => iter,
3734
None => continue,
3835
};
3936

40-
for super_type in supers {
41-
match &super_type {
37+
for super_type in supers_iter {
38+
match super_type {
4239
LuaType::Ref(super_id) => {
4340
// TODO: 不相等时可以判断必要字段是否全部匹配, 如果匹配则认为相等
4441
if super_id == super_type_ref_id {
4542
return Some(true);
4643
}
4744
if !visited.contains(super_id) {
48-
stack.push(super_id.clone());
45+
stack.push(super_id);
4946
}
5047
}
5148
_ => {
52-
if let Some(base_id) = get_base_type_id(&super_type) {
49+
if let Some(base_id) = get_base_type_id(super_type) {
5350
if base_id == *super_type_ref_id {
5451
return Some(true);
5552
}
@@ -62,62 +59,32 @@ fn check_sub_type_of_iterative(
6259
Some(false)
6360
}
6461

65-
#[allow(unused)]
66-
fn check_sub_type_of(
67-
db: &DbIndex,
68-
sub_type_ref_id: &LuaTypeDeclId,
69-
super_type_ref_id: &LuaTypeDeclId,
70-
infer_guard: &mut InferGuard,
71-
) -> Option<bool> {
72-
infer_guard.check(super_type_ref_id).ok()?;
73-
74-
let supers = db.get_type_index().get_super_types(sub_type_ref_id)?;
75-
// dbg!(sub_type_ref_id, super_type_ref_id, &supers);
76-
for super_type in supers {
77-
if let LuaType::Ref(super_id) = &super_type {
78-
if super_id == super_type_ref_id {
79-
return Some(true);
80-
}
81-
82-
if check_sub_type_of(db, sub_type_ref_id, &super_id, infer_guard).unwrap_or(false) {
83-
return Some(true);
84-
}
62+
pub fn get_base_type_id(typ: &LuaType) -> Option<LuaTypeDeclId> {
63+
match typ {
64+
LuaType::Integer | LuaType::IntegerConst(_) | LuaType::DocIntegerConst(_) => {
65+
Some(LuaTypeDeclId::new("integer"))
8566
}
86-
if let Some(super_base_type_id) = get_base_type_id(&super_type) {
87-
if super_base_type_id == *super_type_ref_id {
88-
return Some(true);
89-
}
67+
LuaType::Number | LuaType::FloatConst(_) => Some(LuaTypeDeclId::new("number")),
68+
LuaType::Boolean | LuaType::BooleanConst(_) | LuaType::DocBooleanConst(_) => {
69+
Some(LuaTypeDeclId::new("boolean"))
9070
}
71+
LuaType::String | LuaType::StringConst(_) | LuaType::DocStringConst(_) => {
72+
Some(LuaTypeDeclId::new("string"))
73+
}
74+
LuaType::Table
75+
| LuaType::TableGeneric(_)
76+
| LuaType::TableConst(_)
77+
| LuaType::Tuple(_)
78+
| LuaType::Array(_) => Some(LuaTypeDeclId::new("table")),
79+
LuaType::DocFunction(_) | LuaType::Function | LuaType::Signature(_) => {
80+
Some(LuaTypeDeclId::new("function"))
81+
}
82+
LuaType::Thread => Some(LuaTypeDeclId::new("thread")),
83+
LuaType::Userdata => Some(LuaTypeDeclId::new("userdata")),
84+
LuaType::Io => Some(LuaTypeDeclId::new("io")),
85+
LuaType::Global => Some(LuaTypeDeclId::new("global")),
86+
LuaType::SelfInfer => Some(LuaTypeDeclId::new("self")),
87+
LuaType::Nil => Some(LuaTypeDeclId::new("nil")),
88+
_ => None,
9189
}
92-
93-
Some(false)
94-
}
95-
96-
pub fn get_base_type_id(typ: &LuaType) -> Option<LuaTypeDeclId> {
97-
if typ.is_integer() {
98-
return Some(LuaTypeDeclId::new("integer"));
99-
} else if typ.is_number() {
100-
return Some(LuaTypeDeclId::new("number"));
101-
} else if typ.is_boolean() {
102-
return Some(LuaTypeDeclId::new("boolean"));
103-
} else if typ.is_string() {
104-
return Some(LuaTypeDeclId::new("string"));
105-
} else if typ.is_table() {
106-
return Some(LuaTypeDeclId::new("table"));
107-
} else if typ.is_function() {
108-
return Some(LuaTypeDeclId::new("function"));
109-
} else if typ.is_thread() {
110-
return Some(LuaTypeDeclId::new("thread"));
111-
} else if typ.is_userdata() {
112-
return Some(LuaTypeDeclId::new("userdata"));
113-
} else if typ.is_io() {
114-
return Some(LuaTypeDeclId::new("io"));
115-
} else if typ.is_global() {
116-
return Some(LuaTypeDeclId::new("global"));
117-
} else if typ.is_self_infer() {
118-
return Some(LuaTypeDeclId::new("self"));
119-
} else if typ.is_nil() {
120-
return Some(LuaTypeDeclId::new("nil"));
121-
}
122-
None
12390
}

0 commit comments

Comments
 (0)