Skip to content

Commit 53c10f0

Browse files
committed
feat(util/update-binding): add new utility to update binding in the file
1 parent b22db02 commit 53c10f0

File tree

3 files changed

+692
-168
lines changed

3 files changed

+692
-168
lines changed
Lines changed: 4 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
import type { SgNode, Edit, Range, Kinds, TypesMap } from "@codemod.com/jssg-types/main";
2-
3-
const requireKinds = ["lexical_declaration", "variable_declarator"];
4-
const importKinds = ["import_statement", "import_clause"];
5-
6-
type RemoveBindingReturnType = {
7-
edit?: Edit;
8-
lineToRemove?: Range;
9-
};
2+
import { updateBinding } from "./update-binding.ts";
103

114
/**
125
* Removes a specific binding from an import or require statement.
@@ -40,165 +33,8 @@ type RemoveBindingReturnType = {
4033
* // Returns: undefined (no destructured binding found)
4134
* ```
4235
*/
43-
export function removeBinding(
44-
node: SgNode<TypesMap, Kinds<TypesMap>>,
45-
binding: string,
46-
): RemoveBindingReturnType {
47-
const nodeKind = node.kind().toString();
48-
49-
const identifier = node.find({
50-
rule: {
51-
any: [
52-
{
53-
kind: "identifier",
54-
inside: {
55-
kind: "variable_declarator",
56-
},
57-
},
58-
{
59-
kind: "identifier",
60-
inside: {
61-
kind: "import_clause",
62-
},
63-
},
64-
],
65-
},
66-
});
67-
68-
if (identifier && identifier.text() === binding) {
69-
return {
70-
lineToRemove: node.range(),
71-
};
72-
}
73-
74-
if (requireKinds.includes(nodeKind)) {
75-
return handleNamedRequireBindings(node, binding);
76-
}
77-
78-
if (importKinds.includes(nodeKind)) {
79-
return handleNamedImportBindings(node, binding);
80-
}
81-
}
82-
83-
function handleNamedImportBindings(
84-
node: SgNode<TypesMap, Kinds<TypesMap>>,
85-
binding: string,
86-
): RemoveBindingReturnType {
87-
const namespaceImport = node.find({
88-
rule: {
89-
kind: "identifier",
90-
inside: {
91-
kind: "namespace_import",
92-
},
93-
},
94-
});
95-
96-
if (Boolean(namespaceImport) && namespaceImport.text() === binding) {
97-
return {
98-
lineToRemove: node.range(),
99-
};
100-
}
101-
102-
const namedImports = node.findAll({
103-
rule: {
104-
kind: "import_specifier",
105-
// ignore imports with alias (renamed imports)
106-
not: {
107-
has: {
108-
field: "alias",
109-
kind: "identifier",
110-
},
111-
},
112-
},
36+
export function removeBinding(node: SgNode<TypesMap, Kinds<TypesMap>>, binding: string) {
37+
return updateBinding(node, binding, {
38+
newBinding: undefined,
11339
});
114-
115-
for (const namedImport of namedImports) {
116-
const text = namedImport.text();
117-
if (text === binding) {
118-
if (namedImports.length === 1) {
119-
return {
120-
lineToRemove: node.range(),
121-
};
122-
}
123-
124-
const namedImportsNode = node.find({
125-
rule: {
126-
kind: "named_imports",
127-
},
128-
});
129-
const restNamedImports = namedImports.map((d) => d.text()).filter((d) => d !== binding);
130-
131-
return {
132-
edit: namedImportsNode.replace(`{ ${restNamedImports.join(", ")} }`),
133-
};
134-
}
135-
}
136-
137-
const renamedImports = node.findAll({
138-
rule: {
139-
has: {
140-
field: "alias",
141-
kind: "identifier",
142-
},
143-
},
144-
});
145-
146-
for (const renamedImport of renamedImports) {
147-
if (renamedImport.text() === binding) {
148-
if (renamedImports.length === 1 && namedImports.length === 0) {
149-
return {
150-
lineToRemove: node.range(),
151-
};
152-
}
153-
154-
const namedImportsNode = node.find({
155-
rule: {
156-
kind: "named_imports",
157-
},
158-
});
159-
160-
const aliasStatement = renamedImports.map((alias) => alias.parent());
161-
162-
const restNamedImports = [...namedImports, ...aliasStatement]
163-
.map((d) => d.text())
164-
.filter((d) => d !== renamedImport.parent().text());
165-
166-
return {
167-
edit: namedImportsNode.replace(`{ ${restNamedImports.join(", ")} }`),
168-
};
169-
}
170-
}
171-
}
172-
173-
function handleNamedRequireBindings(
174-
node: SgNode<TypesMap, Kinds<TypesMap>>,
175-
binding: string,
176-
): RemoveBindingReturnType {
177-
const objectPattern = node.find({
178-
rule: {
179-
kind: "object_pattern",
180-
},
181-
});
182-
183-
if (!objectPattern) return;
184-
185-
const declarations = node.findAll({
186-
rule: {
187-
kind: "shorthand_property_identifier_pattern",
188-
},
189-
});
190-
191-
if (declarations.length === 1) {
192-
return {
193-
lineToRemove: node.range(),
194-
};
195-
}
196-
197-
if (declarations.length > 1) {
198-
const restDeclarations = declarations.map((d) => d.text()).filter((d) => d !== binding);
199-
200-
return {
201-
edit: objectPattern.replace(`{ ${restDeclarations.join(", ")} }`),
202-
};
203-
}
20440
}

0 commit comments

Comments
 (0)