semantic-complexity 0.0.1-cedf2072

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.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ast/index.d.ts +2 -0
  3. package/dist/ast/index.d.ts.map +1 -0
  4. package/dist/ast/index.js +2 -0
  5. package/dist/ast/index.js.map +1 -0
  6. package/dist/ast/parser.d.ts +27 -0
  7. package/dist/ast/parser.d.ts.map +1 -0
  8. package/dist/ast/parser.js +273 -0
  9. package/dist/ast/parser.js.map +1 -0
  10. package/dist/compare.d.ts +31 -0
  11. package/dist/compare.d.ts.map +1 -0
  12. package/dist/compare.js +354 -0
  13. package/dist/compare.js.map +1 -0
  14. package/dist/context/index.d.ts +41 -0
  15. package/dist/context/index.d.ts.map +1 -0
  16. package/dist/context/index.js +253 -0
  17. package/dist/context/index.js.map +1 -0
  18. package/dist/graph/call.d.ts +63 -0
  19. package/dist/graph/call.d.ts.map +1 -0
  20. package/dist/graph/call.js +240 -0
  21. package/dist/graph/call.js.map +1 -0
  22. package/dist/graph/dependency.d.ts +52 -0
  23. package/dist/graph/dependency.d.ts.map +1 -0
  24. package/dist/graph/dependency.js +296 -0
  25. package/dist/graph/dependency.js.map +1 -0
  26. package/dist/graph/index.d.ts +3 -0
  27. package/dist/graph/index.d.ts.map +1 -0
  28. package/dist/graph/index.js +3 -0
  29. package/dist/graph/index.js.map +1 -0
  30. package/dist/index.d.ts +21 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +34 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/metrics/cognitive.d.ts +42 -0
  35. package/dist/metrics/cognitive.d.ts.map +1 -0
  36. package/dist/metrics/cognitive.js +204 -0
  37. package/dist/metrics/cognitive.js.map +1 -0
  38. package/dist/metrics/cyclomatic.d.ts +31 -0
  39. package/dist/metrics/cyclomatic.d.ts.map +1 -0
  40. package/dist/metrics/cyclomatic.js +121 -0
  41. package/dist/metrics/cyclomatic.js.map +1 -0
  42. package/dist/metrics/dimensional.d.ts +32 -0
  43. package/dist/metrics/dimensional.d.ts.map +1 -0
  44. package/dist/metrics/dimensional.js +560 -0
  45. package/dist/metrics/dimensional.js.map +1 -0
  46. package/dist/metrics/index.d.ts +26 -0
  47. package/dist/metrics/index.d.ts.map +1 -0
  48. package/dist/metrics/index.js +120 -0
  49. package/dist/metrics/index.js.map +1 -0
  50. package/dist/types.d.ts +341 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +22 -0
  53. package/dist/types.js.map +1 -0
  54. package/package.json +71 -0
@@ -0,0 +1,253 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { parseSourceFile } from '../ast/parser.js';
4
+ import { analyzeFile } from '../metrics/index.js';
5
+ import { DependencyGraph } from '../graph/dependency.js';
6
+ import { CallGraph } from '../graph/call.js';
7
+ /**
8
+ * MCP용 분석 컨텍스트 수집기
9
+ *
10
+ * LLM이 인지복잡도를 정확히 판단할 수 있도록
11
+ * 코드와 관련된 모든 컨텍스트를 수집합니다.
12
+ */
13
+ export class ContextCollector {
14
+ options;
15
+ projectRoot;
16
+ dependencyGraph;
17
+ projectInfo;
18
+ constructor(projectRoot, options) {
19
+ this.projectRoot = path.resolve(projectRoot);
20
+ this.options = { ...getDefaultOptions(), ...options };
21
+ this.dependencyGraph = new DependencyGraph(this.projectRoot);
22
+ this.projectInfo = this.detectProjectInfo();
23
+ }
24
+ /**
25
+ * 파일에 대한 전체 분석 컨텍스트 수집
26
+ */
27
+ async collectContext(filePath) {
28
+ const absPath = path.resolve(filePath);
29
+ const content = fs.readFileSync(absPath, 'utf-8');
30
+ const sourceFile = parseSourceFile(absPath, content);
31
+ // 기본 분석
32
+ const fileResult = analyzeFile(sourceFile);
33
+ // 의존성 분석
34
+ const depNode = this.dependencyGraph.analyzeFile(absPath, content);
35
+ // 호출 그래프
36
+ const callGraph = new CallGraph();
37
+ callGraph.analyzeSourceFile(sourceFile);
38
+ // 관련 파일 분석
39
+ const relatedFiles = await this.analyzeRelatedFiles(absPath, this.options.contextDepth);
40
+ return {
41
+ file: fileResult,
42
+ dependencies: depNode,
43
+ callGraph: callGraph.getAllNodes(),
44
+ relatedFiles,
45
+ projectInfo: this.projectInfo,
46
+ };
47
+ }
48
+ /**
49
+ * MCP 응답용 프롬프트 생성
50
+ *
51
+ * LLM이 인지복잡도를 판단할 수 있도록
52
+ * 구조화된 프롬프트를 생성합니다.
53
+ */
54
+ generatePrompt(context, functionName) {
55
+ const lines = [];
56
+ // 헤더
57
+ lines.push('# 코드 복잡도 분석 요청');
58
+ lines.push('');
59
+ // 프로젝트 정보
60
+ if (context.projectInfo) {
61
+ lines.push('## 프로젝트 정보');
62
+ lines.push(`- 이름: ${context.projectInfo.name}`);
63
+ lines.push(`- 언어: ${context.projectInfo.language}`);
64
+ if (context.projectInfo.framework) {
65
+ lines.push(`- 프레임워크: ${context.projectInfo.framework}`);
66
+ }
67
+ lines.push('');
68
+ }
69
+ // 파일 정보
70
+ lines.push('## 분석 대상 파일');
71
+ lines.push(`경로: ${context.file.filePath}`);
72
+ lines.push('');
73
+ // 기계적 메트릭
74
+ lines.push('## 기계적 복잡도 (참고용)');
75
+ const targetFunctions = functionName
76
+ ? context.file.functions.filter((f) => f.function.name === functionName)
77
+ : context.file.functions;
78
+ for (const func of targetFunctions) {
79
+ lines.push(`### ${func.function.name}`);
80
+ lines.push(`- 위치: ${func.function.location.startLine}행`);
81
+ lines.push(`- 순환복잡도: ${func.cyclomatic}`);
82
+ lines.push(`- 인지복잡도 (SonarSource): ${func.cognitive}`);
83
+ lines.push('');
84
+ if (func.details.length > 0) {
85
+ lines.push('상세:');
86
+ for (const detail of func.details.slice(0, 10)) {
87
+ lines.push(` - ${detail.description} (${detail.location.startLine}행)`);
88
+ }
89
+ if (func.details.length > 10) {
90
+ lines.push(` - ... 외 ${func.details.length - 10}개`);
91
+ }
92
+ lines.push('');
93
+ }
94
+ }
95
+ // 의존성 정보
96
+ lines.push('## 의존성 관계');
97
+ lines.push(`이 파일이 import하는 모듈: ${context.dependencies.imports.length}개`);
98
+ for (const imp of context.dependencies.imports.slice(0, 5)) {
99
+ lines.push(` - ${path.basename(imp)}`);
100
+ }
101
+ lines.push(`이 파일을 import하는 모듈: ${context.dependencies.importedBy.length}개`);
102
+ for (const dep of context.dependencies.importedBy.slice(0, 5)) {
103
+ lines.push(` - ${path.basename(dep)}`);
104
+ }
105
+ lines.push('');
106
+ // 호출 관계
107
+ if (context.callGraph.length > 0) {
108
+ lines.push('## 함수 호출 관계');
109
+ for (const node of context.callGraph.slice(0, 5)) {
110
+ const callCount = node.calls.length;
111
+ const calledByCount = node.calledBy.length;
112
+ lines.push(`- ${node.function.name}: 호출 ${callCount}개, 호출됨 ${calledByCount}개`);
113
+ }
114
+ lines.push('');
115
+ }
116
+ // 분석 요청
117
+ lines.push('## 분석 요청');
118
+ lines.push('위 정보를 바탕으로 다음을 분석해주세요:');
119
+ lines.push('');
120
+ lines.push('1. **실제 인지복잡도 평가**');
121
+ lines.push(' - 알고리즘 패턴 인식 (매핑, 변환, 상태 머신 등)');
122
+ lines.push(' - 도메인 로직 난이도');
123
+ lines.push(' - 추상화 수준 적절성');
124
+ lines.push('');
125
+ lines.push('2. **리팩토링 제안** (필요시)');
126
+ lines.push(' - 함수 분리 가능 지점');
127
+ lines.push(' - 패턴 적용 가능성');
128
+ lines.push(' - 테스트 용이성 개선 방안');
129
+ lines.push('');
130
+ lines.push('3. **복잡도 점수 (1-100)**');
131
+ lines.push(' - 기계적 메트릭과 실제 복잡도의 차이 설명');
132
+ return lines.join('\n');
133
+ }
134
+ /**
135
+ * 관련 파일 분석
136
+ */
137
+ async analyzeRelatedFiles(filePath, depth) {
138
+ const results = [];
139
+ const depTree = this.dependencyGraph.buildDependencyTree(filePath, depth);
140
+ for (const node of depTree) {
141
+ if (node.filePath === filePath)
142
+ continue;
143
+ try {
144
+ const content = fs.readFileSync(node.filePath, 'utf-8');
145
+ const sourceFile = parseSourceFile(node.filePath, content);
146
+ const result = analyzeFile(sourceFile);
147
+ results.push(result);
148
+ }
149
+ catch {
150
+ // 파일 읽기 실패 무시
151
+ }
152
+ }
153
+ return results;
154
+ }
155
+ /**
156
+ * 프로젝트 정보 감지
157
+ */
158
+ detectProjectInfo() {
159
+ try {
160
+ const packageJsonPath = path.join(this.projectRoot, 'package.json');
161
+ if (!fs.existsSync(packageJsonPath))
162
+ return undefined;
163
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
164
+ // 패키지 매니저 감지
165
+ let packageManager = 'npm';
166
+ if (fs.existsSync(path.join(this.projectRoot, 'pnpm-lock.yaml'))) {
167
+ packageManager = 'pnpm';
168
+ }
169
+ else if (fs.existsSync(path.join(this.projectRoot, 'yarn.lock'))) {
170
+ packageManager = 'yarn';
171
+ }
172
+ else if (fs.existsSync(path.join(this.projectRoot, 'bun.lockb'))) {
173
+ packageManager = 'bun';
174
+ }
175
+ // 프레임워크 감지
176
+ const deps = {
177
+ ...packageJson.dependencies,
178
+ ...packageJson.devDependencies,
179
+ };
180
+ let framework;
181
+ if (deps['next'])
182
+ framework = 'Next.js';
183
+ else if (deps['nuxt'])
184
+ framework = 'Nuxt';
185
+ else if (deps['@angular/core'])
186
+ framework = 'Angular';
187
+ else if (deps['vue'])
188
+ framework = 'Vue';
189
+ else if (deps['react'])
190
+ framework = 'React';
191
+ else if (deps['svelte'])
192
+ framework = 'Svelte';
193
+ else if (deps['express'])
194
+ framework = 'Express';
195
+ else if (deps['fastify'])
196
+ framework = 'Fastify';
197
+ else if (deps['nestjs'])
198
+ framework = 'NestJS';
199
+ // 언어 감지
200
+ const hasTsConfig = fs.existsSync(path.join(this.projectRoot, 'tsconfig.json'));
201
+ const language = hasTsConfig
202
+ ? 'typescript'
203
+ : 'javascript';
204
+ return {
205
+ name: packageJson.name || path.basename(this.projectRoot),
206
+ root: this.projectRoot,
207
+ packageManager,
208
+ framework,
209
+ language,
210
+ };
211
+ }
212
+ catch {
213
+ return undefined;
214
+ }
215
+ }
216
+ }
217
+ /**
218
+ * 기본 옵션 반환
219
+ */
220
+ function getDefaultOptions() {
221
+ return {
222
+ cyclomaticThreshold: 10,
223
+ cognitiveThreshold: 15,
224
+ includeTypes: true,
225
+ excludeTests: true,
226
+ excludePatterns: ['node_modules', 'dist', 'build', '.git'],
227
+ contextDepth: 2,
228
+ };
229
+ }
230
+ /**
231
+ * 단일 파일 빠른 분석 (MCP 도구용)
232
+ */
233
+ export async function quickAnalyze(filePath, functionName) {
234
+ const projectRoot = findProjectRoot(filePath);
235
+ const collector = new ContextCollector(projectRoot);
236
+ const context = await collector.collectContext(filePath);
237
+ const prompt = collector.generatePrompt(context, functionName);
238
+ return { context, prompt };
239
+ }
240
+ /**
241
+ * 프로젝트 루트 찾기
242
+ */
243
+ function findProjectRoot(startPath) {
244
+ let current = path.dirname(path.resolve(startPath));
245
+ while (current !== path.dirname(current)) {
246
+ if (fs.existsSync(path.join(current, 'package.json'))) {
247
+ return current;
248
+ }
249
+ current = path.dirname(current);
250
+ }
251
+ return path.dirname(startPath);
252
+ }
253
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAOlC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,OAAO,gBAAgB;IACnB,OAAO,CAAkB;IACzB,WAAW,CAAS;IACpB,eAAe,CAAkB;IACjC,WAAW,CAAe;IAElC,YAAY,WAAmB,EAAE,OAAkC;QACjE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,iBAAiB,EAAE,EAAE,GAAG,OAAO,EAAE,CAAC;QACtD,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC7D,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,QAAgB;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAErD,QAAQ;QACR,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;QAE3C,SAAS;QACT,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAEnE,SAAS;QACT,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;QAClC,SAAS,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAExC,WAAW;QACX,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,mBAAmB,CACjD,OAAO,EACP,IAAI,CAAC,OAAO,CAAC,YAAY,CAC1B,CAAC;QAEF,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,YAAY,EAAE,OAAO;YACrB,SAAS,EAAE,SAAS,CAAC,WAAW,EAAE;YAClC,YAAY;YACZ,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,cAAc,CAAC,OAAwB,EAAE,YAAqB;QAC5D,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,KAAK;QACL,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEf,UAAU;QACV,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;YAChD,KAAK,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;YACpD,IAAI,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;gBAClC,KAAK,CAAC,IAAI,CAAC,YAAY,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC;YAC1D,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;QAED,QAAQ;QACR,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEf,UAAU;QACV,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC/B,MAAM,eAAe,GAAG,YAAY;YAClC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,CAAC;YACxE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;QAE3B,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAC;YACzD,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,0BAA0B,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YACvD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEf,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAClB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;oBAC/C,KAAK,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,WAAW,KAAK,MAAM,CAAC,QAAQ,CAAC,SAAS,IAAI,CAAC,CAAC;gBAC1E,CAAC;gBACD,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;oBAC7B,KAAK,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC;gBACvD,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;QAED,SAAS;QACT,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,sBAAsB,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QACzE,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC3D,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,sBAAsB,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5E,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC9D,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEf,QAAQ;QACR,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC1B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBACjD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;gBACpC,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAC3C,KAAK,CAAC,IAAI,CACR,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,QAAQ,SAAS,UAAU,aAAa,GAAG,CACnE,CAAC;YACJ,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;QAED,QAAQ;QACR,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;QAChD,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAE1C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,mBAAmB,CAC/B,QAAgB,EAChB,KAAa;QAEb,MAAM,OAAO,GAAyB,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAE1E,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ;gBAAE,SAAS;YAEzC,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACxD,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAC3D,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;gBACvC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvB,CAAC;YAAC,MAAM,CAAC;gBACP,cAAc;YAChB,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACK,iBAAiB;QACvB,IAAI,CAAC;YACH,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;YACpE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC;gBAAE,OAAO,SAAS,CAAC;YAEtD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC5B,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAC1C,CAAC;YAEF,aAAa;YACb,IAAI,cAAc,GAAkC,KAAK,CAAC;YAC1D,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC;gBACjE,cAAc,GAAG,MAAM,CAAC;YAC1B,CAAC;iBAAM,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;gBACnE,cAAc,GAAG,MAAM,CAAC;YAC1B,CAAC;iBAAM,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;gBACnE,cAAc,GAAG,KAAK,CAAC;YACzB,CAAC;YAED,WAAW;YACX,MAAM,IAAI,GAAG;gBACX,GAAG,WAAW,CAAC,YAAY;gBAC3B,GAAG,WAAW,CAAC,eAAe;aAC/B,CAAC;YACF,IAAI,SAA6B,CAAC;YAClC,IAAI,IAAI,CAAC,MAAM,CAAC;gBAAE,SAAS,GAAG,SAAS,CAAC;iBACnC,IAAI,IAAI,CAAC,MAAM,CAAC;gBAAE,SAAS,GAAG,MAAM,CAAC;iBACrC,IAAI,IAAI,CAAC,eAAe,CAAC;gBAAE,SAAS,GAAG,SAAS,CAAC;iBACjD,IAAI,IAAI,CAAC,KAAK,CAAC;gBAAE,SAAS,GAAG,KAAK,CAAC;iBACnC,IAAI,IAAI,CAAC,OAAO,CAAC;gBAAE,SAAS,GAAG,OAAO,CAAC;iBACvC,IAAI,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS,GAAG,QAAQ,CAAC;iBACzC,IAAI,IAAI,CAAC,SAAS,CAAC;gBAAE,SAAS,GAAG,SAAS,CAAC;iBAC3C,IAAI,IAAI,CAAC,SAAS,CAAC;gBAAE,SAAS,GAAG,SAAS,CAAC;iBAC3C,IAAI,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS,GAAG,QAAQ,CAAC;YAE9C,QAAQ;YACR,MAAM,WAAW,GAAG,EAAE,CAAC,UAAU,CAC/B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,CAC7C,CAAC;YACF,MAAM,QAAQ,GAA4B,WAAW;gBACnD,CAAC,CAAC,YAAY;gBACd,CAAC,CAAC,YAAY,CAAC;YAEjB,OAAO;gBACL,IAAI,EAAE,WAAW,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;gBACzD,IAAI,EAAE,IAAI,CAAC,WAAW;gBACtB,cAAc;gBACd,SAAS;gBACT,QAAQ;aACT,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;CACF;AAED;;GAEG;AACH,SAAS,iBAAiB;IACxB,OAAO;QACL,mBAAmB,EAAE,EAAE;QACvB,kBAAkB,EAAE,EAAE;QACtB,YAAY,EAAE,IAAI;QAClB,YAAY,EAAE,IAAI;QAClB,eAAe,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC;QAC1D,YAAY,EAAE,CAAC;KAChB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,QAAgB,EAChB,YAAqB;IAErB,MAAM,WAAW,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,IAAI,gBAAgB,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,SAAS,CAAC,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAE/D,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,SAAiB;IACxC,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IAEpD,OAAO,OAAO,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACzC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;YACtD,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,63 @@
1
+ import ts from 'typescript';
2
+ import type { CallNode, CallEdge, FunctionInfo } from '../types.js';
3
+ /**
4
+ * 호출 그래프 빌더
5
+ */
6
+ export declare class CallGraph {
7
+ private nodes;
8
+ private functionMap;
9
+ /**
10
+ * 소스 파일에서 호출 그래프 구축
11
+ */
12
+ analyzeSourceFile(sourceFile: ts.SourceFile): void;
13
+ /**
14
+ * 함수 노드 조회
15
+ */
16
+ getNode(functionKey: string): CallNode | undefined;
17
+ /**
18
+ * 모든 노드 반환
19
+ */
20
+ getAllNodes(): CallNode[];
21
+ /**
22
+ * 특정 함수가 호출하는 함수들
23
+ */
24
+ getCallees(functionKey: string): CallEdge[];
25
+ /**
26
+ * 특정 함수를 호출하는 함수들
27
+ */
28
+ getCallers(functionKey: string): CallEdge[];
29
+ /**
30
+ * 호출 체인 추적 (특정 함수에서 시작하여 호출되는 모든 함수)
31
+ */
32
+ traceCallChain(functionKey: string, maxDepth?: number): Map<string, number>;
33
+ /**
34
+ * 재귀 호출 탐지
35
+ */
36
+ findRecursiveCalls(): FunctionInfo[];
37
+ /**
38
+ * 함수 복잡도 영향도 계산
39
+ * (이 함수가 변경되면 영향받는 함수의 수)
40
+ */
41
+ calculateImpact(functionKey: string): number;
42
+ /**
43
+ * 함수 고유 키 생성
44
+ */
45
+ private getFunctionKey;
46
+ /**
47
+ * 모든 함수 정보 수집
48
+ */
49
+ private collectFunctions;
50
+ /**
51
+ * 호출 관계 분석
52
+ */
53
+ private analyzeCalls;
54
+ /**
55
+ * 호출 표현식 처리
56
+ */
57
+ private processCallExpression;
58
+ }
59
+ /**
60
+ * 호출 그래프를 Mermaid 형식으로 출력 (시각화용)
61
+ */
62
+ export declare function exportToMermaid(graph: CallGraph): string;
63
+ //# sourceMappingURL=call.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../../src/graph/call.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGpE;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,WAAW,CAAwC;IAE3D;;OAEG;IACH,iBAAiB,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,IAAI;IAQlD;;OAEG;IACH,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAIlD;;OAEG;IACH,WAAW,IAAI,QAAQ,EAAE;IAIzB;;OAEG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,EAAE;IAI3C;;OAEG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,EAAE;IAI3C;;OAEG;IACH,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,SAAK,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAsBvE;;OAEG;IACH,kBAAkB,IAAI,YAAY,EAAE;IA4BpC;;;OAGG;IACH,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAwB5C;;OAEG;IACH,OAAO,CAAC,cAAc;IAKtB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA2BxB;;OAEG;IACH,OAAO,CAAC,YAAY;IA2DpB;;OAEG;IACH,OAAO,CAAC,qBAAqB;CAkD9B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAoBxD"}
@@ -0,0 +1,240 @@
1
+ import ts from 'typescript';
2
+ import { getSourceLocation, extractFunctionInfo } from '../ast/parser.js';
3
+ /**
4
+ * 호출 그래프 빌더
5
+ */
6
+ export class CallGraph {
7
+ nodes = new Map();
8
+ functionMap = new Map();
9
+ /**
10
+ * 소스 파일에서 호출 그래프 구축
11
+ */
12
+ analyzeSourceFile(sourceFile) {
13
+ // 1단계: 모든 함수 정보 수집
14
+ this.collectFunctions(sourceFile);
15
+ // 2단계: 호출 관계 분석
16
+ this.analyzeCalls(sourceFile);
17
+ }
18
+ /**
19
+ * 함수 노드 조회
20
+ */
21
+ getNode(functionKey) {
22
+ return this.nodes.get(functionKey);
23
+ }
24
+ /**
25
+ * 모든 노드 반환
26
+ */
27
+ getAllNodes() {
28
+ return Array.from(this.nodes.values());
29
+ }
30
+ /**
31
+ * 특정 함수가 호출하는 함수들
32
+ */
33
+ getCallees(functionKey) {
34
+ return this.nodes.get(functionKey)?.calls ?? [];
35
+ }
36
+ /**
37
+ * 특정 함수를 호출하는 함수들
38
+ */
39
+ getCallers(functionKey) {
40
+ return this.nodes.get(functionKey)?.calledBy ?? [];
41
+ }
42
+ /**
43
+ * 호출 체인 추적 (특정 함수에서 시작하여 호출되는 모든 함수)
44
+ */
45
+ traceCallChain(functionKey, maxDepth = 10) {
46
+ const result = new Map();
47
+ const visited = new Set();
48
+ const traverse = (key, depth) => {
49
+ if (depth > maxDepth || visited.has(key))
50
+ return;
51
+ visited.add(key);
52
+ result.set(key, depth);
53
+ const node = this.nodes.get(key);
54
+ if (!node)
55
+ return;
56
+ for (const edge of node.calls) {
57
+ const calleeKey = this.getFunctionKey(edge.to);
58
+ traverse(calleeKey, depth + 1);
59
+ }
60
+ };
61
+ traverse(functionKey, 0);
62
+ return result;
63
+ }
64
+ /**
65
+ * 재귀 호출 탐지
66
+ */
67
+ findRecursiveCalls() {
68
+ const recursive = [];
69
+ for (const [key, node] of this.nodes) {
70
+ // 직접 재귀
71
+ const directRecursion = node.calls.some((edge) => this.getFunctionKey(edge.to) === key);
72
+ if (directRecursion) {
73
+ recursive.push(node.function);
74
+ continue;
75
+ }
76
+ // 간접 재귀 (자기 자신이 호출 체인에 있는지)
77
+ const chain = this.traceCallChain(key, 20);
78
+ const indirectRecursion = node.calls.some((edge) => {
79
+ const calleeKey = this.getFunctionKey(edge.to);
80
+ return chain.has(calleeKey) && calleeKey !== key;
81
+ });
82
+ if (indirectRecursion) {
83
+ recursive.push(node.function);
84
+ }
85
+ }
86
+ return recursive;
87
+ }
88
+ /**
89
+ * 함수 복잡도 영향도 계산
90
+ * (이 함수가 변경되면 영향받는 함수의 수)
91
+ */
92
+ calculateImpact(functionKey) {
93
+ const visited = new Set();
94
+ const countCallers = (key) => {
95
+ if (visited.has(key))
96
+ return 0;
97
+ visited.add(key);
98
+ const node = this.nodes.get(key);
99
+ if (!node)
100
+ return 0;
101
+ let count = node.calledBy.length;
102
+ for (const edge of node.calledBy) {
103
+ const callerKey = this.getFunctionKey(edge.from);
104
+ count += countCallers(callerKey);
105
+ }
106
+ return count;
107
+ };
108
+ return countCallers(functionKey);
109
+ }
110
+ // ─── Private Methods ───────────────────────────────────────────
111
+ /**
112
+ * 함수 고유 키 생성
113
+ */
114
+ getFunctionKey(func) {
115
+ const prefix = func.className ? `${func.className}.` : '';
116
+ return `${func.location.filePath}:${prefix}${func.name}:${func.location.startLine}`;
117
+ }
118
+ /**
119
+ * 모든 함수 정보 수집
120
+ */
121
+ collectFunctions(sourceFile) {
122
+ const visit = (node, className) => {
123
+ // 클래스 처리
124
+ if (ts.isClassDeclaration(node) || ts.isClassExpression(node)) {
125
+ const name = node.name?.getText(sourceFile) ?? '<anonymous>';
126
+ node.members.forEach((member) => visit(member, name));
127
+ return;
128
+ }
129
+ // 함수 정보 추출
130
+ const funcInfo = extractFunctionInfo(node, sourceFile, className);
131
+ if (funcInfo) {
132
+ const key = this.getFunctionKey(funcInfo);
133
+ this.functionMap.set(funcInfo.name, funcInfo);
134
+ this.nodes.set(key, {
135
+ function: funcInfo,
136
+ calls: [],
137
+ calledBy: [],
138
+ });
139
+ }
140
+ ts.forEachChild(node, (child) => visit(child, className));
141
+ };
142
+ visit(sourceFile);
143
+ }
144
+ /**
145
+ * 호출 관계 분석
146
+ */
147
+ analyzeCalls(sourceFile) {
148
+ const visit = (node, currentFunction, inConditional, isAsync) => {
149
+ // 함수 컨텍스트 업데이트
150
+ if (ts.isFunctionDeclaration(node) ||
151
+ ts.isFunctionExpression(node) ||
152
+ ts.isArrowFunction(node) ||
153
+ ts.isMethodDeclaration(node)) {
154
+ const funcInfo = extractFunctionInfo(node, sourceFile);
155
+ if (funcInfo) {
156
+ const asyncContext = funcInfo.isAsync || isAsync;
157
+ ts.forEachChild(node, (child) => visit(child, funcInfo, false, asyncContext));
158
+ return;
159
+ }
160
+ }
161
+ // 조건부 컨텍스트 추적
162
+ const conditional = inConditional ||
163
+ ts.isIfStatement(node) ||
164
+ ts.isConditionalExpression(node) ||
165
+ ts.isSwitchStatement(node);
166
+ // 호출 표현식 분석
167
+ if (ts.isCallExpression(node) && currentFunction) {
168
+ this.processCallExpression(node, sourceFile, currentFunction, conditional, isAsync);
169
+ }
170
+ // await 표현식은 async 컨텍스트로 표시
171
+ if (ts.isAwaitExpression(node)) {
172
+ ts.forEachChild(node, (child) => visit(child, currentFunction, conditional, true));
173
+ return;
174
+ }
175
+ ts.forEachChild(node, (child) => visit(child, currentFunction, conditional, isAsync));
176
+ };
177
+ // 최상위 레벨 함수부터 분석
178
+ ts.forEachChild(sourceFile, (node) => visit(node, null, false, false));
179
+ }
180
+ /**
181
+ * 호출 표현식 처리
182
+ */
183
+ processCallExpression(node, sourceFile, caller, isConditional, isAsync) {
184
+ let calleeName = null;
185
+ // 호출 대상 이름 추출
186
+ if (ts.isIdentifier(node.expression)) {
187
+ calleeName = node.expression.text;
188
+ }
189
+ else if (ts.isPropertyAccessExpression(node.expression)) {
190
+ calleeName = node.expression.name.text;
191
+ }
192
+ if (!calleeName)
193
+ return;
194
+ // 호출 대상 함수 찾기
195
+ const callee = this.functionMap.get(calleeName);
196
+ if (!callee)
197
+ return;
198
+ const callerKey = this.getFunctionKey(caller);
199
+ const calleeKey = this.getFunctionKey(callee);
200
+ const callerNode = this.nodes.get(callerKey);
201
+ const calleeNode = this.nodes.get(calleeKey);
202
+ if (!callerNode || !calleeNode)
203
+ return;
204
+ const edge = {
205
+ from: caller,
206
+ to: callee,
207
+ location: getSourceLocation(node, sourceFile),
208
+ isConditional,
209
+ isAsync,
210
+ };
211
+ // 중복 방지
212
+ const isDuplicate = callerNode.calls.some((e) => this.getFunctionKey(e.to) === calleeKey &&
213
+ e.location.startLine === edge.location.startLine);
214
+ if (!isDuplicate) {
215
+ callerNode.calls.push(edge);
216
+ calleeNode.calledBy.push(edge);
217
+ }
218
+ }
219
+ }
220
+ /**
221
+ * 호출 그래프를 Mermaid 형식으로 출력 (시각화용)
222
+ */
223
+ export function exportToMermaid(graph) {
224
+ const lines = ['flowchart TD'];
225
+ for (const node of graph.getAllNodes()) {
226
+ const shortName = node.function.className
227
+ ? `${node.function.className}_${node.function.name}`
228
+ : node.function.name;
229
+ for (const edge of node.calls) {
230
+ const targetName = edge.to.className
231
+ ? `${edge.to.className}_${edge.to.name}`
232
+ : edge.to.name;
233
+ const style = edge.isAsync ? '-.->' : '-->';
234
+ const label = edge.isConditional ? '|conditional|' : '';
235
+ lines.push(` ${shortName} ${style}${label} ${targetName}`);
236
+ }
237
+ }
238
+ return lines.join('\n');
239
+ }
240
+ //# sourceMappingURL=call.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call.js","sourceRoot":"","sources":["../../src/graph/call.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { DependencyNode } from '../types.js';
2
+ /**
3
+ * 의존성 그래프 빌더
4
+ */
5
+ export declare class DependencyGraph {
6
+ private nodes;
7
+ private projectRoot;
8
+ constructor(projectRoot: string);
9
+ /**
10
+ * 프로젝트 루트 경로 반환
11
+ */
12
+ getProjectRoot(): string;
13
+ /**
14
+ * 파일의 의존성 분석
15
+ */
16
+ analyzeFile(filePath: string, content?: string): DependencyNode;
17
+ /**
18
+ * 디렉토리 내 모든 파일 분석
19
+ */
20
+ analyzeDirectory(dirPath: string, extensions?: string[]): void;
21
+ /**
22
+ * 특정 파일에서 시작하는 의존성 트리 구축
23
+ */
24
+ buildDependencyTree(filePath: string, maxDepth?: number): DependencyNode[];
25
+ /**
26
+ * 특정 파일을 참조하는 파일들 찾기
27
+ */
28
+ findDependents(filePath: string, maxDepth?: number): DependencyNode[];
29
+ /**
30
+ * 노드 조회
31
+ */
32
+ getNode(filePath: string): DependencyNode | undefined;
33
+ /**
34
+ * 모든 노드 반환
35
+ */
36
+ getAllNodes(): DependencyNode[];
37
+ /**
38
+ * 순환 의존성 탐지
39
+ */
40
+ findCircularDependencies(): string[][];
41
+ private normalizePath;
42
+ private readFile;
43
+ private resolveImportPath;
44
+ private findFiles;
45
+ private rebuildReverseReferences;
46
+ private calculateDepths;
47
+ }
48
+ /**
49
+ * 의존성 그래프를 DOT 형식으로 출력 (시각화용)
50
+ */
51
+ export declare function exportToDot(graph: DependencyGraph): string;
52
+ //# sourceMappingURL=dependency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency.d.ts","sourceRoot":"","sources":["../../src/graph/dependency.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAA0C;IACvD,OAAO,CAAC,WAAW,CAAS;gBAEhB,WAAW,EAAE,MAAM;IAI/B;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,cAAc;IAmD/D;;OAEG;IACH,gBAAgB,CACd,OAAO,EAAE,MAAM,EACf,UAAU,WAAiC,GAC1C,IAAI;IAaP;;OAEG;IACH,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,cAAc,EAAE;IA2BrE;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,cAAc,EAAE;IAyBhE;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAKrD;;OAEG;IACH,WAAW,IAAI,cAAc,EAAE;IAI/B;;OAEG;IACH,wBAAwB,IAAI,MAAM,EAAE,EAAE;IA2CtC,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,SAAS;IA6BjB,OAAO,CAAC,wBAAwB;IAiBhC,OAAO,CAAC,eAAe;CA8BxB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAe1D"}