Skip to content

Commit 1859613

Browse files
committed
update
1 parent 09d4c13 commit 1859613

15 files changed

Lines changed: 441 additions & 272 deletions

File tree

crates/emmylua_code_analysis/src/db_index/declaration/decl_tree.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,8 +376,31 @@ impl LuaDeclarationTree {
376376
}
377377
}
378378

379-
#[derive(Debug)]
379+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
380380
pub enum LuaDeclOrMemberId {
381381
Decl(LuaDeclId),
382382
Member(LuaMemberId),
383383
}
384+
385+
impl LuaDeclOrMemberId {
386+
pub fn as_decl_id(&self) -> Option<LuaDeclId> {
387+
match self {
388+
LuaDeclOrMemberId::Decl(decl_id) => Some(*decl_id),
389+
LuaDeclOrMemberId::Member(_) => None,
390+
}
391+
}
392+
393+
pub fn as_member_id(&self) -> Option<LuaMemberId> {
394+
match self {
395+
LuaDeclOrMemberId::Decl(_) => None,
396+
LuaDeclOrMemberId::Member(member_id) => Some(*member_id),
397+
}
398+
}
399+
400+
pub fn get_position(&self) -> TextSize {
401+
match self {
402+
LuaDeclOrMemberId::Decl(decl_id) => decl_id.position,
403+
LuaDeclOrMemberId::Member(member_id) => member_id.get_position(),
404+
}
405+
}
406+
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,20 @@ pub use cache_options::{CacheOptions, LuaAnalysisPhase};
44
use emmylua_parser::LuaSyntaxId;
55
use std::{collections::HashMap, sync::Arc};
66

7-
use crate::{db_index::LuaType, FileId, FlowId, LuaDeclId, LuaFunctionType};
7+
use crate::{db_index::LuaType, semantic::infer::VarRefId, FileId, FlowId, LuaFunctionType};
88

99
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1010
pub enum CacheKey {
1111
Expr(LuaSyntaxId),
1212
Call(LuaSyntaxId, Option<usize>, LuaType),
13-
FlowNode(LuaDeclId, FlowId),
13+
FlowNode(VarRefId, FlowId),
14+
IndexRefOriginType(VarRefId),
1415
}
1516

1617
#[derive(Debug)]
1718
pub enum CacheEntry {
1819
ReadyCache,
19-
ExprCache(LuaType),
20+
TypeCache(LuaType),
2021
CallCache(Arc<LuaFunctionType>),
2122
}
2223

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

Lines changed: 77 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::collections::HashSet;
22

3-
use emmylua_parser::{LuaExpr, LuaIndexExpr, LuaIndexKey, LuaIndexMemberExpr};
3+
use emmylua_parser::{LuaExpr, LuaIndexExpr, LuaIndexKey, LuaIndexMemberExpr, PathTrait};
4+
use internment::ArcIntern;
45
use rowan::TextRange;
56
use smol_str::SmolStr;
67

@@ -12,11 +13,15 @@ use crate::{
1213
enum_variable_is_param,
1314
semantic::{
1415
generic::{instantiate_type_generic, TypeSubstitutor},
16+
infer::{
17+
infer_name::get_name_expr_var_ref_d, narrow::infer_var_expr_narrow_type, VarRefId,
18+
},
1519
member::get_buildin_type_map_type_id,
1620
type_check::{self, check_type_compact},
1721
InferGuard,
1822
},
19-
InFiled, LuaInferCache, LuaInstanceType, LuaMemberOwner, LuaOperatorOwner, TypeOps,
23+
CacheEntry, CacheKey, InFiled, LuaDeclOrMemberId, LuaInferCache, LuaInstanceType,
24+
LuaMemberOwner, LuaOperatorOwner, TypeOps,
2025
};
2126

2227
use super::{infer_expr, infer_name::infer_global_type, InferFailReason, InferResult};
@@ -85,55 +90,89 @@ fn infer_member_type_pass_flow(
8590
cache: &mut LuaInferCache,
8691
index_expr: LuaIndexExpr,
8792
prefix_type: &LuaType,
88-
mut member_type: LuaType,
93+
member_type: LuaType,
8994
) -> InferResult {
90-
let mut allow_reassign = true;
95+
// let mut allow_reassign = true;
9196
match &prefix_type {
9297
// TODO: flow analysis should not generate corresponding `flow_chain` if the prefix type is an array
9398
LuaType::Array(_) => {
9499
return Ok(member_type.clone());
95100
}
96-
LuaType::Ref(decl_id) => {
97-
let index_key = index_expr.get_index_key().ok_or(InferFailReason::None)?;
98-
let key = LuaMemberKey::from_index_key(db, cache, &index_key)?;
99-
let member_index = db.get_member_index();
100-
if member_index
101-
.get_member_item(&LuaMemberOwner::Type(decl_id.clone()), &key)
102-
.is_some()
103-
{
104-
allow_reassign = false;
105-
}
106-
}
101+
// LuaType::Ref(decl_id) => {
102+
// let index_key = index_expr.get_index_key().ok_or(InferFailReason::None)?;
103+
// let key = LuaMemberKey::from_index_key(db, cache, &index_key)?;
104+
// let member_index = db.get_member_index();
105+
// if member_index
106+
// .get_member_item(&LuaMemberOwner::Type(decl_id.clone()), &key)
107+
// .is_some()
108+
// {
109+
// allow_reassign = false;
110+
// }
111+
// }
107112
_ => {}
108113
}
109114

110-
// let access_path = match index_expr.get_access_path() {
111-
// Some(path) => path,
112-
// None => return Ok(member_type.clone()),
113-
// };
114-
// let var_ref_id = LuaVarRefId::Name(SmolStr::new(&access_path));
115-
// let flow_id = LuaClosureId::from_node(index_expr.syntax());
116-
// let flow_chain = db
117-
// .get_flow_index()
118-
// .get_flow_chain(cache.get_file_id(), var_ref_id);
119-
// if let Some(flow_chain) = flow_chain {
120-
// let root = index_expr.get_root();
121-
// for type_assert in flow_chain.get_type_asserts(index_expr.get_position(), flow_id) {
122-
// let new_type = type_assert.tighten_type(db, cache, &root, member_type.clone())?;
123-
// if type_assert.is_reassign() && !allow_reassign {
124-
// // 允许仅去除 nil
125-
// if member_type.is_nullable() && !new_type.is_nullable() {
126-
// member_type = new_type;
127-
// }
128-
// continue;
129-
// }
130-
// member_type = new_type;
131-
// }
132-
// }
115+
let access_path = match index_expr.get_access_path() {
116+
Some(path) => ArcIntern::new(SmolStr::new(&path)),
117+
None => return Ok(member_type.clone()),
118+
};
119+
120+
let mut prefix_expr = index_expr.get_prefix_expr().ok_or(InferFailReason::None)?;
121+
while let LuaExpr::IndexExpr(index_expr) = prefix_expr {
122+
prefix_expr = index_expr.get_prefix_expr().ok_or(InferFailReason::None)?;
123+
}
124+
125+
if let LuaExpr::NameExpr(name_expr) = prefix_expr {
126+
let decl_or_member_id = match get_name_expr_var_ref_d(db, cache, &name_expr) {
127+
Some(VarRefId::SelfRef(decl_or_id)) => decl_or_id,
128+
Some(VarRefId::VarRef(decl_id)) => LuaDeclOrMemberId::Decl(decl_id),
129+
_ => return Ok(member_type.clone()),
130+
};
131+
132+
let var_ref_id = VarRefId::IndexRef(decl_or_member_id, access_path);
133+
let key = CacheKey::IndexRefOriginType(var_ref_id.clone());
134+
cache.add_cache(&key, CacheEntry::TypeCache(member_type.clone()));
135+
let result = infer_var_expr_narrow_type(db, cache, name_expr, var_ref_id);
136+
match &result {
137+
Err(InferFailReason::None) => return Ok(member_type.clone()),
138+
_ => {}
139+
}
140+
141+
return result;
142+
}
133143

134144
Ok(member_type)
135145
}
136146

147+
pub fn get_index_expr_var_ref_id(
148+
db: &DbIndex,
149+
cache: &mut LuaInferCache,
150+
index_expr: LuaIndexExpr,
151+
) -> Option<VarRefId> {
152+
let access_path = match index_expr.get_access_path() {
153+
Some(path) => ArcIntern::new(SmolStr::new(&path)),
154+
None => return None,
155+
};
156+
157+
let mut prefix_expr = index_expr.get_prefix_expr()?;
158+
while let LuaExpr::IndexExpr(index_expr) = prefix_expr {
159+
prefix_expr = index_expr.get_prefix_expr()?;
160+
}
161+
162+
if let LuaExpr::NameExpr(name_expr) = prefix_expr {
163+
let decl_or_member_id = match get_name_expr_var_ref_d(db, cache, &name_expr) {
164+
Some(VarRefId::SelfRef(decl_or_id)) => decl_or_id,
165+
Some(VarRefId::VarRef(decl_id)) => LuaDeclOrMemberId::Decl(decl_id),
166+
_ => return None,
167+
};
168+
169+
let var_ref_id = VarRefId::IndexRef(decl_or_member_id, access_path);
170+
return Some(var_ref_id);
171+
}
172+
173+
None
174+
}
175+
137176
pub fn infer_member_by_member_key(
138177
db: &DbIndex,
139178
cache: &mut LuaInferCache,

crates/emmylua_code_analysis/src/semantic/infer/infer_name/mod.rs renamed to crates/emmylua_code_analysis/src/semantic/infer/infer_name.rs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
mod narrow;
2-
31
use emmylua_parser::{LuaAstNode, LuaNameExpr};
42

3+
use super::{InferFailReason, InferResult};
54
use crate::{
65
db_index::{DbIndex, LuaDeclOrMemberId},
7-
semantic::infer::infer_name::narrow::infer_name_expr_narrow_type,
6+
semantic::infer::narrow::{infer_var_expr_narrow_type, VarRefId},
87
LuaDecl, LuaDeclExtra, LuaInferCache, LuaMemberId, LuaType, TypeOps,
98
};
109

11-
use super::{InferFailReason, InferResult};
12-
1310
pub fn infer_name_expr(
1411
db: &DbIndex,
1512
cache: &mut LuaInferCache,
@@ -31,20 +28,39 @@ pub fn infer_name_expr(
3128
.ok_or(InferFailReason::None)?;
3229
let decl_id = file_ref.get_decl_id(&range);
3330
if let Some(decl_id) = decl_id {
34-
infer_name_expr_narrow_type(db, cache, name_expr, decl_id)
31+
infer_var_expr_narrow_type(db, cache, name_expr, VarRefId::VarRef(decl_id))
3532
} else {
3633
infer_global_type(db, name)
3734
}
3835
}
3936

4037
fn infer_self(db: &DbIndex, cache: &mut LuaInferCache, name_expr: LuaNameExpr) -> InferResult {
41-
let semantic_id =
38+
let decl_or_member_id =
4239
find_self_decl_or_member_id(db, cache, &name_expr).ok_or(InferFailReason::None)?;
43-
match semantic_id {
44-
LuaDeclOrMemberId::Decl(decl_id) => {
45-
infer_name_expr_narrow_type(db, cache, name_expr, decl_id)
40+
// LuaDeclOrMemberId::Member(member_id) => find_decl_member_type(db, member_id),
41+
infer_var_expr_narrow_type(db, cache, name_expr, VarRefId::SelfRef(decl_or_member_id))
42+
}
43+
44+
pub fn get_name_expr_var_ref_d(
45+
db: &DbIndex,
46+
cache: &mut LuaInferCache,
47+
name_expr: &LuaNameExpr,
48+
) -> Option<VarRefId> {
49+
let name_token = name_expr.get_name_token()?;
50+
let name = name_token.get_name_text();
51+
match name {
52+
"self" => {
53+
let decl_or_id = find_self_decl_or_member_id(db, cache, name_expr)?;
54+
Some(VarRefId::SelfRef(decl_or_id))
55+
}
56+
_ => {
57+
let file_id = cache.get_file_id();
58+
let references_index = db.get_reference_index();
59+
let range = name_expr.get_range();
60+
let file_ref = references_index.get_local_reference(&file_id)?;
61+
let decl_id = file_ref.get_decl_id(&range)?;
62+
Some(VarRefId::VarRef(decl_id))
4663
}
47-
LuaDeclOrMemberId::Member(member_id) => find_decl_member_type(db, member_id),
4864
}
4965
}
5066

@@ -89,7 +105,7 @@ pub fn infer_param(db: &DbIndex, decl: &LuaDecl) -> InferResult {
89105
Err(InferFailReason::UnResolveDeclType(decl.get_id()))
90106
}
91107

92-
fn find_decl_member_type(db: &DbIndex, member_id: LuaMemberId) -> InferResult {
108+
pub fn find_decl_member_type(db: &DbIndex, member_id: LuaMemberId) -> InferResult {
93109
let item = db
94110
.get_member_index()
95111
.get_member_item_by_member_id(member_id)

crates/emmylua_code_analysis/src/semantic/infer/infer_name/narrow/condition_flow/index_flow.rs

Lines changed: 0 additions & 22 deletions
This file was deleted.

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod infer_index;
55
mod infer_name;
66
mod infer_table;
77
mod infer_unary;
8+
mod narrow;
89
mod test;
910

1011
use std::ops::Deref;
@@ -23,6 +24,7 @@ pub use infer_name::{find_self_decl_or_member_id, infer_param};
2324
use infer_table::infer_table_expr;
2425
pub use infer_table::{infer_table_field_value_should_be, infer_table_should_be};
2526
use infer_unary::infer_unary_expr;
27+
pub use narrow::VarRefId;
2628

2729
use rowan::TextRange;
2830
use smol_str::SmolStr;
@@ -42,7 +44,7 @@ pub fn infer_expr(db: &DbIndex, cache: &mut LuaInferCache, expr: LuaExpr) -> Inf
4244
let key = CacheKey::Expr(syntax_id);
4345
match cache.get(&key) {
4446
Some(cache) => match cache {
45-
CacheEntry::ExprCache(ty) => return Ok(ty.clone()),
47+
CacheEntry::TypeCache(ty) => return Ok(ty.clone()),
4648
_ => return Err(InferFailReason::RecursiveInfer),
4749
},
4850
None => {}
@@ -57,7 +59,7 @@ pub fn infer_expr(db: &DbIndex, cache: &mut LuaInferCache, expr: LuaExpr) -> Inf
5759
{
5860
cache.add_cache(
5961
&key,
60-
CacheEntry::ExprCache(bind_type_cache.as_type().clone()),
62+
CacheEntry::TypeCache(bind_type_cache.as_type().clone()),
6163
);
6264
return Ok(bind_type_cache.as_type().clone());
6365
}
@@ -80,14 +82,14 @@ pub fn infer_expr(db: &DbIndex, cache: &mut LuaInferCache, expr: LuaExpr) -> Inf
8082
};
8183

8284
match &result_type {
83-
Ok(result_type) => cache.add_cache(&key, CacheEntry::ExprCache(result_type.clone())),
85+
Ok(result_type) => cache.add_cache(&key, CacheEntry::TypeCache(result_type.clone())),
8486
Err(InferFailReason::None) | Err(InferFailReason::RecursiveInfer) => {
85-
cache.add_cache(&key, CacheEntry::ExprCache(LuaType::Unknown));
87+
cache.add_cache(&key, CacheEntry::TypeCache(LuaType::Unknown));
8688
return Ok(LuaType::Unknown);
8789
}
8890
Err(InferFailReason::FieldNotFound) => {
8991
if cache.get_config().analysis_phase.is_force() {
90-
cache.add_cache(&key, CacheEntry::ExprCache(LuaType::Nil));
92+
cache.add_cache(&key, CacheEntry::TypeCache(LuaType::Nil));
9193
return Ok(LuaType::Nil);
9294
} else {
9395
cache.ready_cache(&key);

0 commit comments

Comments
 (0)