oxc_ecmascript/
bound_names.rs1use oxc_ast::ast::{
2 ArrayPattern, AssignmentPattern, BindingIdentifier, BindingPattern, BindingPatternKind,
3 BindingRestElement, Class, Declaration, ExportNamedDeclaration, FormalParameter,
4 FormalParameters, Function, ImportDeclaration, ImportDeclarationSpecifier, ModuleDeclaration,
5 ObjectPattern, VariableDeclaration,
6};
7
8pub trait BoundName<'a> {
10 fn bound_name<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F);
11}
12
13pub trait BoundNames<'a> {
14 fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F);
15}
16
17impl<'a> BoundNames<'a> for BindingPattern<'a> {
18 fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
19 match &self.kind {
20 BindingPatternKind::BindingIdentifier(ident) => ident.bound_names(f),
21 BindingPatternKind::ArrayPattern(array) => array.bound_names(f),
22 BindingPatternKind::ObjectPattern(object) => object.bound_names(f),
23 BindingPatternKind::AssignmentPattern(assignment) => assignment.bound_names(f),
24 }
25 }
26}
27
28impl<'a> BoundNames<'a> for BindingIdentifier<'a> {
29 fn bound_names<F: FnMut(&Self)>(&self, f: &mut F) {
30 f(self);
31 }
32}
33
34impl<'a> BoundNames<'a> for ArrayPattern<'a> {
35 fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
36 for elem in self.elements.iter().flatten() {
37 elem.bound_names(f);
38 }
39 if let Some(rest) = &self.rest {
40 rest.bound_names(f);
41 }
42 }
43}
44
45impl<'a> BoundNames<'a> for ObjectPattern<'a> {
46 fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
47 for p in &self.properties {
48 p.value.bound_names(f);
49 }
50 if let Some(rest) = &self.rest {
51 rest.bound_names(f);
52 }
53 }
54}
55
56impl<'a> BoundNames<'a> for AssignmentPattern<'a> {
57 fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
58 self.left.bound_names(f);
59 }
60}
61
62impl<'a> BoundNames<'a> for BindingRestElement<'a> {
63 fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
64 self.argument.bound_names(f);
65 }
66}
67
68impl<'a> BoundNames<'a> for FormalParameters<'a> {
69 fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
70 for item in &self.items {
71 item.bound_names(f);
72 }
73 if let Some(rest) = &self.rest {
74 rest.bound_names(f);
75 }
76 }
77}
78
79impl<'a> BoundNames<'a> for Declaration<'a> {
80 fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
81 match self {
82 Declaration::VariableDeclaration(decl) => decl.bound_names(f),
83 Declaration::FunctionDeclaration(func) => func.bound_names(f),
84 Declaration::ClassDeclaration(decl) => decl.bound_names(f),
85 _ => {}
86 }
87 }
88}
89
90impl<'a> BoundNames<'a> for VariableDeclaration<'a> {
91 fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
92 for declarator in &self.declarations {
93 declarator.id.bound_names(f);
94 }
95 }
96}
97
98impl<'a> BoundName<'a> for Function<'a> {
99 fn bound_name<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
100 if let Some(ident) = &self.id {
101 f(ident);
102 }
103 }
104}
105
106impl<'a> BoundNames<'a> for Function<'a> {
107 fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
108 self.bound_name(f);
109 }
110}
111
112impl<'a> BoundName<'a> for Class<'a> {
113 fn bound_name<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
114 if let Some(ident) = &self.id {
115 f(ident);
116 }
117 }
118}
119
120impl<'a> BoundNames<'a> for Class<'a> {
121 fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
122 self.bound_name(f);
123 }
124}
125
126impl<'a> BoundNames<'a> for FormalParameter<'a> {
127 fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
128 self.pattern.bound_names(f);
129 }
130}
131
132impl<'a> BoundNames<'a> for ModuleDeclaration<'a> {
133 fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
134 match self {
135 ModuleDeclaration::ImportDeclaration(decl) => decl.bound_names(f),
136 ModuleDeclaration::ExportNamedDeclaration(decl) => decl.bound_names(f),
137 _ => {}
138 }
139 }
140}
141
142impl<'a> BoundNames<'a> for ImportDeclaration<'a> {
143 fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
144 if let Some(specifiers) = &self.specifiers {
145 for specifier in specifiers {
146 match specifier {
147 ImportDeclarationSpecifier::ImportSpecifier(specifier) => {
148 f(&specifier.local);
149 }
150 ImportDeclarationSpecifier::ImportDefaultSpecifier(specifier) => {
151 f(&specifier.local);
152 }
153 ImportDeclarationSpecifier::ImportNamespaceSpecifier(specifier) => {
154 f(&specifier.local);
155 }
156 }
157 }
158 }
159 }
160}
161
162impl<'a> BoundNames<'a> for ExportNamedDeclaration<'a> {
163 fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
164 if let Some(decl) = &self.declaration {
165 decl.bound_names(f);
166 }
167 }
168}