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 }
567
568 e.return_type.visit_mut_with(child);
569 });
570 }
571
572 fn visit_mut_assign_pat(&mut self, node: &mut AssignPat) {
573 node.left.visit_mut_with(self);
576 node.right.visit_mut_with(self);
577 }
578
579 fn visit_mut_binding_ident(&mut self, i: &mut BindingIdent) {
580 let ident_type = self.ident_type;
581 let in_type = self.in_type;
582
583 self.ident_type = IdentType::Ref;
584 i.type_ann.visit_mut_with(self);
585
586 self.ident_type = ident_type;
587 i.id.visit_mut_with(self);
588
589 self.in_type = in_type;
590 self.ident_type = ident_type;
591 }
592
593 fn visit_mut_block_stmt(&mut self, block: &mut BlockStmt) {
594 self.with_child(ScopeKind::Block, |child| {
595 child.mark_block(&mut block.ctxt);
596 block.visit_mut_children_with(child);
597 })
598 }
599
600 fn visit_mut_break_stmt(&mut self, s: &mut BreakStmt) {
601 let old = self.ident_type;
602 self.ident_type = IdentType::Label;
603 s.label.visit_mut_with(self);
604 self.ident_type = old;
605 }
606
607 fn visit_mut_catch_clause(&mut self, c: &mut CatchClause) {
608 self.with_child(ScopeKind::Fn, |child| {
611 child.ident_type = IdentType::Binding;
612 c.param.visit_mut_with(child);
613 child.ident_type = IdentType::Ref;
614
615 child.mark_block(&mut c.body.ctxt);
616 c.body.visit_mut_children_with(child);
617 });
618 }
619
620 fn visit_mut_class(&mut self, c: &mut Class) {
621 let old_strict_mode = self.strict_mode;
622 self.strict_mode = true;
623
624 let old = self.ident_type;
625 self.ident_type = IdentType::Ref;
626 c.decorators.visit_mut_with(self);
627
628 self.ident_type = IdentType::Ref;
629 c.super_class.visit_mut_with(self);
630
631 self.ident_type = IdentType::Binding;
632 c.type_params.visit_mut_with(self);
633
634 self.ident_type = IdentType::Ref;
635 c.super_type_params.visit_mut_with(self);
636
637 self.ident_type = IdentType::Ref;
638 c.implements.visit_mut_with(self);
639 self.ident_type = old;
640
641 c.body.visit_mut_with(self);
642 self.strict_mode = old_strict_mode;
643 }
644
645 fn visit_mut_class_decl(&mut self, n: &mut ClassDecl) {
646 if n.declare && !self.config.handle_types {
647 return;
648 }
649 self.modify(&mut n.ident, DeclKind::Lexical);
650
651 n.class.decorators.visit_mut_with(self);
652
653 self.with_child(ScopeKind::Fn, |child| {
656 child.ident_type = IdentType::Ref;
657
658 n.class.visit_mut_with(child);
659 });
660 }
661
662 fn visit_mut_class_expr(&mut self, n: &mut ClassExpr) {
663 n.class.super_class.visit_mut_with(self);
666
667 self.with_child(ScopeKind::Fn, |child| {
668 child.ident_type = IdentType::Binding;
669 n.ident.visit_mut_with(child);
670 child.ident_type = IdentType::Ref;
671
672 n.class.visit_mut_with(child);
673 });
674 }
675
676 fn visit_mut_class_method(&mut self, m: &mut ClassMethod) {
677 m.key.visit_mut_with(self);
678
679 for p in m.function.params.iter_mut() {
680 p.decorators.visit_mut_with(self);
681 }
682
683 self.with_child(ScopeKind::Fn, |child| m.function.visit_mut_with(child));
684 }
685
686 fn visit_mut_class_prop(&mut self, p: &mut ClassProp) {
687 p.decorators.visit_mut_with(self);
688
689 if let PropName::Computed(key) = &mut p.key {
690 let old = self.ident_type;
691 self.ident_type = IdentType::Binding;
692 key.expr.visit_mut_with(self);
693 self.ident_type = old;
694 }
695
696 let old = self.ident_type;
697 self.ident_type = IdentType::Ref;
698 p.value.visit_mut_with(self);
699 self.ident_type = old;
700
701 p.type_ann.visit_mut_with(self);
702 }
703
704 fn visit_mut_constructor(&mut self, c: &mut Constructor) {
705 for p in c.params.iter_mut() {
706 match p {
707 ParamOrTsParamProp::TsParamProp(p) => {
708 p.decorators.visit_mut_with(self);
709 }
710 ParamOrTsParamProp::Param(p) => {
711 p.decorators.visit_mut_with(self);
712 }
713 }
714 }
715
716 self.with_child(ScopeKind::Fn, |child| {
717 let old = child.ident_type;
718 child.ident_type = IdentType::Binding;
719 {
720 let params = c
721 .params
722 .iter()
723 .filter(|p| match p {
724 ParamOrTsParamProp::TsParamProp(_) => false,
725 ParamOrTsParamProp::Param(p) => !p.pat.is_rest(),
726 })
727 .flat_map(find_pat_ids::<_, Id>);
728
729 for id in params {
730 child.current.declared_symbols.insert(id.0, DeclKind::Param);
731 }
732 }
733 c.params.visit_mut_with(child);
734 child.ident_type = old;
735
736 if let Some(body) = &mut c.body {
737 child.mark_block(&mut body.ctxt);
738 body.visit_mut_children_with(child);
739 }
740 });
741 }
742
743 fn visit_mut_continue_stmt(&mut self, s: &mut ContinueStmt) {
744 let old = self.ident_type;
745 self.ident_type = IdentType::Label;
746 s.label.visit_mut_with(self);
747 self.ident_type = old;
748 }
749
750 fn visit_mut_export_default_decl(&mut self, e: &mut ExportDefaultDecl) {
751 match &mut e.decl {
754 DefaultDecl::Fn(f) => {
755 if f.ident.is_some() {
756 self.with_child(ScopeKind::Fn, |child| {
757 f.function.visit_mut_with(child);
758 });
759 } else {
760 f.visit_mut_with(self)
761 }
762 }
763 DefaultDecl::Class(c) => {
764 c.class.visit_mut_with(self)
766 }
767 _ => e.visit_mut_children_with(self),
768 }
769 }
770
771 fn visit_mut_export_default_expr(&mut self, node: &mut ExportDefaultExpr) {
772 node.expr.visit_mut_with(self);
773
774 if self.config.handle_types {
775 if let Expr::Ident(i) = &mut *node.expr {
776 self.try_resolving_as_type(i);
777 }
778 }
779 }
780
781 fn visit_mut_export_named_specifier(&mut self, e: &mut ExportNamedSpecifier) {
782 e.visit_mut_children_with(self);
783
784 if self.config.handle_types {
785 match &mut e.orig {
786 ModuleExportName::Ident(orig) => {
787 self.try_resolving_as_type(orig);
788 }
789 ModuleExportName::Str(_) => {}
790 }
791 }
792 }
793
794 fn visit_mut_export_specifier(&mut self, s: &mut ExportSpecifier) {
795 let old = self.ident_type;
796 self.ident_type = IdentType::Ref;
797 s.visit_mut_children_with(self);
798 self.ident_type = old;
799 }
800
801 fn visit_mut_expr(&mut self, expr: &mut Expr) {
802 let _span = if LOG {
803 Some(span!(Level::ERROR, "visit_mut_expr").entered())
804 } else {
805 None
806 };
807
808 let old = self.ident_type;
809 self.ident_type = IdentType::Ref;
810 maybe_grow_default(|| expr.visit_mut_children_with(self));
811 self.ident_type = old;
812 }
813
814 fn visit_mut_fn_decl(&mut self, node: &mut FnDecl) {
815 if node.declare && !self.config.handle_types {
816 return;
817 }
818
819 node.function.decorators.visit_mut_with(self);
821
822 self.with_child(ScopeKind::Fn, |child| node.function.visit_mut_with(child));
823 }
824
825 fn visit_mut_fn_expr(&mut self, e: &mut FnExpr) {
826 e.function.decorators.visit_mut_with(self);
827
828 if let Some(ident) = &mut e.ident {
829 self.with_child(ScopeKind::Fn, |child| {
830 child.modify(ident, DeclKind::Function);
831 child.with_child(ScopeKind::Fn, |child| {
832 e.function.visit_mut_with(child);
833 });
834 });
835 } else {
836 self.with_child(ScopeKind::Fn, |child| {
837 e.function.visit_mut_with(child);
838 });
839 }
840 }
841
842 fn visit_mut_for_in_stmt(&mut self, n: &mut ForInStmt) {
843 self.with_child(ScopeKind::Block, |child| {
844 n.left.visit_mut_with(child);
845 n.right.visit_mut_with(child);
846
847 child.visit_mut_stmt_within_child_scope(&mut n.body);
848 });
849 }
850
851 fn visit_mut_for_of_stmt(&mut self, n: &mut ForOfStmt) {
852 self.with_child(ScopeKind::Block, |child| {
853 n.left.visit_mut_with(child);
854 n.right.visit_mut_with(child);
855
856 child.visit_mut_stmt_within_child_scope(&mut n.body);
857 });
858 }
859
860 fn visit_mut_for_stmt(&mut self, n: &mut ForStmt) {
861 self.with_child(ScopeKind::Block, |child| {
862 child.ident_type = IdentType::Binding;
863 n.init.visit_mut_with(child);
864 child.ident_type = IdentType::Ref;
865 n.test.visit_mut_with(child);
866 child.ident_type = IdentType::Ref;
867 n.update.visit_mut_with(child);
868
869 child.visit_mut_stmt_within_child_scope(&mut n.body);
870 });
871 }
872
873 fn visit_mut_function(&mut self, f: &mut Function) {
874 self.mark_block(&mut f.ctxt);
875 f.type_params.visit_mut_with(self);
876
877 self.ident_type = IdentType::Ref;
878 f.decorators.visit_mut_with(self);
879
880 {
881 let params = f
882 .params
883 .iter()
884 .filter(|p| !p.pat.is_rest())
885 .flat_map(find_pat_ids::<_, Id>);
886
887 for id in params {
888 self.current.declared_symbols.insert(id.0, DeclKind::Param);
889 }
890 }
891 self.ident_type = IdentType::Binding;
892 f.params.visit_mut_with(self);
893
894 f.return_type.visit_mut_with(self);
895
896 self.ident_type = IdentType::Ref;
897 if let Some(body) = &mut f.body {
898 self.mark_block(&mut body.ctxt);
899 let old_strict_mode = self.strict_mode;
900 if !self.strict_mode {
901 self.strict_mode = body
902 .stmts
903 .first()
904 .map(|stmt| stmt.is_use_strict())
905 .unwrap_or(false);
906 }
907 body.visit_mut_children_with(self);
909 self.strict_mode = old_strict_mode;
910 }
911 }
912
913 fn visit_mut_getter_prop(&mut self, f: &mut GetterProp) {
914 let old = self.ident_type;
915 self.ident_type = IdentType::Ref;
916 f.key.visit_mut_with(self);
917 self.ident_type = old;
918
919 f.type_ann.visit_mut_with(self);
920
921 f.body.visit_mut_with(self);
922 }
923
924 fn visit_mut_jsx_element_name(&mut self, node: &mut JSXElementName) {
925 if let JSXElementName::Ident(i) = node {
926 if i.as_ref().starts_with(|c: char| c.is_ascii_lowercase()) {
927 if cfg!(debug_assertions) && LOG {
928 debug!("\t -> JSXElementName");
929 }
930
931 let ctxt = i.ctxt.apply_mark(self.config.unresolved_mark);
932
933 if cfg!(debug_assertions) && LOG {
934 debug!("\t -> {:?}", ctxt);
935 }
936
937 i.ctxt = ctxt;
938
939 return;
940 }
941 }
942
943 node.visit_mut_children_with(self);
944 }
945
946 fn visit_mut_ident(&mut self, i: &mut Ident) {
947 if i.ctxt != SyntaxContext::empty() {
948 return;
949 }
950
951 match self.ident_type {
952 IdentType::Binding => self.modify(i, self.decl_kind),
953 IdentType::Ref => {
954 let Ident { sym, ctxt, .. } = i;
955
956 if cfg!(debug_assertions) && LOG {
957 debug!("IdentRef (type = {}) {}{:?}", self.in_type, sym, ctxt);
958 }
959
960 if *ctxt != SyntaxContext::empty() {
961 return;
962 }
963
964 if let Some(mark) = self.mark_for_ref(sym) {
965 let ctxt = ctxt.apply_mark(mark);
966
967 if cfg!(debug_assertions) && LOG {
968 debug!("\t -> {:?}", ctxt);
969 }
970 i.ctxt = ctxt;
971 } else {
972 if cfg!(debug_assertions) && LOG {
973 debug!("\t -> Unresolved");
974 }
975
976 let ctxt = ctxt.apply_mark(self.config.unresolved_mark);
977
978 if cfg!(debug_assertions) && LOG {
979 debug!("\t -> {:?}", ctxt);
980 }
981
982 i.ctxt = ctxt;
983 self.modify(i, self.decl_kind)
985 }
986 }
987 IdentType::Label => {}
989 }
990 }
991
992 fn visit_mut_import_decl(&mut self, n: &mut ImportDecl) {
993 self.ident_type = IdentType::Binding;
996 let old_in_type = self.in_type;
997 self.in_type = n.type_only;
998 n.visit_mut_children_with(self);
999 self.in_type = old_in_type;
1000 }
1001
1002 fn visit_mut_import_named_specifier(&mut self, s: &mut ImportNamedSpecifier) {
1003 let old = self.ident_type;
1004 self.ident_type = IdentType::Binding;
1005 s.local.visit_mut_with(self);
1006 if self.config.handle_types {
1007 self.current.declared_types.insert(s.local.sym.clone());
1008 }
1009 self.ident_type = old;
1010 }
1011
1012 fn visit_mut_import_specifier(&mut self, s: &mut ImportSpecifier) {
1013 let old = self.ident_type;
1014 self.ident_type = IdentType::Binding;
1015
1016 match s {
1017 ImportSpecifier::Named(ImportNamedSpecifier { imported: None, .. })
1018 | ImportSpecifier::Namespace(..)
1019 | ImportSpecifier::Default(..) => s.visit_mut_children_with(self),
1020 ImportSpecifier::Named(s) => s.local.visit_mut_with(self),
1021 }
1022
1023 self.ident_type = old;
1024 }
1025
1026 fn visit_mut_jsx_attr_name(&mut self, _: &mut JSXAttrName) {}
1030
1031 fn visit_mut_key_value_pat_prop(&mut self, n: &mut KeyValuePatProp) {
1032 n.key.visit_mut_with(self);
1033 n.value.visit_mut_with(self);
1034 }
1035
1036 fn visit_mut_labeled_stmt(&mut self, s: &mut LabeledStmt) {
1037 let old = self.ident_type;
1038 self.ident_type = IdentType::Label;
1039 s.label.visit_mut_with(self);
1040 self.ident_type = old;
1041
1042 s.body.visit_mut_with(self);
1043 }
1044
1045 fn visit_mut_method_prop(&mut self, m: &mut MethodProp) {
1046 m.key.visit_mut_with(self);
1047
1048 self.with_child(ScopeKind::Fn, |child| m.function.visit_mut_with(child));
1050 }
1051
1052 fn visit_mut_module(&mut self, module: &mut Module) {
1053 self.strict_mode = true;
1054 self.is_module = true;
1055 module.visit_mut_children_with(self)
1056 }
1057
1058 fn visit_mut_module_items(&mut self, stmts: &mut Vec<ModuleItem>) {
1059 if !self.in_ts_module && self.current.kind != ScopeKind::Fn {
1060 return stmts.visit_mut_children_with(self);
1061 }
1062
1063 {
1065 let mut hoister = Hoister {
1066 kind: self.decl_kind,
1067 resolver: self,
1068 in_block: false,
1069 in_catch_body: false,
1070 catch_param_decls: Default::default(),
1071 excluded_from_catch: Default::default(),
1072 };
1073 stmts.visit_mut_with(&mut hoister)
1074 }
1075
1076 stmts.visit_mut_children_with(self)
1078 }
1079
1080 fn visit_mut_named_export(&mut self, e: &mut NamedExport) {
1081 if e.src.is_some() {
1082 return;
1083 }
1084
1085 e.visit_mut_children_with(self);
1086 }
1087
1088 fn visit_mut_object_lit(&mut self, o: &mut ObjectLit) {
1089 self.with_child(ScopeKind::Block, |child| {
1090 o.visit_mut_children_with(child);
1091 });
1092 }
1093
1094 fn visit_mut_param(&mut self, param: &mut Param) {
1095 self.ident_type = IdentType::Binding;
1096 param.visit_mut_children_with(self);
1097 }
1098
1099 fn visit_mut_pat(&mut self, p: &mut Pat) {
1100 p.visit_mut_children_with(self);
1101 }
1102
1103 fn visit_mut_private_method(&mut self, m: &mut PrivateMethod) {
1104 m.key.visit_mut_with(self);
1105
1106 {
1107 self.with_child(ScopeKind::Fn, |child| m.function.visit_mut_with(child));
1110 }
1111 }
1112
1113 fn visit_mut_private_name(&mut self, _: &mut PrivateName) {}
1114
1115 fn visit_mut_prop_name(&mut self, n: &mut PropName) {
1116 if let PropName::Computed(c) = n {
1117 c.visit_mut_with(self);
1118 }
1119 }
1120
1121 fn visit_mut_rest_pat(&mut self, node: &mut RestPat) {
1122 node.arg.visit_mut_with(self);
1123 node.type_ann.visit_mut_with(self);
1124 }
1125
1126 fn visit_mut_script(&mut self, script: &mut Script) {
1127 self.strict_mode = script
1128 .body
1129 .first()
1130 .map(|stmt| stmt.is_use_strict())
1131 .unwrap_or(false);
1132 script.visit_mut_children_with(self)
1133 }
1134
1135 fn visit_mut_setter_prop(&mut self, n: &mut SetterProp) {
1136 n.key.visit_mut_with(self);
1137
1138 {
1139 self.with_child(ScopeKind::Fn, |child| {
1140 child.ident_type = IdentType::Binding;
1141 n.this_param.visit_mut_with(child);
1142 n.param.visit_mut_with(child);
1143 n.body.visit_mut_with(child);
1144 });
1145 };
1146 }
1147
1148 fn visit_mut_stmts(&mut self, stmts: &mut Vec<Stmt>) {
1149 let _span = if LOG {
1150 Some(span!(Level::ERROR, "visit_mut_stmts").entered())
1151 } else {
1152 None
1153 };
1154
1155 {
1157 let _span = if LOG {
1158 Some(span!(Level::ERROR, "hoist").entered())
1159 } else {
1160 None
1161 };
1162
1163 let mut hoister = Hoister {
1164 kind: self.decl_kind,
1165 resolver: self,
1166 in_block: false,
1167 in_catch_body: false,
1168 catch_param_decls: Default::default(),
1169 excluded_from_catch: Default::default(),
1170 };
1171 stmts.visit_mut_with(&mut hoister)
1172 }
1173
1174 stmts.visit_mut_children_with(self)
1176 }
1177
1178 fn visit_mut_switch_case(&mut self, n: &mut SwitchCase) {
1179 n.cons.visit_mut_with(self);
1180
1181 n.test.visit_mut_with(self);
1182 }
1183
1184 fn visit_mut_switch_stmt(&mut self, s: &mut SwitchStmt) {
1185 s.discriminant.visit_mut_with(self);
1186
1187 self.with_child(ScopeKind::Block, |child| {
1188 s.cases.visit_mut_with(child);
1189 });
1190 }
1191
1192 fn visit_mut_ts_as_expr(&mut self, n: &mut TsAsExpr) {
1193 if self.config.handle_types {
1194 n.type_ann.visit_mut_with(self);
1195 }
1196
1197 n.expr.visit_mut_with(self);
1198 }
1199
1200 fn visit_mut_ts_call_signature_decl(&mut self, n: &mut TsCallSignatureDecl) {
1201 if !self.config.handle_types {
1202 return;
1203 }
1204
1205 self.with_child(ScopeKind::Fn, |child| {
1206 child.in_type = true;
1207
1208 n.type_params.visit_mut_with(child);
1209 n.params.visit_mut_with(child);
1210 n.type_ann.visit_mut_with(child);
1211 });
1212 }
1213
1214 fn visit_mut_ts_construct_signature_decl(&mut self, decl: &mut TsConstructSignatureDecl) {
1215 if !self.config.handle_types {
1216 return;
1217 }
1218
1219 self.with_child(ScopeKind::Fn, |child| {
1221 child.in_type = true;
1222
1223 decl.type_params.visit_mut_with(child);
1225 decl.params.visit_mut_with(child);
1226 decl.type_ann.visit_mut_with(child);
1227 });
1228 }
1229
1230 fn visit_mut_ts_constructor_type(&mut self, ty: &mut TsConstructorType) {
1231 if !self.config.handle_types {
1232 return;
1233 }
1234
1235 self.with_child(ScopeKind::Fn, |child| {
1236 child.in_type = true;
1237
1238 ty.type_params.visit_mut_with(child);
1239 ty.params.visit_mut_with(child);
1240 ty.type_ann.visit_mut_with(child);
1241 });
1242 }
1243
1244 fn visit_mut_ts_enum_decl(&mut self, decl: &mut TsEnumDecl) {
1245 if decl.declare && !self.config.handle_types {
1246 return;
1247 }
1248 self.modify(&mut decl.id, DeclKind::Lexical);
1249
1250 self.with_child(ScopeKind::Block, |child| {
1251 let member_names = decl.members.iter().filter_map(|m| match &m.id {
1254 TsEnumMemberId::Ident(id) => Some((id.sym.clone(), DeclKind::Lexical)),
1255 TsEnumMemberId::Str(_) => None,
1256 });
1257 child.current.declared_symbols.extend(member_names);
1258
1259 decl.members.visit_mut_with(child);
1260 });
1261 }
1262
1263 fn visit_mut_ts_export_assignment(&mut self, node: &mut TsExportAssignment) {
1264 node.expr.visit_mut_with(self);
1265
1266 if self.config.handle_types {
1267 if let Some(i) = leftmost(&mut node.expr) {
1268 self.try_resolving_as_type(i);
1269 }
1270 }
1271 }
1272
1273 fn visit_mut_ts_expr_with_type_args(&mut self, n: &mut TsExprWithTypeArgs) {
1274 if self.config.handle_types {
1275 let old = self.in_type;
1276 self.in_type = true;
1277 n.visit_mut_children_with(self);
1278 self.in_type = old;
1279 }
1280 }
1281
1282 fn visit_mut_ts_fn_type(&mut self, ty: &mut TsFnType) {
1283 if !self.config.handle_types {
1284 return;
1285 }
1286
1287 self.with_child(ScopeKind::Fn, |child| {
1288 child.in_type = true;
1289
1290 ty.type_params.visit_mut_with(child);
1291 ty.params.visit_mut_with(child);
1292 ty.type_ann.visit_mut_with(child);
1293 });
1294 }
1295
1296 fn visit_mut_ts_getter_signature(&mut self, n: &mut TsGetterSignature) {
1297 if n.computed {
1298 n.key.visit_mut_with(self);
1299 }
1300
1301 n.type_ann.visit_mut_with(self);
1302 }
1303
1304 fn visit_mut_ts_import_equals_decl(&mut self, n: &mut TsImportEqualsDecl) {
1305 self.modify(&mut n.id, DeclKind::Lexical);
1306
1307 n.module_ref.visit_mut_with(self);
1308 }
1309
1310 fn visit_mut_ts_import_type(&mut self, n: &mut TsImportType) {
1311 if !self.config.handle_types {
1312 return;
1313 }
1314
1315 n.type_args.visit_mut_with(self);
1316 }
1317
1318 fn visit_mut_ts_interface_decl(&mut self, n: &mut TsInterfaceDecl) {
1319 let old_in_type = self.in_type;
1321 let old_ident_type = self.ident_type;
1322
1323 self.in_type = true;
1324 self.ident_type = IdentType::Ref;
1325
1326 self.modify(&mut n.id, DeclKind::Type);
1327
1328 if !self.config.handle_types {
1329 self.in_type = old_in_type;
1330 self.ident_type = old_ident_type;
1331 return;
1332 }
1333
1334 self.with_child(ScopeKind::Fn, |child| {
1335 child.in_type = true;
1336
1337 n.type_params.visit_mut_with(child);
1338 n.extends.visit_mut_with(child);
1339 n.body.visit_mut_with(child);
1340 });
1341
1342 self.in_type = old_in_type;
1343 self.ident_type = old_ident_type;
1344 }
1345
1346 fn visit_mut_ts_mapped_type(&mut self, n: &mut TsMappedType) {
1347 if !self.config.handle_types {
1348 return;
1349 }
1350
1351 self.ident_type = IdentType::Binding;
1352 n.type_param.visit_mut_with(self);
1353 self.ident_type = IdentType::Ref;
1354 n.name_type.visit_mut_with(self);
1355
1356 self.ident_type = IdentType::Ref;
1357 n.type_ann.visit_mut_with(self);
1358 }
1359
1360 fn visit_mut_ts_method_signature(&mut self, n: &mut TsMethodSignature) {
1361 if !self.config.handle_types {
1362 return;
1363 }
1364
1365 self.with_child(ScopeKind::Fn, |child| {
1366 child.in_type = true;
1367
1368 n.type_params.visit_mut_with(child);
1369 if n.computed {
1370 n.key.visit_mut_with(child);
1371 }
1372 n.params.visit_mut_with(child);
1373 n.type_ann.visit_mut_with(child);
1374 });
1375 }
1376
1377 fn visit_mut_ts_module_decl(&mut self, decl: &mut TsModuleDecl) {
1378 if decl.declare && !self.config.handle_types {
1379 return;
1380 }
1381
1382 match &mut decl.id {
1383 TsModuleName::Ident(i) => {
1384 self.modify(i, DeclKind::Lexical);
1385 }
1386 TsModuleName::Str(_) => {}
1387 }
1388
1389 self.with_child(ScopeKind::Block, |child| {
1390 child.in_ts_module = true;
1391
1392 decl.body.visit_mut_children_with(child);
1393 });
1394 }
1395
1396 fn visit_mut_ts_namespace_decl(&mut self, n: &mut TsNamespaceDecl) {
1397 if n.declare && !self.config.handle_types {
1398 return;
1399 }
1400
1401 self.modify(&mut n.id, DeclKind::Lexical);
1402
1403 n.body.visit_mut_with(self);
1404 }
1405
1406 fn visit_mut_ts_param_prop_param(&mut self, n: &mut TsParamPropParam) {
1407 self.ident_type = IdentType::Binding;
1408 n.visit_mut_children_with(self)
1409 }
1410
1411 fn visit_mut_ts_property_signature(&mut self, n: &mut TsPropertySignature) {
1412 if !self.config.handle_types {
1413 return;
1414 }
1415
1416 if n.computed {
1417 n.key.visit_mut_with(self);
1418 }
1419
1420 self.with_child(ScopeKind::Fn, |child| {
1421 child.in_type = true;
1422
1423 n.type_ann.visit_mut_with(child);
1424 });
1425 }
1426
1427 fn visit_mut_ts_qualified_name(&mut self, n: &mut TsQualifiedName) {
1428 self.ident_type = IdentType::Ref;
1429
1430 n.left.visit_mut_with(self)
1431 }
1432
1433 fn visit_mut_ts_satisfies_expr(&mut self, n: &mut TsSatisfiesExpr) {
1434 if self.config.handle_types {
1435 n.type_ann.visit_mut_with(self);
1436 }
1437
1438 n.expr.visit_mut_with(self);
1439 }
1440
1441 fn visit_mut_ts_setter_signature(&mut self, n: &mut TsSetterSignature) {
1442 if n.computed {
1443 n.key.visit_mut_with(self);
1444 }
1445
1446 n.param.visit_mut_with(self);
1447 }
1448
1449 fn visit_mut_ts_tuple_element(&mut self, e: &mut TsTupleElement) {
1450 if !self.config.handle_types {
1451 return;
1452 }
1453 self.ident_type = IdentType::Ref;
1454 e.ty.visit_mut_with(self);
1455 }
1456
1457 fn visit_mut_ts_type_alias_decl(&mut self, n: &mut TsTypeAliasDecl) {
1458 let old_in_type = self.in_type;
1460 self.in_type = true;
1461 self.modify(&mut n.id, DeclKind::Type);
1462
1463 if !self.config.handle_types {
1464 self.in_type = old_in_type;
1465 return;
1466 }
1467
1468 self.with_child(ScopeKind::Fn, |child| {
1469 child.in_type = true;
1470
1471 n.type_params.visit_mut_with(child);
1472 n.type_ann.visit_mut_with(child);
1473 });
1474 self.in_type = old_in_type;
1475 }
1476
1477 fn visit_mut_ts_type_assertion(&mut self, n: &mut TsTypeAssertion) {
1478 if self.config.handle_types {
1479 n.type_ann.visit_mut_with(self);
1480 }
1481
1482 n.expr.visit_mut_with(self);
1483 }
1484
1485 fn visit_mut_ts_type_param(&mut self, param: &mut TsTypeParam) {
1486 if !self.config.handle_types {
1487 return;
1488 }
1489 param.name.visit_mut_with(self);
1490
1491 let ident_type = self.ident_type;
1492 param.default.visit_mut_with(self);
1493 param.constraint.visit_mut_with(self);
1494 self.ident_type = ident_type;
1495 }
1496
1497 fn visit_mut_ts_type_params(&mut self, params: &mut Vec<TsTypeParam>) {
1498 for param in params.iter_mut() {
1499 param.name.visit_mut_with(self);
1500 }
1501
1502 params.visit_mut_children_with(self);
1503 }
1504
1505 fn visit_mut_using_decl(&mut self, decl: &mut UsingDecl) {
1506 let old_kind = self.decl_kind;
1507 self.decl_kind = DeclKind::Lexical;
1508 decl.decls.visit_mut_with(self);
1509 self.decl_kind = old_kind;
1510 }
1511
1512 fn visit_mut_var_decl(&mut self, decl: &mut VarDecl) {
1513 if decl.declare && !self.config.handle_types {
1514 return;
1515 }
1516
1517 let old_kind = self.decl_kind;
1518 self.decl_kind = decl.kind.into();
1519 decl.decls.visit_mut_with(self);
1520 self.decl_kind = old_kind;
1521 }
1522
1523 fn visit_mut_var_declarator(&mut self, decl: &mut VarDeclarator) {
1524 let old_type = self.ident_type;
1527 self.ident_type = IdentType::Binding;
1528 decl.name.visit_mut_with(self);
1529 self.ident_type = old_type;
1530
1531 decl.init.visit_mut_children_with(self);
1532 }
1533}
1534
1535fn leftmost(expr: &mut Expr) -> Option<&mut Ident> {
1536 match expr {
1537 Expr::Ident(i) => Some(i),
1538 Expr::Member(MemberExpr { obj, .. }) => leftmost(obj),
1539 Expr::Paren(ParenExpr { expr, .. }) => leftmost(expr),
1540 _ => None,
1541 }
1542}
1543
1544struct Hoister<'a, 'b> {
1546 resolver: &'a mut Resolver<'b>,
1547 kind: DeclKind,
1548 in_block: bool,
1550
1551 in_catch_body: bool,
1552
1553 excluded_from_catch: FxHashSet<Atom>,
1554 catch_param_decls: FxHashSet<Atom>,
1555}
1556
1557impl Hoister<'_, '_> {
1558 fn add_pat_id(&mut self, id: &mut BindingIdent) {
1559 if self.in_catch_body {
1560 if self.resolver.mark_for_ref_inner(&id.sym, true).is_some()
1562 && self.catch_param_decls.contains(&id.sym)
1563 {
1564 return;
1565 }
1566
1567 self.excluded_from_catch.insert(id.sym.clone());
1568 } else {
1569 if self.catch_param_decls.contains(&id.sym)
1571 && !self.excluded_from_catch.contains(&id.sym)
1572 {
1573 return;
1574 }
1575 }
1576
1577 self.resolver.modify(id, self.kind)
1578 }
1579}
1580
1581impl VisitMut for Hoister<'_, '_> {
1582 noop_visit_mut_type!();
1583
1584 #[inline]
1585 fn visit_mut_arrow_expr(&mut self, _: &mut ArrowExpr) {}
1586
1587 fn visit_mut_assign_pat_prop(&mut self, node: &mut AssignPatProp) {
1588 node.visit_mut_children_with(self);
1589
1590 self.add_pat_id(&mut node.key);
1591 }
1592
1593 fn visit_mut_block_stmt(&mut self, n: &mut BlockStmt) {
1594 let old_in_block = self.in_block;
1595 self.in_block = true;
1596 n.visit_mut_children_with(self);
1597 self.in_block = old_in_block;
1598 }
1599
1600 #[inline]
1634 fn visit_mut_catch_clause(&mut self, c: &mut CatchClause) {
1635 let old_exclude = self.excluded_from_catch.clone();
1636 self.excluded_from_catch = Default::default();
1637
1638 let old_in_catch_body = self.in_catch_body;
1639
1640 let params: Vec<Id> = find_pat_ids(&c.param);
1641
1642 let orig = self.catch_param_decls.clone();
1643
1644 self.catch_param_decls
1645 .extend(params.into_iter().map(|v| v.0));
1646
1647 self.in_catch_body = true;
1648 c.body.visit_mut_with(self);
1649
1650 self.in_catch_body = false;
1660 c.param.visit_mut_with(self);
1661
1662 self.catch_param_decls = orig;
1663
1664 self.in_catch_body = old_in_catch_body;
1665 self.excluded_from_catch = old_exclude;
1666 }
1667
1668 fn visit_mut_class_decl(&mut self, node: &mut ClassDecl) {
1669 if node.declare && !self.resolver.config.handle_types {
1670 return;
1671 }
1672 if self.in_block {
1673 return;
1674 }
1675 self.resolver.modify(&mut node.ident, DeclKind::Lexical);
1676
1677 if self.resolver.config.handle_types {
1678 self.resolver
1679 .current
1680 .declared_types
1681 .insert(node.ident.sym.clone());
1682 }
1683 }
1684
1685 #[inline]
1686 fn visit_mut_constructor(&mut self, _: &mut Constructor) {}
1687
1688 #[inline]
1689 fn visit_mut_decl(&mut self, decl: &mut Decl) {
1690 decl.visit_mut_children_with(self);
1691
1692 if self.resolver.config.handle_types {
1693 match decl {
1694 Decl::TsInterface(i) => {
1695 if self.in_block {
1696 return;
1697 }
1698
1699 let old_in_type = self.resolver.in_type;
1700 self.resolver.in_type = true;
1701 self.resolver.modify(&mut i.id, DeclKind::Type);
1702 self.resolver.in_type = old_in_type;
1703 }
1704
1705 Decl::TsTypeAlias(a) => {
1706 let old_in_type = self.resolver.in_type;
1707 self.resolver.in_type = true;
1708 self.resolver.modify(&mut a.id, DeclKind::Type);
1709 self.resolver.in_type = old_in_type;
1710 }
1711
1712 Decl::TsEnum(e) => {
1713 if !self.in_block {
1714 let old_in_type = self.resolver.in_type;
1715 self.resolver.in_type = false;
1716 self.resolver.modify(&mut e.id, DeclKind::Lexical);
1717 self.resolver.in_type = old_in_type;
1718 }
1719 }
1720
1721 Decl::TsModule(v)
1722 if matches!(
1723 &**v,
1724 TsModuleDecl {
1725 global: false,
1726 id: TsModuleName::Ident(_),
1727 ..
1728 },
1729 ) =>
1730 {
1731 if !self.in_block {
1732 let old_in_type = self.resolver.in_type;
1733 self.resolver.in_type = false;
1734 let id = v.id.as_mut_ident().unwrap();
1735 self.resolver.modify(id, DeclKind::Lexical);
1736 self.resolver.in_type = old_in_type;
1737 }
1738 }
1739 _ => {}
1740 }
1741 }
1742 }
1743
1744 fn visit_mut_export_default_decl(&mut self, node: &mut ExportDefaultDecl) {
1745 match &mut node.decl {
1748 DefaultDecl::Fn(f) => {
1749 if let Some(id) = &mut f.ident {
1750 self.resolver.modify(id, DeclKind::Var);
1751 }
1752
1753 f.visit_mut_with(self)
1754 }
1755 DefaultDecl::Class(c) => {
1756 if let Some(id) = &mut c.ident {
1757 self.resolver.modify(id, DeclKind::Lexical);
1758 }
1759
1760 c.visit_mut_with(self)
1761 }
1762 _ => {
1763 node.visit_mut_children_with(self);
1764 }
1765 }
1766 }
1767
1768 #[inline]
1769 fn visit_mut_expr(&mut self, _: &mut Expr) {}
1770
1771 fn visit_mut_fn_decl(&mut self, node: &mut FnDecl) {
1772 if node.declare && !self.resolver.config.handle_types {
1773 return;
1774 }
1775
1776 if self.catch_param_decls.contains(&node.ident.sym) {
1777 return;
1778 }
1779
1780 if self.in_block {
1781 if self.resolver.strict_mode {
1783 return;
1784 }
1785 if let Some(DeclKind::Lexical | DeclKind::Param) =
1788 self.resolver.current.is_declared(&node.ident.sym)
1789 {
1790 return;
1791 }
1792 }
1793
1794 self.resolver.modify(&mut node.ident, DeclKind::Function);
1795 }
1796
1797 #[inline]
1798 fn visit_mut_function(&mut self, _: &mut Function) {}
1799
1800 fn visit_mut_import_default_specifier(&mut self, n: &mut ImportDefaultSpecifier) {
1801 n.visit_mut_children_with(self);
1802
1803 self.resolver.modify(&mut n.local, DeclKind::Lexical);
1804
1805 if self.resolver.config.handle_types {
1806 self.resolver
1807 .current
1808 .declared_types
1809 .insert(n.local.sym.clone());
1810 }
1811 }
1812
1813 fn visit_mut_import_named_specifier(&mut self, n: &mut ImportNamedSpecifier) {
1814 n.visit_mut_children_with(self);
1815
1816 self.resolver.modify(&mut n.local, DeclKind::Lexical);
1817
1818 if self.resolver.config.handle_types {
1819 self.resolver
1820 .current
1821 .declared_types
1822 .insert(n.local.sym.clone());
1823 }
1824 }
1825
1826 fn visit_mut_import_star_as_specifier(&mut self, n: &mut ImportStarAsSpecifier) {
1827 n.visit_mut_children_with(self);
1828
1829 self.resolver.modify(&mut n.local, DeclKind::Lexical);
1830
1831 if self.resolver.config.handle_types {
1832 self.resolver
1833 .current
1834 .declared_types
1835 .insert(n.local.sym.clone());
1836 }
1837 }
1838
1839 #[inline]
1840 fn visit_mut_param(&mut self, _: &mut Param) {}
1841
1842 fn visit_mut_pat(&mut self, node: &mut Pat) {
1843 match node {
1844 Pat::Ident(i) => {
1845 self.add_pat_id(i);
1846 }
1847
1848 _ => node.visit_mut_children_with(self),
1849 }
1850 }
1851
1852 #[inline]
1853 fn visit_mut_assign_target(&mut self, _: &mut AssignTarget) {}
1854
1855 #[inline]
1856 fn visit_mut_setter_prop(&mut self, _: &mut SetterProp) {}
1857
1858 fn visit_mut_switch_stmt(&mut self, s: &mut SwitchStmt) {
1859 s.discriminant.visit_mut_with(self);
1860
1861 let old_in_block = self.in_block;
1862 self.in_block = true;
1863 s.cases.visit_mut_with(self);
1864 self.in_block = old_in_block;
1865 }
1866
1867 #[inline]
1868 fn visit_mut_tagged_tpl(&mut self, _: &mut TaggedTpl) {}
1869
1870 #[inline]
1871 fn visit_mut_tpl(&mut self, _: &mut Tpl) {}
1872
1873 #[inline]
1874 fn visit_mut_ts_module_block(&mut self, _: &mut TsModuleBlock) {}
1875
1876 #[inline]
1877 fn visit_mut_using_decl(&mut self, _: &mut UsingDecl) {}
1878
1879 fn visit_mut_var_decl(&mut self, node: &mut VarDecl) {
1880 if node.declare && !self.resolver.config.handle_types {
1881 return;
1882 }
1883
1884 if self.in_block {
1885 match node.kind {
1886 VarDeclKind::Const | VarDeclKind::Let => return,
1887 _ => {}
1888 }
1889 }
1890
1891 let old_kind = self.kind;
1892 self.kind = node.kind.into();
1893
1894 node.visit_mut_children_with(self);
1895
1896 self.kind = old_kind;
1897 }
1898
1899 fn visit_mut_var_decl_or_expr(&mut self, n: &mut VarDeclOrExpr) {
1900 match n {
1901 VarDeclOrExpr::VarDecl(v)
1902 if matches!(
1903 &**v,
1904 VarDecl {
1905 kind: VarDeclKind::Let | VarDeclKind::Const,
1906 ..
1907 }
1908 ) => {}
1909 _ => {
1910 n.visit_mut_children_with(self);
1911 }
1912 }
1913 }
1914
1915 fn visit_mut_for_head(&mut self, n: &mut ForHead) {
1916 match n {
1917 ForHead::VarDecl(v)
1918 if matches!(
1919 &**v,
1920 VarDecl {
1921 kind: VarDeclKind::Let | VarDeclKind::Const,
1922 ..
1923 }
1924 ) => {}
1925 ForHead::Pat(..) => {}
1935 _ => {
1936 n.visit_mut_children_with(self);
1937 }
1938 }
1939 }
1940
1941 #[inline]
1942 fn visit_mut_var_declarator(&mut self, node: &mut VarDeclarator) {
1943 node.name.visit_mut_with(self);
1944 }
1945
1946 fn visit_mut_module_items(&mut self, items: &mut Vec<ModuleItem>) {
1960 items.iter_mut().for_each(|item| match item {
1961 ModuleItem::Stmt(Stmt::Decl(Decl::Var(v)))
1962 | ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
1963 decl: Decl::Var(v),
1964 ..
1965 })) if matches!(
1966 &**v,
1967 VarDecl {
1968 kind: VarDeclKind::Var,
1969 ..
1970 }
1971 ) =>
1972 {
1973 item.visit_mut_with(self);
1974 }
1975
1976 ModuleItem::Stmt(Stmt::Decl(Decl::Fn(..)))
1977 | ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
1978 decl: Decl::Fn(..),
1979 ..
1980 })) => {
1981 item.visit_mut_with(self);
1982 }
1983 _ => item.visit_mut_with(self),
1984 });
1985 }
1986
1987 fn visit_mut_stmts(&mut self, stmts: &mut Vec<Stmt>) {
1989 let others = stmts
1990 .iter_mut()
1991 .filter_map(|item| match item {
1992 Stmt::Decl(Decl::Var(..)) => {
1993 item.visit_mut_with(self);
1994 None
1995 }
1996 Stmt::Decl(Decl::Fn(..)) => {
1997 item.visit_mut_with(self);
1998 None
1999 }
2000 _ => Some(item),
2001 })
2002 .collect::<Vec<_>>();
2003
2004 for other_stmt in others {
2005 other_stmt.visit_mut_with(self);
2006 }
2007 }
2008}