@@ -98,8 +98,12 @@ fn collect_local_alias(
9898 {
9999 let name_token = local_name. get_name_token ( ) ?;
100100 let preferred_name = name_token. get_name_text ( ) ;
101+ let ref_var = match find_ref_var_decl_id ( semantic_model, value_expr) {
102+ Some ( id) => id,
103+ None => continue ,
104+ } ;
101105
102- local_alias_set. insert ( name, preferred_name. to_string ( ) , semantic_id) ;
106+ local_alias_set. insert ( name, preferred_name. to_string ( ) , semantic_id, ref_var ) ;
103107 local_alias_set. add_disable_check ( value_expr. get_range ( ) ) ;
104108 }
105109 }
@@ -108,6 +112,27 @@ fn collect_local_alias(
108112 Some ( ( ) )
109113}
110114
115+ fn find_ref_var_decl_id (
116+ semantic_model : & SemanticModel ,
117+ expr : & LuaExpr ,
118+ ) -> Option < LuaSemanticDeclId > {
119+ let mut prefix = expr. clone ( ) ;
120+ while let LuaExpr :: IndexExpr ( index_expr) = prefix {
121+ match index_expr. get_prefix_expr ( ) {
122+ Some ( LuaExpr :: NameExpr ( name_expr) ) => {
123+ let node_or_token = NodeOrToken :: Node ( name_expr. syntax ( ) . clone ( ) ) ;
124+ return semantic_model. find_decl ( node_or_token, SemanticDeclLevel :: NoTrace ) ;
125+ }
126+ Some ( LuaExpr :: IndexExpr ( prefix_index_expr) ) => {
127+ prefix = LuaExpr :: IndexExpr ( prefix_index_expr) ;
128+ }
129+ _ => return None ,
130+ }
131+ }
132+
133+ None
134+ }
135+
111136fn is_only_dot_index_expr ( expr : & LuaExpr ) -> Option < bool > {
112137 let mut index_expr = match expr {
113138 LuaExpr :: IndexExpr ( index_expr) => index_expr. clone ( ) ,
@@ -129,6 +154,19 @@ fn is_only_dot_index_expr(expr: &LuaExpr) -> Option<bool> {
129154 }
130155}
131156
157+ fn get_first_name_expr ( expr : & LuaIndexExpr ) -> Option < LuaExpr > {
158+ let mut index_expr = expr. clone ( ) ;
159+ loop {
160+ match index_expr. get_prefix_expr ( ) {
161+ Some ( LuaExpr :: NameExpr ( name_expr) ) => return Some ( LuaExpr :: NameExpr ( name_expr) ) ,
162+ Some ( LuaExpr :: IndexExpr ( prefix_index_expr) ) => {
163+ index_expr = prefix_index_expr;
164+ }
165+ _ => return None ,
166+ }
167+ }
168+ }
169+
132170#[ derive( Debug ) ]
133171struct LocalAliasSet {
134172 local_alias_stack : Vec < HashMap < String , LocalAliasInfo > > ,
@@ -137,7 +175,8 @@ struct LocalAliasSet {
137175
138176#[ derive( Debug ) ]
139177struct LocalAliasInfo {
140- pub decl_id : LuaSemanticDeclId ,
178+ pub ref_var : LuaSemanticDeclId ,
179+ pub ref_field : LuaSemanticDeclId ,
141180 pub preferred_name : String ,
142181 pub invalid : bool ,
143182}
@@ -158,12 +197,19 @@ impl LocalAliasSet {
158197 self . local_alias_stack . pop ( ) ;
159198 }
160199
161- fn insert ( & mut self , name : String , preferred_name : String , decl_id : LuaSemanticDeclId ) {
200+ fn insert (
201+ & mut self ,
202+ name : String ,
203+ preferred_name : String ,
204+ decl_id : LuaSemanticDeclId ,
205+ ref_var : LuaSemanticDeclId ,
206+ ) {
162207 if let Some ( map) = self . local_alias_stack . last_mut ( ) {
163208 map. insert (
164209 name,
165210 LocalAliasInfo {
166- decl_id,
211+ ref_var,
212+ ref_field : decl_id,
167213 preferred_name,
168214 invalid : false ,
169215 } ,
@@ -230,29 +276,40 @@ fn check_index_expr_preference(
230276 return Some ( ( ) ) ;
231277 }
232278
233- if semantic_model. is_reference_to (
279+ let var_expr = get_first_name_expr ( index_expr) ?;
280+ if !semantic_model. is_reference_to (
281+ var_expr. syntax ( ) . clone ( ) ,
282+ alias_info. ref_var . clone ( ) ,
283+ SemanticDeclLevel :: NoTrace ,
284+ ) {
285+ return Some ( ( ) ) ;
286+ }
287+
288+ if !semantic_model. is_reference_to (
234289 index_expr. syntax ( ) . clone ( ) ,
235- alias_info. decl_id . clone ( ) ,
290+ alias_info. ref_field . clone ( ) ,
236291 SemanticDeclLevel :: NoTrace ,
237292 ) {
238- if mutable_index {
239- alias_info. invalid = true ;
240- return Some ( ( ) ) ;
241- }
293+ return Some ( ( ) ) ;
294+ }
242295
243- context. add_diagnostic (
244- DiagnosticCode :: PreferredLocalAlias ,
245- index_expr. get_range ( ) ,
246- t ! (
247- "Prefer use local alias variable '%{name}'" ,
248- name = alias_info. preferred_name
249- )
250- . to_string ( ) ,
251- Some ( json ! ( {
252- "preferredAlias" : alias_info. preferred_name. clone( ) ,
253- } ) ) ,
254- ) ;
296+ if mutable_index {
297+ alias_info. invalid = true ;
298+ return Some ( ( ) ) ;
255299 }
256300
301+ context. add_diagnostic (
302+ DiagnosticCode :: PreferredLocalAlias ,
303+ index_expr. get_range ( ) ,
304+ t ! (
305+ "Prefer use local alias variable '%{name}'" ,
306+ name = alias_info. preferred_name
307+ )
308+ . to_string ( ) ,
309+ Some ( json ! ( {
310+ "preferredAlias" : alias_info. preferred_name. clone( ) ,
311+ } ) ) ,
312+ ) ;
313+
257314 Some ( ( ) )
258315}
0 commit comments