dsh-codegraph-visualizer 0.1.1 → 0.3.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 (58) hide show
  1. package/README.md +391 -226
  2. package/assets/icon-180.png +0 -0
  3. package/assets/icon.svg +30 -0
  4. package/cordis.patch.yml +22 -17
  5. package/dist/CodeGraphAdapter-C8JvcS7m.js +10 -0
  6. package/dist/CodeGraphAdapter-eyrhs0K0.js +422 -0
  7. package/dist/CodeGraphAdapter-eyrhs0K0.js.map +1 -0
  8. package/dist/FileSystemAdapter-CgasSGbB.js +524 -0
  9. package/dist/FileSystemAdapter-CgasSGbB.js.map +1 -0
  10. package/dist/LensAdapter-C9Saf_i_.js +89 -0
  11. package/dist/LensAdapter-C9Saf_i_.js.map +1 -0
  12. package/dist/Logger-DUIJSeNu.js +80 -0
  13. package/dist/Logger-DUIJSeNu.js.map +1 -0
  14. package/dist/TreeSitterAdapter-C-EWy8br.js +631 -0
  15. package/dist/TreeSitterAdapter-C-EWy8br.js.map +1 -0
  16. package/dist/TreeSitterAdapter-C6FcO2_s.js +8 -0
  17. package/dist/client/index.css +8900 -1777
  18. package/dist/client/index.css.map +1 -0
  19. package/dist/client/index.d.ts +634 -0
  20. package/dist/client/index.d.ts.map +1 -0
  21. package/dist/client/index.esm.js +57219 -20978
  22. package/dist/client/index.js.map +1 -0
  23. package/dist/client/{index.js → worker/layoutWorker.js} +7657 -8787
  24. package/dist/client.js +90067 -0
  25. package/dist/codeGraphDb-BT9nZCEO.js +357 -0
  26. package/dist/codeGraphDb-BT9nZCEO.js.map +1 -0
  27. package/dist/codeGraphDb-Bg7bWud2.js +9 -0
  28. package/dist/codeGraphRows-BhZX34uB.js +6 -0
  29. package/dist/codeGraphRows-C7hqu35E.js +246 -0
  30. package/dist/codeGraphRows-C7hqu35E.js.map +1 -0
  31. package/dist/constants-CQq93l3e.js +399 -0
  32. package/dist/constants-CQq93l3e.js.map +1 -0
  33. package/dist/graphFingerprint-CeARo7jG.js +4 -0
  34. package/dist/graphFingerprint-PuxORZUF.js +277 -0
  35. package/dist/graphFingerprint-PuxORZUF.js.map +1 -0
  36. package/dist/graphMetrics-C0F30730.js +555 -0
  37. package/dist/graphMetrics-C0F30730.js.map +1 -0
  38. package/dist/index.d.ts +572 -9
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +14734 -2003
  41. package/dist/index.js.map +1 -1
  42. package/dist/inheritanceEnhancer-Bi3UoYJS.js +291 -0
  43. package/dist/inheritanceEnhancer-Bi3UoYJS.js.map +1 -0
  44. package/dist/layerUtils-DDm-EsaD.js +72 -0
  45. package/dist/layerUtils-DDm-EsaD.js.map +1 -0
  46. package/dist/nativeIndex-Cx7RLXUp.js +5 -0
  47. package/dist/nativeIndex-DlSpD611.js +347 -0
  48. package/dist/nativeIndex-DlSpD611.js.map +1 -0
  49. package/dist/treeSitterExtractors-B1ybKNrC.js +394 -0
  50. package/dist/treeSitterExtractors-B1ybKNrC.js.map +1 -0
  51. package/dist/types-BUDxI_00.js +23 -0
  52. package/dist/types-BUDxI_00.js.map +1 -0
  53. package/locale/en.json +6 -0
  54. package/locale/zh-CN.json +6 -0
  55. package/locale/zh.json +6 -0
  56. package/package.json +100 -20
  57. package/dist/client-cjs/index.cjs +0 -44283
  58. package/dist/client-cjs/index.css +0 -2404
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TreeSitterAdapter-C-EWy8br.js","names":["LANGUAGE_BY_GRAMMAR: Record<SupportedGrammar, SupportedLanguage>","GRAMMAR_BY_EXTENSION: Record<string, SupportedGrammar>","SYMBOL_NODE_TYPES: Record<SupportedGrammar, Record<string, SymbolKind>>","js: Record<string, SymbolKind>","grammar: SupportedGrammar","nodeType: string","filePath: string","best: SupportedGrammar | null","content: string","files: Array<{ filePath: string; content: string }>","allNodes: GraphNode[]","allEdges: GraphEdge[]","errors: string[]","candidates: string[]","rootNode: TreeSitterNode","nodes: GraphNode[]","edges: GraphEdge[]","importSources: string[]","callSites: CallSite[]","node: TreeSitterNode","label: string","stack: Array<{ node: TreeSitterNode; parentId: string | undefined }>","rootNode","graphType: GraphNode['type'] | null","currentParentId: string | undefined","graphNode: GraphNode","result: ASTNode","stack: Array<{ tsNode: TreeSitterNode; astParent: ASTNode }>","astNode: ASTNode"],"sources":["../src/adapters/TreeSitterAdapter.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { scoped } from '../shared/Logger.ts';\nimport { NodeId, EdgeId } from '../types/index.ts';\nimport type { GraphNode, GraphEdge, AdapterResult, CallSite, DataSourceType } from '../types/index.ts';\nimport type { IAnalysisAdapter } from './IAdapter.ts';\nimport type { ASTNode } from '../shared/CFGTypes.ts';\nimport { inferLayerFromPath } from '../shared/layerUtils.ts';\nimport { TREE_SITTER } from '../shared/constants.ts';\n\nconst log = scoped('tree-sitter-adapter');\nimport {\n applyTodoMarkers,\n collectHeritageTargets,\n extractImportSources,\n extractSymbolName,\n IMPORT_STATEMENT_TYPES,\n maybeCollectCallSite,\n} from './treeSitterExtractors.ts';\n\n/**\n * 同步探测「本宿主上是否**存在** AST 分析通道」——给能力位 `astSource` 用\n * (`src/host/prerequisites.ts` 登记探针,`src/host/routes.ts` 接线)。\n *\n * ## 为什么不能直接用 `adapter.isAvailable()`\n *\n * `isAvailable()` 的语义是「解析器**已经**初始化」(`parserCtor !== null`),而初始化发生在\n * 第一次 `parseFile()`/`parseToAst()` 里的 `await this.init()`。插件 `apply()` 时还没有任何\n * 文件被解析过,于是它在**启动后的一整段时间里恒为 false** —— 用它当能力位会让 `/status`\n * 在一个完全正常的宿主上报告「AST 通道不可用」,那是与 `builtin: true` 相反方向但同样虚假的\n * 叙事。能力位回答的是「这条通道存在吗」,不是「它此刻已热了吗」。\n *\n * ## 判据是两条真实探针的**析取**,没有第三条字面量\n *\n * 1. `isAvailable()` —— 已初始化(最强证据,进程生命周期后段基本恒真);\n * 2. 运行时模块**可解析** —— `web-tree-sitter`(解析器)与 `tree-sitter-wasm`(语法 wasm)\n * 都能被 Node 解析到。缺依赖、装坏、profile 里漏装都会让它变 false。\n *\n * ## 诚实边界\n *\n * 本探针**不能**证明语法 wasm 真的能加载(那是异步 `Language.load()` 的事)。它证明的是\n * 「这两个包在这台宿主上存在」。这个窄化的失败面是刻意接受的:它比 `true` 严格更强\n * (字面量 `true` 在任何安装状态下都为真),而要做到「真的能加载」就必须把\n * `checkPrerequisites` 改成 async,代价是 20 余处同步调用点。\n * 非 Node 环境(理论上不该发生:本适配器只在宿主进程运行)直接返回 `false`。\n */\nexport function isTreeSitterRuntimePresent(): boolean {\n if (typeof process === 'undefined' || !process.versions?.node) return false;\n try {\n // 用 `createRequire(import.meta.url)` 而不是 `import.meta.resolve`:后者在 vitest 的\n // 转换管道里是 `undefined`(实测 `typeof import.meta.resolve === 'undefined'`),\n // 而本函数是能力位的判据 —— 一个在测试环境里恒抛的探针会让 `astSource` 假阴性,\n // 而假阴性比假阳性更难被发现(界面上只是「没有 AST 通道」,没有任何报错)。\n const req = createRequire(import.meta.url);\n req.resolve('web-tree-sitter');\n req.resolve('tree-sitter-wasm');\n return true;\n } catch (e) {\n log.debug('tree-sitter runtime not resolvable', { error: e });\n return false;\n }\n}\n\nconst SUPPORTED_LANGUAGES = ['typescript', 'javascript', 'python', 'java', 'rust', 'go'] as const;\ntype SupportedLanguage = typeof SUPPORTED_LANGUAGES[number];\n\n/**\n * Grammar a file is parsed with. `.tsx` needs the JSX-aware `tsx` build: with the plain\n * `typescript` grammar a component containing `<div>…</div>` produces ERROR nodes and the JSX\n * arrow component is swallowed by the error node, so its symbol never reaches the graph\n * (measured: `hasError: true`, 2 ERROR nodes, 0 arrow functions, vs clean parse with `tsx`).\n * `tree-sitter-wasm` ships both grammars.\n */\nconst GRAMMARS = [...SUPPORTED_LANGUAGES, 'tsx'] as const;\ntype SupportedGrammar = typeof GRAMMARS[number];\n\n/** Logical language a grammar belongs to — what `detectLanguage` reports (`.tsx` is TypeScript). */\nconst LANGUAGE_BY_GRAMMAR: Record<SupportedGrammar, SupportedLanguage> = {\n typescript: 'typescript',\n javascript: 'javascript',\n python: 'python',\n java: 'java',\n rust: 'rust',\n go: 'go',\n tsx: 'typescript',\n};\n\n/** Grammar per file extension — `.tsx` must not fall back to the plain `typescript` grammar. */\nconst GRAMMAR_BY_EXTENSION: Record<string, SupportedGrammar> = {\n '.ts': 'typescript',\n '.tsx': 'tsx',\n '.js': 'javascript',\n '.jsx': 'javascript',\n '.mjs': 'javascript',\n '.cjs': 'javascript',\n '.py': 'python',\n '.java': 'java',\n '.rs': 'rust',\n '.go': 'go',\n};\n\nexport interface TreeSitterNode {\n type: string;\n text: string;\n startPosition: { row: number; column: number };\n endPosition: { row: number; column: number };\n childCount: number;\n child(index: number): TreeSitterNode | null;\n childForFieldName(name: string): TreeSitterNode | null;\n children: TreeSitterNode[];\n}\n\ninterface TreeSitterTree {\n rootNode: TreeSitterNode;\n delete(): void;\n}\n\ninterface TreeSitterParser {\n parse(input: string): TreeSitterTree;\n setLanguage(language: TreeSitterLanguage): void;\n delete(): void;\n}\n\ninterface TreeSitterLanguage {\n load(path: string): Promise<TreeSitterLanguage>;\n}\n\ntype SymbolKind = 'function' | 'class' | 'variable' | 'module';\n\n/**\n * Node type → graph symbol kind, **per grammar**. Previously this was one flat set shared by all\n * grammars, which was guesswork: it listed types no supported grammar emits (`struct_declaration`,\n * `const_declaration`) while missing real ones, so Rust functions never reached the graph\n * (`function_item` was absent) and TypeScript variables were labelled `<variable_declaration>`\n * (the *wrapper* was listed instead of `variable_declarator`, the node that actually carries the\n * name).\n *\n * Every entry below was measured against the shipped grammars by\n * `.cycles/probe-grammar-node-types.mjs` (all samples parse with `hasError: false`). A type is\n * listed only when the grammar emits it **and** `extractName` yields a real label for it — a\n * `name` field, a `type` field (`impl_item`), or an identifier child (`assignment`,\n * `let_declaration`). Declaration wrappers are deliberately absent because they carry no name of\n * their own and would enter the graph as `<lexical_declaration>`-style noise:\n * `lexical_declaration`, `variable_declaration`, `var_declaration`, `short_var_declaration`,\n * `type_declaration`, `field_declaration`, plus the `*_body` / `*_type` container nodes.\n */\nconst SYMBOL_NODE_TYPES: Record<SupportedGrammar, Record<string, SymbolKind>> = (() => {\n const js: Record<string, SymbolKind> = {\n function_declaration: 'function',\n method_definition: 'function',\n arrow_function: 'function',\n class_declaration: 'class',\n variable_declarator: 'variable',\n // 【P0-R19-01】import_statement 是语法结构不是符号,不应收成 graph node\n };\n return {\n // The TS grammar is a superset of the JS one; keep them separate so a JS-only change cannot\n // silently leak JSX/TS-only node types into plain JavaScript files.\n typescript: {\n ...js,\n interface_declaration: 'class',\n enum_declaration: 'class',\n type_alias_declaration: 'class',\n },\n tsx: {\n ...js,\n interface_declaration: 'class',\n enum_declaration: 'class',\n type_alias_declaration: 'class',\n },\n javascript: js,\n python: {\n function_definition: 'function',\n class_definition: 'class',\n assignment: 'variable',\n // 【P0-R19-01】同上\n // import_statement: 'module',\n },\n java: {\n method_declaration: 'function',\n constructor_declaration: 'function',\n class_declaration: 'class',\n interface_declaration: 'class',\n enum_declaration: 'class',\n variable_declarator: 'variable',\n // 【P0-R19-01】同上\n // import_declaration: 'module',\n },\n rust: {\n function_item: 'function',\n function_signature_item: 'function',\n closure_expression: 'function',\n struct_item: 'class',\n enum_item: 'class',\n trait_item: 'class',\n impl_item: 'class',\n let_declaration: 'variable',\n const_item: 'variable',\n static_item: 'variable',\n // 【P0-R19-01】同上\n // use_declaration: 'module',\n },\n go: {\n function_declaration: 'function',\n method_declaration: 'function',\n method_elem: 'function',\n type_spec: 'class',\n type_alias: 'class',\n var_spec: 'variable',\n const_spec: 'variable',\n // 【P0-R19-01】同上\n // import_declaration: 'module',\n },\n };\n})();\n\nfunction symbolKindFor(grammar: SupportedGrammar, nodeType: string): SymbolKind | null {\n return SYMBOL_NODE_TYPES[grammar][nodeType] ?? null;\n}\nconst COMMENT_NODE_TYPES = new Set(['comment', 'line_comment', 'block_comment']);\nconst TODO_PATTERNS = /\\b(TODO|FIXME|HACK|XXX|BUG)\\b/g;\n\nexport class TreeSitterAdapter implements IAnalysisAdapter {\n readonly source: DataSourceType = 'tree-sitter';\n private parserCtor: (new () => TreeSitterParser) | null = null;\n /**\n * One parser per grammar. A single shared parser with `setLanguage` swapped per file is not safe:\n * `ensureLanguageLoaded` awaits, so a mixed-language batch (`Promise.all` in `batchScan`) could\n * apply another file's grammar between the await and the parse. Separate instances make the\n * language a property of the parser instead of mutable shared state.\n */\n private parsers = new Map<SupportedGrammar, TreeSitterParser>();\n private languages = new Map<SupportedGrammar, TreeSitterLanguage>();\n private pendingGrammarLoads = new Map<SupportedGrammar, Promise<TreeSitterParser | null>>();\n private initAttempts = 0;\n private static readonly MAX_INIT_ATTEMPTS = 3;\n\n async init(): Promise<void> {\n if (this.parserCtor) return;\n if (this.initAttempts >= TreeSitterAdapter.MAX_INIT_ATTEMPTS) {\n log.warn(`TreeSitter init skipped after ${this.initAttempts} failed attempts`);\n return;\n }\n this.initAttempts++;\n try {\n const { Parser } = await import('web-tree-sitter');\n await Parser.init();\n this.parserCtor = Parser as unknown as new () => TreeSitterParser;\n this.initAttempts = 0;\n log.info('TreeSitter parser initialized');\n } catch (e) {\n log.warn(`Failed to init TreeSitter (attempt ${this.initAttempts}/${TreeSitterAdapter.MAX_INIT_ATTEMPTS})`, e);\n }\n }\n\n isAvailable(): boolean {\n return this.parserCtor !== null;\n }\n\n getSupportedLanguages(): readonly SupportedLanguage[] {\n return SUPPORTED_LANGUAGES;\n }\n\n /** Logical language for a file, or null when the extension is not supported. */\n detectLanguage(filePath: string): SupportedLanguage | null {\n const grammar = this.detectGrammar(filePath);\n return grammar ? LANGUAGE_BY_GRAMMAR[grammar] : null;\n }\n\n /**\n * Grammar to parse a file with. Longest matching extension wins, so the lookup cannot depend on\n * the declaration order of `GRAMMAR_BY_EXTENSION`.\n */\n detectGrammar(filePath: string): SupportedGrammar | null {\n let best: SupportedGrammar | null = null;\n let bestLength = 0;\n for (const [ext, grammar] of Object.entries(GRAMMAR_BY_EXTENSION)) {\n if (ext.length > bestLength && filePath.endsWith(ext)) {\n best = grammar;\n bestLength = ext.length;\n }\n }\n return best;\n }\n\n /**\n * Parser for a grammar, loading its wasm once. Concurrent requests for the same grammar share one\n * in-flight load, so a batch never downloads/compiles the same grammar twice.\n */\n private async ensureParser(grammar: SupportedGrammar): Promise<TreeSitterParser | null> {\n const ready = this.parsers.get(grammar);\n if (ready) return ready;\n const inFlight = this.pendingGrammarLoads.get(grammar);\n if (inFlight) return inFlight;\n\n const pending = (async (): Promise<TreeSitterParser | null> => {\n const ctor = this.parserCtor;\n if (!ctor) return null;\n try {\n const language = await this.loadLanguageWasm(grammar);\n const parser = new ctor();\n parser.setLanguage(language);\n this.languages.set(grammar, language);\n this.parsers.set(grammar, parser);\n return parser;\n } catch (e) {\n log.warn(`Failed to load grammar: ${grammar}`, e);\n return null;\n } finally {\n this.pendingGrammarLoads.delete(grammar);\n }\n })();\n this.pendingGrammarLoads.set(grammar, pending);\n return pending;\n }\n\n async parseFile(filePath: string, content: string): Promise<AdapterResult> {\n if (!this.parserCtor) {\n await this.init();\n if (!this.parserCtor) {\n return { nodes: [], edges: [], source: 'tree-sitter', timestamp: Date.now(), error: 'Parser not initialized' };\n }\n }\n\n const grammar = this.detectGrammar(filePath);\n if (!grammar) {\n return { nodes: [], edges: [], source: 'tree-sitter', timestamp: Date.now(), error: `Unsupported file: ${filePath}` };\n }\n\n const parser = await this.ensureParser(grammar);\n if (!parser) {\n return { nodes: [], edges: [], source: 'tree-sitter', timestamp: Date.now(), error: `Failed to load ${grammar}` };\n }\n\n try {\n const tree = parser.parse(content);\n // P0-R19-01 修复的顺带发现:parseFile 此前只解构 nodes/edges,丢弃了\n // importSources/callSites——单文件路径上「import 语句不再产出节点」后,\n // 模块字符串只存在于 importSources,丢弃即意味着 parseFile 的调用方\n // 拿不到任何依赖数据面(batchScan 路径一直是透传的,两条路径曾漂移)。\n const { nodes, edges, importSources, callSites } = this.extractSymbols(tree.rootNode, filePath, grammar);\n tree.delete();\n return {\n nodes,\n edges,\n source: 'tree-sitter',\n timestamp: Date.now(),\n importsByFile: importSources.length > 0 ? new Map([[filePath, importSources]]) : undefined,\n callSitesByFile: callSites.length > 0 ? new Map([[filePath, callSites]]) : undefined,\n };\n } catch (e) {\n log.warn('parseFile failed', { filePath, error: e });\n return { nodes: [], edges: [], source: 'tree-sitter', timestamp: Date.now(), error: String(e) };\n }\n }\n\n async batchScan(files: Array<{ filePath: string; content: string }>): Promise<AdapterResult> {\n if (!this.parserCtor) {\n await this.init();\n if (!this.parserCtor) {\n return { nodes: [], edges: [], source: 'tree-sitter', timestamp: Date.now(), error: 'Parser not initialized' };\n }\n }\n\n const allNodes: GraphNode[] = [];\n const allEdges: GraphEdge[] = [];\n const errors: string[] = [];\n /** 文件 → 该文件 import 的模块名(cycle-129 · T1;消费方 FileSystemAdapter 解析成边)。 */\n const importsByFile = new Map<string, string[]>();\n /** 文件 → 该文件的调用点(T2;消费方 FileSystemAdapter 解析成 `call` 边)。 */\n const callSitesByFile = new Map<string, CallSite[]>();\n\n for (let i = 0; i < files.length; i += TREE_SITTER.BATCH_SIZE) {\n const batch = files.slice(i, i + TREE_SITTER.BATCH_SIZE);\n const results = await Promise.all(\n batch.map(async (file) => {\n const grammar = this.detectGrammar(file.filePath);\n if (!grammar) return null;\n const parser = await this.ensureParser(grammar);\n if (!parser) return null;\n try {\n const tree = parser.parse(file.content);\n const { nodes, edges, importSources, callSites } = this.extractSymbols(tree.rootNode, file.filePath, grammar);\n tree.delete();\n return { nodes, edges, filePath: file.filePath, importSources, callSites };\n } catch (e) {\n errors.push(`${file.filePath}: ${String(e)}`);\n return null;\n }\n })\n );\n\n for (const result of results) {\n if (result) {\n allNodes.push(...result.nodes);\n allEdges.push(...result.edges);\n if (result.importSources.length > 0) {\n importsByFile.set(result.filePath, result.importSources);\n }\n // 无条件写入(空数组也写):语义上等价于「本文件没有调用点」,而省掉一个分支\n // 是本文件复杂度预算下的刻意选择(walk 已到 101,本轮不新增条件)。\n callSitesByFile.set(result.filePath, result.callSites);\n }\n }\n }\n\n log.info(`batchScan: ${files.length} files, ${allNodes.length} nodes, ${allEdges.length} edges, ${errors.length} errors, import-modules ${importsByFile.size} files, call-sites ${callSitesByFile.size} files`);\n\n return {\n nodes: allNodes,\n edges: allEdges,\n source: 'tree-sitter',\n timestamp: Date.now(),\n importsByFile,\n callSitesByFile,\n ...(errors.length > 0 ? { error: errors.join('; ') } : {}),\n };\n }\n\n private async loadLanguageWasm(grammar: SupportedGrammar): Promise<TreeSitterLanguage> {\n const wasmFile = `tree-sitter-${grammar}.wasm`;\n const { Language } = await import('web-tree-sitter');\n\n const candidates: string[] = [];\n\n // The adapter runs in the host process only (routes.ts / analysisRoutes.ts); `tree-sitter-wasm`\n // ships `out/<lang>/tree-sitter-<lang>.wasm` and resolves it next to its own module, which is\n // correct both in this repo and in an installed profile. DSH serves no asset route for plugin\n // files, so browser-style candidates (`plugins/…`, `node_modules/…`, `document.baseURI`) could\n // never resolve and were removed rather than left as a second copy of a refuted assumption.\n if (typeof process !== 'undefined' && process.versions?.node) {\n try {\n const { getWasmPath } = await import('tree-sitter-wasm');\n candidates.push(getWasmPath(grammar));\n } catch (e) { log.debug('tree-sitter-wasm not available', { error: e }); }\n }\n\n // Last resort: let web-tree-sitter resolve the bare file name itself.\n candidates.push(wasmFile);\n\n for (const path of candidates) {\n try {\n return await (Language as unknown as TreeSitterLanguage).load(path);\n } catch (e) { log.debug('candidate path failed', { path, error: e }); }\n }\n throw new Error(`Cannot load ${wasmFile} from any candidate path`);\n }\n\n private extractSymbols(rootNode: TreeSitterNode, filePath: string, grammar: SupportedGrammar): { nodes: GraphNode[]; edges: GraphEdge[]; importSources: string[]; callSites: CallSite[] } {\n const nodes: GraphNode[] = [];\n const edges: GraphEdge[] = [];\n const visited = new Set<string>();\n const nodeMap = new Map<string, GraphNode>();\n // import 模块源(cycle-129 · T1):本文件 import 的模块名去重收集。\n const importSources: string[] = [];\n // 调用点(T2):语法事实收集,被调名 → 符号的裁决由 FileSystemAdapter 负责。\n const callSites: CallSite[] = [];\n\n const extractName = extractSymbolName;\n\n const makeId = (node: TreeSitterNode, label: string): string =>\n `${filePath}:${label}:${node.startPosition.row}`;\n\n /**\n * 提取一个 class/interface 声明节点的全部继承目标(cycle-123)。\n *\n * 两种语法形态(tree-sitter-typescript 实测,见测试 fixture):\n * - `extends_type_clause`:interface 的 extends(直接子节点,`type_identifier` 列表),\n * 子节点序列为 [extends, ident, ',', ident, ...];\n * - `class_heritage`:class 的 extends/implements 容器,内含 `extends_clause`\n * (`extends` + type 列表)与 `implements_clause`(`implements` + type 列表)。\n * - Rust 的 `impl_item` 无继承语义(trait impl 不是继承),不提取。\n * - Python 的 `class_definition` 用 `argument_list` 表达基类(tree-sitter-python\n * 的 `superclasses` 字段),一并覆盖(kind 判定走 clause 名单)。\n *\n * 返回 `clauseKind`(extends/implements)用于边类型映射:`extends → 'extend'`、\n * `implements → 'implement'`(与上游 codegraph 的 kind 语义一致)。\n * 目标统一返回占位 id 策略(消费方造 `${filePath}:<type>:<name>`),由\n * merger 按 label 归并——避免遍历时序依赖(子符号可能尚未入 nodeMap)。\n */\n /**\n * import 模块源提取(cycle-129 · T1:原生依赖图的缺口)。\n *\n * import_statement(TS/JS)与 import_declaration(Python/Java/Rust use)的\n * `source` 字段持有模块名字符串。此前 walk 只把 import 节点收成 module 节点\n * (symbolKindFor 命中 `import_statement: 'module'`),模块字符串被丢弃——\n * 原生图永远没有 `import` 边,依赖视图(dependencies view)在原生通道上是\n * 空的。本函数返回去重后的模块名列表(同一模块多次 import 只记一条的输入)。\n *\n * 语法形态(各 grammar 实测):\n * - TS/JS `import_statement`:`source` 字段是 string 节点(含引号,剥掉);\n * - Python `import_statement` / `import_from_statement`:module_name /\n * `dotted_name`(无引号);`relative_import`(from . import x)跳过——\n * 相对层级语义留待后续(登记为缺口);\n * - Rust `use_declaration`:`argument` 字段(scoped_identifier 树),取\n * 整段文本按 `::` 保留(Rust 路径语义与文件路径不直接对应,消费方\n * 解析不到就跳过——与「解析不到就跳过」的总策略一致)。\n * - Java `import_declaration`:`scoped_identifier`/`package` 文本(点分名)。\n *\n * 刻意**不在这里解析成文件路径**:模块名 → 文件的映射需要 workspace 上下文\n * (扩展名歧义、index 解析、tsconfig paths),由 FileSystemAdapter(T2)\n * 统一裁决——适配器保持「语法事实收集者」,不做语义猜测。\n */\n const walk = (rootNode: TreeSitterNode): void => {\n const stack: Array<{ node: TreeSitterNode; parentId: string | undefined }> = [{ node: rootNode, parentId: undefined }];\n while (stack.length > 0) {\n const { node, parentId } = stack.pop()!;\n if (!node) continue;\n const nodeType = node.type;\n\n // import 模块源提取(cycle-129 · T1;P0-R19-01 语义更新):在符号判定之前\n // 拦截——import 节点**不再**被收成 module 图节点(SYMBOL_NODE_TYPES 已移除\n // 该映射:import 语句是语法结构不是符号,1777 个 `<import_statement>` 伪节点\n // 曾把 dsh-anic 的 342 个 dir: 目录节点挤出 /bootstrap 的 LIMIT 50,画布塌缩\n // 成 \"Projects (50)\" 单簇)。它的模块字符串仍记入 importSources,供\n // FileSystemAdapter 解析成 `import` 边——依赖图数据面完整保留。\n // 提取函数在模块级(extractImportSources,复杂度独立记账——本文件\n // 复杂度曾在 cycle-129 超预算 117/100,抽离后回落)。\n if (IMPORT_STATEMENT_TYPES.has(nodeType)) {\n const sources = extractImportSources(node);\n if (sources.length > 0) importSources.push(...sources);\n }\n\n // 调用点(T2):语法事实,「名字 → 符号」的裁决由 FileSystemAdapter 完成。\n // 无条件调用一次并 push(判定全在纯函数里)——本文件已贴近复杂度预算,\n // walk 里不新增条件语句。`parentId` 此刻仍是**最近的符号祖先**。\n const callSite = maybeCollectCallSite(\n node,\n nodeType,\n parentId,\n parentId ? nodeMap.get(parentId)?.type : undefined,\n );\n if (callSite) callSites.push(callSite);\n\n let graphType: GraphNode['type'] | null = null;\n const symbolKind = symbolKindFor(grammar, nodeType);\n if (symbolKind) graphType = symbolKind;\n\n let currentParentId: string | undefined = parentId;\n\n if (graphType) {\n const label = extractName(node);\n const id = makeId(node, label);\n\n if (!visited.has(id)) {\n visited.add(id);\n const graphNode: GraphNode = {\n id: NodeId(id),\n label,\n type: graphType,\n filePath,\n lineNumber: node.startPosition.row + 1,\n properties: { source: 'tree-sitter', nodeType },\n ...(parentId ? { parentId: NodeId(parentId) } : {}),\n layer: inferLayerFromPath(filePath),\n };\n nodes.push(graphNode);\n nodeMap.set(id, graphNode);\n\n // 继承边提取(cycle-123,研究报告 Phase 1 P0 数据质量缺口):\n // 上游 codegraph 索引对 `interface extends` 的检出为 0(本仓量化:\n // 源码 17 处 extends,索引只出 9 条 class→class,interface→interface\n // 全部漏检——tree-sitter-wasm 的 TypeScript grammar 对空体\n // `interface X extends Y, Z {}` 的处理覆盖不足)。这里的 AST 提取\n // 是**数据增补**:与上游边同型(`extend` / `implement`),经\n // GraphDataMerger 归因裁决时 `edgeOrigin: 'ast'` 为最高档,但\n // 不覆盖上游 db 行(见 EDGE_ORIGIN_RANK 的排序语义:同 origin\n // 时上游保留)。合并去重在 merger 侧按 (source,target,type) 完成。\n //\n // 两语法形态(tree-sitter-typescript 实测):\n // - interface: `extends_type_clause`(直接子节点,内含 type_identifier 列表)\n // - class: `class_heritage` → `implements_clause` / `extends_clause`\n // 端点解析:本文件内的目标用 nodeMap 命中精确 id;跨文件目标用\n // `type:<name>` 占位 id(与上游 imports 的宽松端点同策略——\n // merger 的身份裁决会把同 label 节点归并)。\n const heritageTargets = collectHeritageTargets(node);\n if (heritageTargets.length > 0) {\n for (const { clauseKind, targetName } of heritageTargets) {\n const edgeType = clauseKind === 'extends' ? 'extend' : 'implement';\n // 跨文件目标用占位 id(与上游 imports 的宽松端点同策略——\n // merger 的身份裁决按 label 归并同名列,多文件重复继承同一\n // 基类时边端点会归并到同一条)。同文件目标也是占位 id:\n // walker 的 nodeMap 查询发生在遍历中、子符号可能尚未入表,\n // 用 label 归并比「遍历时序依赖」更稳健。\n const targetId = NodeId(`${filePath}:<type>:${targetName}`);\n const selfId = NodeId(id);\n // 自继承(X extends X,极端但合法)跳过:占位 id 的 targetName\n // 段与声明 label 相同即自指(id 形态不同不能直接比)。\n if (targetName === label) continue;\n edges.push({\n id: EdgeId(`tsedge:${id}->${targetId}`),\n source: selfId,\n target: targetId,\n type: edgeType,\n properties: { edgeOrigin: 'ast', edgeLocatable: false, targetName, line: node.startPosition.row + 1 },\n });\n }\n }\n\n if (parentId) {\n // 边来源归因(P1-N4):这是 `edgeOrigin: 'ast'` 在全仓的**第一个生产者**。\n //\n // 修前 `properties` 是空对象,而 `src/merger/GraphDataMerger.ts` 的\n // `EDGE_ORIGIN_RANK.ast = 3`(最高档)因此**从未在真实数据上生效过** ——\n // 那一层裁决只是\"为将来留位\",没有任何一条边能走到它。本仓反复记录过这类\n // 缺陷(\"特性实现了但永远不会运行\"),所以这里不是\"顺便补个字段\",\n // 而是让一条已声明的裁决规则第一次真的具备输入。\n //\n // 为什么可以断言是 `ast`:这条边不是从任何索引表读出来的,也不是启发式拼的,\n // 它是**语法树父子关系**的直接投影 —— 子符号节点就在父符号节点的子树里,\n // 归属无歧义。`db` 档位(SQLite edges 行)与 `heuristic` 档位都不是这种证据。\n //\n // `edgeLocatable`:两端都是本文件里的符号节点,且都带 `lineNumber`\n // (`node.startPosition.row + 1`),因此这一行走源码可回溯。\n //\n // **已知代价(有意接受)**:`properties` 参与 `computeGraphFingerprint`\n // (`src/shared/graphFingerprint.ts:108` 的 `stableStringify(edge.properties)`),\n // 加键会让已存快照**一次性**失配 ⇒ 每次升级后的第一次扫描会多写一行快照\n // (`saveSnapshot` 按指纹去重,不 bump `FINGERPRINT.VERSION`)。选择不 bump:\n // bump 会让所有历史快照永久不可比,而这一次失配是自愈的。\n const line = node.startPosition.row + 1;\n edges.push({\n id: EdgeId(`tsedge:${parentId}->${id}`),\n source: NodeId(parentId),\n target: NodeId(id),\n type: 'contains',\n properties: { edgeOrigin: 'ast', edgeLocatable: true, line },\n });\n }\n }\n currentParentId = id;\n }\n\n // TODO/FIXME 标记(cycle-122 的 todoMarkerMode 数据面):打标逻辑已搬到模块级\n // 纯函数。这一步是**复杂度预算**驱动的:walk 在本轮之前就是 101(超 100 预算),\n // 把这段原有的 5 个条件语句移出后回到预算内,才谈得上「本轮不新增分支」。\n // 语义等价(HACK/XXX/BUG 与 TODO/FIXME 一样算「有此标记」)。\n if (COMMENT_NODE_TYPES.has(nodeType)) {\n const parentNode = parentId ? nodeMap.get(parentId) : undefined;\n const matches = node.text.match(TODO_PATTERNS);\n if (parentNode && matches) applyTodoMarkers(parentNode, matches);\n }\n\n for (let i = (node.childCount || 0) - 1; i >= 0; i--) {\n const child = node.child(i);\n if (child) stack.push({ node: child, parentId: currentParentId });\n }\n }\n };\n\n walk(rootNode);\n return { nodes, edges, importSources: [...new Set(importSources)], callSites };\n }\n\n async parseToAst(filePath: string, content: string): Promise<ASTNode | null> {\n if (!this.parserCtor) {\n await this.init();\n if (!this.parserCtor) {\n log.warn('parseToAst: parser not initialized after init()');\n return null;\n }\n }\n const grammar = this.detectGrammar(filePath);\n if (!grammar) {\n log.warn(`parseToAst: unsupported file extension: ${filePath}`);\n return null;\n }\n const parser = await this.ensureParser(grammar);\n if (!parser) {\n log.warn(`parseToAst: failed to load grammar ${grammar}`);\n return null;\n }\n try {\n const tree = parser.parse(content);\n const astRoot = this.convertToAstNode(tree.rootNode);\n tree.delete();\n return astRoot;\n } catch (e) {\n log.warn(`parseToAst: parse failed for ${filePath}:`, e);\n return null;\n }\n }\n\n private convertToAstNode(rootNode: TreeSitterNode): ASTNode {\n const result: ASTNode = {\n type: rootNode.type,\n text: rootNode.text,\n startPosition: { row: rootNode.startPosition.row, column: rootNode.startPosition.column },\n endPosition: { row: rootNode.endPosition.row, column: rootNode.endPosition.column },\n children: [],\n };\n const stack: Array<{ tsNode: TreeSitterNode; astParent: ASTNode }> = [];\n for (let i = (rootNode.childCount || 0) - 1; i >= 0; i--) {\n const child = rootNode.child(i);\n if (child) stack.push({ tsNode: child, astParent: result });\n }\n while (stack.length > 0) {\n const { tsNode, astParent } = stack.pop()!;\n const astNode: ASTNode = {\n type: tsNode.type,\n text: tsNode.text,\n startPosition: { row: tsNode.startPosition.row, column: tsNode.startPosition.column },\n endPosition: { row: tsNode.endPosition.row, column: tsNode.endPosition.column },\n children: [],\n };\n astParent.children.push(astNode);\n for (let i = (tsNode.childCount || 0) - 1; i >= 0; i--) {\n const child = tsNode.child(i);\n if (child) stack.push({ tsNode: child, astParent: astNode });\n }\n }\n return result;\n }\n\n destroy(): void {\n for (const parser of this.parsers.values()) {\n try { parser.delete(); } catch (e) { log.debug('parser cleanup failed', { error: e }); }\n }\n for (const language of this.languages.values()) {\n try { (language as unknown as { delete?: () => void }).delete?.(); } catch (e) { log.debug('language cleanup failed', { error: e }); }\n }\n this.parsers.clear();\n this.languages.clear();\n this.pendingGrammarLoads.clear();\n this.parserCtor = null;\n this.initAttempts = 0;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import "./types-BUDxI_00.js";
2
+ import "./constants-CQq93l3e.js";
3
+ import "./Logger-DUIJSeNu.js";
4
+ import "./layerUtils-DDm-EsaD.js";
5
+ import "./treeSitterExtractors-B1ybKNrC.js";
6
+ import { TreeSitterAdapter, isTreeSitterRuntimePresent } from "./TreeSitterAdapter-C-EWy8br.js";
7
+
8
+ export { TreeSitterAdapter, isTreeSitterRuntimePresent };