1+ use oxc_ast:: AstKind ;
12use oxc_diagnostics:: OxcDiagnostic ;
23use oxc_macros:: declare_oxc_lint;
3- use oxc_semantic:: SymbolId ;
4+ use oxc_semantic:: { AstNode , SymbolId } ;
45use oxc_span:: Span ;
56
67use crate :: { context:: LintContext , rule:: Rule } ;
@@ -50,18 +51,34 @@ declare_oxc_lint!(
5051) ;
5152
5253impl Rule for NoConstAssign {
53- fn run_on_symbol ( & self , symbol_id : SymbolId , ctx : & LintContext < ' _ > ) {
54- let symbol_table = ctx. scoping ( ) ;
55- if symbol_table. symbol_flags ( symbol_id) . is_const_variable ( ) {
56- for reference in symbol_table. get_resolved_references ( symbol_id) {
57- if reference. is_write ( ) {
58- ctx. diagnostic ( no_const_assign_diagnostic (
59- symbol_table. symbol_name ( symbol_id) ,
60- symbol_table. symbol_span ( symbol_id) ,
61- ctx. semantic ( ) . reference_span ( reference) ,
62- ) ) ;
54+ fn run < ' a > ( & self , node : & AstNode < ' a > , ctx : & LintContext < ' a > ) {
55+ match node. kind ( ) {
56+ AstKind :: VariableDeclarator ( decl) if decl. kind . is_const ( ) || decl. kind . is_using ( ) => {
57+ for ident in decl. id . get_binding_identifiers ( ) {
58+ check_symbol_id ( ident. symbol_id ( ) , ctx) ;
6359 }
6460 }
61+ AstKind :: BindingRestElement ( rest) => {
62+ for ident in rest. argument . get_binding_identifiers ( ) {
63+ check_symbol_id ( ident. symbol_id ( ) , ctx) ;
64+ }
65+ }
66+ _ => { }
67+ }
68+ }
69+ }
70+
71+ fn check_symbol_id ( symbol_id : SymbolId , ctx : & LintContext < ' _ > ) {
72+ let symbol_table = ctx. scoping ( ) ;
73+ if symbol_table. symbol_flags ( symbol_id) . is_const_variable ( ) {
74+ for reference in symbol_table. get_resolved_references ( symbol_id) {
75+ if reference. is_write ( ) {
76+ ctx. diagnostic ( no_const_assign_diagnostic (
77+ symbol_table. symbol_name ( symbol_id) ,
78+ symbol_table. symbol_span ( symbol_id) ,
79+ ctx. semantic ( ) . reference_span ( reference) ,
80+ ) ) ;
81+ }
6582 }
6683 }
6784}
@@ -86,6 +103,11 @@ fn test() {
86103 ( "const a = 1; { let a = 2; { a += 1; } }" , None ) ,
87104 ( "const foo = 1;let bar;bar[foo ?? foo] = 42;" , None ) ,
88105 ( "const FOO = 1; ({ files = FOO } = arg1); " , None ) ,
106+ // using + await using
107+ ( "using x = foo();" , None ) ,
108+ ( "await using x = foo();" , None ) ,
109+ ( "using x = foo(); bar(x);" , None ) ,
110+ ( "await using x = foo(); bar(x);" , None ) ,
89111 ] ;
90112
91113 let fail = vec ! [
@@ -107,6 +129,15 @@ fn test() {
107129 ( "const [a, b, ...[c, ...d]] = [1, 2, 3, 4, 5]; d = 123" , None ) ,
108130 ( "const d = 123; [a, b, ...[c, ...d]] = [1, 2, 3, 4, 5]" , None ) ,
109131 ( "const b = 0; ({a, ...b} = {a: 1, c: 2, d: 3})" , None ) ,
132+ // using + await using
133+ ( "using x = foo(); x = 1;" , None ) ,
134+ ( "await using x = foo(); x = 1;" , None ) ,
135+ ( "using x = foo(); x ??= bar();" , None ) ,
136+ ( "await using x = foo(); x ||= bar();" , None ) ,
137+ ( "using x = foo(); [x, y] = bar();" , None ) ,
138+ ( "await using x = foo(); [x = baz, y] = bar();" , None ) ,
139+ ( "using x = foo(); ({a: x} = bar());" , None ) ,
140+ ( "await using x = foo(); ({a: x = baz} = bar());" , None ) ,
110141 ] ;
111142
112143 Tester :: new ( NoConstAssign :: NAME , NoConstAssign :: PLUGIN , pass, fail) . test_and_snapshot ( ) ;
0 commit comments