1use rustc_hash::{FxHashMap, FxHashSet};
2use swc_atoms::Atom;
3use swc_common::{Mark, SyntaxContext};
4use swc_ecma_ast::*;
5use swc_ecma_utils::{find_pat_ids, stack_size::maybe_grow_default};
6use swc_ecma_visit::{
7 noop_visit_mut_type, visit_mut_obj_and_computed, visit_mut_pass, VisitMut, VisitMutWith,
8};
9use tracing::{debug, span, Level};
10
11use crate::scope::{DeclKind, IdentType, ScopeKind};
12
13#[cfg(test)]
14mod tests;
15
16const LOG: bool = false && cfg!(debug_assertions);
17
18pub fn resolver(
131 unresolved_mark: Mark,
132 top_level_mark: Mark,
133 typescript: bool,
134) -> impl 'static + Pass + VisitMut {
135 assert_ne!(
136 unresolved_mark,
137 Mark::root(),
138 "Marker provided to resolver should not be the root mark"
139 );
140
141 let _ = SyntaxContext::empty().apply_mark(unresolved_mark);
142 let _ = SyntaxContext::empty().apply_mark(top_level_mark);
143
144 visit_mut_pass(Resolver {
145 current: Scope::new(ScopeKind::Fn, top_level_mark, None),
146 ident_type: IdentType::Ref,
147 in_type: false,
148 is_module: false,
149 in_ts_module: false,
150 decl_kind: DeclKind::Lexical,
151 strict_mode: false,
152 config: InnerConfig {
153 handle_types: typescript,
154 unresolved_mark,
155 top_level_mark,
156 },
157 })
158}
159
160#[derive(Debug, Clone)]
161struct Scope<'a> {
162 parent: Option<&'a Scope<'a>>,
164
165 kind: ScopeKind,
167
168 mark: Mark,
170
171 declared_symbols: FxHashMap<Atom, DeclKind>,
173
174 declared_types: FxHashSet<Atom>,
176}
177
178impl<'a> Scope<'a> {
179 pub fn new(kind: ScopeKind, mark: Mark, parent: Option<&'a Scope<'a>>) -> Self {
180 Scope {
181 parent,
182 kind,
183 mark,
184 declared_symbols: Default::default(),
185 declared_types: Default::default(),
186 }
187 }
188
189 fn is_declared(&self, symbol: &Atom) -> Option<&DeclKind> {
190 self.declared_symbols
191 .get(symbol)
192 .or_else(|| self.parent?.is_declared(symbol))
193 }
194}
195
196struct Resolver<'a> {
202 current: Scope<'a>,
203 ident_type: IdentType,
204 in_type: bool,
205 is_module: bool,
206 in_ts_module: bool,
207 decl_kind: DeclKind,
208 strict_mode: bool,
209
210 config: InnerConfig,
211}
212
213#[derive(Debug, Clone, Copy)]
214struct InnerConfig {
215 handle_types: bool,
216 unresolved_mark: Mark,
217 top_level_mark: Mark,
218}
219
220#[allow(clippy::needless_lifetimes)]
221impl<'a> Resolver<'a> {
222 #[cfg(test)]
223 fn new(current: Scope<'a>, config: InnerConfig) -> Self {
224 Resolver {
225 current,
226 ident_type: IdentType::Ref,
227 in_type: false,
228 is_module: false,
229 in_ts_module: false,
230 config,
231 decl_kind: DeclKind::Lexical,
232 strict_mode: false,
233 }
234 }
235
236 fn with_child<F>(&self, kind: ScopeKind, op: F)
237 where
238 F: for<'aa> FnOnce(&mut Resolver<'aa>),
239 {
240 let mut child = Resolver {
241 current: Scope::new(
242 kind,
243 Mark::fresh(self.config.top_level_mark),
244 Some(&self.current),
245 ),
246 ident_type: IdentType::Ref,
247 config: self.config,
248 in_type: self.in_type,
249 is_module: self.is_module,
250 in_ts_module: self.in_ts_module,
251 decl_kind: self.decl_kind,
252 strict_mode: self.strict_mode,
253 };
254
255 op(&mut child);
256 }
257
258 fn visit_mut_stmt_within_child_scope(&mut self, s: &mut Stmt) {
259 self.with_child(ScopeKind::Block, |child| match s {
260 Stmt::Block(s) => {
261 child.mark_block(&mut s.ctxt);
262 s.visit_mut_children_with(child);
263 }
264 _ => s.visit_mut_with(child),
265 });
266 }
267
268 fn mark_for_ref(&self, sym: &Atom) -> Option<Mark> {
270 self.mark_for_ref_inner(sym, false)
271 }
272
273 fn mark_for_ref_inner(&self, sym: &Atom, stop_an_fn_scope: bool) -> Option<Mark> {
274 if self.config.handle_types && self.in_type {
275 let mut mark = self.current.mark;
276 let mut scope = Some(&self.current);
277
278 while let Some(cur) = scope {
279 if cur.declared_types.contains(sym) {
282 if mark == Mark::root() {
283 break;
284 }
285 return Some(mark);
286 }
287
288 if cur.kind == ScopeKind::Fn && stop_an_fn_scope {
289 return None;
290 }
291
292 if let Some(parent) = &cur.parent {
293 mark = parent.mark;
294 }
295 scope = cur.parent;
296 }
297 }
298
299 let mut mark = self.current.mark;
300 let mut scope = Some(&self.current);
301
302 while let Some(cur) = scope {
303 if cur.declared_symbols.contains_key(sym) {
304 if mark == Mark::root() {
305 return None;
306 }
307
308 return match &**sym {
309 "undefined" | "NaN" | "Infinity"
312 if mark == self.config.top_level_mark && !self.is_module =>
313 {
314 Some(self.config.unresolved_mark)
315 }
316 _ => Some(mark),
317 };
318 }
319
320 if cur.kind == ScopeKind::Fn && stop_an_fn_scope {
321 return None;
322 }
323
324 if let Some(parent) = &cur.parent {
325 mark = parent.mark;
326 }
327 scope = cur.parent;
328 }
329
330 None
331 }
332
333 fn modify(&mut self, id: &mut Ident, kind: DeclKind) {
335 if cfg!(debug_assertions) && LOG {
336 debug!(
337 "Binding (type = {}) {}{:?} {:?}",
338 self.in_type, id.sym, id.ctxt, kind
339 );
340 }
341
342 if id.ctxt != SyntaxContext::empty() {
343 return;
344 }
345
346 if self.in_type {
347 self.current.declared_types.insert(id.sym.clone());
348 } else {
349 self.current.declared_symbols.insert(id.sym.clone(), kind);
350 }
351
352 let mark = self.current.mark;
353
354 if mark != Mark::root() {
355 id.ctxt = id.ctxt.apply_mark(mark);
356 }
357 }
358
359 fn mark_block(&mut self, ctxt: &mut SyntaxContext) {
360 if *ctxt != SyntaxContext::empty() {
361 return;
362 }
363
364 let mark = self.current.mark;
365
366 if mark != Mark::root() {
367 *ctxt = ctxt.apply_mark(mark)
368 }
369 }
370
371 fn try_resolving_as_type(&mut self, i: &mut Ident) {
372 if i.ctxt.outer() == self.config.unresolved_mark {
373 i.ctxt = SyntaxContext::empty()
374 }
375
376 self.in_type = true;
377 i.visit_mut_with(self);
378 self.in_type = false;
379 }
380}
381
382macro_rules! typed {
383 ($name:ident, $T:ty) => {
384 fn $name(&mut self, node: &mut $T) {
385 if self.config.handle_types {
386 node.visit_mut_children_with(self)
387 }
388 }
389 };
390}
391
392macro_rules! typed_ref {
393 ($name:ident, $T:ty) => {
394 fn $name(&mut self, node: &mut $T) {
395 if self.config.handle_types {
396 let in_type = self.in_type;
397 let ident_type = self.ident_type;
398 self.in_type = true;
399 node.visit_mut_children_with(self);
400 self.ident_type = ident_type;
401 self.in_type = in_type;
402 }
403 }
404 };
405}
406
407macro_rules! typed_ref_init {
408 ($name:ident, $T:ty) => {
409 fn $name(&mut self, node: &mut $T) {
410 if self.config.handle_types {
411 let in_type = self.in_type;
412 let ident_type = self.ident_type;
413 self.ident_type = IdentType::Ref;
414 self.in_type = true;
415 node.visit_mut_children_with(self);
416 self.ident_type = ident_type;
417 self.in_type = in_type;
418 }
419 }
420 };
421}
422
423macro_rules! typed_decl {
424 ($name:ident, $T:ty) => {
425 fn $name(&mut self, node: &mut $T) {
426 if self.config.handle_types {
427 let in_type = self.in_type;
428 self.ident_type = IdentType::Binding;
429 self.in_type = true;
430 node.visit_mut_children_with(self);
431 self.in_type = in_type;
432 }
433 }
434 };
435}
436
437macro_rules! noop {
438 ($name:ident, $T:ty) => {
439 #[inline]
440 fn $name(&mut self, _: &mut $T) {}
441 };
442}
443
444impl VisitMut for Resolver<'_> {
445 noop!(visit_mut_accessibility, Accessibility);
446
447 noop!(visit_mut_true_plus_minus, TruePlusMinus);
448
449 noop!(visit_mut_ts_keyword_type, TsKeywordType);
450
451 noop!(visit_mut_ts_keyword_type_kind, TsKeywordTypeKind);
452
453 noop!(visit_mut_ts_type_operator_op, TsTypeOperatorOp);
454
455 noop!(visit_mut_ts_enum_member_id, TsEnumMemberId);
456
457 noop!(visit_mut_ts_external_module_ref, TsExternalModuleRef);
458
459 noop!(visit_mut_ts_module_name, TsModuleName);
460
461 noop!(visit_mut_ts_this_type, TsThisType);
462
463 typed_ref!(visit_mut_ts_array_type, TsArrayType);
464
465 typed_ref!(visit_mut_ts_conditional_type, TsConditionalType);
466
467 typed_ref_init!(
468 visit_mut_ts_type_param_instantiation,
469 TsTypeParamInstantiation
470 );
471
472 typed_ref!(visit_mut_ts_type_query, TsTypeQuery);
473
474 typed_ref!(visit_mut_ts_type_query_expr, TsTypeQueryExpr);
475
476 typed_ref!(visit_mut_ts_type_operator, TsTypeOperator);
477
478 typed_ref_init!(visit_mut_ts_type, TsType);
479
480 typed_ref_init!(visit_mut_ts_type_ann, TsTypeAnn);
481
482 typed!(
483 visit_mut_ts_union_or_intersection_type,
484 TsUnionOrIntersectionType
485 );
486
487 typed!(visit_mut_ts_fn_or_constructor_type, TsFnOrConstructorType);
488
489 typed_ref!(visit_mut_ts_union_type, TsUnionType);
490
491 typed_ref!(visit_mut_ts_infer_type, TsInferType);
492
493 typed_ref!(visit_mut_ts_tuple_type, TsTupleType);
494
495 typed_ref!(visit_mut_ts_intersection_type, TsIntersectionType);
496
497 typed_ref!(visit_mut_ts_type_ref, TsTypeRef);
498
499 typed_decl!(visit_mut_ts_type_param_decl, TsTypeParamDecl);
500
501 typed!(visit_mut_ts_fn_param, TsFnParam);
502
503 typed!(visit_mut_ts_indexed_access_type, TsIndexedAccessType);
504
505 typed!(visit_mut_ts_index_signature, TsIndexSignature);
506
507 typed!(visit_mut_ts_interface_body, TsInterfaceBody);
508
509 typed!(visit_mut_ts_parenthesized_type, TsParenthesizedType);
510
511 typed!(visit_mut_ts_type_lit, TsTypeLit);
512
513 typed!(visit_mut_ts_type_element, TsTypeElement);
514
515 typed!(visit_mut_ts_optional_type, TsOptionalType);
516
517 typed!(visit_mut_ts_rest_type, TsRestType);
518
519 typed!(visit_mut_ts_type_predicate, TsTypePredicate);
520
521 typed_ref!(visit_mut_ts_this_type_or_ident, TsThisTypeOrIdent);
522
523 visit_mut_obj_and_computed!();
524
525 typed!(visit_mut_ts_namespace_export_decl, TsNamespaceExportDecl);
527
528 fn visit_mut_arrow_expr(&mut self, e: &mut ArrowExpr) {
529 self.with_child(ScopeKind::Fn, |child| {
530 e.type_params.visit_mut_with(child);
531
532 let old = child.ident_type;
533 child.ident_type = IdentType::Binding;
534 {
535 let params = e
536 .params
537 .iter()
538 .filter(|p| !p.is_rest())
539 .flat_map(find_pat_ids::<_, Id>);
540
541 for id in params {
542 child.current.declared_symbols.insert(id.0, DeclKind::Param);
543 }
544 }
545 e.params.visit_mut_with(child);
546 child.ident_type = old;
547
548 match &mut *e.body {
549 BlockStmtOrExpr::BlockStmt(s) => {
550 child.mark_block(&mut s.ctxt);
551
552 let old_strict_mode = child.strict_mode;
553
554 if !child.strict_mode {
555 child.strict_mode = s
556 .stmts
557 .first()
558 .map(|stmt| stmt.is_use_strict())
559 .unwrap_or(false);
560 }
561 s.stmts.visit_mut_with(child);
563 child.strict_mode = old_strict_mode;
564 }
565 BlockStmtOrExpr::Expr(e) => e.visit_mut_with(child),
566 #[cfg(swc_ast_unknown)]
567 _ => (),
568 }
569
570 e.return_type.visit_mut_with(child);
571 });
572 }
573
574 fn visit_mut_assign_pat(&mut self, node: &mut AssignPat) {
575 node.left.visit_mut_with(self);
578 node.right.visit_mut_with(self);
579 }
580
581 fn visit_mut_binding_ident(&mut self, i: &mut BindingIdent) {
582 let ident_type = self.ident_type;
583 let in_type = self.in_type;
584
585 self.ident_type = IdentType::Ref;
586 i.type_ann.visit_mut_with(self);
587
588 self.ident_type = ident_type;
589 i.id.visit_mut_with(self);
590
591 self.in_type = in_type;
592 self.ident_type = ident_type;
593 }
594
595 fn visit_mut_block_stmt(&mut self, block: &mut BlockStmt) {
596 self.with_child(ScopeKind::Block, |child| {
597 child.mark_block(&mut block.ctxt);
598 block.visit_mut_children_with(child);
599 })
600 }
601
602 fn visit_mut_break_stmt(&mut self, s: &mut BreakStmt) {
603 let old = self.ident_type;
604 self.ident_type = IdentType::Label;
605 s.label.visit_mut_with(self);
606 self.ident_type = old;
607 }
608
609 fn visit_mut_catch_clause(&mut self, c: &mut CatchClause) {
610 self.with_child(ScopeKind::Fn, |child| {
613 child.ident_type = IdentType::Binding;
614 c.param.visit_mut_with(child);
615 child.ident_type = IdentType::Ref;
616
617 child.mark_block(&mut c.body.ctxt);
618 c.body.visit_mut_children_with(child);
619 });
620 }
621
622 fn visit_mut_class(&mut self, c: &mut Class) {
623 let old_strict_mode = self.strict_mode;
624 self.strict_mode = true;
625
626 let old = self.ident_type;
627 self.ident_type = IdentType::Ref;
628 c.decorators.visit_mut_with(self);
629
630 self.ident_type = IdentType::Ref;
631 c.super_class.visit_mut_with(self);
632
633 self.ident_type = IdentType::Binding;
634 c.type_params.visit_mut_with(self);
635
636 self.ident_type = IdentType::Ref;
637 c.super_type_params.visit_mut_with(self);
638
639 self.ident_type = IdentType::Ref;
640 c.implements.visit_mut_with(self);
641 self.ident_type = old;
642
643 c.body.visit_mut_with(self);
644 self.strict_mode = old_strict_mode;
645 }
646
647 fn visit_mut_class_decl(&mut self, n: &mut ClassDecl) {
648 if n.declare && !self.config.handle_types {
649 return;
650 }
651 self.modify(&mut n.ident, DeclKind::Lexical);
652
653 n.class.decorators.visit_mut_with(self);
654
655 self.with_child(ScopeKind::Fn, |child| {
658 child.ident_type = IdentType::Ref;
659
660 n.class.visit_mut_with(child);
661 });
662 }
663
664 fn visit_mut_class_expr(&mut self, n: &mut ClassExpr) {
665 n.class.super_class.visit_mut_with(self);
668
669 self.with_child(ScopeKind::Fn, |child| {
670 child.ident_type = IdentType::Binding;
671 n.ident.visit_mut_with(child);
672 child.ident_type = IdentType::Ref;
673
674 n.class.visit_mut_with(child);
675 });
676 }
677
678 fn visit_mut_class_method(&mut self, m: &mut ClassMethod) {
679 m.key.visit_mut_with(self);
680
681 for p in m.function.params.iter_mut() {
682 p.decorators.visit_mut_with(self);
683 }
684
685 self.with_child(ScopeKind::Fn, |child| m.function.visit_mut_with(child));
686 }
687
688 fn visit_mut_class_prop(&mut self, p: &mut ClassProp) {
689 p.decorators.visit_mut_with(self);
690
691 if let PropName::Computed(key) = &mut p.key {
692 let old = self.ident_type;
693 self.ident_type = IdentType::Binding;
694 key.expr.visit_mut_with(self);
695 self.ident_type = old;
696 }
697
698 let old = self.ident_type;
699 self.ident_type = IdentType::Ref;
700 p.value.visit_mut_with(self);
701 self.ident_type = old;
702
703 p.type_ann.visit_mut_with(self);
704 }
705
706 fn visit_mut_constructor(&mut self, c: &mut Constructor) {
707 for p in c.params.iter_mut() {
708 match p {
709 ParamOrTsParamProp::TsParamProp(p) => {
710 p.decorators.visit_mut_with(self);
711 }
712 ParamOrTsParamProp::Param(p) => {
713 p.decorators.visit_mut_with(self);
714 }
715 #[cfg(swc_ast_unknown)]
716 _ => (),
717 }
718 }
719
720 self.with_child(ScopeKind::Fn, |child| {
721 let old = child.ident_type;
722 child.ident_type = IdentType::Binding;
723 {
724 let params = c
725 .params
726 .iter()
727 .filter(|p| match p {
728 ParamOrTsParamProp::TsParamProp(_) => false,
729 ParamOrTsParamProp::Param(p) => !p.pat.is_rest(),
730 #[cfg(swc_ast_unknown)]
731 _ => false,
732 })
733 .flat_map(find_pat_ids::<_, Id>);
734
735 for id in params {
736 child.current.declared_symbols.insert(id.0, DeclKind::Param);
737 }
738 }
739 c.params.visit_mut_with(child);
740 child.ident_type = old;
741
742 if let Some(body) = &mut c.body {
743 child.mark_block(&mut body.ctxt);
744 body.visit_mut_children_with(child);
745 }
746 });
747 }
748
749 fn visit_mut_continue_stmt(&mut self, s: &mut ContinueStmt) {
750 let old = self.ident_type;
751 self.ident_type = IdentType::Label;
752 s.label.visit_mut_with(self);
753 self.ident_type = old;
754 }
755
756 fn visit_mut_export_default_decl(&mut self, e: &mut ExportDefaultDecl) {
757 match &mut e.decl {
760 DefaultDecl::Fn(f) => {
761 if f.ident.is_some() {
762 self.with_child(ScopeKind::Fn, |child| {
763 f.function.visit_mut_with(child);
764 });
765 } else {
766 f.visit_mut_with(self)
767 }
768 }
769 DefaultDecl::Class(c) => {
770 c.class.visit_mut_with(self)
772 }
773 _ => e.visit_mut_children_with(self),
774 }
775 }
776
777 fn visit_mut_export_default_expr(&mut self, node: &mut ExportDefaultExpr) {
778 node.expr.visit_mut_with(self);
779
780 if self.config.handle_types {
781 if let Expr::Ident(i) = &mut *node.expr {
782 self.try_resolving_as_type(i);
783 }
784 }
785 }
786
787 fn visit_mut_export_named_specifier(&mut self, e: &mut ExportNamedSpecifier) {
788 e.visit_mut_children_with(self);
789
790 if self.config.handle_types {
791 match &mut e.orig {
792 ModuleExportName::Ident(orig) => {
793 self.try_resolving_as_type(orig);
794 }
795 ModuleExportName::Str(_) => {}
796 #[cfg(swc_ast_unknown)]
797 _ => {}
798 }
799 }
800 }
801
802 fn visit_mut_export_specifier(&mut self, s: &mut ExportSpecifier) {
803 let old = self.ident_type;
804 self.ident_type = IdentType::Ref;
805 s.visit_mut_children_with(self);
806 self.ident_type = old;
807 }
808
809 fn visit_mut_expr(&mut self, expr: &mut Expr) {
810 let _span = if LOG {
811 Some(span!(Level::ERROR, "visit_mut_expr").entered())
812 } else {
813 None
814 };
815
816 let old = self.ident_type;
817 self.ident_type = IdentType::Ref;
818 maybe_grow_default(|| expr.visit_mut_children_with(self));
819 self.ident_type = old;
820 }
821
822 fn visit_mut_fn_decl(&mut self, node: &mut FnDecl) {
823 if node.declare && !self.config.handle_types {
824 return;
825 }
826
827 node.function.decorators.visit_mut_with(self);
829
830 self.with_child(ScopeKind::Fn, |child| node.function.visit_mut_with(child));
831 }
832
833 fn visit_mut_fn_expr(&mut self, e: &mut FnExpr) {
834 e.function.decorators.visit_mut_with(self);
835
836 if let Some(ident) = &mut e.ident {
837 self.with_child(ScopeKind::Fn, |child| {
838 child.modify(ident, DeclKind::Function);
839 child.with_child(ScopeKind::Fn, |child| {
840 e.function.visit_mut_with(child);
841 });
842 });
843 } else {
844 self.with_child(ScopeKind::Fn, |child| {
845 e.function.visit_mut_with(child);
846 });
847 }
848 }
849
850 fn visit_mut_for_in_stmt(&mut self, n: &mut ForInStmt) {
851 self.with_child(ScopeKind::Block, |child| {
852 n.left.visit_mut_with(child);
853 n.right.visit_mut_with(child);
854
855 child.visit_mut_stmt_within_child_scope(&mut n.body);
856 });
857 }
858
859 fn visit_mut_for_of_stmt(&mut self, n: &mut ForOfStmt) {
860 self.with_child(ScopeKind::Block, |child| {
861 n.left.visit_mut_with(child);
862 n.right.visit_mut_with(child);
863
864 child.visit_mut_stmt_within_child_scope(&mut n.body);
865 });
866 }
867
868 fn visit_mut_for_stmt(&mut self, n: &mut ForStmt) {
869 self.with_child(ScopeKind::Block, |child| {
870 child.ident_type = IdentType::Binding;
871 n.init.visit_mut_with(child);
872 child.ident_type = IdentType::Ref;
873 n.test.visit_mut_with(child);
874 child.ident_type = IdentType::Ref;
875 n.update.visit_mut_with(child);
876
877 child.visit_mut_stmt_within_child_scope(&mut n.body);
878 });
879 }
880
881 fn visit_mut_function(&mut self, f: &mut Function) {
882 self.mark_block(&mut f.ctxt);
883 f.type_params.visit_mut_with(self);
884
885 self.ident_type = IdentType::Ref;
886 f.decorators.visit_mut_with(self);
887
888 {
889 let params = f
890 .params
891 .iter()
892 .filter(|p| !p.pat.is_rest())
893 .flat_map(find_pat_ids::<_, Id>);
894
895 for id in params {
896 self.current.declared_symbols.insert(id.0, DeclKind::Param);
897 }
898 }
899 self.ident_type = IdentType::Binding;
900 f.params.visit_mut_with(self);
901
902 f.return_type.visit_mut_with(self);
903
904 self.ident_type = IdentType::Ref;
905 if let Some(body) = &mut f.body {
906 self.mark_block(&mut body.ctxt);
907 let old_strict_mode = self.strict_mode;
908 if !self.strict_mode {
909 self.strict_mode = body
910 .stmts
911 .first()
912 .map(|stmt| stmt.is_use_strict())
913 .unwrap_or(false);
914 }
915 body.visit_mut_children_with(self);
917 self.strict_mode = old_strict_mode;
918 }
919 }
920
921 fn visit_mut_getter_prop(&mut self, f: &mut GetterProp) {
922 let old = self.ident_type;
923 self.ident_type = IdentType::Ref;
924 f.key.visit_mut_with(self);
925 self.ident_type = old;
926
927 f.type_ann.visit_mut_with(self);
928
929 f.body.visit_mut_with(self);
930 }
931
932 fn visit_mut_jsx_element_name(&mut self, node: &mut JSXElementName) {
933 if let JSXElementName::Ident(i) = node {
934 if i.as_ref().starts_with(|c: char| c.is_ascii_lowercase()) {
935 if cfg!(debug_assertions) && LOG {
936 debug!("\t -> JSXElementName");
937 }
938
939 let ctxt = i.ctxt.apply_mark(self.config.unresolved_mark);
940
941 if cfg!(debug_assertions) && LOG {
942 debug!("\t -> {:?}", ctxt);
943 }
944
945 i.ctxt = ctxt;
946
947 return;
948 }
949 }
950
951 node.visit_mut_children_with(self);
952 }
953
954 fn visit_mut_ident(&mut self, i: &mut Ident) {
955 if i.ctxt != SyntaxContext::empty() {
956 return;
957 }
958
959 match self.ident_type {
960 IdentType::Binding => self.modify(i, self.decl_kind),
961 IdentType::Ref => {
962 let Ident { sym, ctxt, .. } = i;
963
964 if cfg!(debug_assertions) && LOG {
965 debug!("IdentRef (type = {}) {}{:?}", self.in_type, sym, ctxt);
966 }
967
968 if *ctxt != SyntaxContext::empty() {
969 return;
970 }
971
972 if let Some(mark) = self.mark_for_ref(sym) {
973 let ctxt = ctxt.apply_mark(mark);
974
975 if cfg!(debug_assertions) && LOG {
976 debug!("\t -> {:?}", ctxt);
977 }
978 i.ctxt = ctxt;
979 } else {
980 if cfg!(debug_assertions) && LOG {
981 debug!("\t -> Unresolved");
982 }
983
984 let ctxt = ctxt.apply_mark(self.config.unresolved_mark);
985
986 if cfg!(debug_assertions) && LOG {
987 debug!("\t -> {:?}", ctxt);
988 }
989
990 i.ctxt = ctxt;
991 self.modify(i, self.decl_kind)
993 }
994 }
995 IdentType::Label => {}
997 }
998 }
999
1000 fn visit_mut_import_decl(&mut self, n: &mut ImportDecl) {
1001 self.ident_type = IdentType::Binding;
1004 let old_in_type = self.in_type;
1005 self.in_type = n.type_only;
1006 n.visit_mut_children_with(self);
1007 self.in_type = old_in_type;
1008 }
1009
1010 fn visit_mut_import_named_specifier(&mut self, s: &mut ImportNamedSpecifier) {
1011 let old = self.ident_type;
1012 self.ident_type = IdentType::Binding;
1013 s.local.visit_mut_with(self);
1014 if self.config.handle_types {
1015 self.current.declared_types.insert(s.local.sym.clone());
1016 }
1017 self.ident_type = old;
1018 }
1019
1020 fn visit_mut_import_specifier(&mut self, s: &mut ImportSpecifier) {
1021 let old = self.ident_type;
1022 self.ident_type = IdentType::Binding;
1023
1024 match s {
1025 ImportSpecifier::Named(ImportNamedSpecifier { imported: None, .. })
1026 | ImportSpecifier::Namespace(..)
1027 | ImportSpecifier::Default(..) => s.visit_mut_children_with(self),
1028 ImportSpecifier::Named(s) => s.local.visit_mut_with(self),
1029 #[cfg(swc_ast_unknown)]
1030 _ => (),
1031 }
1032
1033 self.ident_type = old;
1034 }
1035
1036 fn visit_mut_jsx_attr_name(&mut self, _: &mut JSXAttrName) {}
1040
1041 fn visit_mut_key_value_pat_prop(&mut self, n: &mut KeyValuePatProp) {
1042 n.key.visit_mut_with(self);
1043 n.value.visit_mut_with(self);
1044 }
1045
1046 fn visit_mut_labeled_stmt(&mut self, s: &mut LabeledStmt) {
1047 let old = self.ident_type;
1048 self.ident_type = IdentType::Label;
1049 s.label.visit_mut_with(self);
1050 self.ident_type = old;
1051
1052 s.body.visit_mut_with(self);
1053 }
1054
1055 fn visit_mut_method_prop(&mut self, m: &mut MethodProp) {
1056 m.key.visit_mut_with(self);
1057
1058 self.with_child(ScopeKind::Fn, |child| m.function.visit_mut_with(child));
1060 }
1061
1062 fn visit_mut_module(&mut self, module: &mut Module) {
1063 self.strict_mode = true;
1064 self.is_module = true;
1065 module.visit_mut_children_with(self)
1066 }
1067
1068 fn visit_mut_module_items(&mut self, stmts: &mut Vec<ModuleItem>) {
1069 if !self.in_ts_module && self.current.kind != ScopeKind::Fn {
1070 return stmts.visit_mut_children_with(self);
1071 }
1072
1073 {
1075 let mut hoister = Hoister {
1076 kind: self.decl_kind,
1077 resolver: self,
1078 in_block: false,
1079 in_catch_body: false,
1080 catch_param_decls: Default::default(),
1081 excluded_from_catch: Default::default(),
1082 };
1083 stmts.visit_mut_with(&mut hoister)
1084 }
1085
1086 stmts.visit_mut_children_with(self)
1088 }
1089
1090 fn visit_mut_named_export(&mut self, e: &mut NamedExport) {
1091 if e.src.is_some() {
1092 return;
1093 }
1094
1095 e.visit_mut_children_with(self);
1096 }
1097
1098 fn visit_mut_object_lit(&mut self, o: &mut ObjectLit) {
1099 self.with_child(ScopeKind::Block, |child| {
1100 o.visit_mut_children_with(child);
1101 });
1102 }
1103
1104 fn visit_mut_param(&mut self, param: &mut Param) {
1105 self.ident_type = IdentType::Binding;
1106 param.visit_mut_children_with(self);
1107 }
1108
1109 fn visit_mut_pat(&mut self, p: &mut Pat) {
1110 p.visit_mut_children_with(self);
1111 }
1112
1113 fn visit_mut_private_method(&mut self, m: &mut PrivateMethod) {
1114 m.key.visit_mut_with(self);
1115
1116 {
1117 self.with_child(ScopeKind::Fn, |child| m.function.visit_mut_with(child));
1120 }
1121 }
1122
1123 fn visit_mut_private_name(&mut self, _: &mut PrivateName) {}
1124
1125 fn visit_mut_prop_name(&mut self, n: &mut PropName) {
1126 if let PropName::Computed(c) = n {
1127 c.visit_mut_with(self);
1128 }
1129 }
1130
1131 fn visit_mut_rest_pat(&mut self, node: &mut RestPat) {
1132 node.arg.visit_mut_with(self);
1133 node.type_ann.visit_mut_with(self);
1134 }
1135
1136 fn visit_mut_script(&mut self, script: &mut Script) {
1137 self.strict_mode = script
1138 .body
1139 .first()
1140 .map(|stmt| stmt.is_use_strict())
1141 .unwrap_or(false);
1142 script.visit_mut_children_with(self)
1143 }
1144
1145 fn visit_mut_setter_prop(&mut self, n: &mut SetterProp) {
1146 n.key.visit_mut_with(self);
1147
1148 {
1149 self.with_child(ScopeKind::Fn, |child| {
1150 child.ident_type = IdentType::Binding;
1151 n.this_param.visit_mut_with(child);
1152 n.param.visit_mut_with(child);
1153 n.body.visit_mut_with(child);
1154 });
1155 };
1156 }
1157
1158 fn visit_mut_stmts(&mut self, stmts: &mut Vec<Stmt>) {
1159 let _span = if LOG {
1160 Some(span!(Level::ERROR, "visit_mut_stmts").entered())
1161 } else {
1162 None
1163 };
1164
1165 {
1167 let _span = if LOG {
1168 Some(span!(Level::ERROR, "hoist").entered())
1169 } else {
1170 None
1171 };
1172
1173 let mut hoister = Hoister {
1174 kind: self.decl_kind,
1175 resolver: self,
1176 in_block: false,
1177 in_catch_body: false,
1178 catch_param_decls: Default::default(),
1179 excluded_from_catch: Default::default(),
1180 };
1181 stmts.visit_mut_with(&mut hoister)
1182 }
1183
1184 stmts.visit_mut_children_with(self)
1186 }
1187
1188 fn visit_mut_switch_case(&mut self, n: &mut SwitchCase) {
1189 n.cons.visit_mut_with(self);
1190
1191 n.test.visit_mut_with(self);
1192 }
1193
1194 fn visit_mut_switch_stmt(&mut self, s: &mut SwitchStmt) {
1195 s.discriminant.visit_mut_with(self);
1196
1197 self.with_child(ScopeKind::Block, |child| {
1198 s.cases.visit_mut_with(child);
1199 });
1200 }
1201
1202 fn visit_mut_ts_as_expr(&mut self, n: &mut TsAsExpr) {
1203 if self.config.handle_types {
1204 n.type_ann.visit_mut_with(self);
1205 }
1206
1207 n.expr.visit_mut_with(self);
1208 }
1209
1210 fn visit_mut_ts_call_signature_decl(&mut self, n: &mut TsCallSignatureDecl) {
1211 if !self.config.handle_types {
1212 return;
1213 }
1214
1215 self.with_child(ScopeKind::Fn, |child| {
1216 child.in_type = true;
1217
1218 n.type_params.visit_mut_with(child);
1219 n.params.visit_mut_with(child);
1220 n.type_ann.visit_mut_with(child);
1221 });
1222 }
1223
1224 fn visit_mut_ts_construct_signature_decl(&mut self, decl: &mut TsConstructSignatureDecl) {
1225 if !self.config.handle_types {
1226 return;
1227 }
1228
1229 self.with_child(ScopeKind::Fn, |child| {
1231 child.in_type = true;
1232
1233 decl.type_params.visit_mut_with(child);
1235 decl.params.visit_mut_with(child);
1236 decl.type_ann.visit_mut_with(child);
1237 });
1238 }
1239
1240 fn visit_mut_ts_constructor_type(&mut self, ty: &mut TsConstructorType) {
1241 if !self.config.handle_types {
1242 return;
1243 }
1244
1245 self.with_child(ScopeKind::Fn, |child| {
1246 child.in_type = true;
1247
1248 ty.type_params.visit_mut_with(child);
1249 ty.params.visit_mut_with(child);
1250 ty.type_ann.visit_mut_with(child);
1251 });
1252 }
1253
1254 fn visit_mut_ts_enum_decl(&mut self, decl: &mut TsEnumDecl) {
1255 if decl.declare && !self.config.handle_types {
1256 return;
1257 }
1258 self.modify(&mut decl.id, DeclKind::Lexical);
1259
1260 self.with_child(ScopeKind::Block, |child| {
1261 let member_names = decl.members.iter().filter_map(|m| match &m.id {
1264 TsEnumMemberId::Ident(id) => Some((id.sym.clone(), DeclKind::Lexical)),
1265 TsEnumMemberId::Str(_) => None,
1266 #[cfg(swc_ast_unknown)]
1267 _ => None,
1268 });
1269 child.current.declared_symbols.extend(member_names);
1270
1271 decl.members.visit_mut_with(child);
1272 });
1273 }
1274
1275 fn visit_mut_ts_export_assignment(&mut self, node: &mut TsExportAssignment) {
1276 node.expr.visit_mut_with(self);
1277
1278 if self.config.handle_types {
1279 if let Some(i) = leftmost(&mut node.expr) {
1280 self.try_resolving_as_type(i);
1281 }
1282 }
1283 }
1284
1285 fn visit_mut_ts_expr_with_type_args(&mut self, n: &mut TsExprWithTypeArgs) {
1286 if self.config.handle_types {
1287 let old = self.in_type;
1288 self.in_type = true;
1289 n.visit_mut_children_with(self);
1290 self.in_type = old;
1291 }
1292 }
1293
1294 fn visit_mut_ts_fn_type(&mut self, ty: &mut TsFnType) {
1295 if !self.config.handle_types {
1296 return;
1297 }
1298
1299 self.with_child(ScopeKind::Fn, |child| {
1300 child.in_type = true;
1301
1302 ty.type_params.visit_mut_with(child);
1303 ty.params.visit_mut_with(child);
1304 ty.type_ann.visit_mut_with(child);
1305 });
1306 }
1307
1308 fn visit_mut_ts_getter_signature(&mut self, n: &mut TsGetterSignature) {
1309 if n.computed {
1310 n.key.visit_mut_with(self);
1311 }
1312
1313 n.type_ann.visit_mut_with(self);
1314 }
1315
1316 fn visit_mut_ts_import_equals_decl(&mut self, n: &mut TsImportEqualsDecl) {
1317 self.modify(&mut n.id, DeclKind::Lexical);
1318
1319 n.module_ref.visit_mut_with(self);
1320 }
1321
1322 fn visit_mut_ts_import_type(&mut self, n: &mut TsImportType) {
1323 if !self.config.handle_types {
1324 return;
1325 }
1326
1327 n.type_args.visit_mut_with(self);
1328 }
1329
1330 fn visit_mut_ts_interface_decl(&mut self, n: &mut TsInterfaceDecl) {
1331 let old_in_type = self.in_type;
1333 let old_ident_type = self.ident_type;
1334
1335 self.in_type = true;
1336 self.ident_type = IdentType::Ref;
1337
1338 self.modify(&mut n.id, DeclKind::Type);
1339
1340 if !self.config.handle_types {
1341 self.in_type = old_in_type;
1342 self.ident_type = old_ident_type;
1343 return;
1344 }
1345
1346 self.with_child(ScopeKind::Fn, |child| {
1347 child.in_type = true;
1348
1349 n.type_params.visit_mut_with(child);
1350 n.extends.visit_mut_with(child);
1351 n.body.visit_mut_with(child);
1352 });
1353
1354 self.in_type = old_in_type;
1355 self.ident_type = old_ident_type;
1356 }
1357
1358 fn visit_mut_ts_mapped_type(&mut self, n: &mut TsMappedType) {
1359 if !self.config.handle_types {
1360 return;
1361 }
1362
1363 self.ident_type = IdentType::Binding;
1364 n.type_param.visit_mut_with(self);
1365 self.ident_type = IdentType::Ref;
1366 n.name_type.visit_mut_with(self);
1367
1368 self.ident_type = IdentType::Ref;
1369 n.type_ann.visit_mut_with(self);
1370 }
1371
1372 fn visit_mut_ts_method_signature(&mut self, n: &mut TsMethodSignature) {
1373 if !self.config.handle_types {
1374 return;
1375 }
1376
1377 self.with_child(ScopeKind::Fn, |child| {
1378 child.in_type = true;
1379
1380 n.type_params.visit_mut_with(child);
1381 if n.computed {
1382 n.key.visit_mut_with(child);
1383 }
1384 n.params.visit_mut_with(child);
1385 n.type_ann.visit_mut_with(child);
1386 });
1387 }
1388
1389 fn visit_mut_ts_module_decl(&mut self, decl: &mut TsModuleDecl) {
1390 if decl.declare && !self.config.handle_types {
1391 return;
1392 }
1393
1394 match &mut decl.id {
1395 TsModuleName::Ident(i) => {
1396 self.modify(i, DeclKind::Lexical);
1397 }
1398 TsModuleName::Str(_) => {}
1399 #[cfg(swc_ast_unknown)]
1400 _ => {}
1401 }
1402
1403 self.with_child(ScopeKind::Block, |child| {
1404 child.in_ts_module = true;
1405
1406 decl.body.visit_mut_children_with(child);
1407 });
1408 }
1409
1410 fn visit_mut_ts_namespace_decl(&mut self, n: &mut TsNamespaceDecl) {
1411 if n.declare && !self.config.handle_types {
1412 return;
1413 }
1414
1415 self.modify(&mut n.id, DeclKind::Lexical);
1416
1417 n.body.visit_mut_with(self);
1418 }
1419
1420 fn visit_mut_ts_param_prop_param(&mut self, n: &mut TsParamPropParam) {
1421 self.ident_type = IdentType::Binding;
1422 n.visit_mut_children_with(self)
1423 }
1424
1425 fn visit_mut_ts_property_signature(&mut self, n: &mut TsPropertySignature) {
1426 if !self.config.handle_types {
1427 return;
1428 }
1429
1430 if n.computed {
1431 n.key.visit_mut_with(self);
1432 }
1433
1434 self.with_child(ScopeKind::Fn, |child| {
1435 child.in_type = true;
1436
1437 n.type_ann.visit_mut_with(child);
1438 });
1439 }
1440
1441 fn visit_mut_ts_qualified_name(&mut self, n: &mut TsQualifiedName) {
1442 self.ident_type = IdentType::Ref;
1443
1444 n.left.visit_mut_with(self)
1445 }
1446
1447 fn visit_mut_ts_satisfies_expr(&mut self, n: &mut TsSatisfiesExpr) {
1448 if self.config.handle_types {
1449 n.type_ann.visit_mut_with(self);
1450 }
1451
1452 n.expr.visit_mut_with(self);
1453 }
1454
1455 fn visit_mut_ts_setter_signature(&mut self, n: &mut TsSetterSignature) {
1456 if n.computed {
1457 n.key.visit_mut_with(self);
1458 }
1459
1460 n.param.visit_mut_with(self);
1461 }
1462
1463 fn visit_mut_ts_tuple_element(&mut self, e: &mut TsTupleElement) {
1464 if !self.config.handle_types {
1465 return;
1466 }
1467 self.ident_type = IdentType::Ref;
1468 e.ty.visit_mut_with(self);
1469 }
1470
1471 fn visit_mut_ts_type_alias_decl(&mut self, n: &mut TsTypeAliasDecl) {
1472 let old_in_type = self.in_type;
1474 self.in_type = true;
1475 self.modify(&mut n.id, DeclKind::Type);
1476
1477 if !self.config.handle_types {
1478 self.in_type = old_in_type;
1479 return;
1480 }
1481
1482 self.with_child(ScopeKind::Fn, |child| {
1483 child.in_type = true;
1484
1485 n.type_params.visit_mut_with(child);
1486 n.type_ann.visit_mut_with(child);
1487 });
1488 self.in_type = old_in_type;
1489 }
1490
1491 fn visit_mut_ts_type_assertion(&mut self, n: &mut TsTypeAssertion) {
1492 if self.config.handle_types {
1493 n.type_ann.visit_mut_with(self);
1494 }
1495
1496 n.expr.visit_mut_with(self);
1497 }
1498
1499 fn visit_mut_ts_type_param(&mut self, param: &mut TsTypeParam) {
1500 if !self.config.handle_types {
1501 return;
1502 }
1503 param.name.visit_mut_with(self);
1504
1505 let ident_type = self.ident_type;
1506 param.default.visit_mut_with(self);
1507 param.constraint.visit_mut_with(self);
1508 self.ident_type = ident_type;
1509 }
1510
1511 fn visit_mut_ts_type_params(&mut self, params: &mut Vec<TsTypeParam>) {
1512 for param in params.iter_mut() {
1513 param.name.visit_mut_with(self);
1514 }
1515
1516 params.visit_mut_children_with(self);
1517 }
1518
1519 fn visit_mut_using_decl(&mut self, decl: &mut UsingDecl) {
1520 let old_kind = self.decl_kind;
1521 self.decl_kind = DeclKind::Lexical;
1522 decl.decls.visit_mut_with(self);
1523 self.decl_kind = old_kind;
1524 }
1525
1526 fn visit_mut_var_decl(&mut self, decl: &mut VarDecl) {
1527 if decl.declare && !self.config.handle_types {
1528 return;
1529 }
1530
1531 let old_kind = self.decl_kind;
1532 self.decl_kind = decl.kind.into();
1533 decl.decls.visit_mut_with(self);
1534 self.decl_kind = old_kind;
1535 }
1536
1537 fn visit_mut_var_declarator(&mut self, decl: &mut VarDeclarator) {
1538 let old_type = self.ident_type;
1541 self.ident_type = IdentType::Binding;
1542 decl.name.visit_mut_with(self);
1543 self.ident_type = old_type;
1544
1545 decl.init.visit_mut_children_with(self);
1546 }
1547}
1548
1549fn leftmost(expr: &mut Expr) -> Option<&mut Ident> {
1550 match expr {
1551 Expr::Ident(i) => Some(i),
1552 Expr::Member(MemberExpr { obj, .. }) => leftmost(obj),
1553 Expr::Paren(ParenExpr { expr, .. }) => leftmost(expr),
1554 _ => None,
1555 }
1556}
1557
1558struct Hoister<'a, 'b> {
1560 resolver: &'a mut Resolver<'b>,
1561 kind: DeclKind,
1562 in_block: bool,
1564
1565 in_catch_body: bool,
1566
1567 excluded_from_catch: FxHashSet<Atom>,
1568 catch_param_decls: FxHashSet<Atom>,
1569}
1570
1571impl Hoister<'_, '_> {
1572 fn add_pat_id(&mut self, id: &mut BindingIdent) {
1573 if self.in_catch_body {
1574 if self.resolver.mark_for_ref_inner(&id.sym, true).is_some()
1576 && self.catch_param_decls.contains(&id.sym)
1577 {
1578 return;
1579 }
1580
1581 self.excluded_from_catch.insert(id.sym.clone());
1582 } else {
1583 if self.catch_param_decls.contains(&id.sym)
1585 && !self.excluded_from_catch.contains(&id.sym)
1586 {
1587 return;
1588 }
1589 }
1590
1591 self.resolver.modify(id, self.kind)
1592 }
1593}
1594
1595impl VisitMut for Hoister<'_, '_> {
1596 noop_visit_mut_type!();
1597
1598 #[inline]
1599 fn visit_mut_arrow_expr(&mut self, _: &mut ArrowExpr) {}
1600
1601 fn visit_mut_assign_pat_prop(&mut self, node: &mut AssignPatProp) {
1602 node.visit_mut_children_with(self);
1603
1604 self.add_pat_id(&mut node.key);
1605 }
1606
1607 fn visit_mut_block_stmt(&mut self, n: &mut BlockStmt) {
1608 let old_in_block = self.in_block;
1609 self.in_block = true;
1610 n.visit_mut_children_with(self);
1611 self.in_block = old_in_block;
1612 }
1613
1614 #[inline]
1648 fn visit_mut_catch_clause(&mut self, c: &mut CatchClause) {
1649 let old_exclude = self.excluded_from_catch.clone();
1650 self.excluded_from_catch = Default::default();
1651
1652 let old_in_catch_body = self.in_catch_body;
1653
1654 let params: Vec<Id> = find_pat_ids(&c.param);
1655
1656 let orig = self.catch_param_decls.clone();
1657
1658 self.catch_param_decls
1659 .extend(params.into_iter().map(|v| v.0));
1660
1661 self.in_catch_body = true;
1662 c.body.visit_mut_with(self);
1663
1664 self.in_catch_body = false;
1674 c.param.visit_mut_with(self);
1675
1676 self.catch_param_decls = orig;
1677
1678 self.in_catch_body = old_in_catch_body;
1679 self.excluded_from_catch = old_exclude;
1680 }
1681
1682 fn visit_mut_class_decl(&mut self, node: &mut ClassDecl) {
1683 if node.declare && !self.resolver.config.handle_types {
1684 return;
1685 }
1686 if self.in_block {
1687 return;
1688 }
1689 self.resolver.modify(&mut node.ident, DeclKind::Lexical);
1690
1691 if self.resolver.config.handle_types {
1692 self.resolver
1693 .current
1694 .declared_types
1695 .insert(node.ident.sym.clone());
1696 }
1697 }
1698
1699 #[inline]
1700 fn visit_mut_constructor(&mut self, _: &mut Constructor) {}
1701
1702 #[inline]
1703 fn visit_mut_decl(&mut self, decl: &mut Decl) {
1704 decl.visit_mut_children_with(self);
1705
1706 if self.resolver.config.handle_types {
1707 match decl {
1708 Decl::TsInterface(i) => {
1709 if self.in_block {
1710 return;
1711 }
1712
1713 let old_in_type = self.resolver.in_type;
1714 self.resolver.in_type = true;
1715 self.resolver.modify(&mut i.id, DeclKind::Type);
1716 self.resolver.in_type = old_in_type;
1717 }
1718
1719 Decl::TsTypeAlias(a) => {
1720 let old_in_type = self.resolver.in_type;
1721 self.resolver.in_type = true;
1722 self.resolver.modify(&mut a.id, DeclKind::Type);
1723 self.resolver.in_type = old_in_type;
1724 }
1725
1726 Decl::TsEnum(e) => {
1727 if !self.in_block {
1728 let old_in_type = self.resolver.in_type;
1729 self.resolver.in_type = false;
1730 self.resolver.modify(&mut e.id, DeclKind::Lexical);
1731 self.resolver.in_type = old_in_type;
1732 }
1733 }
1734
1735 Decl::TsModule(v)
1736 if matches!(
1737 &**v,
1738 TsModuleDecl {
1739 global: false,
1740 id: TsModuleName::Ident(_),
1741 ..
1742 },
1743 ) =>
1744 {
1745 if !self.in_block {
1746 let old_in_type = self.resolver.in_type;
1747 self.resolver.in_type = false;
1748 let id = v.id.as_mut_ident().unwrap();
1749 self.resolver.modify(id, DeclKind::Lexical);
1750 self.resolver.in_type = old_in_type;
1751 }
1752 }
1753 _ => {}
1754 }
1755 }
1756 }
1757
1758 fn visit_mut_export_default_decl(&mut self, node: &mut ExportDefaultDecl) {
1759 match &mut node.decl {
1762 DefaultDecl::Fn(f) => {
1763 if let Some(id) = &mut f.ident {
1764 self.resolver.modify(id, DeclKind::Var);
1765 }
1766
1767 f.visit_mut_with(self)
1768 }
1769 DefaultDecl::Class(c) => {
1770 if let Some(id) = &mut c.ident {
1771 self.resolver.modify(id, DeclKind::Lexical);
1772 }
1773
1774 c.visit_mut_with(self)
1775 }
1776 _ => {
1777 node.visit_mut_children_with(self);
1778 }
1779 }
1780 }
1781
1782 #[inline]
1783 fn visit_mut_expr(&mut self, _: &mut Expr) {}
1784
1785 fn visit_mut_fn_decl(&mut self, node: &mut FnDecl) {
1786 if node.declare && !self.resolver.config.handle_types {
1787 return;
1788 }
1789
1790 if self.catch_param_decls.contains(&node.ident.sym) {
1791 return;
1792 }
1793
1794 if self.in_block {
1795 if self.resolver.strict_mode {
1797 return;
1798 }
1799 if let Some(DeclKind::Lexical | DeclKind::Param) =
1802 self.resolver.current.is_declared(&node.ident.sym)
1803 {
1804 return;
1805 }
1806 }
1807
1808 self.resolver.modify(&mut node.ident, DeclKind::Function);
1809 }
1810
1811 #[inline]
1812 fn visit_mut_function(&mut self, _: &mut Function) {}
1813
1814 fn visit_mut_import_default_specifier(&mut self, n: &mut ImportDefaultSpecifier) {
1815 n.visit_mut_children_with(self);
1816
1817 self.resolver.modify(&mut n.local, DeclKind::Lexical);
1818
1819 if self.resolver.config.handle_types {
1820 self.resolver
1821 .current
1822 .declared_types
1823 .insert(n.local.sym.clone());
1824 }
1825 }
1826
1827 fn visit_mut_import_named_specifier(&mut self, n: &mut ImportNamedSpecifier) {
1828 n.visit_mut_children_with(self);
1829
1830 self.resolver.modify(&mut n.local, DeclKind::Lexical);
1831
1832 if self.resolver.config.handle_types {
1833 self.resolver
1834 .current
1835 .declared_types
1836 .insert(n.local.sym.clone());
1837 }
1838 }
1839
1840 fn visit_mut_import_star_as_specifier(&mut self, n: &mut ImportStarAsSpecifier) {
1841 n.visit_mut_children_with(self);
1842
1843 self.resolver.modify(&mut n.local, DeclKind::Lexical);
1844
1845 if self.resolver.config.handle_types {
1846 self.resolver
1847 .current
1848 .declared_types
1849 .insert(n.local.sym.clone());
1850 }
1851 }
1852
1853 #[inline]
1854 fn visit_mut_param(&mut self, _: &mut Param) {}
1855
1856 fn visit_mut_pat(&mut self, node: &mut Pat) {
1857 match node {
1858 Pat::Ident(i) => {
1859 self.add_pat_id(i);
1860 }
1861
1862 _ => node.visit_mut_children_with(self),
1863 }
1864 }
1865
1866 #[inline]
1867 fn visit_mut_assign_target(&mut self, _: &mut AssignTarget) {}
1868
1869 #[inline]
1870 fn visit_mut_setter_prop(&mut self, _: &mut SetterProp) {}
1871
1872 fn visit_mut_switch_stmt(&mut self, s: &mut SwitchStmt) {
1873 s.discriminant.visit_mut_with(self);
1874
1875 let old_in_block = self.in_block;
1876 self.in_block = true;
1877 s.cases.visit_mut_with(self);
1878 self.in_block = old_in_block;
1879 }
1880
1881 #[inline]
1882 fn visit_mut_tagged_tpl(&mut self, _: &mut TaggedTpl) {}
1883
1884 #[inline]
1885 fn visit_mut_tpl(&mut self, _: &mut Tpl) {}
1886
1887 #[inline]
1888 fn visit_mut_ts_module_block(&mut self, _: &mut TsModuleBlock) {}
1889
1890 #[inline]
1891 fn visit_mut_using_decl(&mut self, node: &mut UsingDecl) {
1892 if self.in_block {
1893 return;
1894 }
1895
1896 let old_kind = self.kind;
1897 self.kind = DeclKind::Lexical;
1898 node.visit_mut_children_with(self);
1899 self.kind = old_kind;
1900 }
1901
1902 fn visit_mut_var_decl(&mut self, node: &mut VarDecl) {
1903 if node.declare && !self.resolver.config.handle_types {
1904 return;
1905 }
1906
1907 if self.in_block {
1908 match node.kind {
1909 VarDeclKind::Const | VarDeclKind::Let => return,
1910 _ => {}
1911 }
1912 }
1913
1914 let old_kind = self.kind;
1915 self.kind = node.kind.into();
1916
1917 node.visit_mut_children_with(self);
1918
1919 self.kind = old_kind;
1920 }
1921
1922 fn visit_mut_var_decl_or_expr(&mut self, n: &mut VarDeclOrExpr) {
1923 match n {
1924 VarDeclOrExpr::VarDecl(v)
1925 if matches!(
1926 &**v,
1927 VarDecl {
1928 kind: VarDeclKind::Let | VarDeclKind::Const,
1929 ..
1930 }
1931 ) => {}
1932 _ => {
1933 n.visit_mut_children_with(self);
1934 }
1935 }
1936 }
1937
1938 fn visit_mut_for_head(&mut self, n: &mut ForHead) {
1939 match n {
1940 ForHead::VarDecl(v)
1941 if matches!(
1942 &**v,
1943 VarDecl {
1944 kind: VarDeclKind::Let | VarDeclKind::Const,
1945 ..
1946 }
1947 ) => {}
1948 ForHead::Pat(..) => {}
1958 _ => {
1959 n.visit_mut_children_with(self);
1960 }
1961 }
1962 }
1963
1964 #[inline]
1965 fn visit_mut_var_declarator(&mut self, node: &mut VarDeclarator) {
1966 node.name.visit_mut_with(self);
1967 }
1968
1969 fn visit_mut_module_items(&mut self, items: &mut Vec<ModuleItem>) {
1983 items.iter_mut().for_each(|item| match item {
1984 ModuleItem::Stmt(Stmt::Decl(Decl::Var(v)))
1985 | ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
1986 decl: Decl::Var(v),
1987 ..
1988 })) if matches!(
1989 &**v,
1990 VarDecl {
1991 kind: VarDeclKind::Var,
1992 ..
1993 }
1994 ) =>
1995 {
1996 item.visit_mut_with(self);
1997 }
1998
1999 ModuleItem::Stmt(Stmt::Decl(Decl::Fn(..)))
2000 | ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
2001 decl: Decl::Fn(..),
2002 ..
2003 })) => {
2004 item.visit_mut_with(self);
2005 }
2006 _ => item.visit_mut_with(self),
2007 });
2008 }
2009
2010 fn visit_mut_stmts(&mut self, stmts: &mut Vec<Stmt>) {
2012 let others = stmts
2013 .iter_mut()
2014 .filter_map(|item| match item {
2015 Stmt::Decl(Decl::Var(..)) => {
2016 item.visit_mut_with(self);
2017 None
2018 }
2019 Stmt::Decl(Decl::Fn(..)) => {
2020 item.visit_mut_with(self);
2021 None
2022 }
2023 _ => Some(item),
2024 })
2025 .collect::<Vec<_>>();
2026
2027 for other_stmt in others {
2028 other_stmt.visit_mut_with(self);
2029 }
2030 }
2031}