11use 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 ;
45use rowan:: TextRange ;
56use 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
2227use 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+
137176pub fn infer_member_by_member_key (
138177 db : & DbIndex ,
139178 cache : & mut LuaInferCache ,
0 commit comments