vue-hook-optimizer 0.0.58 → 0.0.60

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js CHANGED
@@ -358,6 +358,108 @@ function processSetup(ast, parentScope, parentPath, _spread, _lineOffset = 0) {
358
358
  }
359
359
  }
360
360
  }, parentScope, parentPath);
361
+ function traverseHooks(node, patentScope) {
362
+ if (node.type === "ExpressionStatement" && node.expression.type === "CallExpression" && node.expression.callee.type === "Identifier" || node.type === "CallExpression" && node.callee.type === "Identifier") {
363
+ const hookName = (() => {
364
+ if (node.type === "ExpressionStatement" && node.expression.type === "CallExpression" && node.expression.callee.type === "Identifier") {
365
+ return node.expression.callee.name;
366
+ }
367
+ if (node.type === "CallExpression" && node.callee.type === "Identifier") {
368
+ return node.callee.name;
369
+ }
370
+ })() || "";
371
+ if (!hookName) {
372
+ return;
373
+ }
374
+ const hookBinding = patentScope.getBinding(hookName);
375
+ if (!(hookBinding === void 0 || hookBinding?.scope.block.type === "Program" || parentScope === hookBinding?.scope)) {
376
+ return;
377
+ }
378
+ const expression = node.type === "ExpressionStatement" ? node.expression : node;
379
+ const watchArgs = /* @__PURE__ */ new Set();
380
+ if (hookName === "provide") {
381
+ traverse2(expression, {
382
+ 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.block.type === "Program" || parentScope === binding?.scope)) {
385
+ const _node = nodeCollection.getNode(path1.node.name);
386
+ if (_node?.info?.used) {
387
+ _node?.info?.used?.add(hookName);
388
+ } else if (_node) {
389
+ _node.info = {
390
+ ..._node?.info,
391
+ used: /* @__PURE__ */ new Set([hookName])
392
+ };
393
+ }
394
+ }
395
+ }
396
+ }, patentScope, node);
397
+ } else if (hookName === "watch") {
398
+ if (expression.arguments[0].type === "Identifier") {
399
+ const binding = patentScope.getBinding(expression.arguments[0].name);
400
+ if (graph.nodes.has(expression.arguments[0].name) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
401
+ watchArgs.add(expression.arguments[0]);
402
+ }
403
+ } else {
404
+ traverse2(expression.arguments[0], {
405
+ Identifier(path1) {
406
+ const binding = path1.scope.getBinding(path1.node.name);
407
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
408
+ watchArgs.add(path1.node);
409
+ }
410
+ }
411
+ }, patentScope, node);
412
+ }
413
+ } else if (hookName === "useEffect" && expression.arguments[1].type === "ArrayExpression") {
414
+ traverse2(expression.arguments[1], {
415
+ Identifier(path1) {
416
+ const binding = path1.scope.getBinding(path1.node.name);
417
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
418
+ watchArgs.add(path1.node);
419
+ }
420
+ }
421
+ }, patentScope, node);
422
+ }
423
+ expression.arguments.forEach((argNode, index) => {
424
+ if (hookName === "watch" && index === 0 && argNode.type === "Identifier") {
425
+ const _node = nodeCollection.getNode(argNode.name);
426
+ if (_node?.info?.used) {
427
+ _node?.info?.used?.add(hookName);
428
+ } else if (_node) {
429
+ _node.info = {
430
+ ..._node?.info,
431
+ used: /* @__PURE__ */ new Set([hookName])
432
+ };
433
+ }
434
+ return;
435
+ }
436
+ traverse2(argNode, {
437
+ Identifier(path1) {
438
+ const binding = path1.scope.getBinding(path1.node.name);
439
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
440
+ if (["watch", "useEffect"].includes(hookName) && watchArgs.size > 0) {
441
+ const watchArgsNames = Array.from(watchArgs).map((arg) => arg.name);
442
+ watchArgs.forEach((watchArg) => {
443
+ if (!watchArgsNames.includes(path1.node.name)) {
444
+ graph.edges.get(watchArg.name)?.add(path1.node.name);
445
+ }
446
+ });
447
+ }
448
+ const _node = nodeCollection.getNode(path1.node.name);
449
+ if (_node?.info?.used) {
450
+ _node?.info?.used?.add(hookName);
451
+ } else if (_node) {
452
+ _node.info = {
453
+ ..._node?.info,
454
+ used: /* @__PURE__ */ new Set([hookName])
455
+ };
456
+ }
457
+ }
458
+ }
459
+ }, patentScope, node);
460
+ });
461
+ }
462
+ }
361
463
  traverse2(ast, {
362
464
  FunctionDeclaration(path) {
363
465
  const name = path.node.id?.name;
@@ -435,6 +537,9 @@ function processSetup(ast, parentScope, parentPath, _spread, _lineOffset = 0) {
435
537
  "ArrowFunctionExpression",
436
538
  "FunctionDeclaration"
437
539
  ].includes(path.node.init.type) && path.node.id.type === "Identifier") {
540
+ if (path.node.init.type === "CallExpression" && path.node.init.callee.type === "Identifier" && ["watch", "watchEffect"].includes(path.node.init.callee.name)) {
541
+ traverseHooks(path.node.init, path.scope);
542
+ }
438
543
  const name = path.node.id?.name;
439
544
  if (name && graph.nodes.has(name)) {
440
545
  traverse2(path.node.init, {
@@ -511,94 +616,35 @@ function processSetup(ast, parentScope, parentPath, _spread, _lineOffset = 0) {
511
616
  }
512
617
  },
513
618
  ExpressionStatement(path) {
514
- if (path.node.expression.type === "CallExpression" && path.node.expression.callee.type === "Identifier") {
515
- const hookName = path.node.expression.callee.name;
516
- const hookBinding = path.scope.getBinding(hookName);
517
- if (!(hookBinding === void 0 || hookBinding?.scope.block.type === "Program" || parentScope === hookBinding?.scope)) {
518
- return;
519
- }
520
- const watchArgs = /* @__PURE__ */ new Set();
521
- if (hookName === "provide") {
522
- traverse2(path.node.expression, {
523
- Identifier(path1) {
524
- const binding = path1.scope.getBinding(path1.node.name);
525
- if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
526
- const _node = nodeCollection.getNode(path1.node.name);
527
- if (_node?.info?.used) {
528
- _node?.info?.used?.add(hookName);
529
- } else if (_node) {
530
- _node.info = {
531
- ..._node?.info,
532
- used: /* @__PURE__ */ new Set([hookName])
533
- };
534
- }
535
- }
536
- }
537
- }, path.scope, path);
538
- } else if (hookName === "watch") {
539
- if (path.node.expression.arguments[0].type === "Identifier") {
540
- const binding = path.scope.getBinding(path.node.expression.arguments[0].name);
541
- if (graph.nodes.has(path.node.expression.arguments[0].name) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
542
- watchArgs.add(path.node.expression.arguments[0]);
543
- }
544
- } else {
545
- traverse2(path.node.expression.arguments[0], {
546
- Identifier(path1) {
547
- const binding = path1.scope.getBinding(path1.node.name);
548
- if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
549
- watchArgs.add(path1.node);
550
- }
551
- }
552
- }, path.scope, path);
619
+ if (path.type === "ExpressionStatement" && path.node.expression.type === "CallExpression" && path.node.expression.callee.type === "Identifier") {
620
+ const name = path.node.expression.callee.name;
621
+ if (graph.nodes.has(name) && path.scope.block.type === "Program") {
622
+ const _node = nodeCollection.getNode(name);
623
+ if (_node?.info?.used) {
624
+ _node?.info?.used?.add("Call Expression");
625
+ } else if (_node) {
626
+ _node.info = {
627
+ ..._node?.info,
628
+ used: /* @__PURE__ */ new Set(["Call Expression"])
629
+ };
553
630
  }
554
- } else if (hookName === "useEffect" && path.node.expression.arguments[1].type === "ArrayExpression") {
555
- traverse2(path.node.expression.arguments[1], {
556
- Identifier(path1) {
557
- const binding = path1.scope.getBinding(path1.node.name);
558
- if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
559
- watchArgs.add(path1.node);
560
- }
561
- }
562
- }, path.scope, path);
631
+ } else {
632
+ traverseHooks(path.node.expression, path.scope);
633
+ }
634
+ }
635
+ if (path.type === "ExpressionStatement" && path.node.expression.type === "AssignmentExpression" && path.node.expression.right.type === "CallExpression" && path.node.expression.right.callee.type === "Identifier") {
636
+ traverseHooks(path.node.expression.right, path.scope);
637
+ }
638
+ if (path.type === "ExpressionStatement" && path.node.expression.type === "AssignmentExpression" && path.node.expression.left.type === "Identifier" && graph.nodes.has(path.node.expression.left.name) && path.scope.block.type === "Program") {
639
+ const _node = nodeCollection.getNode(path.node.expression.left.name);
640
+ if (_node?.info?.used) {
641
+ _node?.info?.used?.add("Assignment Expression");
642
+ } else if (_node) {
643
+ _node.info = {
644
+ ..._node?.info,
645
+ used: /* @__PURE__ */ new Set(["Assignment Expression"])
646
+ };
563
647
  }
564
- path.node.expression.arguments.forEach((argNode, index) => {
565
- if (hookName === "watch" && index === 0 && argNode.type === "Identifier") {
566
- const _node = nodeCollection.getNode(argNode.name);
567
- if (_node?.info?.used) {
568
- _node?.info?.used?.add(hookName);
569
- } else if (_node) {
570
- _node.info = {
571
- ..._node?.info,
572
- used: /* @__PURE__ */ new Set([hookName])
573
- };
574
- }
575
- return;
576
- }
577
- traverse2(argNode, {
578
- Identifier(path1) {
579
- const binding = path1.scope.getBinding(path1.node.name);
580
- if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
581
- if (["watch", "useEffect"].includes(hookName) && watchArgs.size > 0) {
582
- const watchArgsNames = Array.from(watchArgs).map((arg) => arg.name);
583
- watchArgs.forEach((watchArg) => {
584
- if (!watchArgsNames.includes(path1.node.name)) {
585
- graph.edges.get(watchArg.name)?.add(path1.node.name);
586
- }
587
- });
588
- }
589
- const _node = nodeCollection.getNode(path1.node.name);
590
- if (_node?.info?.used) {
591
- _node?.info?.used?.add(hookName);
592
- } else if (_node) {
593
- _node.info = {
594
- ..._node?.info,
595
- used: /* @__PURE__ */ new Set([hookName])
596
- };
597
- }
598
- }
599
- }
600
- }, path.scope, path);
601
- });
602
648
  }
603
649
  }
604
650
  }, parentScope, parentPath);
@@ -2024,6 +2070,9 @@ function findLinearPaths(graph) {
2024
2070
  const visitedNodes = /* @__PURE__ */ new Set();
2025
2071
  const nodeInDegrees = /* @__PURE__ */ new Map();
2026
2072
  for (const [node, edges] of graph.entries()) {
2073
+ if (!nodeInDegrees.has(node)) {
2074
+ nodeInDegrees.set(node, 0);
2075
+ }
2027
2076
  for (const edge of edges) {
2028
2077
  const inDegree = nodeInDegrees.get(edge) || 0;
2029
2078
  nodeInDegrees.set(edge, inDegree + 1);
@@ -2201,11 +2250,16 @@ function gen(graph, nodesUsedInTemplate, nodesUsedInStyle = /* @__PURE__ */ new
2201
2250
  }
2202
2251
  const paths = findLinearPaths(g);
2203
2252
  paths.forEach((path) => {
2204
- suggestions.push({
2205
- type: "warning" /* warning */,
2206
- message: `Nodes [${path.length > 10 ? `${path.slice(0, 10).map((node) => node.label).join(",")}...(${path.length})` : path.map((node) => node.label).join(",")}] are have function chain calls, perhaps you can refactor it.`,
2207
- nodeInfo: path
2208
- });
2253
+ const firstUsedNodeIndex = path.findIndex((node) => usedNodes.has(node.label));
2254
+ const reverseLastNotUsedNodeIndex = path.slice().reverse().findIndex((node) => !usedNodes.has(node.label));
2255
+ const lastNotUsedNodeIndex = reverseLastNotUsedNodeIndex !== -1 ? path.length - 1 - reverseLastNotUsedNodeIndex : -1;
2256
+ if (firstUsedNodeIndex > -1 && firstUsedNodeIndex < lastNotUsedNodeIndex) {
2257
+ suggestions.push({
2258
+ type: "warning" /* warning */,
2259
+ message: `Nodes [${path.length > 10 ? `${path.slice(0, 10).map((node) => node.label).join(",")}...(${path.length})` : path.map((node) => node.label).join(",")}] are have function chain calls, perhaps you can refactor it.`,
2260
+ nodeInfo: path
2261
+ });
2262
+ }
2209
2263
  });
2210
2264
  if (g.size > 5) {
2211
2265
  const ap = findArticulationPoints(g);
@@ -2234,6 +2288,13 @@ function gen(graph, nodesUsedInTemplate, nodesUsedInStyle = /* @__PURE__ */ new
2234
2288
  }
2235
2289
 
2236
2290
  // src/vis.ts
2291
+ function filterNodeUserd(used) {
2292
+ const usedArray = Array.from(used || []);
2293
+ return new Set(usedArray.filter((u) => ![
2294
+ "Assignment Expression",
2295
+ "Call Expression"
2296
+ ].includes(u)));
2297
+ }
2237
2298
  function getVisData(graph, nodesUsedInTemplate, nodesUsedInStyle = /* @__PURE__ */ new Set()) {
2238
2299
  const usedNodes = /* @__PURE__ */ new Set([...nodesUsedInTemplate, ...nodesUsedInStyle]);
2239
2300
  const nodes = [];
@@ -2244,7 +2305,7 @@ function getVisData(graph, nodesUsedInTemplate, nodesUsedInStyle = /* @__PURE__
2244
2305
  label: node.label,
2245
2306
  shape: node.type === "var" ? "dot" : "diamond",
2246
2307
  group: usedNodes.has(node.label) || node.info?.used?.size ? "used" : "normal",
2247
- title: `${node.info?.used?.size ? `used by ${Array.from(node.info?.used || [])?.map((i) => `\`${i}\``).join(",")}
2308
+ title: `${filterNodeUserd(node.info?.used).size ? `used by ${Array.from(filterNodeUserd(node.info?.used))?.map((i) => `\`${i}\``).join(",")}
2248
2309
 
2249
2310
  ` : ""}${usedNodes.has(node.label) ? `used in ${[
2250
2311
  nodesUsedInStyle.has(node.label) ? "style" : "",