agent-ide 0.1.10 → 0.2.0

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 (227) hide show
  1. package/README.md +89 -12
  2. package/dist/application/services/module-coordinator.service.d.ts +0 -1
  3. package/dist/application/services/module-coordinator.service.d.ts.map +1 -1
  4. package/dist/application/services/module-coordinator.service.js +2 -8
  5. package/dist/application/services/module-coordinator.service.js.map +1 -1
  6. package/dist/core/analysis/index.d.ts +1 -4
  7. package/dist/core/analysis/index.d.ts.map +1 -1
  8. package/dist/core/analysis/index.js +1 -7
  9. package/dist/core/analysis/index.js.map +1 -1
  10. package/dist/core/dependency/dependency-analyzer.d.ts.map +1 -1
  11. package/dist/core/dependency/dependency-analyzer.js +10 -0
  12. package/dist/core/dependency/dependency-analyzer.js.map +1 -1
  13. package/dist/core/indexing/index-engine.d.ts +4 -0
  14. package/dist/core/indexing/index-engine.d.ts.map +1 -1
  15. package/dist/core/indexing/index-engine.js +25 -1
  16. package/dist/core/indexing/index-engine.js.map +1 -1
  17. package/dist/core/indexing/symbol-index.d.ts +4 -0
  18. package/dist/core/indexing/symbol-index.d.ts.map +1 -1
  19. package/dist/core/indexing/symbol-index.js +17 -0
  20. package/dist/core/indexing/symbol-index.js.map +1 -1
  21. package/dist/core/move/import-resolver.d.ts.map +1 -1
  22. package/dist/core/move/import-resolver.js +8 -0
  23. package/dist/core/move/import-resolver.js.map +1 -1
  24. package/dist/core/move/move-service.js +7 -7
  25. package/dist/core/move/move-service.js.map +1 -1
  26. package/dist/core/refactor/swift-extractor.d.ts +98 -0
  27. package/dist/core/refactor/swift-extractor.d.ts.map +1 -0
  28. package/dist/core/refactor/swift-extractor.js +283 -0
  29. package/dist/core/refactor/swift-extractor.js.map +1 -0
  30. package/dist/core/rename/reference-updater.d.ts.map +1 -1
  31. package/dist/core/rename/reference-updater.js +16 -8
  32. package/dist/core/rename/reference-updater.js.map +1 -1
  33. package/dist/core/search/engines/text-engine.js +1 -1
  34. package/dist/core/search/engines/text-engine.js.map +1 -1
  35. package/dist/core/shit-score/grading.d.ts +39 -0
  36. package/dist/core/shit-score/grading.d.ts.map +1 -0
  37. package/dist/core/shit-score/grading.js +253 -0
  38. package/dist/core/shit-score/grading.js.map +1 -0
  39. package/dist/core/shit-score/index.d.ts +9 -0
  40. package/dist/core/shit-score/index.d.ts.map +1 -0
  41. package/dist/core/shit-score/index.js +8 -0
  42. package/dist/core/shit-score/index.js.map +1 -0
  43. package/dist/core/shit-score/score-calculator.d.ts +75 -0
  44. package/dist/core/shit-score/score-calculator.d.ts.map +1 -0
  45. package/dist/core/shit-score/score-calculator.js +240 -0
  46. package/dist/core/shit-score/score-calculator.js.map +1 -0
  47. package/dist/core/shit-score/shit-score-analyzer.d.ts +84 -0
  48. package/dist/core/shit-score/shit-score-analyzer.d.ts.map +1 -0
  49. package/dist/core/shit-score/shit-score-analyzer.js +595 -0
  50. package/dist/core/shit-score/shit-score-analyzer.js.map +1 -0
  51. package/dist/core/shit-score/types.d.ts +231 -0
  52. package/dist/core/shit-score/types.d.ts.map +1 -0
  53. package/dist/core/shit-score/types.js +73 -0
  54. package/dist/core/shit-score/types.js.map +1 -0
  55. package/dist/core/snapshot/code-compressor.d.ts +39 -0
  56. package/dist/core/snapshot/code-compressor.d.ts.map +1 -0
  57. package/dist/core/snapshot/code-compressor.js +211 -0
  58. package/dist/core/snapshot/code-compressor.js.map +1 -0
  59. package/dist/core/snapshot/config.d.ts +60 -0
  60. package/dist/core/snapshot/config.d.ts.map +1 -0
  61. package/dist/core/snapshot/config.js +136 -0
  62. package/dist/core/snapshot/config.js.map +1 -0
  63. package/dist/core/snapshot/index.d.ts +23 -0
  64. package/dist/core/snapshot/index.d.ts.map +1 -0
  65. package/dist/core/snapshot/index.js +27 -0
  66. package/dist/core/snapshot/index.js.map +1 -0
  67. package/dist/core/snapshot/snapshot-differ.d.ts +54 -0
  68. package/dist/core/snapshot/snapshot-differ.d.ts.map +1 -0
  69. package/dist/core/snapshot/snapshot-differ.js +262 -0
  70. package/dist/core/snapshot/snapshot-differ.js.map +1 -0
  71. package/dist/core/snapshot/snapshot-engine.d.ts +94 -0
  72. package/dist/core/snapshot/snapshot-engine.d.ts.map +1 -0
  73. package/dist/core/snapshot/snapshot-engine.js +492 -0
  74. package/dist/core/snapshot/snapshot-engine.js.map +1 -0
  75. package/dist/core/snapshot/types.d.ts +216 -0
  76. package/dist/core/snapshot/types.d.ts.map +1 -0
  77. package/dist/core/snapshot/types.js +79 -0
  78. package/dist/core/snapshot/types.js.map +1 -0
  79. package/dist/infrastructure/parser/analysis-types.d.ts +198 -0
  80. package/dist/infrastructure/parser/analysis-types.d.ts.map +1 -0
  81. package/dist/infrastructure/parser/analysis-types.js +6 -0
  82. package/dist/infrastructure/parser/analysis-types.js.map +1 -0
  83. package/dist/infrastructure/parser/base.d.ts +36 -0
  84. package/dist/infrastructure/parser/base.d.ts.map +1 -1
  85. package/dist/infrastructure/parser/base.js +72 -0
  86. package/dist/infrastructure/parser/base.js.map +1 -1
  87. package/dist/infrastructure/parser/index.d.ts +1 -0
  88. package/dist/infrastructure/parser/index.d.ts.map +1 -1
  89. package/dist/infrastructure/parser/index.js.map +1 -1
  90. package/dist/infrastructure/parser/interface.d.ts +63 -0
  91. package/dist/infrastructure/parser/interface.d.ts.map +1 -1
  92. package/dist/infrastructure/parser/interface.js +11 -1
  93. package/dist/infrastructure/parser/interface.js.map +1 -1
  94. package/dist/interfaces/cli/cli.d.ts +24 -0
  95. package/dist/interfaces/cli/cli.d.ts.map +1 -1
  96. package/dist/interfaces/cli/cli.js +1417 -141
  97. package/dist/interfaces/cli/cli.js.map +1 -1
  98. package/dist/plugins/javascript/parser.d.ts +41 -0
  99. package/dist/plugins/javascript/parser.d.ts.map +1 -1
  100. package/dist/plugins/javascript/parser.js +284 -0
  101. package/dist/plugins/javascript/parser.js.map +1 -1
  102. package/dist/plugins/swift/analyzers/complexity-analyzer.d.ts +41 -0
  103. package/dist/plugins/swift/analyzers/complexity-analyzer.d.ts.map +1 -0
  104. package/dist/plugins/swift/analyzers/complexity-analyzer.js +206 -0
  105. package/dist/plugins/swift/analyzers/complexity-analyzer.js.map +1 -0
  106. package/dist/plugins/swift/analyzers/duplication-detector.d.ts +89 -0
  107. package/dist/plugins/swift/analyzers/duplication-detector.d.ts.map +1 -0
  108. package/dist/plugins/swift/analyzers/duplication-detector.js +271 -0
  109. package/dist/plugins/swift/analyzers/duplication-detector.js.map +1 -0
  110. package/dist/plugins/swift/analyzers/error-handling-checker.d.ts +34 -0
  111. package/dist/plugins/swift/analyzers/error-handling-checker.d.ts.map +1 -0
  112. package/dist/plugins/swift/analyzers/error-handling-checker.js +135 -0
  113. package/dist/plugins/swift/analyzers/error-handling-checker.js.map +1 -0
  114. package/dist/plugins/swift/analyzers/naming-checker.d.ts +47 -0
  115. package/dist/plugins/swift/analyzers/naming-checker.d.ts.map +1 -0
  116. package/dist/plugins/swift/analyzers/naming-checker.js +161 -0
  117. package/dist/plugins/swift/analyzers/naming-checker.js.map +1 -0
  118. package/dist/plugins/swift/analyzers/pattern-detector.d.ts +78 -0
  119. package/dist/plugins/swift/analyzers/pattern-detector.d.ts.map +1 -0
  120. package/dist/plugins/swift/analyzers/pattern-detector.js +247 -0
  121. package/dist/plugins/swift/analyzers/pattern-detector.js.map +1 -0
  122. package/dist/plugins/swift/analyzers/security-checker.d.ts +38 -0
  123. package/dist/plugins/swift/analyzers/security-checker.d.ts.map +1 -0
  124. package/dist/plugins/swift/analyzers/security-checker.js +135 -0
  125. package/dist/plugins/swift/analyzers/security-checker.js.map +1 -0
  126. package/dist/plugins/swift/analyzers/test-coverage-checker.d.ts +26 -0
  127. package/dist/plugins/swift/analyzers/test-coverage-checker.d.ts.map +1 -0
  128. package/dist/plugins/swift/analyzers/test-coverage-checker.js +63 -0
  129. package/dist/plugins/swift/analyzers/test-coverage-checker.js.map +1 -0
  130. package/dist/plugins/swift/analyzers/type-safety-checker.d.ts +41 -0
  131. package/dist/plugins/swift/analyzers/type-safety-checker.d.ts.map +1 -0
  132. package/dist/plugins/swift/analyzers/type-safety-checker.js +121 -0
  133. package/dist/plugins/swift/analyzers/type-safety-checker.js.map +1 -0
  134. package/dist/plugins/swift/analyzers/unused-symbol-detector.d.ts +38 -0
  135. package/dist/plugins/swift/analyzers/unused-symbol-detector.d.ts.map +1 -0
  136. package/dist/plugins/swift/analyzers/unused-symbol-detector.js +211 -0
  137. package/dist/plugins/swift/analyzers/unused-symbol-detector.js.map +1 -0
  138. package/dist/plugins/swift/dependency-analyzer.d.ts +33 -0
  139. package/dist/plugins/swift/dependency-analyzer.d.ts.map +1 -0
  140. package/dist/plugins/swift/dependency-analyzer.js +95 -0
  141. package/dist/plugins/swift/dependency-analyzer.js.map +1 -0
  142. package/dist/plugins/swift/index.d.ts +14 -0
  143. package/dist/plugins/swift/index.d.ts.map +1 -0
  144. package/dist/plugins/swift/index.js +19 -0
  145. package/dist/plugins/swift/index.js.map +1 -0
  146. package/dist/plugins/swift/parser.d.ts +160 -0
  147. package/dist/plugins/swift/parser.d.ts.map +1 -0
  148. package/dist/plugins/swift/parser.js +670 -0
  149. package/dist/plugins/swift/parser.js.map +1 -0
  150. package/dist/plugins/swift/swift-bridge/swift-parser +0 -0
  151. package/dist/plugins/swift/symbol-extractor.d.ts +46 -0
  152. package/dist/plugins/swift/symbol-extractor.d.ts.map +1 -0
  153. package/dist/plugins/swift/symbol-extractor.js +187 -0
  154. package/dist/plugins/swift/symbol-extractor.js.map +1 -0
  155. package/dist/plugins/swift/types.d.ts +137 -0
  156. package/dist/plugins/swift/types.d.ts.map +1 -0
  157. package/dist/plugins/swift/types.js +212 -0
  158. package/dist/plugins/swift/types.js.map +1 -0
  159. package/dist/plugins/typescript/analyzers/complexity-analyzer.d.ts +39 -0
  160. package/dist/plugins/typescript/analyzers/complexity-analyzer.d.ts.map +1 -0
  161. package/dist/plugins/typescript/analyzers/complexity-analyzer.js +196 -0
  162. package/dist/plugins/typescript/analyzers/complexity-analyzer.js.map +1 -0
  163. package/dist/{core/analysis → plugins/typescript/analyzers}/duplication-detector.d.ts +34 -3
  164. package/dist/plugins/typescript/analyzers/duplication-detector.d.ts.map +1 -0
  165. package/dist/plugins/typescript/analyzers/duplication-detector.js +695 -0
  166. package/dist/plugins/typescript/analyzers/duplication-detector.js.map +1 -0
  167. package/dist/plugins/typescript/analyzers/error-handling-checker.d.ts +26 -0
  168. package/dist/plugins/typescript/analyzers/error-handling-checker.d.ts.map +1 -0
  169. package/dist/plugins/typescript/analyzers/error-handling-checker.js +84 -0
  170. package/dist/plugins/typescript/analyzers/error-handling-checker.js.map +1 -0
  171. package/dist/plugins/typescript/analyzers/naming-checker.d.ts +30 -0
  172. package/dist/plugins/typescript/analyzers/naming-checker.d.ts.map +1 -0
  173. package/dist/plugins/typescript/analyzers/naming-checker.js +116 -0
  174. package/dist/plugins/typescript/analyzers/naming-checker.js.map +1 -0
  175. package/dist/plugins/typescript/analyzers/pattern-detector.d.ts +80 -0
  176. package/dist/plugins/typescript/analyzers/pattern-detector.d.ts.map +1 -0
  177. package/dist/plugins/typescript/analyzers/pattern-detector.js +267 -0
  178. package/dist/plugins/typescript/analyzers/pattern-detector.js.map +1 -0
  179. package/dist/plugins/typescript/analyzers/security-checker.d.ts +34 -0
  180. package/dist/plugins/typescript/analyzers/security-checker.d.ts.map +1 -0
  181. package/dist/plugins/typescript/analyzers/security-checker.js +126 -0
  182. package/dist/plugins/typescript/analyzers/security-checker.js.map +1 -0
  183. package/dist/plugins/typescript/analyzers/test-coverage-checker.d.ts +22 -0
  184. package/dist/plugins/typescript/analyzers/test-coverage-checker.d.ts.map +1 -0
  185. package/dist/plugins/typescript/analyzers/test-coverage-checker.js +62 -0
  186. package/dist/plugins/typescript/analyzers/test-coverage-checker.js.map +1 -0
  187. package/dist/plugins/typescript/analyzers/type-safety-checker.d.ts +32 -0
  188. package/dist/plugins/typescript/analyzers/type-safety-checker.d.ts.map +1 -0
  189. package/dist/plugins/typescript/analyzers/type-safety-checker.js +86 -0
  190. package/dist/plugins/typescript/analyzers/type-safety-checker.js.map +1 -0
  191. package/dist/plugins/typescript/analyzers/unused-symbol-detector.d.ts +47 -0
  192. package/dist/plugins/typescript/analyzers/unused-symbol-detector.d.ts.map +1 -0
  193. package/dist/plugins/typescript/analyzers/unused-symbol-detector.js +152 -0
  194. package/dist/plugins/typescript/analyzers/unused-symbol-detector.js.map +1 -0
  195. package/dist/plugins/typescript/parser.d.ts +41 -0
  196. package/dist/plugins/typescript/parser.d.ts.map +1 -1
  197. package/dist/plugins/typescript/parser.js +336 -0
  198. package/dist/plugins/typescript/parser.js.map +1 -1
  199. package/dist/shared/types/symbol.d.ts +7 -1
  200. package/dist/shared/types/symbol.d.ts.map +1 -1
  201. package/dist/shared/types/symbol.js +8 -2
  202. package/dist/shared/types/symbol.js.map +1 -1
  203. package/package.json +17 -7
  204. package/bin/mcp-server.js +0 -20
  205. package/dist/core/analysis/complexity-analyzer.d.ts +0 -81
  206. package/dist/core/analysis/complexity-analyzer.d.ts.map +0 -1
  207. package/dist/core/analysis/complexity-analyzer.js +0 -255
  208. package/dist/core/analysis/complexity-analyzer.js.map +0 -1
  209. package/dist/core/analysis/dead-code-detector.d.ts +0 -152
  210. package/dist/core/analysis/dead-code-detector.d.ts.map +0 -1
  211. package/dist/core/analysis/dead-code-detector.js +0 -351
  212. package/dist/core/analysis/dead-code-detector.js.map +0 -1
  213. package/dist/core/analysis/duplication-detector.d.ts.map +0 -1
  214. package/dist/core/analysis/duplication-detector.js +0 -433
  215. package/dist/core/analysis/duplication-detector.js.map +0 -1
  216. package/dist/interfaces/mcp/index.d.ts +0 -7
  217. package/dist/interfaces/mcp/index.d.ts.map +0 -1
  218. package/dist/interfaces/mcp/index.js +0 -6
  219. package/dist/interfaces/mcp/index.js.map +0 -1
  220. package/dist/interfaces/mcp/mcp-server.d.ts +0 -34
  221. package/dist/interfaces/mcp/mcp-server.d.ts.map +0 -1
  222. package/dist/interfaces/mcp/mcp-server.js +0 -162
  223. package/dist/interfaces/mcp/mcp-server.js.map +0 -1
  224. package/dist/interfaces/mcp/mcp.d.ts +0 -52
  225. package/dist/interfaces/mcp/mcp.d.ts.map +0 -1
  226. package/dist/interfaces/mcp/mcp.js +0 -853
  227. package/dist/interfaces/mcp/mcp.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-safety-checker.js","sourceRoot":"","sources":["../../../../src/plugins/typescript/analyzers/type-safety-checker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAa7B;;GAEG;AACH,MAAM,OAAO,iBAAiB;IAC5B;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,KAAe,EAAE,WAAmB;QAC9C,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,IAAI,UAAU,GAAG,CAAC,CAAC;QAEnB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjC,SAAS;YACX,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBAEjD,qBAAqB;gBACrB,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;gBAC/C,IAAI,UAAU,EAAE,CAAC;oBACf,YAAY,IAAI,UAAU,CAAC,MAAM,CAAC;gBACpC,CAAC;gBAED,gBAAgB;gBAChB,MAAM,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;gBACrD,IAAI,eAAe,EAAE,CAAC;oBACpB,aAAa,IAAI,eAAe,CAAC,MAAM,CAAC;gBAC1C,CAAC;gBAED,oBAAoB;gBACpB,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;gBAClD,IAAI,YAAY,EAAE,CAAC;oBACjB,UAAU,IAAI,YAAY,CAAC,MAAM,CAAC;gBACpC,CAAC;gBAED,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC/C,IAAI,cAAc,EAAE,CAAC;oBACnB,UAAU,IAAI,cAAc,CAAC,MAAM,CAAC;gBACtC,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY;YACd,CAAC;QACH,CAAC;QAED,mBAAmB;QACnB,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QAE7D,OAAO;YACL,YAAY;YACZ,aAAa;YACb,UAAU;YACV,iBAAiB,EAAE,cAAc,CAAC,iBAAiB;YACnD,uBAAuB,EAAE,cAAc,CAAC,uBAAuB;SAChE,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,aAAa,CAAC,WAAmB;QAI7C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QAE7D,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACzD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACnC,MAAM,eAAe,GAAG,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC;YAErD,OAAO;gBACL,iBAAiB,EAAE,eAAe,CAAC,MAAM,KAAK,IAAI;gBAClD,uBAAuB,EACrB,eAAe,CAAC,gBAAgB,KAAK,IAAI,IAAI,eAAe,CAAC,MAAM,KAAK,IAAI;aAC/E,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;gBACL,iBAAiB,EAAE,KAAK;gBACxB,uBAAuB,EAAE,KAAK;aAC/B,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,IAAY;QACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC;CACF"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * TypeScript 未使用符號檢測器
3
+ * 檢測未使用的變數、函式、類別
4
+ */
5
+ import type { Symbol, AST } from '../../../shared/types/index.js';
6
+ import type { UnusedCode } from '../../../infrastructure/parser/analysis-types.js';
7
+ import type { TypeScriptAST } from '../types.js';
8
+ /**
9
+ * 未使用符號檢測器
10
+ */
11
+ export declare class UnusedSymbolDetector {
12
+ /**
13
+ * 檢測未使用的符號
14
+ * @param ast TypeScript AST 物件
15
+ * @param allSymbols 所有符號列表
16
+ * @param findReferences 查找引用的函式(從 parser 傳入)
17
+ * @returns 未使用的符號列表
18
+ */
19
+ detect(ast: TypeScriptAST, allSymbols: Symbol[], findReferences: (ast: AST, symbol: Symbol) => Promise<any[]>): Promise<UnusedCode[]>;
20
+ /**
21
+ * 建立引用映射表(批次處理)
22
+ * 優化:使用 Promise.all 並行處理多個符號
23
+ */
24
+ private buildReferenceMap;
25
+ /**
26
+ * 檢查符號是否已匯出
27
+ */
28
+ private isExported;
29
+ /**
30
+ * 檢查是否為函式參數
31
+ */
32
+ private isParameter;
33
+ /**
34
+ * 檢查是否為 public 或 protected 類別成員
35
+ * 這些成員可能被子類別或外部程式碼使用,單檔案模式無法檢測
36
+ */
37
+ private isPublicOrProtectedMember;
38
+ /**
39
+ * 映射符號類型到 UnusedCode 類型
40
+ */
41
+ private mapSymbolType;
42
+ /**
43
+ * 計算檢測置信度
44
+ */
45
+ private calculateConfidence;
46
+ }
47
+ //# sourceMappingURL=unused-symbol-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unused-symbol-detector.d.ts","sourceRoot":"","sources":["../../../../src/plugins/typescript/analyzers/unused-symbol-detector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,gCAAgC,CAAC;AAElE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kDAAkD,CAAC;AACnF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;GAEG;AACH,qBAAa,oBAAoB;IAC/B;;;;;;OAMG;IACG,MAAM,CACV,GAAG,EAAE,aAAa,EAClB,UAAU,EAAE,MAAM,EAAE,EACpB,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC,GAC3D,OAAO,CAAC,UAAU,EAAE,CAAC;IAqDxB;;;OAGG;YACW,iBAAiB;IAmC/B;;OAEG;IACH,OAAO,CAAC,UAAU;IAIlB;;OAEG;IACH,OAAO,CAAC,WAAW;IAUnB;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAgBjC;;OAEG;IACH,OAAO,CAAC,aAAa;IAcrB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAc5B"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * TypeScript 未使用符號檢測器
3
+ * 檢測未使用的變數、函式、類別
4
+ */
5
+ import { SymbolType, ReferenceType } from '../../../shared/types/index.js';
6
+ /**
7
+ * 未使用符號檢測器
8
+ */
9
+ export class UnusedSymbolDetector {
10
+ /**
11
+ * 檢測未使用的符號
12
+ * @param ast TypeScript AST 物件
13
+ * @param allSymbols 所有符號列表
14
+ * @param findReferences 查找引用的函式(從 parser 傳入)
15
+ * @returns 未使用的符號列表
16
+ */
17
+ async detect(ast, allSymbols, findReferences) {
18
+ const unused = [];
19
+ // 優化:提早過濾,只對需要檢測的符號建立 reference map
20
+ const symbolsToCheck = allSymbols.filter(symbol => {
21
+ // 跳過已匯出的符號
22
+ if (this.isExported(symbol)) {
23
+ return false;
24
+ }
25
+ // 跳過函式參數
26
+ if (this.isParameter(symbol)) {
27
+ return false;
28
+ }
29
+ // 跳過 public/protected 類別成員
30
+ if (this.isPublicOrProtectedMember(symbol)) {
31
+ return false;
32
+ }
33
+ return true;
34
+ });
35
+ // 只對需要檢測的符號建立 reference map
36
+ const referenceMap = await this.buildReferenceMap(ast, symbolsToCheck, findReferences);
37
+ for (const symbol of symbolsToCheck) {
38
+ // 從映射表中查找引用(O(1))
39
+ const references = referenceMap.get(symbol.name) || [];
40
+ // 過濾出實際使用(非定義)的引用
41
+ const usageReferences = references.filter(ref => ref.type === ReferenceType.Usage);
42
+ if (usageReferences.length === 0) {
43
+ unused.push({
44
+ type: this.mapSymbolType(symbol.type),
45
+ name: symbol.name,
46
+ location: {
47
+ filePath: symbol.location.filePath,
48
+ line: symbol.location.range.start.line,
49
+ column: symbol.location.range.start.column
50
+ },
51
+ confidence: this.calculateConfidence(references),
52
+ reason: `${this.mapSymbolType(symbol.type)} '${symbol.name}' 已宣告但從未使用`
53
+ });
54
+ }
55
+ }
56
+ return unused;
57
+ }
58
+ /**
59
+ * 建立引用映射表(批次處理)
60
+ * 優化:使用 Promise.all 並行處理多個符號
61
+ */
62
+ async buildReferenceMap(ast, symbols, findReferences) {
63
+ const referenceMap = new Map();
64
+ // 如果符號數量很少,直接處理
65
+ if (symbols.length === 0) {
66
+ return referenceMap;
67
+ }
68
+ // 增加批次大小以提升效能
69
+ const batchSize = 50;
70
+ for (let i = 0; i < symbols.length; i += batchSize) {
71
+ const batch = symbols.slice(i, i + batchSize);
72
+ // 批次並行處理
73
+ await Promise.all(batch.map(async (symbol) => {
74
+ try {
75
+ const references = await findReferences(ast, symbol);
76
+ referenceMap.set(symbol.name, references);
77
+ }
78
+ catch (error) {
79
+ // 查找失敗時記錄空引用
80
+ referenceMap.set(symbol.name, []);
81
+ }
82
+ }));
83
+ }
84
+ return referenceMap;
85
+ }
86
+ /**
87
+ * 檢查符號是否已匯出
88
+ */
89
+ isExported(symbol) {
90
+ return symbol.modifiers?.includes('export') || false;
91
+ }
92
+ /**
93
+ * 檢查是否為函式參數
94
+ */
95
+ isParameter(symbol) {
96
+ // 檢查 scope,如果 parent 是 function 且符號在參數位置,就是參數
97
+ if (symbol.scope?.type === 'function') {
98
+ // 簡化判斷:如果符號類型是 Variable 且在 function scope 內,可能是參數或局部變數
99
+ // 更準確的判斷需要檢查 AST 節點類型
100
+ return false; // 暫時保守處理,不跳過任何符號
101
+ }
102
+ return false;
103
+ }
104
+ /**
105
+ * 檢查是否為 public 或 protected 類別成員
106
+ * 這些成員可能被子類別或外部程式碼使用,單檔案模式無法檢測
107
+ */
108
+ isPublicOrProtectedMember(symbol) {
109
+ const modifiers = symbol.modifiers || [];
110
+ // 如果有 public 或 protected 修飾符
111
+ if (modifiers.includes('public') || modifiers.includes('protected')) {
112
+ return true;
113
+ }
114
+ // 檢查 scope:如果是類別成員(scope.parent.type === 'class'),且沒有 private 修飾符,預設就是 public
115
+ if (symbol.scope?.parent?.type === 'class' && !modifiers.includes('private')) {
116
+ return true;
117
+ }
118
+ return false;
119
+ }
120
+ /**
121
+ * 映射符號類型到 UnusedCode 類型
122
+ */
123
+ mapSymbolType(symbolType) {
124
+ switch (symbolType) {
125
+ case SymbolType.Function:
126
+ return 'function';
127
+ case SymbolType.Class:
128
+ return 'class';
129
+ case SymbolType.Variable:
130
+ case SymbolType.Constant:
131
+ return 'variable';
132
+ default:
133
+ return 'variable';
134
+ }
135
+ }
136
+ /**
137
+ * 計算檢測置信度
138
+ */
139
+ calculateConfidence(references) {
140
+ // 如果完全沒有引用(連定義都不算),置信度最高
141
+ if (references.length === 0) {
142
+ return 1.0;
143
+ }
144
+ // 如果只有定義引用,沒有使用引用
145
+ const usageRefs = references.filter((ref) => ref.type === ReferenceType.Usage);
146
+ if (usageRefs.length === 0) {
147
+ return 0.95;
148
+ }
149
+ return 0.9;
150
+ }
151
+ }
152
+ //# sourceMappingURL=unused-symbol-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unused-symbol-detector.js","sourceRoot":"","sources":["../../../../src/plugins/typescript/analyzers/unused-symbol-detector.ts"],"names":[],"mappings":"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"}
@@ -130,5 +130,46 @@ export declare class TypeScriptParser implements ParserPlugin, Disposable {
130
130
  * 檢查符號是否被遮蔽
131
131
  */
132
132
  private isShadowed;
133
+ /**
134
+ * 檢測未使用的符號
135
+ */
136
+ detectUnusedSymbols(ast: AST, allSymbols: Symbol[]): Promise<import('../../infrastructure/parser/analysis-types.js').UnusedCode[]>;
137
+ /**
138
+ * 分析程式碼複雜度
139
+ */
140
+ analyzeComplexity(code: string, ast: AST): Promise<import('../../infrastructure/parser/analysis-types.js').ComplexityMetrics>;
141
+ /**
142
+ * 提取程式碼片段(用於重複代碼檢測)
143
+ */
144
+ extractCodeFragments(code: string, filePath: string): Promise<import('../../infrastructure/parser/analysis-types.js').CodeFragment[]>;
145
+ private extractTopLevelComments;
146
+ private extractMethods;
147
+ private extractConstants;
148
+ private extractConfigObjects;
149
+ private tokenizeCode;
150
+ /**
151
+ * 檢測樣板模式
152
+ */
153
+ detectPatterns(code: string, ast: AST): Promise<import('../../infrastructure/parser/analysis-types.js').PatternMatch[]>;
154
+ /**
155
+ * 檢查型別安全問題
156
+ */
157
+ checkTypeSafety(code: string, ast: AST): Promise<import('../../infrastructure/parser/analysis-types.js').TypeSafetyIssue[]>;
158
+ /**
159
+ * 檢查錯誤處理問題
160
+ */
161
+ checkErrorHandling(code: string, ast: AST): Promise<import('../../infrastructure/parser/analysis-types.js').ErrorHandlingIssue[]>;
162
+ /**
163
+ * 檢查安全性問題
164
+ */
165
+ checkSecurity(code: string, ast: AST): Promise<import('../../infrastructure/parser/analysis-types.js').SecurityIssue[]>;
166
+ /**
167
+ * 檢查命名規範問題
168
+ */
169
+ checkNamingConventions(symbols: Symbol[], filePath: string): Promise<import('../../infrastructure/parser/analysis-types.js').NamingIssue[]>;
170
+ /**
171
+ * 判斷檔案是否為測試檔案
172
+ */
173
+ isTestFile(filePath: string): boolean;
133
174
  }
134
175
  //# sourceMappingURL=parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/plugins/typescript/parser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/plugins/typescript/parser.ts"],"names":[],"mappings":"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"}
@@ -973,5 +973,341 @@ export class TypeScriptParser {
973
973
  }
974
974
  return false;
975
975
  }
976
+ // ===== 新增:程式碼分析方法 =====
977
+ /**
978
+ * 檢測未使用的符號
979
+ */
980
+ async detectUnusedSymbols(ast, allSymbols) {
981
+ const { UnusedSymbolDetector } = await import('./analyzers/unused-symbol-detector.js');
982
+ const detector = new UnusedSymbolDetector();
983
+ return detector.detect(ast, allSymbols, this.findReferences.bind(this));
984
+ }
985
+ /**
986
+ * 分析程式碼複雜度
987
+ */
988
+ async analyzeComplexity(code, ast) {
989
+ const { ComplexityAnalyzer } = await import('./analyzers/complexity-analyzer.js');
990
+ const analyzer = new ComplexityAnalyzer();
991
+ return analyzer.analyze(code, ast);
992
+ }
993
+ /**
994
+ * 提取程式碼片段(用於重複代碼檢測)
995
+ */
996
+ async extractCodeFragments(code, filePath) {
997
+ const fragments = [];
998
+ // 1. 提取頂層註解
999
+ const commentFragments = await this.extractTopLevelComments(code, filePath);
1000
+ fragments.push(...commentFragments);
1001
+ // 2. 提取方法
1002
+ const methodFragments = await this.extractMethods(code, filePath);
1003
+ fragments.push(...methodFragments);
1004
+ // 3. 提取常數定義
1005
+ const constantFragments = await this.extractConstants(code, filePath);
1006
+ fragments.push(...constantFragments);
1007
+ // 4. 提取配置物件
1008
+ const configFragments = await this.extractConfigObjects(code, filePath);
1009
+ fragments.push(...configFragments);
1010
+ return fragments;
1011
+ }
1012
+ async extractTopLevelComments(code, filePath) {
1013
+ const { createHash } = await import('crypto');
1014
+ const fragments = [];
1015
+ const lines = code.split('\n');
1016
+ let commentStart = -1;
1017
+ let inBlockComment = false;
1018
+ for (let i = 0; i < Math.min(50, lines.length); i++) {
1019
+ const line = lines[i].trim();
1020
+ if ((line.startsWith('/**') || line.startsWith('/*')) && commentStart === -1) {
1021
+ commentStart = i;
1022
+ inBlockComment = true;
1023
+ }
1024
+ if (inBlockComment && line.includes('*/')) {
1025
+ const commentEnd = i;
1026
+ const commentCode = lines.slice(commentStart, commentEnd + 1).join('\n');
1027
+ const lineCount = commentEnd - commentStart + 1;
1028
+ if (lineCount >= 3) {
1029
+ fragments.push({
1030
+ type: 'comment',
1031
+ code: commentCode,
1032
+ tokens: this.tokenizeCode(commentCode, true),
1033
+ location: { filePath, startLine: commentStart + 1, endLine: commentEnd + 1 },
1034
+ hash: createHash('md5').update(commentCode).digest('hex')
1035
+ });
1036
+ }
1037
+ commentStart = -1;
1038
+ inBlockComment = false;
1039
+ }
1040
+ // 遇到非註解行就停止
1041
+ if (!inBlockComment && line && !line.startsWith('//') && !line.startsWith('*')) {
1042
+ break;
1043
+ }
1044
+ }
1045
+ return fragments;
1046
+ }
1047
+ async extractMethods(code, filePath) {
1048
+ const { createHash } = await import('crypto');
1049
+ const fragments = [];
1050
+ const lines = code.split('\n');
1051
+ for (let i = 0; i < lines.length; i++) {
1052
+ const line = lines[i];
1053
+ // 匹配方法定義
1054
+ if (/(async\s+)?(function\s+\w+|const\s+\w+\s*=\s*(async\s+)?\([^)]*\)\s*=>|\w+\s*\([^)]*\)\s*{)/.test(line)) {
1055
+ let braceCount = (line.match(/{/g) || []).length - (line.match(/}/g) || []).length;
1056
+ let endLine = i;
1057
+ // 找到方法結尾
1058
+ for (let j = i + 1; j < lines.length && braceCount > 0; j++) {
1059
+ braceCount += (lines[j].match(/{/g) || []).length;
1060
+ braceCount -= (lines[j].match(/}/g) || []).length;
1061
+ endLine = j;
1062
+ }
1063
+ if (endLine > i && (endLine - i + 1) >= 3) {
1064
+ const methodCode = lines.slice(i, endLine + 1).join('\n');
1065
+ fragments.push({
1066
+ type: 'method',
1067
+ code: methodCode,
1068
+ tokens: this.tokenizeCode(methodCode, false),
1069
+ location: { filePath, startLine: i + 1, endLine: endLine + 1 },
1070
+ hash: createHash('md5').update(methodCode).digest('hex')
1071
+ });
1072
+ }
1073
+ }
1074
+ }
1075
+ return fragments;
1076
+ }
1077
+ async extractConstants(code, filePath) {
1078
+ const { createHash } = await import('crypto');
1079
+ const fragments = [];
1080
+ const lines = code.split('\n');
1081
+ for (let i = 0; i < lines.length; i++) {
1082
+ const line = lines[i];
1083
+ // 匹配 export const XXX = { ... }
1084
+ if (/export\s+const\s+\w+\s*=\s*{/.test(line)) {
1085
+ let braceCount = 1;
1086
+ let endLine = i;
1087
+ for (let j = i + 1; j < lines.length && braceCount > 0; j++) {
1088
+ braceCount += (lines[j].match(/{/g) || []).length;
1089
+ braceCount -= (lines[j].match(/}/g) || []).length;
1090
+ endLine = j;
1091
+ }
1092
+ if (endLine > i && (endLine - i + 1) >= 3) {
1093
+ const constantCode = lines.slice(i, endLine + 1).join('\n');
1094
+ fragments.push({
1095
+ type: 'constant',
1096
+ code: constantCode,
1097
+ tokens: this.tokenizeCode(constantCode, false),
1098
+ location: { filePath, startLine: i + 1, endLine: endLine + 1 },
1099
+ hash: createHash('md5').update(constantCode).digest('hex')
1100
+ });
1101
+ }
1102
+ }
1103
+ }
1104
+ return fragments;
1105
+ }
1106
+ async extractConfigObjects(code, filePath) {
1107
+ const { createHash } = await import('crypto');
1108
+ const fragments = [];
1109
+ const lines = code.split('\n');
1110
+ for (let i = 0; i < lines.length; i++) {
1111
+ const line = lines[i];
1112
+ // 匹配配置物件模式
1113
+ if (/config|Config|options|Options/.test(line) && /{/.test(line)) {
1114
+ let braceCount = (line.match(/{/g) || []).length - (line.match(/}/g) || []).length;
1115
+ let endLine = i;
1116
+ for (let j = i + 1; j < lines.length && braceCount > 0; j++) {
1117
+ braceCount += (lines[j].match(/{/g) || []).length;
1118
+ braceCount -= (lines[j].match(/}/g) || []).length;
1119
+ endLine = j;
1120
+ }
1121
+ if (endLine > i && (endLine - i + 1) >= 3) {
1122
+ const configCode = lines.slice(i, endLine + 1).join('\n');
1123
+ fragments.push({
1124
+ type: 'config',
1125
+ code: configCode,
1126
+ tokens: this.tokenizeCode(configCode, false),
1127
+ location: { filePath, startLine: i + 1, endLine: endLine + 1 },
1128
+ hash: createHash('md5').update(configCode).digest('hex')
1129
+ });
1130
+ }
1131
+ }
1132
+ }
1133
+ return fragments;
1134
+ }
1135
+ tokenizeCode(code, includeComments) {
1136
+ if (includeComments) {
1137
+ return code.split(/\s+/).filter(t => t.length > 0);
1138
+ }
1139
+ // 移除註解
1140
+ const withoutComments = code
1141
+ .replace(/\/\*[\s\S]*?\*\//g, '')
1142
+ .replace(/\/\/.*/g, '');
1143
+ return withoutComments.split(/\s+/).filter(t => t.length > 0);
1144
+ }
1145
+ /**
1146
+ * 檢測樣板模式
1147
+ */
1148
+ async detectPatterns(code, ast) {
1149
+ const { PatternDetector, PatternType } = await import('./analyzers/pattern-detector.js');
1150
+ const detector = new PatternDetector();
1151
+ const groups = await detector.detectAll([ast.sourceFile]);
1152
+ const patterns = [];
1153
+ for (const [type, group] of groups.entries()) {
1154
+ patterns.push({
1155
+ pattern: type,
1156
+ type: 'boilerplate',
1157
+ locations: group.instances.map(instance => ({
1158
+ filePath: instance.file,
1159
+ startLine: instance.startLine,
1160
+ endLine: instance.endLine
1161
+ })),
1162
+ count: group.count,
1163
+ severity: group.count > 10 ? 'high' : group.count > 5 ? 'medium' : 'low',
1164
+ suggestion: group.recommendation
1165
+ });
1166
+ }
1167
+ return patterns;
1168
+ }
1169
+ /**
1170
+ * 檢查型別安全問題
1171
+ */
1172
+ async checkTypeSafety(code, ast) {
1173
+ const { TypeSafetyChecker } = await import('./analyzers/type-safety-checker.js');
1174
+ const checker = new TypeSafetyChecker();
1175
+ const result = await checker.check([ast.sourceFile], process.cwd());
1176
+ const issues = [];
1177
+ // any 型別使用
1178
+ for (let i = 0; i < result.anyTypeCount; i++) {
1179
+ issues.push({
1180
+ type: 'any-type',
1181
+ location: { filePath: ast.sourceFile, line: 0, column: 0 },
1182
+ message: '使用了 any 型別,降低型別安全性',
1183
+ severity: 'warning'
1184
+ });
1185
+ }
1186
+ // @ts-ignore 指令
1187
+ for (let i = 0; i < result.tsIgnoreCount; i++) {
1188
+ issues.push({
1189
+ type: 'ignore-directive',
1190
+ location: { filePath: ast.sourceFile, line: 0, column: 0 },
1191
+ message: '使用了 @ts-ignore 忽略型別檢查',
1192
+ severity: 'warning'
1193
+ });
1194
+ }
1195
+ // as any 轉型
1196
+ for (let i = 0; i < result.asAnyCount; i++) {
1197
+ issues.push({
1198
+ type: 'unsafe-cast',
1199
+ location: { filePath: ast.sourceFile, line: 0, column: 0 },
1200
+ message: '使用了 as any 強制轉型',
1201
+ severity: 'error'
1202
+ });
1203
+ }
1204
+ return issues;
1205
+ }
1206
+ /**
1207
+ * 檢查錯誤處理問題
1208
+ */
1209
+ async checkErrorHandling(code, ast) {
1210
+ const issues = [];
1211
+ const lines = code.split('\n');
1212
+ // 檢測空 catch 區塊
1213
+ for (let i = 0; i < lines.length; i++) {
1214
+ const line = lines[i];
1215
+ if (/catch\s*\([^)]*\)\s*\{\s*\}/.test(line)) {
1216
+ issues.push({
1217
+ type: 'empty-catch',
1218
+ location: { filePath: ast.sourceFile, line: i + 1, column: 0 },
1219
+ message: '空的 catch 區塊,應該處理錯誤或記錄日誌',
1220
+ severity: 'warning'
1221
+ });
1222
+ }
1223
+ // 檢測靜默吞錯(catch 內只有註解)
1224
+ if (/catch\s*\([^)]*\)\s*\{[^}]*\/\/\s*(ignore|skip|TODO)[^}]*\}/.test(line)) {
1225
+ issues.push({
1226
+ type: 'silent-error',
1227
+ location: { filePath: ast.sourceFile, line: i + 1, column: 0 },
1228
+ message: 'catch 區塊靜默吞錯,只有註解沒有實際處理',
1229
+ severity: 'warning'
1230
+ });
1231
+ }
1232
+ }
1233
+ return issues;
1234
+ }
1235
+ /**
1236
+ * 檢查安全性問題
1237
+ */
1238
+ async checkSecurity(code, ast) {
1239
+ const issues = [];
1240
+ const lines = code.split('\n');
1241
+ for (let i = 0; i < lines.length; i++) {
1242
+ const line = lines[i];
1243
+ // 檢測硬編碼密碼
1244
+ if (/(password|passwd|pwd|secret|apiKey|token)\s*[:=]\s*['"][^'"]{3,}['"]/.test(line) &&
1245
+ !/(process\.env|config\.|import)/.test(line)) {
1246
+ issues.push({
1247
+ type: 'hardcoded-secret',
1248
+ location: { filePath: ast.sourceFile, line: i + 1, column: 0 },
1249
+ message: '硬編碼的密碼或密鑰,應使用環境變數',
1250
+ severity: 'critical'
1251
+ });
1252
+ }
1253
+ // 檢測 eval 使用
1254
+ if (/\beval\s*\(/.test(line)) {
1255
+ issues.push({
1256
+ type: 'unsafe-eval',
1257
+ location: { filePath: ast.sourceFile, line: i + 1, column: 0 },
1258
+ message: '使用 eval 可能導致代碼注入風險',
1259
+ severity: 'high'
1260
+ });
1261
+ }
1262
+ // 檢測 innerHTML
1263
+ if (/\.innerHTML\s*=/.test(line) && !/(DOMPurify|sanitize)/.test(line)) {
1264
+ issues.push({
1265
+ type: 'xss-vulnerability',
1266
+ location: { filePath: ast.sourceFile, line: i + 1, column: 0 },
1267
+ message: '直接設定 innerHTML 可能導致 XSS 攻擊',
1268
+ severity: 'medium'
1269
+ });
1270
+ }
1271
+ }
1272
+ return issues;
1273
+ }
1274
+ /**
1275
+ * 檢查命名規範問題
1276
+ */
1277
+ async checkNamingConventions(symbols, filePath) {
1278
+ const issues = [];
1279
+ for (const symbol of symbols) {
1280
+ // 檢測底線開頭變數(JavaScript/TypeScript 規範不建議)
1281
+ if (symbol.name.startsWith('_') && symbol.type === SymbolType.Variable) {
1282
+ issues.push({
1283
+ type: 'invalid-naming',
1284
+ symbolName: symbol.name,
1285
+ symbolType: symbol.type,
1286
+ location: {
1287
+ filePath,
1288
+ line: symbol.location.range.start.line,
1289
+ column: symbol.location.range.start.column
1290
+ },
1291
+ message: `變數 "${symbol.name}" 以底線開頭,違反命名規範`
1292
+ });
1293
+ }
1294
+ // 檢測常數未使用大寫(如果標記為 const)
1295
+ if (symbol.modifiers?.includes('const') &&
1296
+ symbol.type === SymbolType.Variable &&
1297
+ !/^[A-Z_]+$/.test(symbol.name) &&
1298
+ symbol.name.length > 1) {
1299
+ // 這是建議性質,不一定要強制
1300
+ }
1301
+ }
1302
+ return issues;
1303
+ }
1304
+ /**
1305
+ * 判斷檔案是否為測試檔案
1306
+ */
1307
+ isTestFile(filePath) {
1308
+ return /\.(test|spec)\.(ts|tsx)$/.test(filePath) ||
1309
+ filePath.includes('/__tests__/') ||
1310
+ filePath.includes('/__mocks__/');
1311
+ }
976
1312
  }
977
1313
  //# sourceMappingURL=parser.js.map