Skip to content

Commit fbb6f18

Browse files
committed
fix: handle interface with factory
1 parent e84d557 commit fbb6f18

6 files changed

Lines changed: 96 additions & 9 deletions

File tree

.changeset/rude-beds-argue.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@softnetics/what-the-dep": minor
3+
---
4+
5+
Reduce bundle size and bug fixes

src/walk/1-create-container.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { DependencyGraph } from "./graph";
33
import { globalTypeChecker, globalContext } from ".";
44
import { listDependenciesOfClass } from "./2-list-dependency";
55
import { hashSymbol, isWhatTheDepMethod } from "./utils";
6-
import { handleGet } from "./3-modify-get";
6+
import { getFactoryDependencies, handleGet } from "./3-modify-get";
77
import { createContextFromGraph } from "./4-create-context";
88

99
type ContainerRegisterMethod = "register" | "registerSingleton";
@@ -89,7 +89,7 @@ export const handleContainer = (
8989
if (registerMethod === "get") {
9090
// case 2 of get
9191
handleGet(node, transformList);
92-
return node;
92+
return ts.visitEachChild(node, visitor, globalContext);
9393
}
9494

9595
if (!isContainerRegisterMethod(registerMethod)) {
@@ -116,10 +116,18 @@ export const handleContainer = (
116116
`Could not find symbol of ${identifier.getText()}`
117117
);
118118
}
119-
const dependencies = listDependenciesOfClass(
120-
OriginalClassSymbol,
121-
identifier
122-
);
119+
120+
let dependencies: string[] = [];
121+
122+
if (factoryNode) {
123+
// dont care a class dependency and check a get of a factory
124+
dependencies = getFactoryDependencies(factoryNode);
125+
} else {
126+
dependencies = listDependenciesOfClass(
127+
OriginalClassSymbol,
128+
identifier
129+
);
130+
}
123131

124132
const graphRegisterMethod =
125133
registerMethod === "register" ? "transient" : "singleton";

src/walk/3-modify-get.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import ts from "typescript";
22
import { DependencyGraph } from "./graph";
3-
import { globalTypeChecker } from ".";
3+
import { globalTypeChecker, globalContext } from ".";
44
import { hashSymbol } from "./utils";
55

66
export const handleGet = (
@@ -21,3 +21,33 @@ export const handleGet = (
2121
);
2222
transformList.set(node, newNode);
2323
};
24+
25+
export const getFactoryDependencies = (factory: ts.Expression) => {
26+
const dependencies: string[] = [];
27+
28+
let getSymbol: ts.Symbol | undefined;
29+
const visitor = (node: ts.Node): ts.Node => {
30+
if (!getSymbol && ts.isParameter(node)) {
31+
getSymbol = globalTypeChecker.getTypeAtLocation(node).getSymbol();
32+
}
33+
if (ts.isCallExpression(node)) {
34+
if (ts.isIdentifier(node.expression)) {
35+
const symbol = globalTypeChecker
36+
.getTypeAtLocation(node.expression)
37+
.getSymbol();
38+
if (symbol && symbol === getSymbol) {
39+
const classOrInterface = node.typeArguments![0];
40+
const hash = hashSymbol(
41+
globalTypeChecker.getTypeAtLocation(classOrInterface).getSymbol()!
42+
);
43+
dependencies.push(hash);
44+
}
45+
}
46+
}
47+
return ts.visitEachChild(node, visitor, globalContext);
48+
};
49+
50+
ts.visitNode(factory, visitor);
51+
52+
return dependencies;
53+
};

src/walk/4-create-context.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
} from "./source-templates";
1313

1414
export const createContextFromGraph = (graph: DependencyGraph) => {
15+
graph.print();
1516
const properties = graph.topologicalSort().map((hash) => {
1617
const resolved = graph.resolve(hash);
1718
if (!resolved) {

src/walk/index.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ export const transformerFactory = (
1515
return (context) => (rootNode) => {
1616
globalContext = context;
1717
const visitor = (node: ts.Node): ts.Node => {
18-
//1. find `const ModuleName = new Container();`
18+
// Find container initialization
19+
// 1. const container = new Container();
20+
// 2. const container = (new Container()).register();
21+
22+
// case 1
1923
if (
2024
ts.isVariableStatement(node) &&
2125
node.declarationList.declarations.length === 1
@@ -58,6 +62,45 @@ export const transformerFactory = (
5862
}
5963
}
6064
}
65+
66+
// case 2
67+
if (
68+
ts.isCallExpression(node) &&
69+
ts.isPropertyAccessExpression(node.expression)
70+
) {
71+
// dig into expression to find the identifier
72+
let expressionChildren = node.expression.getChildren();
73+
while (!ts.isIdentifier(expressionChildren[0])) {
74+
if (ts.isParenthesizedExpression(expressionChildren[0])) {
75+
// (new Container()).register()
76+
if (ts.isNewExpression(expressionChildren[0].expression)) {
77+
const containerNode =
78+
expressionChildren[0].expression.getChildren()[1];
79+
handleContainer(
80+
rootNode,
81+
containerNode,
82+
globalTypeChecker.getSymbolAtLocation(containerNode)!,
83+
program,
84+
transformList
85+
);
86+
}
87+
}
88+
if (ts.isNewExpression(expressionChildren[0])) {
89+
const containerNode = expressionChildren[0].getChildren()[1];
90+
handleContainer(
91+
rootNode,
92+
containerNode,
93+
globalTypeChecker.getSymbolAtLocation(containerNode)!,
94+
program,
95+
transformList
96+
);
97+
}
98+
expressionChildren = expressionChildren[0].getChildren();
99+
if (expressionChildren.length <= 2) {
100+
break;
101+
}
102+
}
103+
}
61104
return ts.visitEachChild(node, visitor, context);
62105
};
63106

tsup.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { defineConfig } from "tsup";
22

33
export default defineConfig({
4-
entry: ["src/index.ts", "src/create.ts"],
4+
entry: ["src/plugin.ts", "src/container.ts"],
55
splitting: true,
66
minify: true,
77
clean: true,

0 commit comments

Comments
 (0)