@@ -4,7 +4,7 @@ use oxc_ast::{
44} ;
55use oxc_diagnostics:: OxcDiagnostic ;
66use oxc_macros:: declare_oxc_lint;
7- use oxc_semantic:: { AstNode , NodeId , Reference , SymbolId } ;
7+ use oxc_semantic:: { AstNode , NodeId , Reference } ;
88use oxc_span:: { GetSpan , Span } ;
99use oxc_syntax:: operator:: UnaryOperator ;
1010
@@ -54,78 +54,95 @@ const REFLECT_MUTATION_METHODS: [&str; 4] =
5454 [ "defineProperty" , "deleteProperty" , "set" , "setPrototypeOf" ] ;
5555
5656impl Rule for NoImportAssign {
57- fn run_on_symbol ( & self , symbol_id : SymbolId , ctx : & LintContext < ' _ > ) {
58- let symbol_table = ctx. scoping ( ) ;
59- if symbol_table. symbol_flags ( symbol_id) . is_import ( ) {
60- let kind = ctx. nodes ( ) . kind ( symbol_table. symbol_declaration ( symbol_id) ) ;
61- let is_namespace_specifier = matches ! ( kind, AstKind :: ImportNamespaceSpecifier ( _) ) ;
62- for reference in symbol_table. get_resolved_references ( symbol_id) {
63- if is_namespace_specifier {
64- let parent_node = ctx. nodes ( ) . parent_node ( reference. node_id ( ) ) ;
65- if parent_node. kind ( ) . is_member_expression_kind ( ) {
66- let expr = parent_node. kind ( ) ;
67- let parent_parent_node = ctx. nodes ( ) . parent_node ( parent_node. id ( ) ) ;
68- let is_unary_expression_with_delete_operator = |kind| matches ! ( kind, AstKind :: UnaryExpression ( expr) if expr. operator == UnaryOperator :: Delete ) ;
69- let parent_parent_kind = parent_parent_node. kind ( ) ;
70- if ( matches ! ( parent_parent_kind, AstKind :: IdentifierReference ( _) )
71- || is_unary_expression_with_delete_operator ( parent_parent_kind)
72- || matches ! ( parent_parent_kind, AstKind :: ChainExpression ( _) if is_unary_expression_with_delete_operator( ctx. nodes( ) . parent_kind( parent_parent_node. id( ) ) ) ) )
73- && let Some ( ( span, _) ) = match expr {
74- AstKind :: StaticMemberExpression ( expr) => {
75- Some ( expr. static_property_info ( ) )
57+ fn run < ' a > ( & self , node : & AstNode < ' a > , ctx : & LintContext < ' a > ) {
58+ if let AstKind :: ImportDeclaration ( import_decl) = node. kind ( ) {
59+ let symbol_table = ctx. scoping ( ) ;
60+ if let Some ( specifiers) = & import_decl. specifiers {
61+ for specifier in specifiers {
62+ let symbol_id = specifier. local ( ) . symbol_id ( ) ;
63+ let is_namespace_specifier = matches ! (
64+ specifier,
65+ oxc_ast:: ast:: ImportDeclarationSpecifier :: ImportNamespaceSpecifier ( _)
66+ ) ;
67+ for reference in symbol_table. get_resolved_references ( symbol_id) {
68+ if is_namespace_specifier {
69+ let parent_node = ctx. nodes ( ) . parent_node ( reference. node_id ( ) ) ;
70+ if parent_node. kind ( ) . is_member_expression_kind ( ) {
71+ let expr = parent_node. kind ( ) ;
72+ let parent_parent_node = ctx. nodes ( ) . parent_node ( parent_node. id ( ) ) ;
73+ let is_unary_expression_with_delete_operator = |kind| {
74+ matches ! (
75+ kind,
76+ AstKind :: UnaryExpression ( expr)
77+ if expr. operator == UnaryOperator :: Delete
78+ )
79+ } ;
80+ let parent_parent_kind = parent_parent_node. kind ( ) ;
81+ if ( matches ! ( parent_parent_kind, AstKind :: IdentifierReference ( _) )
82+ || is_unary_expression_with_delete_operator ( parent_parent_kind)
83+ || matches ! ( parent_parent_kind, AstKind :: ChainExpression ( _) if is_unary_expression_with_delete_operator( ctx. nodes( ) . parent_kind( parent_parent_node. id( ) ) ) ) )
84+ && let Some ( ( span, _) ) = match expr {
85+ AstKind :: StaticMemberExpression ( expr) => {
86+ Some ( expr. static_property_info ( ) )
87+ }
88+ AstKind :: ComputedMemberExpression ( expr) => {
89+ expr. static_property_info ( )
90+ }
91+ _ => return ,
92+ }
93+ && span != ctx. semantic ( ) . reference_span ( reference)
94+ {
95+ return ctx
96+ . diagnostic ( no_import_assign_diagnostic ( expr. span ( ) ) ) ;
7697 }
77- AstKind :: ComputedMemberExpression ( expr) => {
78- expr. static_property_info ( )
98+ // Check for assignment to namespace property
99+ match expr {
100+ AstKind :: StaticMemberExpression ( member_expr) => {
101+ let condition_met = is_assignment_condition_met (
102+ & parent_parent_kind,
103+ parent_node. span ( ) ,
104+ true , // is_static
105+ ) ;
106+ check_namespace_member_assignment (
107+ & member_expr. object ,
108+ parent_node,
109+ reference,
110+ ctx,
111+ condition_met,
112+ ) ;
113+ }
114+ AstKind :: ComputedMemberExpression ( member_expr) => {
115+ let condition_met = is_assignment_condition_met (
116+ & parent_parent_kind,
117+ parent_node. span ( ) ,
118+ false , // is_static
119+ ) ;
120+ check_namespace_member_assignment (
121+ & member_expr. object ,
122+ parent_node,
123+ reference,
124+ ctx,
125+ condition_met,
126+ ) ;
127+ }
128+ _ => { }
79129 }
80- _ => return ,
81130 }
82- && span != ctx. semantic ( ) . reference_span ( reference)
83- {
84- return ctx. diagnostic ( no_import_assign_diagnostic ( expr. span ( ) ) ) ;
85131 }
86- // Check for assignment to namespace property
87- match expr {
88- AstKind :: StaticMemberExpression ( member_expr) => {
89- let condition_met = is_assignment_condition_met (
90- & parent_parent_kind,
91- parent_node. span ( ) ,
92- true , // is_static
93- ) ;
94- check_namespace_member_assignment (
95- & member_expr. object ,
96- parent_node,
97- reference,
98- ctx,
99- condition_met,
100- ) ;
101- }
102- AstKind :: ComputedMemberExpression ( member_expr) => {
103- let condition_met = is_assignment_condition_met (
104- & parent_parent_kind,
105- parent_node. span ( ) ,
106- false , // is_static
107- ) ;
108- check_namespace_member_assignment (
109- & member_expr. object ,
110- parent_node,
111- reference,
132+
133+ if reference. is_write ( )
134+ || ( is_namespace_specifier
135+ && is_argument_of_well_known_mutation_function (
136+ reference. node_id ( ) ,
112137 ctx,
113- condition_met,
114- ) ;
115- }
116- _ => { }
138+ ) )
139+ {
140+ ctx. diagnostic ( no_import_assign_diagnostic (
141+ ctx. semantic ( ) . reference_span ( reference) ,
142+ ) ) ;
117143 }
118144 }
119145 }
120-
121- if reference. is_write ( )
122- || ( is_namespace_specifier
123- && is_argument_of_well_known_mutation_function ( reference. node_id ( ) , ctx) )
124- {
125- ctx. diagnostic ( no_import_assign_diagnostic (
126- ctx. semantic ( ) . reference_span ( reference) ,
127- ) ) ;
128- }
129146 }
130147 }
131148 }
0 commit comments