vue-hook-optimizer 0.0.83 → 0.0.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +409 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -4
- package/dist/index.d.ts +19 -4
- package/dist/index.js +409 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -142,6 +142,408 @@ function getRelationType(path) {
|
|
|
142
142
|
return "get";
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
//#endregion
|
|
146
|
+
//#region src/analyze/hook.ts
|
|
147
|
+
const traverse$4 = __babel_traverse.default.default?.default || __babel_traverse.default.default || __babel_traverse.default;
|
|
148
|
+
const watchHooks$1 = [
|
|
149
|
+
"watch",
|
|
150
|
+
"watchArray",
|
|
151
|
+
"watchAtMost",
|
|
152
|
+
"watchDebounced",
|
|
153
|
+
"watchDeep",
|
|
154
|
+
"watchIgnorable",
|
|
155
|
+
"watchImmediate",
|
|
156
|
+
"watchOnce",
|
|
157
|
+
"watchPausable",
|
|
158
|
+
"watchThrottled",
|
|
159
|
+
"watchTriggerable",
|
|
160
|
+
"watchWithFilter"
|
|
161
|
+
];
|
|
162
|
+
const reactEffects = [
|
|
163
|
+
"useEffect",
|
|
164
|
+
"useLayoutEffect",
|
|
165
|
+
"useInsertionEffect",
|
|
166
|
+
"useMemo",
|
|
167
|
+
"useCallback"
|
|
168
|
+
];
|
|
169
|
+
const allEffectHooks = [
|
|
170
|
+
...watchHooks$1,
|
|
171
|
+
"watchEffect",
|
|
172
|
+
...reactEffects
|
|
173
|
+
];
|
|
174
|
+
function processHookFunction(functionPath, lineOffset = 0, externalHookName = "", framework = "vue") {
|
|
175
|
+
const nodeCollection = new NodeCollection(lineOffset);
|
|
176
|
+
const nodesUsedInReturn = /* @__PURE__ */ new Set();
|
|
177
|
+
const graph = {
|
|
178
|
+
nodes: /* @__PURE__ */ new Set(),
|
|
179
|
+
edges: /* @__PURE__ */ new Map()
|
|
180
|
+
};
|
|
181
|
+
const functionNode = functionPath.node;
|
|
182
|
+
const hookName = externalHookName || (functionNode.type === "FunctionDeclaration" && functionNode.id ? functionNode.id.name : "");
|
|
183
|
+
const bodyNode = functionNode.body;
|
|
184
|
+
if (bodyNode.type !== "BlockStatement") return {
|
|
185
|
+
graph,
|
|
186
|
+
nodeCollection,
|
|
187
|
+
nodesUsedInReturn,
|
|
188
|
+
hookName
|
|
189
|
+
};
|
|
190
|
+
const functionScope = functionPath.scope;
|
|
191
|
+
if (functionNode.params) functionNode.params.forEach((param) => {
|
|
192
|
+
if (param.type === "Identifier") {
|
|
193
|
+
graph.nodes.add(param.name);
|
|
194
|
+
nodeCollection.addNode(param.name, param, { comment: "" });
|
|
195
|
+
if (!graph.edges.get(param.name)) graph.edges.set(param.name, /* @__PURE__ */ new Set());
|
|
196
|
+
} else if (param.type === "AssignmentPattern" && param.left.type === "Identifier") {
|
|
197
|
+
graph.nodes.add(param.left.name);
|
|
198
|
+
nodeCollection.addNode(param.left.name, param.left, { comment: "" });
|
|
199
|
+
if (!graph.edges.get(param.left.name)) graph.edges.set(param.left.name, /* @__PURE__ */ new Set());
|
|
200
|
+
} else if (param.type === "ObjectPattern") param.properties.forEach((prop) => {
|
|
201
|
+
if (prop.type === "ObjectProperty" && prop.value.type === "Identifier") {
|
|
202
|
+
graph.nodes.add(prop.value.name);
|
|
203
|
+
nodeCollection.addNode(prop.value.name, prop.value, { comment: "" });
|
|
204
|
+
if (!graph.edges.get(prop.value.name)) graph.edges.set(prop.value.name, /* @__PURE__ */ new Set());
|
|
205
|
+
} else if (prop.type === "RestElement" && prop.argument.type === "Identifier") {
|
|
206
|
+
graph.nodes.add(prop.argument.name);
|
|
207
|
+
nodeCollection.addNode(prop.argument.name, prop.argument, { comment: "" });
|
|
208
|
+
if (!graph.edges.get(prop.argument.name)) graph.edges.set(prop.argument.name, /* @__PURE__ */ new Set());
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
else if (param.type === "ArrayPattern") param.elements.forEach((element) => {
|
|
212
|
+
if (element?.type === "Identifier") {
|
|
213
|
+
graph.nodes.add(element.name);
|
|
214
|
+
nodeCollection.addNode(element.name, element, { comment: "" });
|
|
215
|
+
if (!graph.edges.get(element.name)) graph.edges.set(element.name, /* @__PURE__ */ new Set());
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
traverse$4(bodyNode, {
|
|
220
|
+
VariableDeclaration(path) {
|
|
221
|
+
path.node.declarations.forEach((declaration) => {
|
|
222
|
+
if (declaration.id.type === "Identifier") {
|
|
223
|
+
const name = declaration.id.name;
|
|
224
|
+
const binding = path.scope.getBinding(name);
|
|
225
|
+
if (binding && binding.scope === functionScope) {
|
|
226
|
+
graph.nodes.add(name);
|
|
227
|
+
nodeCollection.addNode(name, declaration, { comment: getComment(path.node) });
|
|
228
|
+
if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
|
|
229
|
+
}
|
|
230
|
+
} else if (declaration.id.type === "ObjectPattern") declaration.id.properties.forEach((property) => {
|
|
231
|
+
if (property.type === "ObjectProperty" && property.value.type === "Identifier") {
|
|
232
|
+
const name = property.value.name;
|
|
233
|
+
const binding = path.scope.getBinding(name);
|
|
234
|
+
if (binding && binding.scope === functionScope) {
|
|
235
|
+
graph.nodes.add(name);
|
|
236
|
+
nodeCollection.addNode(name, property.value, { comment: getComment(property) });
|
|
237
|
+
if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
|
|
238
|
+
}
|
|
239
|
+
} else if (property.type === "RestElement" && property.argument.type === "Identifier") {
|
|
240
|
+
const name = property.argument.name;
|
|
241
|
+
const binding = path.scope.getBinding(name);
|
|
242
|
+
if (binding && binding.scope === functionScope) {
|
|
243
|
+
graph.nodes.add(name);
|
|
244
|
+
nodeCollection.addNode(name, property.argument, { comment: getComment(property) });
|
|
245
|
+
if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
else if (declaration.id.type === "ArrayPattern") declaration.id.elements.forEach((element) => {
|
|
250
|
+
if (element?.type === "Identifier") {
|
|
251
|
+
const name = element.name;
|
|
252
|
+
const binding = path.scope.getBinding(name);
|
|
253
|
+
if (binding && binding.scope === functionScope) {
|
|
254
|
+
graph.nodes.add(name);
|
|
255
|
+
nodeCollection.addNode(name, element, { comment: getComment(path.node) });
|
|
256
|
+
if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
},
|
|
262
|
+
FunctionDeclaration(path) {
|
|
263
|
+
const name = path.node.id?.name;
|
|
264
|
+
if (name) {
|
|
265
|
+
const binding = path.scope.getBinding(name);
|
|
266
|
+
if (binding && binding.scope === functionScope) {
|
|
267
|
+
graph.nodes.add(name);
|
|
268
|
+
nodeCollection.addNode(name, path.node.id, {
|
|
269
|
+
isMethod: true,
|
|
270
|
+
comment: getComment(path.node)
|
|
271
|
+
});
|
|
272
|
+
if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}, functionScope, functionPath);
|
|
277
|
+
function traverseHooks(node, parentScope) {
|
|
278
|
+
if (node.type === "ExpressionStatement" && node.expression.type === "CallExpression" && node.expression.callee.type === "Identifier" || node.type === "CallExpression" && node.callee.type === "Identifier") {
|
|
279
|
+
const hookName$1 = (() => {
|
|
280
|
+
if (node.type === "ExpressionStatement" && node.expression.type === "CallExpression" && node.expression.callee.type === "Identifier") return node.expression.callee.name;
|
|
281
|
+
if (node.type === "CallExpression" && node.callee.type === "Identifier") return node.callee.name;
|
|
282
|
+
})() || "";
|
|
283
|
+
if (!hookName$1) return;
|
|
284
|
+
const hookBinding = parentScope.getBinding(hookName$1);
|
|
285
|
+
if (!(hookBinding === void 0 || hookBinding?.scope === functionScope)) return;
|
|
286
|
+
const expression = node.type === "ExpressionStatement" ? node.expression : node;
|
|
287
|
+
const watchArgs = /* @__PURE__ */ new Set();
|
|
288
|
+
if (watchHooks$1.includes(hookName$1)) {
|
|
289
|
+
if (expression.arguments[0]?.type === "Identifier") {
|
|
290
|
+
const binding = parentScope.getBinding(expression.arguments[0].name);
|
|
291
|
+
if (binding && graph.nodes.has(expression.arguments[0].name) && binding.scope === functionScope) watchArgs.add(expression.arguments[0]);
|
|
292
|
+
} else if (expression.arguments[0]) traverse$4(expression.arguments[0], { Identifier(path1) {
|
|
293
|
+
const binding = path1.scope.getBinding(path1.node.name);
|
|
294
|
+
if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && binding?.scope === functionScope) watchArgs.add(path1.node);
|
|
295
|
+
} }, parentScope, node);
|
|
296
|
+
}
|
|
297
|
+
expression.arguments.forEach((argNode, index) => {
|
|
298
|
+
if (watchHooks$1.includes(hookName$1) && index === 0 && argNode.type === "Identifier") {
|
|
299
|
+
const _node = nodeCollection.getNode(argNode.name);
|
|
300
|
+
if (_node?.info?.used) _node?.info?.used?.add(hookName$1);
|
|
301
|
+
else if (_node) _node.info = {
|
|
302
|
+
..._node?.info,
|
|
303
|
+
used: new Set([hookName$1])
|
|
304
|
+
};
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
if (argNode.type === "Identifier") {
|
|
308
|
+
const binding = parentScope.getBinding(argNode.name);
|
|
309
|
+
if (binding && graph.nodes.has(argNode.name) && binding.scope === functionScope) {
|
|
310
|
+
const _node = nodeCollection.getNode(argNode.name);
|
|
311
|
+
if (_node?.info?.used) _node?.info?.used?.add(hookName$1);
|
|
312
|
+
else if (_node) _node.info = {
|
|
313
|
+
..._node?.info,
|
|
314
|
+
used: new Set([hookName$1])
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
} else traverse$4(argNode, { Identifier(path1) {
|
|
318
|
+
const binding = path1.scope.getBinding(path1.node.name);
|
|
319
|
+
if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && binding?.scope === functionScope) {
|
|
320
|
+
if ([...watchHooks$1].includes(hookName$1) && watchArgs.size > 0) {
|
|
321
|
+
const watchArgsNames = Array.from(watchArgs).map((arg) => arg.name);
|
|
322
|
+
watchArgs.forEach((watchArg) => {
|
|
323
|
+
if (!watchArgsNames.includes(path1.node.name)) graph.edges.get(watchArg.name)?.add({
|
|
324
|
+
label: path1.node.name,
|
|
325
|
+
type: getRelationType(path1)
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
const _node = nodeCollection.getNode(path1.node.name);
|
|
330
|
+
if (_node?.info?.used) _node?.info?.used?.add(hookName$1);
|
|
331
|
+
else if (_node) _node.info = {
|
|
332
|
+
..._node?.info,
|
|
333
|
+
used: new Set([hookName$1])
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
} }, parentScope, node);
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
traverse$4(bodyNode, {
|
|
341
|
+
FunctionDeclaration(path) {
|
|
342
|
+
const name = path.node.id?.name;
|
|
343
|
+
if (name && graph.nodes.has(name) && path.scope.getBinding(name)?.scope === functionScope) traverse$4(path.node.body, { Identifier(path1) {
|
|
344
|
+
const binding = path1.scope.getBinding(path1.node.name);
|
|
345
|
+
if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && binding?.scope === functionScope) graph.edges.get(name)?.add({
|
|
346
|
+
label: path1.node.name,
|
|
347
|
+
type: getRelationType(path1)
|
|
348
|
+
});
|
|
349
|
+
} }, path.scope, path);
|
|
350
|
+
},
|
|
351
|
+
VariableDeclarator(path) {
|
|
352
|
+
if (path.node.init) {
|
|
353
|
+
if (path.node.id.type === "Identifier") {
|
|
354
|
+
const name = path.node.id.name;
|
|
355
|
+
if (name && graph.nodes.has(name) && path.scope.getBinding(name)?.scope === functionScope) {
|
|
356
|
+
if (path.node.init.type === "CallExpression" && path.node.init.callee.type === "Identifier" && allEffectHooks.includes(path.node.init.callee.name)) traverseHooks(path.node.init, path.scope);
|
|
357
|
+
traverse$4(path.node.init, { Identifier(path1) {
|
|
358
|
+
const binding = path1.scope.getBinding(path1.node.name);
|
|
359
|
+
if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && binding?.scope === functionScope) graph.edges.get(name)?.add({
|
|
360
|
+
label: path1.node.name,
|
|
361
|
+
type: getRelationType(path1)
|
|
362
|
+
});
|
|
363
|
+
} }, path.scope, path);
|
|
364
|
+
}
|
|
365
|
+
} else if (path.node.id.type === "ObjectPattern") path.node.id.properties.forEach((property) => {
|
|
366
|
+
if (property.type === "ObjectProperty" && property.value.type === "Identifier") {
|
|
367
|
+
const name = property.value.name;
|
|
368
|
+
const isValidNode = name && graph.nodes.has(name) && path.node.init && path.scope.getBinding(name)?.scope === functionScope;
|
|
369
|
+
if (isValidNode) traverse$4(path.node.init, { Identifier(path1) {
|
|
370
|
+
const binding = path1.scope.getBinding(path1.node.name);
|
|
371
|
+
if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && binding?.scope === functionScope) graph.edges.get(name)?.add({
|
|
372
|
+
label: path1.node.name,
|
|
373
|
+
type: getRelationType(path1)
|
|
374
|
+
});
|
|
375
|
+
} }, path.scope, path);
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
else if (path.node.id.type === "ArrayPattern") path.node.id.elements.forEach((element) => {
|
|
379
|
+
if (element?.type === "Identifier") {
|
|
380
|
+
const name = element.name;
|
|
381
|
+
const isValidNode = name && graph.nodes.has(name) && path.node.init && path.scope.getBinding(name)?.scope === functionScope;
|
|
382
|
+
if (isValidNode) traverse$4(path.node.init, { Identifier(path1) {
|
|
383
|
+
const binding = path1.scope.getBinding(path1.node.name);
|
|
384
|
+
if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && binding?.scope === functionScope) graph.edges.get(name)?.add({
|
|
385
|
+
label: path1.node.name,
|
|
386
|
+
type: getRelationType(path1)
|
|
387
|
+
});
|
|
388
|
+
} }, path.scope, path);
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
},
|
|
393
|
+
ObjectMethod(path) {
|
|
394
|
+
if (path.node.key.type === "Identifier" && graph.nodes.has(path.node.key.name)) {
|
|
395
|
+
const name = path.node.key.name;
|
|
396
|
+
traverse$4(path.node.body, { Identifier(path1) {
|
|
397
|
+
const binding = path1.scope.getBinding(path1.node.name);
|
|
398
|
+
if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && binding?.scope === functionScope) graph.edges.get(name)?.add({
|
|
399
|
+
label: path1.node.name,
|
|
400
|
+
type: getRelationType(path1)
|
|
401
|
+
});
|
|
402
|
+
} }, path.scope, path);
|
|
403
|
+
}
|
|
404
|
+
},
|
|
405
|
+
ObjectProperty(path) {
|
|
406
|
+
if (path.node.key.type === "Identifier" && graph.nodes.has(path.node.key.name)) {
|
|
407
|
+
const name = path.node.key.name;
|
|
408
|
+
traverse$4(path.node.value, { Identifier(path1) {
|
|
409
|
+
if (path1.node.name === name) return;
|
|
410
|
+
const binding = path1.scope.getBinding(path1.node.name);
|
|
411
|
+
if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && binding?.scope === functionScope) graph.edges.get(name)?.add({
|
|
412
|
+
label: path1.node.name,
|
|
413
|
+
type: getRelationType(path1)
|
|
414
|
+
});
|
|
415
|
+
} }, path.scope, path);
|
|
416
|
+
}
|
|
417
|
+
},
|
|
418
|
+
ExpressionStatement(path) {
|
|
419
|
+
if (path.node.expression.type === "CallExpression" && path.node.expression.callee.type === "Identifier") {
|
|
420
|
+
const name = path.node.expression.callee.name;
|
|
421
|
+
if (graph.nodes.has(name) && path.scope.getBinding(name)?.scope === functionScope) {
|
|
422
|
+
const _node = nodeCollection.getNode(name);
|
|
423
|
+
if (_node?.info?.used) _node?.info?.used?.add("Call Expression");
|
|
424
|
+
else if (_node) _node.info = {
|
|
425
|
+
..._node?.info,
|
|
426
|
+
used: new Set(["Call Expression"])
|
|
427
|
+
};
|
|
428
|
+
} else traverseHooks(path.node.expression, path.scope);
|
|
429
|
+
}
|
|
430
|
+
if (path.node.expression.type === "AssignmentExpression" && path.node.expression.right.type === "CallExpression" && path.node.expression.right.callee.type === "Identifier") traverseHooks(path.node.expression.right, path.scope);
|
|
431
|
+
}
|
|
432
|
+
}, functionScope, functionPath);
|
|
433
|
+
traverse$4(bodyNode, { ReturnStatement(path) {
|
|
434
|
+
const fnParent = path.findParent((p) => p.isFunction());
|
|
435
|
+
if (fnParent && fnParent.node !== functionNode) return;
|
|
436
|
+
if (path.node.argument?.type === "ObjectExpression") {
|
|
437
|
+
const returnNode = path.node.argument;
|
|
438
|
+
traverse$4(returnNode, {
|
|
439
|
+
ObjectProperty(path3) {
|
|
440
|
+
if (path3.parent === returnNode) {
|
|
441
|
+
if (path3.node.key.type === "Identifier" && path3.node.value.type === "Identifier") nodesUsedInReturn.add(path3.node.value.name);
|
|
442
|
+
}
|
|
443
|
+
},
|
|
444
|
+
SpreadElement(path3) {
|
|
445
|
+
if (path3.node.argument.type === "Identifier") nodesUsedInReturn.add(path3.node.argument.name);
|
|
446
|
+
}
|
|
447
|
+
}, path.scope, path);
|
|
448
|
+
} else if (path.node.argument?.type === "ArrayExpression") path.node.argument.elements.forEach((element) => {
|
|
449
|
+
if (element?.type === "Identifier") nodesUsedInReturn.add(element.name);
|
|
450
|
+
});
|
|
451
|
+
else if (path.node.argument?.type === "Identifier") nodesUsedInReturn.add(path.node.argument.name);
|
|
452
|
+
} }, functionScope, functionPath);
|
|
453
|
+
return {
|
|
454
|
+
graph,
|
|
455
|
+
nodeCollection,
|
|
456
|
+
nodesUsedInReturn,
|
|
457
|
+
hookName
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
function analyzeHook(content, lineOffset = 0, framework = "vue") {
|
|
461
|
+
const ast = (0, __vue_compiler_sfc.babelParse)(content, {
|
|
462
|
+
sourceType: "module",
|
|
463
|
+
plugins: ["typescript", "jsx"]
|
|
464
|
+
});
|
|
465
|
+
const results = [];
|
|
466
|
+
function walkCallExpressionChain(node, path, pathSegments) {
|
|
467
|
+
if (node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression") try {
|
|
468
|
+
return path.get(pathSegments.join("."));
|
|
469
|
+
} catch {
|
|
470
|
+
return void 0;
|
|
471
|
+
}
|
|
472
|
+
if (node.type === "CallExpression") for (let i = 0; i < node.arguments.length; i++) {
|
|
473
|
+
const arg = node.arguments[i];
|
|
474
|
+
if (arg.type === "ArrowFunctionExpression" || arg.type === "FunctionExpression") try {
|
|
475
|
+
return path.get([
|
|
476
|
+
...pathSegments,
|
|
477
|
+
"arguments",
|
|
478
|
+
i
|
|
479
|
+
].join("."));
|
|
480
|
+
} catch {}
|
|
481
|
+
else if (arg.type === "CallExpression") {
|
|
482
|
+
const result = walkCallExpressionChain(arg, path, [
|
|
483
|
+
...pathSegments,
|
|
484
|
+
"arguments",
|
|
485
|
+
i
|
|
486
|
+
]);
|
|
487
|
+
if (result) return result;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
return void 0;
|
|
491
|
+
}
|
|
492
|
+
function extractHookFromDeclarator(decl, varPath) {
|
|
493
|
+
const init = decl.init;
|
|
494
|
+
const hookName = decl.id.type === "Identifier" ? decl.id.name : "";
|
|
495
|
+
if (!init) return;
|
|
496
|
+
const funcPath = walkCallExpressionChain(init, varPath, ["init"]);
|
|
497
|
+
if (funcPath) results.push(processHookFunction(funcPath, lineOffset, hookName, framework));
|
|
498
|
+
}
|
|
499
|
+
traverse$4(ast, {
|
|
500
|
+
ExportDefaultDeclaration(path) {
|
|
501
|
+
const declaration = path.node.declaration;
|
|
502
|
+
if (declaration.type === "FunctionDeclaration" && declaration.id?.name.startsWith("use")) {
|
|
503
|
+
const funcPath = path.get("declaration");
|
|
504
|
+
results.push(processHookFunction(funcPath, lineOffset, "", framework));
|
|
505
|
+
}
|
|
506
|
+
},
|
|
507
|
+
ExportNamedDeclaration(path) {
|
|
508
|
+
const declaration = path.node.declaration;
|
|
509
|
+
if (declaration?.type === "FunctionDeclaration" && declaration.id?.name.startsWith("use")) {
|
|
510
|
+
const funcPath = path.get("declaration");
|
|
511
|
+
results.push(processHookFunction(funcPath, lineOffset, "", framework));
|
|
512
|
+
} else if (declaration?.type === "VariableDeclaration") declaration.declarations.forEach((decl) => {
|
|
513
|
+
if (decl.id.type === "Identifier" && decl.id.name.startsWith("use")) {
|
|
514
|
+
const varPath = path.get("declaration.declarations").find((p) => {
|
|
515
|
+
const node = p.node;
|
|
516
|
+
const nodeId = node.id;
|
|
517
|
+
return nodeId.type === "Identifier" && nodeId.name === decl.id.name;
|
|
518
|
+
});
|
|
519
|
+
if (varPath) extractHookFromDeclarator(decl, varPath);
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
},
|
|
523
|
+
FunctionDeclaration(path) {
|
|
524
|
+
if (path.node.id?.name.startsWith("use") && path.parent.type === "Program") results.push(processHookFunction(path, lineOffset, "", framework));
|
|
525
|
+
},
|
|
526
|
+
VariableDeclaration(path) {
|
|
527
|
+
if (path.parent.type === "Program") path.node.declarations.forEach((decl) => {
|
|
528
|
+
if (decl.id.type === "Identifier" && decl.id.name.startsWith("use")) {
|
|
529
|
+
const declName = decl.id.name;
|
|
530
|
+
const varPath = path.get("declarations").find((p) => {
|
|
531
|
+
const node = p.node;
|
|
532
|
+
const nodeId = node.id;
|
|
533
|
+
return nodeId.type === "Identifier" && nodeId.name === declName;
|
|
534
|
+
});
|
|
535
|
+
if (varPath) extractHookFromDeclarator(decl, varPath);
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
return results.map((result) => ({
|
|
541
|
+
graph: result.nodeCollection.map(result.graph),
|
|
542
|
+
nodesUsedInReturn: result.nodesUsedInReturn,
|
|
543
|
+
hookName: result.hookName
|
|
544
|
+
}));
|
|
545
|
+
}
|
|
546
|
+
|
|
145
547
|
//#endregion
|
|
146
548
|
//#region src/analyze/setupScript.ts
|
|
147
549
|
const traverse$3 = __babel_traverse.default.default?.default || __babel_traverse.default.default || __babel_traverse.default;
|
|
@@ -1802,7 +2204,6 @@ function buildWeightedGraph(graph, options = {}) {
|
|
|
1802
2204
|
const { semanticWeight = 1, similarityThreshold = .3 } = options;
|
|
1803
2205
|
const weighted = /* @__PURE__ */ new Map();
|
|
1804
2206
|
const allNodes = /* @__PURE__ */ new Set();
|
|
1805
|
-
const connectedPairs = /* @__PURE__ */ new Set();
|
|
1806
2207
|
for (const [node, edges] of graph) {
|
|
1807
2208
|
allNodes.add(node);
|
|
1808
2209
|
for (const edge of edges) allNodes.add(edge.node);
|
|
@@ -1814,8 +2215,6 @@ function buildWeightedGraph(graph, options = {}) {
|
|
|
1814
2215
|
weighted.get(node).set(edge.node, Math.max(currentWeight, structuralWeight));
|
|
1815
2216
|
const reverseWeight = weighted.get(edge.node).get(node) || 0;
|
|
1816
2217
|
weighted.get(edge.node).set(node, Math.max(reverseWeight, structuralWeight));
|
|
1817
|
-
const pairKey = [node.label, edge.node.label].sort().join("|");
|
|
1818
|
-
connectedPairs.add(pairKey);
|
|
1819
2218
|
}
|
|
1820
2219
|
if (semanticWeight > 0) {
|
|
1821
2220
|
const nodeWordsCache = /* @__PURE__ */ new Map();
|
|
@@ -1842,14 +2241,11 @@ function buildWeightedGraph(graph, options = {}) {
|
|
|
1842
2241
|
const wordsB = nodeWordsCache.get(nodeB);
|
|
1843
2242
|
const similarity = calculateSemanticSimilarityCached(nodeA.label, nodeB.label, wordsA, wordsB);
|
|
1844
2243
|
if (similarity > similarityThreshold) {
|
|
1845
|
-
const isConnected = connectedPairs.has(comparedKey);
|
|
1846
2244
|
const semanticEdgeWeight = similarity * semanticWeight;
|
|
1847
|
-
const currentAB = weighted.get(nodeA).get(nodeB)
|
|
1848
|
-
|
|
1849
|
-
weighted.get(
|
|
1850
|
-
|
|
1851
|
-
const newWeightBA = isConnected ? Math.max(currentBA, semanticEdgeWeight) : currentBA + semanticEdgeWeight;
|
|
1852
|
-
weighted.get(nodeB).set(nodeA, Math.min(newWeightBA, 2));
|
|
2245
|
+
const currentAB = weighted.get(nodeA).get(nodeB);
|
|
2246
|
+
if (typeof currentAB === "number") weighted.get(nodeA).set(nodeB, Math.min(Math.max(currentAB, semanticEdgeWeight), 2));
|
|
2247
|
+
const currentBA = weighted.get(nodeB).get(nodeA);
|
|
2248
|
+
if (typeof currentBA === "number") weighted.get(nodeB).set(nodeA, Math.min(Math.max(currentBA, semanticEdgeWeight), 2));
|
|
1853
2249
|
}
|
|
1854
2250
|
}
|
|
1855
2251
|
}
|
|
@@ -2333,7 +2729,7 @@ function filterNodeUserd(used) {
|
|
|
2333
2729
|
const usedArray = Array.from(used || []);
|
|
2334
2730
|
return new Set(usedArray.filter((u) => !["Assignment Expression", "Call Expression"].includes(u)));
|
|
2335
2731
|
}
|
|
2336
|
-
function getVisData(graph, nodesUsedInTemplate, nodesUsedInStyle = /* @__PURE__ */ new Set()) {
|
|
2732
|
+
function getVisData(graph, nodesUsedInTemplate, nodesUsedInStyle = /* @__PURE__ */ new Set(), usedLabel) {
|
|
2337
2733
|
const usedNodes = new Set([...nodesUsedInTemplate, ...nodesUsedInStyle]);
|
|
2338
2734
|
const nodes = [];
|
|
2339
2735
|
const edges = [];
|
|
@@ -2356,7 +2752,7 @@ function getVisData(graph, nodesUsedInTemplate, nodesUsedInStyle = /* @__PURE__
|
|
|
2356
2752
|
shape: node.type === "var" ? "dot" : "diamond",
|
|
2357
2753
|
group: usedNodes.has(node.label) || node.info?.used?.size ? "used" : "normal",
|
|
2358
2754
|
size: 20 + 1.6 ** (inDegree * .75 + outDegree * .25),
|
|
2359
|
-
title: `${filterNodeUserd(node.info?.used).size ? `used by ${Array.from(filterNodeUserd(node.info?.used))?.map((i) => `\`${i}\``).join(",")}\n\n` : ""}${usedNodes.has(node.label) ? `used in ${[nodesUsedInStyle.has(node.label) ? "style" : "", nodesUsedInTemplate.has(node.label) ? "template" : ""].filter(Boolean).join(" and ")}\n\n` : ""}${node.info?.comment || ""}`.trim() || void 0,
|
|
2755
|
+
title: `${filterNodeUserd(node.info?.used).size ? `used by ${Array.from(filterNodeUserd(node.info?.used))?.map((i) => `\`${i}\``).join(",")}\n\n` : ""}${usedNodes.has(node.label) ? `used in ${[nodesUsedInStyle.has(node.label) ? "style" : "", nodesUsedInTemplate.has(node.label) ? usedLabel || "template" : ""].filter(Boolean).join(" and ")}\n\n` : ""}${node.info?.comment || ""}`.trim() || void 0,
|
|
2360
2756
|
info: node.info
|
|
2361
2757
|
});
|
|
2362
2758
|
});
|
|
@@ -2381,6 +2777,7 @@ function getVisData(graph, nodesUsedInTemplate, nodesUsedInStyle = /* @__PURE__
|
|
|
2381
2777
|
|
|
2382
2778
|
//#endregion
|
|
2383
2779
|
exports.SuggestionType = SuggestionType;
|
|
2780
|
+
exports.analyzeHook = analyzeHook;
|
|
2384
2781
|
exports.analyzeOptions = analyze;
|
|
2385
2782
|
exports.analyzeSetupScript = analyze$1;
|
|
2386
2783
|
exports.analyzeStyle = analyze$2;
|