Skip to content

Commit f2211c6

Browse files
committed
refactor cache
1 parent bc8903b commit f2211c6

8 files changed

Lines changed: 80 additions & 72 deletions

File tree

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

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,32 @@ use std::{collections::HashMap, sync::Arc};
66

77
use crate::{db_index::LuaType, semantic::infer::VarRefId, FileId, FlowId, LuaFunctionType};
88

9-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
10-
pub enum CacheKey {
11-
Expr(LuaSyntaxId),
12-
Call(LuaSyntaxId, Option<usize>, LuaType),
13-
FlowNode(VarRefId, FlowId),
14-
IndexRefOriginType(VarRefId),
15-
}
16-
179
#[derive(Debug)]
18-
pub enum CacheEntry {
19-
ReadyCache,
20-
TypeCache(LuaType),
21-
CallCache(Arc<LuaFunctionType>),
10+
pub enum CacheEntry<T> {
11+
Ready,
12+
Cache(T),
2213
}
2314

2415
#[derive(Debug)]
2516
pub struct LuaInferCache {
2617
file_id: FileId,
2718
config: CacheOptions,
28-
cache: HashMap<CacheKey, CacheEntry>,
19+
pub expr_cache: HashMap<LuaSyntaxId, CacheEntry<LuaType>>,
20+
pub call_cache:
21+
HashMap<(LuaSyntaxId, Option<usize>, LuaType), CacheEntry<Arc<LuaFunctionType>>>,
22+
pub flow_node_cache: HashMap<(VarRefId, FlowId), CacheEntry<LuaType>>,
23+
pub index_ref_origin_type_cache: HashMap<VarRefId, CacheEntry<LuaType>>,
2924
}
3025

3126
impl LuaInferCache {
3227
pub fn new(file_id: FileId, config: CacheOptions) -> Self {
3328
Self {
3429
file_id,
3530
config,
36-
cache: HashMap::new(),
31+
expr_cache: HashMap::new(),
32+
call_cache: HashMap::new(),
33+
flow_node_cache: HashMap::new(),
34+
index_ref_origin_type_cache: HashMap::new(),
3735
}
3836
}
3937

@@ -45,28 +43,14 @@ impl LuaInferCache {
4543
self.file_id
4644
}
4745

48-
// 表达式缓存相关方法
49-
pub fn ready_cache(&mut self, key: &CacheKey) {
50-
self.cache.insert(key.clone(), CacheEntry::ReadyCache);
51-
}
52-
53-
pub fn add_cache(&mut self, key: &CacheKey, value: CacheEntry) {
54-
self.cache.insert(key.clone(), value);
55-
}
56-
57-
pub fn get(&self, key: &CacheKey) -> Option<&CacheEntry> {
58-
self.cache.get(key)
59-
}
60-
61-
pub fn remove(&mut self, key: &CacheKey) {
62-
self.cache.remove(key);
63-
}
64-
6546
pub fn set_phase(&mut self, phase: LuaAnalysisPhase) {
6647
self.config.analysis_phase = phase;
6748
}
6849

6950
pub fn clear(&mut self) {
70-
self.cache.clear();
51+
self.expr_cache.clear();
52+
self.call_cache.clear();
53+
self.flow_node_cache.clear();
54+
self.index_ref_origin_type_cache.clear();
7155
}
7256
}

crates/emmylua_code_analysis/src/semantic/infer/infer_call/mod.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use super::{
1313
use crate::semantic::generic::instantiate_doc_function;
1414
use crate::semantic::infer_expr;
1515
use crate::{
16-
CacheEntry, CacheKey, DbIndex, InFiled, LuaFunctionType, LuaGenericType, LuaInstanceType,
16+
CacheEntry, DbIndex, InFiled, LuaFunctionType, LuaGenericType, LuaInstanceType,
1717
LuaOperatorMetaMethod, LuaOperatorOwner, LuaSignatureId, LuaType, LuaTypeDeclId, LuaUnionType,
1818
};
1919
use infer_require::infer_require_call;
@@ -33,16 +33,16 @@ pub fn infer_call_expr_func(
3333
args_count: Option<usize>,
3434
) -> InferCallFuncResult {
3535
let syntax_id = call_expr.get_syntax_id();
36-
let key = CacheKey::Call(syntax_id, args_count, call_expr_type.clone());
37-
match cache.get(&key) {
36+
let key = (syntax_id, args_count, call_expr_type.clone());
37+
match cache.call_cache.get(&key) {
3838
Some(cache) => match cache {
39-
CacheEntry::CallCache(ty) => return Ok(ty.clone()),
39+
CacheEntry::Cache(ty) => return Ok(ty.clone()),
4040
_ => return Err(InferFailReason::RecursiveInfer),
4141
},
4242
None => {}
4343
}
4444

45-
cache.ready_cache(&key);
45+
cache.call_cache.insert(key.clone(), CacheEntry::Ready);
4646
let result = match &call_expr_type {
4747
LuaType::DocFunction(func) => {
4848
infer_doc_function(db, cache, &func, call_expr.clone(), args_count)
@@ -120,10 +120,12 @@ pub fn infer_call_expr_func(
120120

121121
match &result {
122122
Ok(func_ty) => {
123-
cache.add_cache(&key, CacheEntry::CallCache(func_ty.clone()));
123+
cache
124+
.call_cache
125+
.insert(key, CacheEntry::Cache(func_ty.clone()));
124126
}
125127
Err(r) if r.is_need_resolve() => {
126-
cache.remove(&key);
128+
cache.call_cache.remove(&key);
127129
}
128130
_ => {}
129131
}

crates/emmylua_code_analysis/src/semantic/infer/infer_index.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ use crate::{
2020
type_check::{self, check_type_compact},
2121
InferGuard,
2222
},
23-
CacheEntry, CacheKey, InFiled, LuaDeclOrMemberId, LuaInferCache, LuaInstanceType,
24-
LuaMemberOwner, LuaOperatorOwner, TypeOps,
23+
CacheEntry, InFiled, LuaDeclOrMemberId, LuaInferCache, LuaInstanceType, LuaMemberOwner,
24+
LuaOperatorOwner, TypeOps,
2525
};
2626

2727
use super::{infer_expr, infer_name::infer_global_type, InferFailReason, InferResult};
@@ -118,8 +118,10 @@ fn infer_member_type_pass_flow(
118118
};
119119

120120
let var_ref_id = VarRefId::IndexRef(decl_or_member_id, access_path);
121-
let key = CacheKey::IndexRefOriginType(var_ref_id.clone());
122-
cache.add_cache(&key, CacheEntry::TypeCache(member_type.clone()));
121+
let key = var_ref_id.clone();
122+
cache
123+
.index_ref_origin_type_cache
124+
.insert(key, CacheEntry::Cache(member_type.clone()));
123125
let result = infer_var_expr_narrow_type(db, cache, name_expr, var_ref_id);
124126
match &result {
125127
Err(InferFailReason::None) => return Ok(member_type.clone()),

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

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,17 @@ use crate::{
3434
InFiled, InferGuard, LuaMemberKey, VariadicType,
3535
};
3636

37-
use super::{member::infer_raw_member_type, CacheEntry, CacheKey, LuaInferCache};
37+
use super::{member::infer_raw_member_type, CacheEntry, LuaInferCache};
3838

3939
pub type InferResult = Result<LuaType, InferFailReason>;
4040
pub use infer_call::InferCallFuncResult;
4141

4242
pub fn infer_expr(db: &DbIndex, cache: &mut LuaInferCache, expr: LuaExpr) -> InferResult {
4343
let syntax_id = expr.get_syntax_id();
44-
let key = CacheKey::Expr(syntax_id);
45-
match cache.get(&key) {
44+
let key = syntax_id;
45+
match cache.expr_cache.get(&key) {
4646
Some(cache) => match cache {
47-
CacheEntry::TypeCache(ty) => return Ok(ty.clone()),
47+
CacheEntry::Cache(ty) => return Ok(ty.clone()),
4848
_ => return Err(InferFailReason::RecursiveInfer),
4949
},
5050
None => {}
@@ -57,14 +57,13 @@ pub fn infer_expr(db: &DbIndex, cache: &mut LuaInferCache, expr: LuaExpr) -> Inf
5757
.get_type_index()
5858
.get_type_cache(&in_filed_syntax_id.into())
5959
{
60-
cache.add_cache(
61-
&key,
62-
CacheEntry::TypeCache(bind_type_cache.as_type().clone()),
63-
);
60+
cache
61+
.expr_cache
62+
.insert(key, CacheEntry::Cache(bind_type_cache.as_type().clone()));
6463
return Ok(bind_type_cache.as_type().clone());
6564
}
6665

67-
cache.ready_cache(&key);
66+
cache.expr_cache.insert(key, CacheEntry::Ready);
6867
let result_type = match expr {
6968
LuaExpr::CallExpr(call_expr) => infer_call_expr(db, cache, call_expr),
7069
LuaExpr::TableExpr(table_expr) => infer_table_expr(db, cache, table_expr),
@@ -82,21 +81,29 @@ pub fn infer_expr(db: &DbIndex, cache: &mut LuaInferCache, expr: LuaExpr) -> Inf
8281
};
8382

8483
match &result_type {
85-
Ok(result_type) => cache.add_cache(&key, CacheEntry::TypeCache(result_type.clone())),
84+
Ok(result_type) => {
85+
cache
86+
.expr_cache
87+
.insert(key, CacheEntry::Cache(result_type.clone()));
88+
}
8689
Err(InferFailReason::None) | Err(InferFailReason::RecursiveInfer) => {
87-
cache.add_cache(&key, CacheEntry::TypeCache(LuaType::Unknown));
90+
cache
91+
.expr_cache
92+
.insert(key, CacheEntry::Cache(LuaType::Unknown));
8893
return Ok(LuaType::Unknown);
8994
}
9095
Err(InferFailReason::FieldNotFound) => {
9196
if cache.get_config().analysis_phase.is_force() {
92-
cache.add_cache(&key, CacheEntry::TypeCache(LuaType::Nil));
97+
cache
98+
.expr_cache
99+
.insert(key, CacheEntry::Cache(LuaType::Nil));
93100
return Ok(LuaType::Nil);
94101
} else {
95-
cache.ready_cache(&key);
102+
cache.expr_cache.insert(key, CacheEntry::Ready);
96103
}
97104
}
98105
_ => {
99-
cache.remove(&key);
106+
cache.expr_cache.remove(&key);
100107
}
101108
}
102109

crates/emmylua_code_analysis/src/semantic/infer/narrow/get_type_at_flow.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use crate::{
1414
},
1515
InferResult, VarRefId,
1616
},
17-
CacheEntry, CacheKey, DbIndex, FlowId, FlowNode, FlowNodeKind, FlowTree, InferFailReason,
18-
LuaInferCache, LuaType, TypeOps,
17+
CacheEntry, DbIndex, FlowId, FlowNode, FlowNodeKind, FlowTree, InferFailReason, LuaInferCache,
18+
LuaType, TypeOps,
1919
};
2020

2121
pub fn get_type_at_flow(
@@ -26,9 +26,9 @@ pub fn get_type_at_flow(
2626
var_ref_id: &VarRefId,
2727
flow_id: FlowId,
2828
) -> InferResult {
29-
let key = CacheKey::FlowNode(var_ref_id.clone(), flow_id);
30-
if let Some(cache_entry) = cache.get(&key) {
31-
if let CacheEntry::TypeCache(narrow_type) = cache_entry {
29+
let key = (var_ref_id.clone(), flow_id);
30+
if let Some(cache_entry) = cache.flow_node_cache.get(&key) {
31+
if let CacheEntry::Cache(narrow_type) = cache_entry {
3232
return Ok(narrow_type.clone());
3333
}
3434
}
@@ -160,8 +160,9 @@ pub fn get_type_at_flow(
160160
}
161161
}
162162

163-
let value = CacheEntry::TypeCache(result_type.clone());
164-
cache.add_cache(&key, value);
163+
cache
164+
.flow_node_cache
165+
.insert(key, CacheEntry::Cache(result_type.clone()));
165166
Ok(result_type)
166167
}
167168

crates/emmylua_code_analysis/src/semantic/infer/narrow/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010
infer_name::{find_decl_member_type, infer_global_type},
1111
InferResult,
1212
},
13-
CacheEntry, CacheKey, DbIndex, FlowAntecedent, FlowId, FlowNode, FlowTree, InferFailReason,
13+
CacheEntry, DbIndex, FlowAntecedent, FlowId, FlowNode, FlowTree, InferFailReason,
1414
LuaInferCache, LuaType,
1515
};
1616
use emmylua_parser::{LuaAstNode, LuaChunk, LuaNameExpr};
@@ -60,10 +60,9 @@ fn get_var_ref_type(db: &DbIndex, cache: &mut LuaInferCache, var_ref_id: &VarRef
6060
} else if let Some(member_id) = var_ref_id.get_member_id_ref() {
6161
find_decl_member_type(db, member_id)
6262
} else {
63-
let key = CacheKey::IndexRefOriginType(var_ref_id.clone());
64-
if let Some(type_cache) = cache.get(&key) {
63+
if let Some(type_cache) = cache.index_ref_origin_type_cache.get(&var_ref_id) {
6564
match type_cache {
66-
CacheEntry::TypeCache(ty) => return Ok(ty.clone()),
65+
CacheEntry::Cache(ty) => return Ok(ty.clone()),
6766
_ => {}
6867
}
6968
}

crates/emmylua_code_analysis/src/semantic/infer/narrow/narrow_type/mod.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
mod false_or_nil_type;
22

3-
use crate::{get_real_type, DbIndex, LuaType, LuaUnionType};
3+
use crate::{get_real_type, DbIndex, LuaType, LuaUnionType, TypeOps};
44
pub use false_or_nil_type::{narrow_false_or_nil, remove_false_or_nil};
55

66
// need to be optimized
@@ -147,6 +147,19 @@ pub fn narrow_down_type(db: &DbIndex, source: LuaType, target: LuaType) -> Optio
147147
return Some(LuaType::BooleanConst(true));
148148
}
149149
}
150+
LuaType::Union(target_u) => {
151+
let source_types = target_u
152+
.get_types()
153+
.into_iter()
154+
.filter_map(|t| narrow_down_type(db, real_source_ref.clone(), t))
155+
.collect::<Vec<_>>();
156+
let mut result_type = LuaType::Unknown;
157+
for source_type in source_types {
158+
result_type = TypeOps::Union.apply(db, &result_type, &source_type);
159+
}
160+
return Some(result_type);
161+
}
162+
LuaType::Variadic(_) => return Some(source),
150163
_ => {
151164
opt_result = Some(source.clone());
152165
}
@@ -156,8 +169,8 @@ pub fn narrow_down_type(db: &DbIndex, source: LuaType, target: LuaType) -> Optio
156169
LuaType::Union(union) => {
157170
let mut union_types = union
158171
.get_types()
159-
.iter()
160-
.filter_map(|t| narrow_down_type(db, t.clone(), target.clone()))
172+
.into_iter()
173+
.filter_map(|t| narrow_down_type(db, t, target.clone()))
161174
.collect::<Vec<_>>();
162175

163176
union_types.dedup();

crates/emmylua_code_analysis/src/semantic/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::cell::RefCell;
1313
use std::collections::HashMap;
1414
use std::{collections::HashSet, sync::Arc};
1515

16-
pub use cache::{CacheEntry, CacheKey, CacheOptions, LuaAnalysisPhase, LuaInferCache};
16+
pub use cache::{CacheEntry, CacheOptions, LuaAnalysisPhase, LuaInferCache};
1717
pub use decl::enum_variable_is_param;
1818
use emmylua_parser::{
1919
LuaCallExpr, LuaChunk, LuaExpr, LuaIndexKey, LuaParseError, LuaSyntaxNode, LuaSyntaxToken,

0 commit comments

Comments
 (0)