@@ -33,7 +33,7 @@ impl Checker for PreferredLocalAliasChecker {
33
33
LuaAst :: LuaIndexExpr ( index_expr) => {
34
34
check_index_expr_preference (
35
35
context,
36
- & local_alias_set,
36
+ & mut local_alias_set,
37
37
semantic_model,
38
38
& index_expr,
39
39
) ;
@@ -130,10 +130,17 @@ fn is_only_dot_index_expr(expr: &LuaExpr) -> Option<bool> {
130
130
131
131
#[ derive( Debug ) ]
132
132
struct LocalAliasSet {
133
- local_alias_stack : Vec < HashMap < String , ( LuaSemanticDeclId , String ) > > ,
133
+ local_alias_stack : Vec < HashMap < String , LocalAliasInfo > > ,
134
134
disable_check : HashSet < TextRange > ,
135
135
}
136
136
137
+ #[ derive( Debug ) ]
138
+ struct LocalAliasInfo {
139
+ pub decl_id : LuaSemanticDeclId ,
140
+ pub preferred_name : String ,
141
+ pub invalid : bool ,
142
+ }
143
+
137
144
impl LocalAliasSet {
138
145
fn new ( ) -> Self {
139
146
LocalAliasSet {
@@ -152,14 +159,21 @@ impl LocalAliasSet {
152
159
153
160
fn insert ( & mut self , name : String , preferred_name : String , decl_id : LuaSemanticDeclId ) {
154
161
if let Some ( map) = self . local_alias_stack . last_mut ( ) {
155
- map. insert ( name, ( decl_id, preferred_name) ) ;
162
+ map. insert (
163
+ name,
164
+ LocalAliasInfo {
165
+ decl_id,
166
+ preferred_name,
167
+ invalid : false ,
168
+ } ,
169
+ ) ;
156
170
}
157
171
}
158
172
159
- fn get ( & self , name : & str ) -> Option < ( LuaSemanticDeclId , String ) > {
160
- for map in self . local_alias_stack . iter ( ) . rev ( ) {
161
- if let Some ( item) = map. get ( name) {
162
- return Some ( item. clone ( ) ) ;
173
+ fn get ( & mut self , name : & str ) -> Option < & mut LocalAliasInfo > {
174
+ for map in self . local_alias_stack . iter_mut ( ) . rev ( ) {
175
+ if let Some ( item) = map. get_mut ( name) {
176
+ return Some ( item) ;
163
177
}
164
178
}
165
179
None
@@ -176,7 +190,7 @@ impl LocalAliasSet {
176
190
177
191
fn check_index_expr_preference (
178
192
context : & mut DiagnosticContext ,
179
- local_alias_set : & LocalAliasSet ,
193
+ local_alias_set : & mut LocalAliasSet ,
180
194
semantic_model : & SemanticModel ,
181
195
index_expr : & LuaIndexExpr ,
182
196
) -> Option < ( ) > {
@@ -190,15 +204,16 @@ fn check_index_expr_preference(
190
204
}
191
205
192
206
let parent = index_expr. get_parent :: < LuaAst > ( ) ?;
207
+ let mut mutable_index = false ;
193
208
match parent {
194
209
LuaAst :: LuaAssignStat ( assign_stat) => {
195
210
let eq = assign_stat. get_assign_op ( ) ?;
196
211
if eq. get_position ( ) > index_expr. get_position ( ) {
197
- return Some ( ( ) ) ;
212
+ mutable_index = true ;
198
213
}
199
214
}
200
215
LuaAst :: LuaFuncStat ( _) => {
201
- return Some ( ( ) ) ;
216
+ mutable_index = true ;
202
217
}
203
218
_ => { }
204
219
}
@@ -209,18 +224,27 @@ fn check_index_expr_preference(
209
224
_ => return Some ( ( ) ) ,
210
225
} ;
211
226
212
- let ( semantic_id, preferred_name) = local_alias_set. get ( & name) ?;
227
+ let alias_info = local_alias_set. get ( & name) ?;
228
+ if alias_info. invalid {
229
+ return Some ( ( ) ) ;
230
+ }
231
+
213
232
if semantic_model. is_reference_to (
214
233
index_expr. syntax ( ) . clone ( ) ,
215
- semantic_id ,
234
+ alias_info . decl_id . clone ( ) ,
216
235
SemanticDeclLevel :: NoTrace ,
217
236
) {
237
+ if mutable_index {
238
+ alias_info. invalid = true ;
239
+ return Some ( ( ) ) ;
240
+ }
241
+
218
242
context. add_diagnostic (
219
243
DiagnosticCode :: PreferredLocalAlias ,
220
244
index_expr. get_range ( ) ,
221
245
t ! (
222
246
"Prefer use local alias variable '%{name}'" ,
223
- name = preferred_name
247
+ name = alias_info . preferred_name
224
248
)
225
249
. to_string ( ) ,
226
250
None ,
0 commit comments