agent-ide 0.8.1 → 0.8.2

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 (311) hide show
  1. package/dist/application/index.d.ts +1 -12
  2. package/dist/application/index.d.ts.map +1 -1
  3. package/dist/application/index.js +0 -16
  4. package/dist/application/index.js.map +1 -1
  5. package/dist/application/services/cache-coordinator.service.d.ts.map +1 -1
  6. package/dist/application/services/cache-coordinator.service.js.map +1 -1
  7. package/dist/application/services/module-coordinator.service.d.ts +3 -8
  8. package/dist/application/services/module-coordinator.service.d.ts.map +1 -1
  9. package/dist/application/services/module-coordinator.service.js +5 -139
  10. package/dist/application/services/module-coordinator.service.js.map +1 -1
  11. package/dist/application/types.d.ts +0 -63
  12. package/dist/application/types.d.ts.map +1 -1
  13. package/dist/application/types.js +1 -9
  14. package/dist/application/types.js.map +1 -1
  15. package/dist/core/call-hierarchy/call-hierarchy-analyzer.d.ts.map +1 -1
  16. package/dist/core/call-hierarchy/call-hierarchy-analyzer.js +3 -5
  17. package/dist/core/call-hierarchy/call-hierarchy-analyzer.js.map +1 -1
  18. package/dist/core/change-signature/change-signature-service.d.ts +9 -0
  19. package/dist/core/change-signature/change-signature-service.d.ts.map +1 -1
  20. package/dist/core/change-signature/change-signature-service.js +86 -4
  21. package/dist/core/change-signature/change-signature-service.js.map +1 -1
  22. package/dist/core/change-signature/signature-parser.d.ts +46 -4
  23. package/dist/core/change-signature/signature-parser.d.ts.map +1 -1
  24. package/dist/core/change-signature/signature-parser.js +180 -9
  25. package/dist/core/change-signature/signature-parser.js.map +1 -1
  26. package/dist/core/deadcode/dead-code-detector.d.ts +22 -1
  27. package/dist/core/deadcode/dead-code-detector.d.ts.map +1 -1
  28. package/dist/core/deadcode/dead-code-detector.js +134 -61
  29. package/dist/core/deadcode/dead-code-detector.js.map +1 -1
  30. package/dist/core/deadcode/dead-code-remover.d.ts +11 -93
  31. package/dist/core/deadcode/dead-code-remover.d.ts.map +1 -1
  32. package/dist/core/deadcode/dead-code-remover.js +71 -690
  33. package/dist/core/deadcode/dead-code-remover.js.map +1 -1
  34. package/dist/core/deadcode/file-operations.d.ts +85 -0
  35. package/dist/core/deadcode/file-operations.d.ts.map +1 -0
  36. package/dist/core/deadcode/file-operations.js +263 -0
  37. package/dist/core/deadcode/file-operations.js.map +1 -0
  38. package/dist/core/deadcode/import-cleaner.d.ts +63 -0
  39. package/dist/core/deadcode/import-cleaner.d.ts.map +1 -0
  40. package/dist/core/deadcode/import-cleaner.js +229 -0
  41. package/dist/core/deadcode/import-cleaner.js.map +1 -0
  42. package/dist/core/deadcode/import-parser.d.ts +79 -0
  43. package/dist/core/deadcode/import-parser.d.ts.map +1 -0
  44. package/dist/core/deadcode/import-parser.js +229 -0
  45. package/dist/core/deadcode/import-parser.js.map +1 -0
  46. package/dist/core/deadcode/range-expander.d.ts +38 -0
  47. package/dist/core/deadcode/range-expander.d.ts.map +1 -0
  48. package/dist/core/deadcode/range-expander.js +175 -0
  49. package/dist/core/deadcode/range-expander.js.map +1 -0
  50. package/dist/core/deadcode/types.d.ts +2 -0
  51. package/dist/core/deadcode/types.d.ts.map +1 -1
  52. package/dist/core/deadcode/types.js.map +1 -1
  53. package/dist/core/find-references/index.d.ts +2 -2
  54. package/dist/core/find-references/index.d.ts.map +1 -1
  55. package/dist/core/find-references/index.js +1 -1
  56. package/dist/core/find-references/index.js.map +1 -1
  57. package/dist/core/move/import-resolver.d.ts +5 -0
  58. package/dist/core/move/import-resolver.d.ts.map +1 -1
  59. package/dist/core/move/import-resolver.js +7 -0
  60. package/dist/core/move/import-resolver.js.map +1 -1
  61. package/dist/core/move/move-service.d.ts +39 -1
  62. package/dist/core/move/move-service.d.ts.map +1 -1
  63. package/dist/core/move/move-service.js +230 -63
  64. package/dist/core/move/move-service.js.map +1 -1
  65. package/dist/core/move/types.d.ts.map +1 -1
  66. package/dist/core/move-member/member-extractor.d.ts.map +1 -1
  67. package/dist/core/move-member/member-extractor.js +2 -2
  68. package/dist/core/move-member/member-extractor.js.map +1 -1
  69. package/dist/core/move-member/move-member-service.d.ts +6 -0
  70. package/dist/core/move-member/move-member-service.d.ts.map +1 -1
  71. package/dist/core/move-member/move-member-service.js +60 -3
  72. package/dist/core/move-member/move-member-service.js.map +1 -1
  73. package/dist/core/move-member/types.d.ts.map +1 -1
  74. package/dist/core/rename/reference-updater.d.ts +1 -35
  75. package/dist/core/rename/reference-updater.d.ts.map +1 -1
  76. package/dist/core/rename/reference-updater.js +4 -250
  77. package/dist/core/rename/reference-updater.js.map +1 -1
  78. package/dist/core/rename/rename-engine.d.ts +14 -22
  79. package/dist/core/rename/rename-engine.d.ts.map +1 -1
  80. package/dist/core/rename/rename-engine.js +37 -207
  81. package/dist/core/rename/rename-engine.js.map +1 -1
  82. package/dist/core/rename/scope-analyzer.d.ts.map +1 -1
  83. package/dist/core/shared/index.d.ts +1 -1
  84. package/dist/core/shared/index.d.ts.map +1 -1
  85. package/dist/core/shared/index.js +1 -1
  86. package/dist/core/shared/index.js.map +1 -1
  87. package/dist/core/shared/indexing/index-engine.d.ts +1 -1
  88. package/dist/core/shared/indexing/index-engine.d.ts.map +1 -1
  89. package/dist/core/shared/indexing/index-engine.js +1 -1
  90. package/dist/core/shared/indexing/index-engine.js.map +1 -1
  91. package/dist/core/shared/symbol-finder/call-site-parser.d.ts +71 -0
  92. package/dist/core/shared/symbol-finder/call-site-parser.d.ts.map +1 -0
  93. package/dist/core/shared/symbol-finder/call-site-parser.js +369 -0
  94. package/dist/core/shared/symbol-finder/call-site-parser.js.map +1 -0
  95. package/dist/core/shared/symbol-finder/index.d.ts +9 -0
  96. package/dist/core/shared/symbol-finder/index.d.ts.map +1 -0
  97. package/dist/core/shared/symbol-finder/index.js +12 -0
  98. package/dist/core/shared/symbol-finder/index.js.map +1 -0
  99. package/dist/core/shared/{symbol-finder.d.ts → symbol-finder/symbol-finder.d.ts} +27 -133
  100. package/dist/core/shared/symbol-finder/symbol-finder.d.ts.map +1 -0
  101. package/dist/core/shared/symbol-finder/symbol-finder.js +544 -0
  102. package/dist/core/shared/symbol-finder/symbol-finder.js.map +1 -0
  103. package/dist/core/shared/symbol-finder/text-matcher.d.ts +45 -0
  104. package/dist/core/shared/symbol-finder/text-matcher.d.ts.map +1 -0
  105. package/dist/core/shared/symbol-finder/text-matcher.js +195 -0
  106. package/dist/core/shared/symbol-finder/text-matcher.js.map +1 -0
  107. package/dist/core/shared/symbol-finder/types.d.ts +108 -0
  108. package/dist/core/shared/symbol-finder/types.d.ts.map +1 -0
  109. package/dist/core/shared/symbol-finder/types.js +71 -0
  110. package/dist/core/shared/symbol-finder/types.js.map +1 -0
  111. package/dist/core/snapshot/snapshot-generator.d.ts +16 -4
  112. package/dist/core/snapshot/snapshot-generator.d.ts.map +1 -1
  113. package/dist/core/snapshot/snapshot-generator.js +91 -18
  114. package/dist/core/snapshot/snapshot-generator.js.map +1 -1
  115. package/dist/infrastructure/cache/cache-manager.d.ts.map +1 -1
  116. package/dist/infrastructure/cache/cache-manager.js +4 -0
  117. package/dist/infrastructure/cache/cache-manager.js.map +1 -1
  118. package/dist/infrastructure/cache/index.d.ts +15 -9
  119. package/dist/infrastructure/cache/index.d.ts.map +1 -1
  120. package/dist/infrastructure/cache/index.js +5 -5
  121. package/dist/infrastructure/cache/index.js.map +1 -1
  122. package/dist/infrastructure/cache/memory-cache.d.ts.map +1 -1
  123. package/dist/infrastructure/cache/memory-cache.js.map +1 -1
  124. package/dist/infrastructure/cache/strategies.d.ts.map +1 -1
  125. package/dist/infrastructure/cache/strategies.js +2 -1
  126. package/dist/infrastructure/cache/strategies.js.map +1 -1
  127. package/dist/infrastructure/cache/types.d.ts +4 -4
  128. package/dist/infrastructure/cache/types.d.ts.map +1 -1
  129. package/dist/infrastructure/changeset/change-applicator.d.ts +95 -0
  130. package/dist/infrastructure/changeset/change-applicator.d.ts.map +1 -0
  131. package/dist/infrastructure/changeset/change-applicator.js +466 -0
  132. package/dist/infrastructure/changeset/change-applicator.js.map +1 -0
  133. package/dist/infrastructure/changeset/changeset-builder.d.ts +107 -0
  134. package/dist/infrastructure/changeset/changeset-builder.d.ts.map +1 -0
  135. package/dist/infrastructure/changeset/changeset-builder.js +183 -0
  136. package/dist/infrastructure/changeset/changeset-builder.js.map +1 -0
  137. package/dist/infrastructure/changeset/changeset-converter.d.ts +15 -0
  138. package/dist/infrastructure/changeset/changeset-converter.d.ts.map +1 -0
  139. package/dist/infrastructure/changeset/changeset-converter.js +369 -0
  140. package/dist/infrastructure/changeset/changeset-converter.js.map +1 -0
  141. package/dist/infrastructure/changeset/index.d.ts +9 -0
  142. package/dist/infrastructure/changeset/index.d.ts.map +1 -0
  143. package/dist/infrastructure/changeset/index.js +11 -0
  144. package/dist/infrastructure/changeset/index.js.map +1 -0
  145. package/dist/infrastructure/changeset/types.d.ts +110 -0
  146. package/dist/infrastructure/changeset/types.d.ts.map +1 -0
  147. package/dist/infrastructure/changeset/types.js +6 -0
  148. package/dist/infrastructure/changeset/types.js.map +1 -0
  149. package/dist/infrastructure/parser/base.d.ts.map +1 -1
  150. package/dist/infrastructure/parser/base.js +4 -3
  151. package/dist/infrastructure/parser/base.js.map +1 -1
  152. package/dist/infrastructure/parser/interface.d.ts +4 -2
  153. package/dist/infrastructure/parser/interface.d.ts.map +1 -1
  154. package/dist/infrastructure/parser/interface.js.map +1 -1
  155. package/dist/infrastructure/storage/file-system.d.ts.map +1 -1
  156. package/dist/infrastructure/storage/file-system.js +61 -54
  157. package/dist/infrastructure/storage/file-system.js.map +1 -1
  158. package/dist/interfaces/cli/commands/change-signature.command.d.ts.map +1 -1
  159. package/dist/interfaces/cli/commands/change-signature.command.js +31 -107
  160. package/dist/interfaces/cli/commands/change-signature.command.js.map +1 -1
  161. package/dist/interfaces/cli/commands/deadcode.command.js +51 -46
  162. package/dist/interfaces/cli/commands/deadcode.command.js.map +1 -1
  163. package/dist/interfaces/cli/commands/find-references.command.d.ts.map +1 -1
  164. package/dist/interfaces/cli/commands/find-references.command.js +18 -3
  165. package/dist/interfaces/cli/commands/find-references.command.js.map +1 -1
  166. package/dist/interfaces/cli/commands/move-member.command.d.ts.map +1 -1
  167. package/dist/interfaces/cli/commands/move-member.command.js +32 -103
  168. package/dist/interfaces/cli/commands/move-member.command.js.map +1 -1
  169. package/dist/interfaces/cli/commands/move.command.js +43 -54
  170. package/dist/interfaces/cli/commands/move.command.js.map +1 -1
  171. package/dist/interfaces/cli/commands/rename.command.js +27 -61
  172. package/dist/interfaces/cli/commands/rename.command.js.map +1 -1
  173. package/dist/interfaces/cli/output-formatter.d.ts +2 -2
  174. package/dist/interfaces/cli/output-formatter.d.ts.map +1 -1
  175. package/dist/interfaces/cli/output-formatter.js.map +1 -1
  176. package/dist/plugins/javascript/parser.d.ts +11 -10
  177. package/dist/plugins/javascript/parser.d.ts.map +1 -1
  178. package/dist/plugins/javascript/parser.js +57 -53
  179. package/dist/plugins/javascript/parser.js.map +1 -1
  180. package/dist/plugins/javascript/pattern-analyzer.d.ts.map +1 -1
  181. package/dist/plugins/javascript/pattern-analyzer.js +4 -3
  182. package/dist/plugins/javascript/pattern-analyzer.js.map +1 -1
  183. package/dist/plugins/javascript/reference-finder.d.ts +21 -0
  184. package/dist/plugins/javascript/reference-finder.d.ts.map +1 -1
  185. package/dist/plugins/javascript/reference-finder.js +119 -76
  186. package/dist/plugins/javascript/reference-finder.js.map +1 -1
  187. package/dist/plugins/javascript/types.d.ts +4 -7
  188. package/dist/plugins/javascript/types.d.ts.map +1 -1
  189. package/dist/plugins/javascript/types.js +9 -9
  190. package/dist/plugins/javascript/types.js.map +1 -1
  191. package/dist/plugins/shared/parser-helpers.js.map +1 -1
  192. package/dist/{shared → plugins/shared}/utils/array.d.ts +6 -1
  193. package/dist/plugins/shared/utils/array.d.ts.map +1 -0
  194. package/dist/plugins/shared/utils/array.js.map +1 -0
  195. package/dist/{shared → plugins/shared}/utils/async.d.ts +1 -1
  196. package/dist/plugins/shared/utils/async.d.ts.map +1 -0
  197. package/dist/{shared → plugins/shared}/utils/async.js +2 -0
  198. package/dist/plugins/shared/utils/async.js.map +1 -0
  199. package/dist/{shared → plugins/shared}/utils/index.d.ts +0 -20
  200. package/dist/plugins/shared/utils/index.d.ts.map +1 -0
  201. package/dist/{shared → plugins/shared}/utils/index.js +0 -20
  202. package/dist/plugins/shared/utils/index.js.map +1 -0
  203. package/dist/plugins/shared/utils/memory-monitor.d.ts.map +1 -0
  204. package/dist/plugins/shared/utils/memory-monitor.js.map +1 -0
  205. package/dist/{shared → plugins/shared}/utils/object.d.ts +6 -6
  206. package/dist/plugins/shared/utils/object.d.ts.map +1 -0
  207. package/dist/{shared → plugins/shared}/utils/object.js +21 -3
  208. package/dist/plugins/shared/utils/object.js.map +1 -0
  209. package/dist/plugins/shared/utils/path.d.ts.map +1 -0
  210. package/dist/plugins/shared/utils/path.js.map +1 -0
  211. package/dist/{shared → plugins/shared}/utils/string.d.ts +1 -1
  212. package/dist/plugins/shared/utils/string.d.ts.map +1 -0
  213. package/dist/{shared → plugins/shared}/utils/string.js +7 -4
  214. package/dist/plugins/shared/utils/string.js.map +1 -0
  215. package/dist/plugins/typescript/declaration-analyzer.d.ts +4 -4
  216. package/dist/plugins/typescript/declaration-analyzer.d.ts.map +1 -1
  217. package/dist/plugins/typescript/declaration-analyzer.js +9 -6
  218. package/dist/plugins/typescript/declaration-analyzer.js.map +1 -1
  219. package/dist/plugins/typescript/language-service.d.ts +1 -1
  220. package/dist/plugins/typescript/language-service.d.ts.map +1 -1
  221. package/dist/plugins/typescript/parser.d.ts +3 -2
  222. package/dist/plugins/typescript/parser.d.ts.map +1 -1
  223. package/dist/plugins/typescript/parser.js +18 -13
  224. package/dist/plugins/typescript/parser.js.map +1 -1
  225. package/dist/plugins/typescript/reference-finder.d.ts +3 -0
  226. package/dist/plugins/typescript/reference-finder.d.ts.map +1 -1
  227. package/dist/plugins/typescript/reference-finder.js +5 -2
  228. package/dist/plugins/typescript/reference-finder.js.map +1 -1
  229. package/dist/plugins/typescript/symbol-extractor.d.ts +4 -0
  230. package/dist/plugins/typescript/symbol-extractor.d.ts.map +1 -1
  231. package/dist/plugins/typescript/symbol-extractor.js +18 -4
  232. package/dist/plugins/typescript/symbol-extractor.js.map +1 -1
  233. package/dist/plugins/typescript/types.d.ts +0 -3
  234. package/dist/plugins/typescript/types.d.ts.map +1 -1
  235. package/dist/plugins/typescript/types.js +6 -9
  236. package/dist/plugins/typescript/types.js.map +1 -1
  237. package/dist/shared/errors/index.d.ts +1 -1
  238. package/dist/shared/errors/index.d.ts.map +1 -1
  239. package/dist/shared/errors/parser-error.js +5 -5
  240. package/dist/shared/errors/parser-error.js.map +1 -1
  241. package/dist/shared/errors/validation-error.d.ts +2 -2
  242. package/dist/shared/errors/validation-error.d.ts.map +1 -1
  243. package/dist/shared/errors/validation-error.js.map +1 -1
  244. package/dist/shared/types/ast.d.ts +4 -4
  245. package/dist/shared/types/ast.d.ts.map +1 -1
  246. package/dist/shared/types/ast.js.map +1 -1
  247. package/dist/shared/types/core.d.ts +1 -1
  248. package/dist/shared/types/core.d.ts.map +1 -1
  249. package/dist/shared/types/index.d.ts +1 -0
  250. package/dist/shared/types/index.d.ts.map +1 -1
  251. package/dist/shared/types/index.js +2 -0
  252. package/dist/shared/types/index.js.map +1 -1
  253. package/dist/shared/types/line-number.d.ts +22 -0
  254. package/dist/shared/types/line-number.d.ts.map +1 -0
  255. package/dist/shared/types/line-number.js +28 -0
  256. package/dist/shared/types/line-number.js.map +1 -0
  257. package/package.json +2 -2
  258. package/dist/application/services/workflow-engine.service.d.ts +0 -76
  259. package/dist/application/services/workflow-engine.service.d.ts.map +0 -1
  260. package/dist/application/services/workflow-engine.service.js +0 -405
  261. package/dist/application/services/workflow-engine.service.js.map +0 -1
  262. package/dist/application/workflows/analysis-workflow.d.ts +0 -239
  263. package/dist/application/workflows/analysis-workflow.d.ts.map +0 -1
  264. package/dist/application/workflows/analysis-workflow.js +0 -395
  265. package/dist/application/workflows/analysis-workflow.js.map +0 -1
  266. package/dist/application/workflows/base-workflow.d.ts +0 -108
  267. package/dist/application/workflows/base-workflow.d.ts.map +0 -1
  268. package/dist/application/workflows/base-workflow.js +0 -236
  269. package/dist/application/workflows/base-workflow.js.map +0 -1
  270. package/dist/application/workflows/index.d.ts +0 -115
  271. package/dist/application/workflows/index.d.ts.map +0 -1
  272. package/dist/application/workflows/index.js +0 -218
  273. package/dist/application/workflows/index.js.map +0 -1
  274. package/dist/application/workflows/refactor-workflow.d.ts +0 -107
  275. package/dist/application/workflows/refactor-workflow.d.ts.map +0 -1
  276. package/dist/application/workflows/refactor-workflow.js +0 -310
  277. package/dist/application/workflows/refactor-workflow.js.map +0 -1
  278. package/dist/core/shared/symbol-finder.d.ts.map +0 -1
  279. package/dist/core/shared/symbol-finder.js +0 -882
  280. package/dist/core/shared/symbol-finder.js.map +0 -1
  281. package/dist/plugins/javascript/code-analyzer.d.ts +0 -68
  282. package/dist/plugins/javascript/code-analyzer.d.ts.map +0 -1
  283. package/dist/plugins/javascript/code-analyzer.js +0 -302
  284. package/dist/plugins/javascript/code-analyzer.js.map +0 -1
  285. package/dist/plugins/javascript/index.d.ts +0 -12
  286. package/dist/plugins/javascript/index.d.ts.map +0 -1
  287. package/dist/plugins/javascript/index.js +0 -16
  288. package/dist/plugins/javascript/index.js.map +0 -1
  289. package/dist/plugins/typescript/index.d.ts +0 -14
  290. package/dist/plugins/typescript/index.d.ts.map +0 -1
  291. package/dist/plugins/typescript/index.js +0 -13
  292. package/dist/plugins/typescript/index.js.map +0 -1
  293. package/dist/shared/utils/array.d.ts.map +0 -1
  294. package/dist/shared/utils/array.js.map +0 -1
  295. package/dist/shared/utils/async.d.ts.map +0 -1
  296. package/dist/shared/utils/async.js.map +0 -1
  297. package/dist/shared/utils/index.d.ts.map +0 -1
  298. package/dist/shared/utils/index.js.map +0 -1
  299. package/dist/shared/utils/memory-monitor.d.ts.map +0 -1
  300. package/dist/shared/utils/memory-monitor.js.map +0 -1
  301. package/dist/shared/utils/object.d.ts.map +0 -1
  302. package/dist/shared/utils/object.js.map +0 -1
  303. package/dist/shared/utils/path.d.ts.map +0 -1
  304. package/dist/shared/utils/path.js.map +0 -1
  305. package/dist/shared/utils/string.d.ts.map +0 -1
  306. package/dist/shared/utils/string.js.map +0 -1
  307. /package/dist/{shared → plugins/shared}/utils/array.js +0 -0
  308. /package/dist/{shared → plugins/shared}/utils/memory-monitor.d.ts +0 -0
  309. /package/dist/{shared → plugins/shared}/utils/memory-monitor.js +0 -0
  310. /package/dist/{shared → plugins/shared}/utils/path.d.ts +0 -0
  311. /package/dist/{shared → plugins/shared}/utils/path.js +0 -0
@@ -1,882 +0,0 @@
1
- /**
2
- * 統一的符號查找器
3
- * 整合 AST 分析和文字匹配,提供跨檔案符號查找能力
4
- */
5
- import { SymbolType } from '../../shared/types/symbol.js';
6
- import { ScopedReferenceKind } from '../../infrastructure/parser/interface.js';
7
- /**
8
- * 符號引用類型
9
- */
10
- export var SymbolReferenceType;
11
- (function (SymbolReferenceType) {
12
- SymbolReferenceType["Definition"] = "definition";
13
- SymbolReferenceType["Usage"] = "usage";
14
- SymbolReferenceType["Import"] = "import";
15
- SymbolReferenceType["Export"] = "export";
16
- })(SymbolReferenceType || (SymbolReferenceType = {}));
17
- /**
18
- * 類別成員類型
19
- */
20
- export var ClassMemberType;
21
- (function (ClassMemberType) {
22
- ClassMemberType["Method"] = "method";
23
- ClassMemberType["Property"] = "property";
24
- ClassMemberType["Getter"] = "getter";
25
- ClassMemberType["Setter"] = "setter";
26
- ClassMemberType["Constructor"] = "constructor";
27
- })(ClassMemberType || (ClassMemberType = {}));
28
- /**
29
- * 符號查找器
30
- */
31
- export class SymbolFinder {
32
- parserRegistry;
33
- fileSystem;
34
- constructor(parserRegistry, fileSystem) {
35
- this.parserRegistry = parserRegistry;
36
- this.fileSystem = fileSystem;
37
- }
38
- /**
39
- * 查找符號定義
40
- */
41
- async findDefinition(filePath, symbolName) {
42
- const content = await this.readFile(filePath);
43
- if (!content) {
44
- return null;
45
- }
46
- const parser = this.getParser(filePath);
47
- if (!parser) {
48
- return null;
49
- }
50
- try {
51
- const ast = await parser.parse(content, filePath);
52
- const symbols = await parser.extractSymbols(ast);
53
- const symbol = symbols.find(s => s.name === symbolName);
54
- if (!symbol) {
55
- return null;
56
- }
57
- // 優先使用 Parser 的 getDocumentation 方法(AST 精確解析)
58
- // 若 Parser 不支援或返回 null,fallback 到行號回掃邏輯
59
- let documentation;
60
- if (parser.getDocumentation) {
61
- const doc = parser.getDocumentation(content, symbol.name, symbol.type, symbol.location.range.start.line);
62
- documentation = doc?.rawText;
63
- }
64
- if (!documentation) {
65
- documentation = this.extractDocumentationByLineScanning(content, symbol);
66
- }
67
- return {
68
- symbol,
69
- signature: this.extractSignature(content, symbol),
70
- documentation
71
- };
72
- }
73
- catch {
74
- return null;
75
- }
76
- }
77
- /**
78
- * 批次查找符號的引用(一次遍歷所有檔案,減少重複解析)
79
- * 時間複雜度:O(M × N),M=檔案數,N=符號數
80
- * 優化點:M 次檔案讀取/解析(一次遍歷 M 檔查找 N 符號),
81
- * 而非 N×M 次(N 符號各遍歷 M 檔)
82
- */
83
- async findReferencesMultiple(symbolNames, projectFiles) {
84
- const results = new Map();
85
- // 初始化結果 Map
86
- for (const name of symbolNames) {
87
- results.set(name, []);
88
- }
89
- // 一次遍歷所有檔案
90
- for (const filePath of projectFiles) {
91
- const content = await this.readFile(filePath);
92
- if (!content) {
93
- continue;
94
- }
95
- const parser = this.getParser(filePath);
96
- if (!parser) {
97
- // 降級到文字匹配
98
- this.findReferencesMultipleByText(filePath, content, symbolNames, results);
99
- continue;
100
- }
101
- try {
102
- const ast = await parser.parse(content, filePath);
103
- // 對每個目標符號查找引用
104
- for (const symbolName of symbolNames) {
105
- const dummySymbol = {
106
- name: symbolName,
107
- type: SymbolType.Variable,
108
- location: {
109
- filePath,
110
- range: {
111
- start: { line: 1, column: 1, offset: undefined },
112
- end: { line: 1, column: 1, offset: undefined }
113
- }
114
- },
115
- scope: undefined,
116
- modifiers: []
117
- };
118
- const references = await parser.findReferences(ast, dummySymbol);
119
- const refs = results.get(symbolName);
120
- if (!refs) {
121
- continue;
122
- }
123
- for (const ref of references) {
124
- refs.push({
125
- symbolName,
126
- location: ref.location,
127
- type: ref.type === 'definition'
128
- ? SymbolReferenceType.Definition
129
- : SymbolReferenceType.Usage
130
- });
131
- }
132
- }
133
- }
134
- catch {
135
- // Parser 失敗,降級到文字匹配
136
- this.findReferencesMultipleByText(filePath, content, symbolNames, results);
137
- }
138
- }
139
- return results;
140
- }
141
- /**
142
- * 批次文字匹配查找(降級方法)
143
- */
144
- findReferencesMultipleByText(filePath, content, symbolNames, results) {
145
- const lines = content.split('\n');
146
- for (const symbolName of symbolNames) {
147
- const regex = new RegExp(`\\b${this.escapeRegex(symbolName)}\\b`, 'g');
148
- const refs = results.get(symbolName);
149
- if (!refs) {
150
- continue;
151
- }
152
- for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
153
- const line = lines[lineIndex];
154
- let match;
155
- while ((match = regex.exec(line)) !== null) {
156
- refs.push({
157
- symbolName,
158
- location: {
159
- filePath,
160
- range: {
161
- start: { line: lineIndex + 1, column: match.index + 1, offset: undefined },
162
- end: { line: lineIndex + 1, column: match.index + 1 + symbolName.length, offset: undefined }
163
- }
164
- },
165
- type: SymbolReferenceType.Usage,
166
- context: line.trim()
167
- });
168
- }
169
- }
170
- }
171
- }
172
- /**
173
- * 查找檔案中的符號引用
174
- */
175
- async findReferencesInFile(filePath, symbolName) {
176
- const content = await this.readFile(filePath);
177
- if (!content) {
178
- return [];
179
- }
180
- const parser = this.getParser(filePath);
181
- if (!parser) {
182
- // 降級到文字匹配
183
- return this.findReferencesByText(filePath, content, symbolName);
184
- }
185
- try {
186
- const ast = await parser.parse(content, filePath);
187
- // 建立虛擬符號用於查找
188
- const dummySymbol = {
189
- name: symbolName,
190
- type: SymbolType.Variable,
191
- location: {
192
- filePath,
193
- range: {
194
- start: { line: 1, column: 1, offset: undefined },
195
- end: { line: 1, column: 1, offset: undefined }
196
- }
197
- },
198
- scope: undefined,
199
- modifiers: []
200
- };
201
- const references = await parser.findReferences(ast, dummySymbol);
202
- const lines = content.split('\n');
203
- return references.map(ref => {
204
- const lineIndex = ref.location.range.start.line - 1;
205
- // 保留原始行內容(不 trim),讓 diff 輸出保持正確的縮排
206
- const context = lineIndex >= 0 && lineIndex < lines.length
207
- ? lines[lineIndex]
208
- : undefined;
209
- return {
210
- symbolName,
211
- location: ref.location,
212
- type: ref.type === 'definition'
213
- ? SymbolReferenceType.Definition
214
- : SymbolReferenceType.Usage,
215
- context
216
- };
217
- });
218
- }
219
- catch {
220
- // Parser 失敗,降級到文字匹配
221
- return this.findReferencesByText(filePath, content, symbolName);
222
- }
223
- }
224
- /**
225
- * 使用完整符號資訊查找檔案中的引用(作用域感知版本)
226
- *
227
- * 此方法會:
228
- * 1. 使用完整的符號資訊(包含類型、作用域等)進行精確匹配
229
- * 2. 過濾掉註解和字串中的符號
230
- * 3. 包含完整的程式碼上下文
231
- *
232
- * @param filePath 檔案路徑
233
- * @param symbol 完整的符號資訊
234
- * @returns 符號引用陣列
235
- */
236
- async findReferencesInFileWithSymbol(filePath, symbol) {
237
- const content = await this.readFile(filePath);
238
- if (!content) {
239
- return [];
240
- }
241
- const parser = this.getParser(filePath);
242
- if (!parser) {
243
- // 降級到文字匹配(但會過濾字串和註解)
244
- return this.findReferencesByTextFiltered(filePath, content, symbol.name);
245
- }
246
- try {
247
- const ast = await parser.parse(content, filePath);
248
- // 使用完整符號資訊進行查找
249
- const references = await parser.findReferences(ast, symbol);
250
- const lines = content.split('\n');
251
- return references.map(ref => {
252
- const lineIndex = ref.location.range.start.line - 1;
253
- // 保留原始行內容(不 trim),讓 diff 輸出保持正確的縮排
254
- const context = lineIndex >= 0 && lineIndex < lines.length
255
- ? lines[lineIndex]
256
- : undefined;
257
- return {
258
- symbolName: symbol.name,
259
- location: ref.location,
260
- type: ref.type === 'definition'
261
- ? SymbolReferenceType.Definition
262
- : SymbolReferenceType.Usage,
263
- context
264
- };
265
- });
266
- }
267
- catch {
268
- // Parser 失敗,降級到文字匹配
269
- return this.findReferencesByTextFiltered(filePath, content, symbol.name);
270
- }
271
- }
272
- /**
273
- * 在多個檔案中查找符號引用(使用完整符號資訊)
274
- *
275
- * @param symbol 完整的符號資訊
276
- * @param projectFiles 專案檔案列表
277
- * @returns 所有找到的引用
278
- */
279
- async findReferencesWithSymbol(symbol, projectFiles) {
280
- const allReferences = [];
281
- for (const filePath of projectFiles) {
282
- const refs = await this.findReferencesInFileWithSymbol(filePath, symbol);
283
- allReferences.push(...refs);
284
- }
285
- return allReferences;
286
- }
287
- // ===== 作用域感知的符號查找(優先使用 Parser 語義分析) =====
288
- /**
289
- * 使用 Parser 的 findScopedReferences 方法查找符號引用(作用域感知版本)
290
- *
291
- * 此方法優先使用 Parser 的語義分析能力來精確匹配符號,
292
- * 可以區分不同類別的同名方法。
293
- *
294
- * @example
295
- * ```typescript
296
- * // 區分 Dog.bark() 和 Car.bark()
297
- * const refs = await finder.findScopedReferencesInFile(
298
- * 'src/animals.ts',
299
- * 'bark',
300
- * { className: 'Dog' }
301
- * );
302
- * ```
303
- *
304
- * @param filePath 檔案路徑
305
- * @param symbolName 符號名稱
306
- * @param options 作用域查找選項(可限定類別等)
307
- * @returns 符號引用陣列
308
- */
309
- async findScopedReferencesInFile(filePath, symbolName, options) {
310
- const content = await this.readFile(filePath);
311
- if (!content) {
312
- return [];
313
- }
314
- const parser = this.getParser(filePath);
315
- // 優先使用 Parser 的 findScopedReferences 方法
316
- if (parser && typeof parser.findScopedReferences === 'function') {
317
- const scopedRefs = parser.findScopedReferences(content, symbolName, options);
318
- if (scopedRefs) {
319
- const lines = content.split('\n');
320
- return scopedRefs.map(ref => {
321
- const lineIndex = ref.location.range.start.line - 1;
322
- const context = lineIndex >= 0 && lineIndex < lines.length
323
- ? lines[lineIndex]
324
- : undefined;
325
- // 轉換 ScopedReferenceKind 到 SymbolReferenceType
326
- const type = this.scopedReferenceKindToType(ref.kind);
327
- return {
328
- symbolName,
329
- location: {
330
- filePath,
331
- range: ref.location.range
332
- },
333
- type,
334
- context,
335
- containerName: ref.containerName,
336
- isMethodCall: ref.kind === ScopedReferenceKind.Call
337
- };
338
- });
339
- }
340
- }
341
- // Fallback:使用原有的文字匹配(帶過濾)
342
- return this.findReferencesByTextFiltered(filePath, content, symbolName);
343
- }
344
- /**
345
- * 在多個檔案中查找符號引用(作用域感知版本)
346
- *
347
- * @param symbolName 符號名稱
348
- * @param projectFiles 專案檔案列表
349
- * @param options 作用域查找選項
350
- * @returns 所有找到的引用
351
- */
352
- async findScopedReferences(symbolName, projectFiles, options) {
353
- const allReferences = [];
354
- for (const filePath of projectFiles) {
355
- const refs = await this.findScopedReferencesInFile(filePath, symbolName, options);
356
- allReferences.push(...refs);
357
- }
358
- return allReferences;
359
- }
360
- /**
361
- * 轉換 ScopedReferenceKind 到 SymbolReferenceType
362
- */
363
- scopedReferenceKindToType(kind) {
364
- switch (kind) {
365
- case ScopedReferenceKind.Write:
366
- return SymbolReferenceType.Definition;
367
- case ScopedReferenceKind.Call:
368
- case ScopedReferenceKind.Read:
369
- default:
370
- return SymbolReferenceType.Usage;
371
- }
372
- }
373
- /**
374
- * 查找函式的所有呼叫點
375
- */
376
- async findCallSites(functionName, projectFiles) {
377
- const results = [];
378
- for (const filePath of projectFiles) {
379
- const callSites = await this.findCallSitesInFile(filePath, functionName);
380
- results.push(...callSites);
381
- }
382
- return results;
383
- }
384
- /**
385
- * 查找檔案中的函式呼叫點
386
- */
387
- async findCallSitesInFile(filePath, functionName) {
388
- const content = await this.readFile(filePath);
389
- if (!content) {
390
- return [];
391
- }
392
- const parser = this.getParser(filePath);
393
- if (!parser) {
394
- return [];
395
- }
396
- try {
397
- // 驗證檔案可解析(確保語法正確)
398
- await parser.parse(content, filePath);
399
- // 查找所有函式呼叫
400
- const callSites = [];
401
- const lines = content.split('\n');
402
- // 使用正則表達式查找呼叫點
403
- const callPattern = new RegExp(`(?:(\\w+)\\.)?${this.escapeRegex(functionName)}\\s*\\(`, 'g');
404
- // 函式定義的關鍵字模式(用於排除函式定義)
405
- const definitionKeywords = /(?:^|[\s{;])(async\s+)?(function\s+|static\s+|private\s+|public\s+|protected\s+|get\s+|set\s+)/;
406
- for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
407
- const line = lines[lineIndex];
408
- let match;
409
- while ((match = callPattern.exec(line)) !== null) {
410
- const receiver = match[1];
411
- const startColumn = match.index + 1;
412
- // 排除函式定義:檢查前面是否有定義關鍵字
413
- const beforeMatch = line.substring(0, match.index);
414
- if (definitionKeywords.test(beforeMatch)) {
415
- continue;
416
- }
417
- // 排除方法定義:檢查是否在類別中定義方法(沒有 receiver 且後面有返回類型)
418
- if (!receiver) {
419
- // 找到對應的右括號(支援多行)
420
- const argsStart = match.index + match[0].length - 1;
421
- const multilineResult = this.findMatchingCloseParenMultiline(lines, lineIndex, argsStart);
422
- if (multilineResult.index >= 0) {
423
- // 檢查右括號後是否有冒號(表示返回類型,即方法定義)
424
- const closingLine = lines[multilineResult.line];
425
- const afterParen = closingLine.substring(multilineResult.index + 1).trim();
426
- if (afterParen.startsWith(':') || afterParen.startsWith('{')) {
427
- continue;
428
- }
429
- }
430
- }
431
- // 解析參數(支援多行)
432
- const argsStart = match.index + match[0].length - 1;
433
- const multilineArgs = this.extractArgumentsStringMultiline(lines, lineIndex, argsStart);
434
- const args = this.parseArgumentsMultiline(multilineArgs.content, lineIndex + 1, argsStart);
435
- callSites.push({
436
- functionName,
437
- location: {
438
- filePath,
439
- range: {
440
- start: { line: lineIndex + 1, column: startColumn, offset: undefined },
441
- end: { line: multilineArgs.endLine + 1, column: multilineArgs.endColumn + 1, offset: undefined }
442
- }
443
- },
444
- arguments: args,
445
- isMethodCall: !!receiver,
446
- receiver
447
- });
448
- }
449
- }
450
- return callSites;
451
- }
452
- catch {
453
- return [];
454
- }
455
- }
456
- /**
457
- * 查找類別成員
458
- */
459
- async findClassMembers(filePath, className) {
460
- const content = await this.readFile(filePath);
461
- if (!content) {
462
- return [];
463
- }
464
- const parser = this.getParser(filePath);
465
- if (!parser) {
466
- return [];
467
- }
468
- try {
469
- const ast = await parser.parse(content, filePath);
470
- const symbols = await parser.extractSymbols(ast);
471
- // 查找類別
472
- const classSymbol = symbols.find(s => s.name === className && s.type === 'class');
473
- if (!classSymbol) {
474
- return [];
475
- }
476
- // 查找類別成員
477
- return symbols
478
- .filter(s => {
479
- // 檢查是否在類別範圍內
480
- const classRange = classSymbol.location.range;
481
- const symbolRange = s.location.range;
482
- return s.location.filePath === filePath
483
- && symbolRange.start.line >= classRange.start.line
484
- && symbolRange.end.line <= classRange.end.line
485
- && s.name !== className;
486
- })
487
- .map(s => ({
488
- name: s.name,
489
- type: this.symbolTypeToMemberType(s.type),
490
- location: s.location,
491
- modifiers: [...s.modifiers],
492
- valueType: undefined
493
- }));
494
- }
495
- catch {
496
- return [];
497
- }
498
- }
499
- /**
500
- * 讀取檔案內容
501
- */
502
- async readFile(filePath) {
503
- try {
504
- const content = await this.fileSystem.readFile(filePath, 'utf-8');
505
- return typeof content === 'string' ? content : content.toString('utf-8');
506
- }
507
- catch {
508
- return null;
509
- }
510
- }
511
- /**
512
- * 取得對應的 Parser
513
- */
514
- getParser(filePath) {
515
- const extension = this.getFileExtension(filePath);
516
- return this.parserRegistry.getParser(extension);
517
- }
518
- /**
519
- * 取得檔案副檔名
520
- */
521
- getFileExtension(filePath) {
522
- const lastDot = filePath.lastIndexOf('.');
523
- return lastDot >= 0 ? filePath.substring(lastDot) : '';
524
- }
525
- /**
526
- * 使用文字匹配查找引用(降級方法)
527
- */
528
- findReferencesByText(filePath, content, symbolName) {
529
- const references = [];
530
- const lines = content.split('\n');
531
- const regex = new RegExp(`\\b${this.escapeRegex(symbolName)}\\b`, 'g');
532
- for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
533
- const line = lines[lineIndex];
534
- let match;
535
- while ((match = regex.exec(line)) !== null) {
536
- const startColumn = match.index + 1;
537
- references.push({
538
- symbolName,
539
- location: {
540
- filePath,
541
- range: {
542
- start: { line: lineIndex + 1, column: startColumn, offset: undefined },
543
- end: { line: lineIndex + 1, column: startColumn + symbolName.length, offset: undefined }
544
- }
545
- },
546
- type: SymbolReferenceType.Usage,
547
- // 保留原始行內容(不 trim),讓 diff 輸出保持正確的縮排
548
- context: line
549
- });
550
- }
551
- }
552
- return references;
553
- }
554
- /**
555
- * 使用文字匹配查找引用(過濾字串和註解版本)
556
- *
557
- * 此方法會過濾掉:
558
- * 1. 字串字面值中的符號(單引號、雙引號、模板字串)
559
- * 2. 單行註解中的符號(// 和 #)
560
- * 3. 多行註解中的符號
561
- */
562
- findReferencesByTextFiltered(filePath, content, symbolName) {
563
- const references = [];
564
- const lines = content.split('\n');
565
- const regex = new RegExp(`\\b${this.escapeRegex(symbolName)}\\b`, 'g');
566
- let inBlockComment = false;
567
- for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
568
- const line = lines[lineIndex];
569
- let match;
570
- // 追蹤多行註解狀態
571
- if (inBlockComment) {
572
- const closeCommentIndex = line.indexOf('*/');
573
- if (closeCommentIndex >= 0) {
574
- inBlockComment = false;
575
- }
576
- else {
577
- continue; // 整行在多行註解中,跳過
578
- }
579
- }
580
- while ((match = regex.exec(line)) !== null) {
581
- const position = match.index;
582
- // 檢查是否在字串中
583
- if (this.isInString(line, position)) {
584
- continue;
585
- }
586
- // 檢查是否在單行註解中
587
- if (this.isInSingleLineComment(line, position)) {
588
- continue;
589
- }
590
- // 檢查是否在多行註解開始後
591
- const openCommentIndex = line.lastIndexOf('/*', position);
592
- if (openCommentIndex >= 0) {
593
- const closeCommentIndex = line.indexOf('*/', openCommentIndex);
594
- if (closeCommentIndex < 0 || closeCommentIndex > position) {
595
- // 在未關閉的多行註解中
596
- if (closeCommentIndex < 0) {
597
- inBlockComment = true;
598
- }
599
- continue;
600
- }
601
- }
602
- const startColumn = position + 1;
603
- references.push({
604
- symbolName,
605
- location: {
606
- filePath,
607
- range: {
608
- start: { line: lineIndex + 1, column: startColumn, offset: undefined },
609
- end: { line: lineIndex + 1, column: startColumn + symbolName.length, offset: undefined }
610
- }
611
- },
612
- type: SymbolReferenceType.Usage,
613
- // 保留原始行內容(不 trim),讓 diff 輸出保持正確的縮排
614
- context: line
615
- });
616
- }
617
- }
618
- return references;
619
- }
620
- /**
621
- * 檢查位置是否在字串字面值中
622
- */
623
- isInString(line, position) {
624
- let inSingleQuote = false;
625
- let inDoubleQuote = false;
626
- let inTemplate = false;
627
- for (let i = 0; i < position; i++) {
628
- const char = line[i];
629
- const prevChar = i > 0 ? line[i - 1] : '';
630
- // 跳過轉義字元
631
- if (prevChar === '\\') {
632
- continue;
633
- }
634
- if (char === '\'' && !inDoubleQuote && !inTemplate) {
635
- inSingleQuote = !inSingleQuote;
636
- }
637
- else if (char === '"' && !inSingleQuote && !inTemplate) {
638
- inDoubleQuote = !inDoubleQuote;
639
- }
640
- else if (char === '`' && !inSingleQuote && !inDoubleQuote) {
641
- inTemplate = !inTemplate;
642
- }
643
- }
644
- return inSingleQuote || inDoubleQuote || inTemplate;
645
- }
646
- /**
647
- * 檢查位置是否在單行註解中
648
- */
649
- isInSingleLineComment(line, position) {
650
- const beforePosition = line.substring(0, position);
651
- // TypeScript/JavaScript 單行註解
652
- if (beforePosition.includes('//')) {
653
- return true;
654
- }
655
- // Python/Shell 單行註解
656
- if (beforePosition.includes('#')) {
657
- // 排除 # 在字串中的情況
658
- const hashIndex = beforePosition.indexOf('#');
659
- if (!this.isInString(line, hashIndex)) {
660
- return true;
661
- }
662
- }
663
- return false;
664
- }
665
- /**
666
- * 提取函式簽名
667
- */
668
- extractSignature(content, symbol) {
669
- const lines = content.split('\n');
670
- const line = lines[symbol.location.range.start.line - 1];
671
- return line?.trim();
672
- }
673
- /**
674
- * 提取文件註解(行號回掃方式)
675
- * 這是 fallback 方法,當 Parser 不支援 getDocumentation 時使用
676
- */
677
- extractDocumentationByLineScanning(content, symbol) {
678
- const lines = content.split('\n');
679
- const lineIndex = symbol.location.range.start.line - 2; // 前一行
680
- if (lineIndex < 0) {
681
- return undefined;
682
- }
683
- // 查找 JSDoc 或區塊註解
684
- const docLines = [];
685
- let i = lineIndex;
686
- while (i >= 0) {
687
- const line = lines[i].trim();
688
- if (line.endsWith('*/')) {
689
- // 找到註解結尾,開始收集
690
- docLines.unshift(line);
691
- i--;
692
- while (i >= 0 && !lines[i].trim().startsWith('/**') && !lines[i].trim().startsWith('/*')) {
693
- docLines.unshift(lines[i].trim());
694
- i--;
695
- }
696
- if (i >= 0) {
697
- docLines.unshift(lines[i].trim());
698
- }
699
- break;
700
- }
701
- else if (line.startsWith('//')) {
702
- // 單行註解
703
- docLines.unshift(line.substring(2).trim());
704
- i--;
705
- }
706
- else if (line === '') {
707
- i--;
708
- }
709
- else {
710
- break;
711
- }
712
- }
713
- return docLines.length > 0 ? docLines.join('\n') : undefined;
714
- }
715
- /**
716
- /**
717
- * 提取參數字串(支援多行)
718
- * @returns { content: 完整參數字串, endLine: 結束行索引, endColumn: 結束欄位 }
719
- */
720
- extractArgumentsStringMultiline(lines, startLine, startIndex) {
721
- let depth = 1;
722
- let lineIndex = startLine;
723
- let charIndex = startIndex + 1;
724
- let result = '';
725
- while (lineIndex < lines.length && depth > 0) {
726
- const line = lines[lineIndex];
727
- while (charIndex < line.length && depth > 0) {
728
- const char = line[charIndex];
729
- if (char === '(') {
730
- depth++;
731
- }
732
- else if (char === ')') {
733
- depth--;
734
- }
735
- if (depth > 0) {
736
- result += char;
737
- }
738
- charIndex++;
739
- }
740
- if (depth > 0 && lineIndex < lines.length - 1) {
741
- // 保留換行符號
742
- result += '\n';
743
- lineIndex++;
744
- charIndex = 0;
745
- }
746
- else {
747
- break;
748
- }
749
- }
750
- return {
751
- content: result,
752
- endLine: lineIndex,
753
- endColumn: charIndex - 1
754
- };
755
- }
756
- /**
757
- * 解析參數(支援多行)
758
- */
759
- parseArgumentsMultiline(argsString, baseLine, baseColumn) {
760
- if (!argsString.trim()) {
761
- return [];
762
- }
763
- const args = [];
764
- const parts = this.splitArguments(argsString);
765
- let currentLine = baseLine;
766
- let column = baseColumn + 1;
767
- for (let i = 0; i < parts.length; i++) {
768
- const part = parts[i];
769
- const trimmed = part.trim();
770
- // 計算參數中的換行數
771
- const newlines = (part.match(/\n/g) || []).length;
772
- // 檢查是否是具名參數
773
- const namedMatch = trimmed.match(/^(\w+)\s*[:=]\s*(.+)$/s);
774
- args.push({
775
- index: i,
776
- name: namedMatch ? namedMatch[1] : undefined,
777
- value: namedMatch ? namedMatch[2].trim() : trimmed,
778
- range: {
779
- start: { line: currentLine, column, offset: undefined },
780
- end: { line: currentLine + newlines, column: column + part.length, offset: undefined }
781
- }
782
- });
783
- // 更新行號和欄位
784
- if (newlines > 0) {
785
- currentLine += newlines;
786
- // 計算最後一行的欄位位置
787
- const lastNewlineIndex = part.lastIndexOf('\n');
788
- column = part.length - lastNewlineIndex;
789
- }
790
- else {
791
- column += part.length + 1; // +1 for comma
792
- }
793
- }
794
- return args;
795
- }
796
- /**
797
- /**
798
- * 找到匹配的右括號位置(支援多行)
799
- * @returns { line: 行索引, index: 該行的字元索引 }
800
- */
801
- findMatchingCloseParenMultiline(lines, startLine, openParenIndex) {
802
- let depth = 1;
803
- let lineIndex = startLine;
804
- let charIndex = openParenIndex + 1;
805
- while (lineIndex < lines.length && depth > 0) {
806
- const line = lines[lineIndex];
807
- while (charIndex < line.length && depth > 0) {
808
- const char = line[charIndex];
809
- if (char === '(') {
810
- depth++;
811
- }
812
- else if (char === ')') {
813
- depth--;
814
- if (depth === 0) {
815
- return { line: lineIndex, index: charIndex };
816
- }
817
- }
818
- charIndex++;
819
- }
820
- lineIndex++;
821
- charIndex = 0;
822
- }
823
- return { line: -1, index: -1 };
824
- }
825
- /**
826
- /**
827
- * 分割參數(考慮巢狀括號)
828
- */
829
- splitArguments(argsString) {
830
- const result = [];
831
- let current = '';
832
- let depth = 0;
833
- for (const char of argsString) {
834
- if (char === '(' || char === '[' || char === '{') {
835
- depth++;
836
- current += char;
837
- }
838
- else if (char === ')' || char === ']' || char === '}') {
839
- depth--;
840
- current += char;
841
- }
842
- else if (char === ',' && depth === 0) {
843
- result.push(current);
844
- current = '';
845
- }
846
- else {
847
- current += char;
848
- }
849
- }
850
- if (current.trim()) {
851
- result.push(current);
852
- }
853
- return result;
854
- }
855
- /**
856
- * 符號類型轉換為成員類型
857
- */
858
- symbolTypeToMemberType(type) {
859
- switch (type) {
860
- case 'function':
861
- return ClassMemberType.Method;
862
- case 'variable':
863
- case 'property':
864
- return ClassMemberType.Property;
865
- default:
866
- return ClassMemberType.Property;
867
- }
868
- }
869
- /**
870
- * 跳脫正則表達式特殊字元
871
- */
872
- escapeRegex(str) {
873
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
874
- }
875
- }
876
- /**
877
- * 建立 SymbolFinder 實例
878
- */
879
- export function createSymbolFinder(parserRegistry, fileSystem) {
880
- return new SymbolFinder(parserRegistry, fileSystem);
881
- }
882
- //# sourceMappingURL=symbol-finder.js.map