@plebeiantech/lat.md 0.12.3-fork.13 → 0.12.3-fork.14
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.
- package/README.md +24 -0
- package/dist/src/cli/check-context.d.ts +56 -0
- package/dist/src/cli/check-context.js +215 -0
- package/dist/src/cli/check-coverage.js +9 -5
- package/dist/src/cli/check-frontmatter.js +1 -1
- package/dist/src/cli/check-mode.js +1 -1
- package/dist/src/cli/check-status.js +1 -1
- package/dist/src/cli/check.d.ts +19 -12
- package/dist/src/cli/check.js +259 -206
- package/dist/src/cli/context.js +1 -1
- package/dist/src/cli/expand.d.ts +1 -2
- package/dist/src/cli/expand.js +52 -5
- package/dist/src/cli/external.d.ts +11 -0
- package/dist/src/cli/external.js +185 -0
- package/dist/src/cli/fork-instructions.d.ts +1 -0
- package/dist/src/cli/fork-instructions.js +3 -2
- package/dist/src/cli/hook.d.ts +26 -0
- package/dist/src/cli/hook.js +112 -40
- package/dist/src/cli/index.js +55 -3
- package/dist/src/cli/init.d.ts +1 -0
- package/dist/src/cli/init.js +40 -2
- package/dist/src/cli/locate.js +4 -3
- package/dist/src/cli/refs.d.ts +2 -1
- package/dist/src/cli/refs.js +88 -43
- package/dist/src/cli/reindex.js +2 -1
- package/dist/src/cli/search.d.ts +12 -3
- package/dist/src/cli/search.js +45 -49
- package/dist/src/cli/section.d.ts +3 -1
- package/dist/src/cli/section.js +114 -38
- package/dist/src/code-refs.d.ts +17 -5
- package/dist/src/code-refs.js +246 -65
- package/dist/src/context.d.ts +3 -0
- package/dist/src/document-formats.d.ts +7 -0
- package/dist/src/document-formats.js +39 -0
- package/dist/src/extensions/alert-marker.d.ts +25 -0
- package/dist/src/extensions/alert-marker.js +55 -0
- package/dist/src/external-documents.d.ts +56 -0
- package/dist/src/external-documents.js +404 -0
- package/dist/src/external-sources.d.ts +136 -0
- package/dist/src/external-sources.js +1098 -0
- package/dist/src/fork/antigravity-hook.d.ts +47 -0
- package/dist/src/fork/antigravity-hook.js +424 -0
- package/dist/src/fork/antigravity-init.d.ts +17 -0
- package/dist/src/fork/antigravity-init.js +124 -0
- package/dist/src/fork/frontmatter-fields.d.ts +36 -0
- package/dist/src/fork/frontmatter-fields.js +23 -0
- package/dist/src/format.d.ts +5 -2
- package/dist/src/format.js +8 -3
- package/dist/src/graph-export.js +1 -1
- package/dist/src/lattice-model.d.ts +77 -0
- package/dist/src/lattice-model.js +464 -0
- package/dist/src/lattice.d.ts +9 -104
- package/dist/src/lattice.js +69 -516
- package/dist/src/markdown-analysis-cache.d.ts +20 -0
- package/dist/src/markdown-analysis-cache.js +139 -0
- package/dist/src/markdown-analysis-worker.d.ts +16 -0
- package/dist/src/markdown-analysis-worker.js +33 -0
- package/dist/src/markdown-analysis.d.ts +50 -0
- package/dist/src/markdown-analysis.js +139 -0
- package/dist/src/markdown-analyzer-loader.d.ts +4 -0
- package/dist/src/markdown-analyzer-loader.js +13 -0
- package/dist/src/markdown-validation.d.ts +25 -0
- package/dist/src/markdown-validation.js +104 -0
- package/dist/src/mcp/server.js +27 -11
- package/dist/src/parser-cache.d.ts +17 -0
- package/dist/src/parser-cache.js +65 -0
- package/dist/src/parser-import.d.ts +8 -0
- package/dist/src/parser-import.js +1 -0
- package/dist/src/parser.js +80 -5
- package/dist/src/path.d.ts +2 -0
- package/dist/src/path.js +4 -0
- package/dist/src/profiler.d.ts +16 -0
- package/dist/src/profiler.js +81 -0
- package/dist/src/project-analysis.d.ts +59 -0
- package/dist/src/project-analysis.js +233 -0
- package/dist/src/project-discovery.d.ts +6 -0
- package/dist/src/project-discovery.js +30 -0
- package/dist/src/repository-path.d.ts +11 -0
- package/dist/src/repository-path.js +52 -0
- package/dist/src/search/db.d.ts +1 -1
- package/dist/src/search/db.js +2 -2
- package/dist/src/search/embedder.d.ts +2 -1
- package/dist/src/search/embedder.js +6 -5
- package/dist/src/search/index.d.ts +2 -1
- package/dist/src/search/index.js +10 -8
- package/dist/src/search/query.d.ts +20 -0
- package/dist/src/search/query.js +67 -0
- package/dist/src/search/search.d.ts +3 -1
- package/dist/src/search/search.js +5 -2
- package/dist/src/source-formats.d.ts +7 -0
- package/dist/src/source-formats.js +26 -0
- package/dist/src/source-parser.d.ts +44 -4
- package/dist/src/source-parser.js +494 -57
- package/dist/src/view/client/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/src/view/client/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/src/view/client/assets/MarkdownEditor-B7quqPb8.js +28 -0
- package/dist/src/view/client/assets/OrbitControls-DwcpQNja.js +1 -0
- package/dist/src/view/client/assets/STLLoader-CLWTKt5i.js +1 -0
- package/dist/src/view/client/assets/abnfDiagram-VCTEODGH-V7-T6qsl.js +1 -0
- package/dist/src/view/client/assets/arc-BnwR8Bu7.js +1 -0
- package/dist/src/view/client/assets/architectureDiagram-5GKGNRK7-u97vDna9.js +36 -0
- package/dist/src/view/client/assets/blockDiagram-I7D4REHJ-DETl8e_H.js +129 -0
- package/dist/src/view/client/assets/c4Diagram-7LVT6UL2-DJRAT1Ve.js +38 -0
- package/dist/src/view/client/assets/channel-BwQbnWCN.js +1 -0
- package/dist/src/view/client/assets/chunk-2Q5K7J3B-C0TmOC1Q.js +1 -0
- package/dist/src/view/client/assets/chunk-5VM5RSS4-dfBOrYE6.js +15 -0
- package/dist/src/view/client/assets/chunk-F27PBJKO-DAnks99K.js +1 -0
- package/dist/src/view/client/assets/chunk-IMKFNOWR-CPjB07if.js +231 -0
- package/dist/src/view/client/assets/chunk-JWPE2WC7-VvU_gZI6.js +1 -0
- package/dist/src/view/client/assets/chunk-POPQ4Y6H-DDUbVF55.js +1 -0
- package/dist/src/view/client/assets/chunk-SVP7TREG-BHROkr6D.js +88 -0
- package/dist/src/view/client/assets/chunk-TICWLB2K-95PzGIOg.js +206 -0
- package/dist/src/view/client/assets/chunk-XXDRQBXY-MdmuLhIs.js +1 -0
- package/dist/src/view/client/assets/classDiagram-ZZMXUADV-HvQKkIS-.js +1 -0
- package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-HvQKkIS-.js +1 -0
- package/dist/src/view/client/assets/cose-bilkent-JH36ORCC-CauUf_rN.js +1 -0
- package/dist/src/view/client/assets/cynefin-OW5HDTMX-CeA8IKWo.js +166 -0
- package/dist/src/view/client/assets/cynefinDiagram-5FMLGOSQ-L1rtcT8l.js +62 -0
- package/dist/src/view/client/assets/cytoscape.esm-DzSz-X2X.js +321 -0
- package/dist/src/view/client/assets/dagre-GXQ25YYZ-DLQwTa3H.js +4 -0
- package/dist/src/view/client/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/dist/src/view/client/assets/diagram-S7CK7UJ4-kbKdIyXG.js +30 -0
- package/dist/src/view/client/assets/diagram-UQ7AKVKN-kmzp92RC.js +41 -0
- package/dist/src/view/client/assets/diagram-VSXAHHWV-EXJTU8qq.js +3 -0
- package/dist/src/view/client/assets/diagram-VX7I27RA-DAiIyMCG.js +24 -0
- package/dist/src/view/client/assets/diagram-Z3DM3KII-G9wz50ZV.js +24 -0
- package/dist/src/view/client/assets/ebnfDiagram-PWID7BFC-D2tVRCNA.js +1 -0
- package/dist/src/view/client/assets/erDiagram-RLTQ6QDP-C925J5A3.js +99 -0
- package/dist/src/view/client/assets/flowDiagram-HODETNUW-DzoCa-Nq.js +168 -0
- package/dist/src/view/client/assets/ganttDiagram-EL5Y4UJY-D2ebbg4p.js +292 -0
- package/dist/src/view/client/assets/gitGraphDiagram-WWUBYQGX-B4QratYy.js +106 -0
- package/dist/src/view/client/assets/index-BnENo9bV.js +1 -0
- package/dist/src/view/client/assets/index-D0ajr_Ja.css +1 -0
- package/dist/src/view/client/assets/index-KZcnpXJH.js +321 -0
- package/dist/src/view/client/assets/infoDiagram-27XIBGKW-DL4mtHkt.js +2 -0
- package/dist/src/view/client/assets/init-Gi6I4Gst.js +1 -0
- package/dist/src/view/client/assets/ishikawaDiagram-5VMMS53U-CW4mto2d.js +70 -0
- package/dist/src/view/client/assets/journeyDiagram-3NMN7TZE-8R4eacFW.js +139 -0
- package/dist/src/view/client/assets/kanban-definition-UXKFOSKX-Cy9ioXEJ.js +89 -0
- package/dist/src/view/client/assets/katex-HP8lGamR.js +257 -0
- package/dist/src/view/client/assets/layout-C0MFuhth.js +1 -0
- package/dist/src/view/client/assets/linear-Dv3N4dQR.js +1 -0
- package/dist/src/view/client/assets/logo-small-RR_KBOAT.svg +149 -0
- package/dist/src/view/client/assets/maplibre-gl-DnqZgfUS.js +800 -0
- package/dist/src/view/client/assets/mermaid.core-bds9A7e2.js +310 -0
- package/dist/src/view/client/assets/mindmap-definition-YA3MSWOX-DjmGW355.js +96 -0
- package/dist/src/view/client/assets/ordinal-Cboi1Yqb.js +1 -0
- package/dist/src/view/client/assets/pegDiagram-XKGWAZYB-BWsZp0ab.js +1 -0
- package/dist/src/view/client/assets/pieDiagram-E7YTZNPT-CCH2gGR-.js +39 -0
- package/dist/src/view/client/assets/quadrantDiagram-AXDQQJYC-CjocPJFz.js +7 -0
- package/dist/src/view/client/assets/railroadDiagram-O6MQD6OU-BjLeb2KF.js +1 -0
- package/dist/src/view/client/assets/requirementDiagram-BXWQKSXE-Ct6AoXRr.js +84 -0
- package/dist/src/view/client/assets/sankeyDiagram-P5KCCOFB-CIpgGN_w.js +40 -0
- package/dist/src/view/client/assets/sequenceDiagram-WJ2MYXX4-DrmLFj6w.js +162 -0
- package/dist/src/view/client/assets/sizeCapture-INFHLROL-BdFMe2Lr.js +1 -0
- package/dist/src/view/client/assets/stateDiagram-D77RDMKH-Zd9F1goW.js +1 -0
- package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-ByIKCftl.js +1 -0
- package/dist/src/view/client/assets/swimlanes-42K2YHIH-a7VFwi00.js +1 -0
- package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-CzxaUHB-.js +8 -0
- package/dist/src/view/client/assets/three.module-PDSP0dbZ.js +4108 -0
- package/dist/src/view/client/assets/timeline-definition-24CTP7MA-BExPu6X5.js +120 -0
- package/dist/src/view/client/assets/vennDiagram-4TSXK5OY-PC1MU3si.js +34 -0
- package/dist/src/view/client/assets/wardleyDiagram-VM6X3IG4-DNWqU3fa.js +78 -0
- package/dist/src/view/client/assets/xychartDiagram-S5SC5T6Z-E1uA28_D.js +7 -0
- package/dist/src/view/client/index.html +2 -2
- package/dist/src/view/client-shell.d.ts +2 -0
- package/dist/src/view/client-shell.js +5 -0
- package/dist/src/view/diagnostics.d.ts +3 -2
- package/dist/src/view/diagnostics.js +49 -58
- package/dist/src/view/document-edit.d.ts +8 -0
- package/dist/src/view/document-edit.js +25 -0
- package/dist/src/view/document-route.d.ts +12 -0
- package/dist/src/view/document-route.js +93 -0
- package/dist/src/view/document-tree.d.ts +18 -0
- package/dist/src/view/document-tree.js +139 -0
- package/dist/src/view/external-document-tree.d.ts +3 -0
- package/dist/src/view/external-document-tree.js +674 -0
- package/dist/src/view/git-diff.js +187 -0
- package/dist/src/view/git.js +1 -1
- package/dist/src/view/graph.d.ts +3 -2
- package/dist/src/view/graph.js +94 -7
- package/dist/src/view/highlight.d.ts +10 -2
- package/dist/src/view/highlight.js +4540 -1360
- package/dist/src/view/markdown.d.ts +3 -2
- package/dist/src/view/markdown.js +214 -53
- package/dist/src/view/protocol.d.ts +59 -6
- package/dist/src/view/references.d.ts +10 -25
- package/dist/src/view/references.js +117 -107
- package/dist/src/view/repository.d.ts +13 -3
- package/dist/src/view/repository.js +234 -15
- package/dist/src/view/search.d.ts +1 -1
- package/dist/src/view/search.js +3 -7
- package/dist/src/view/server.d.ts +11 -2
- package/dist/src/view/server.js +212 -70
- package/dist/src/view/source-target.js +5 -8
- package/dist/src/view/static-build.d.ts +1 -0
- package/dist/src/view/static-build.js +245 -42
- package/dist/src/view/static-protocol.d.ts +19 -2
- package/dist/src/view/store.d.ts +16 -3
- package/dist/src/view/store.js +228 -36
- package/dist/src/view/table-of-contents.d.ts +2 -2
- package/dist/src/view/table-of-contents.js +2 -22
- package/dist/src/walk.d.ts +5 -3
- package/dist/src/walk.js +102 -8
- package/package.json +46 -8
- package/plugins/lat-md/README.md +61 -0
- package/plugins/lat-md/hooks.json +38 -0
- package/plugins/lat-md/plugin.json +9 -0
- package/plugins/lat-md/rules/AGENTS.md +118 -0
- package/plugins/lat-md/skills/lat-md/SKILL.md +178 -0
- package/plugins/lat-md/skills/lat-md-conventions/SKILL.md +182 -0
- package/templates/AGENTS.md +15 -3
- package/templates/cursor-rules.md +12 -3
- package/templates/skill/SKILL.md +22 -1
- package/dist/src/view/client/assets/index-C3iaZyYT.css +0 -1
- package/dist/src/view/client/assets/index-KWi67IMz.js +0 -334
- package/dist/src/view/client/assets/logo-CNF8zs47.svg +0 -182
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { createRequire } from 'node:module';
|
|
4
|
+
import { performance } from 'node:perf_hooks';
|
|
5
|
+
import { PARSER_CACHE_VERSION, hashParserContent, parsedCachePath, parserCacheIdentity, readParsedCache, writeParsedCache, } from './parser-cache.js';
|
|
4
6
|
import { Parser, Language, } from 'web-tree-sitter';
|
|
7
|
+
import { sourceFileExtension, } from './source-formats.js';
|
|
5
8
|
// Lazy singleton for the parser
|
|
6
9
|
let parserReady = null;
|
|
7
10
|
let parserInstance = null;
|
|
@@ -21,25 +24,22 @@ async function ensureParser() {
|
|
|
21
24
|
}
|
|
22
25
|
return parserInstance;
|
|
23
26
|
}
|
|
24
|
-
/**
|
|
25
|
-
* truth for which source file extensions lat supports. */
|
|
27
|
+
/** Every supported source extension must declare a tree-sitter grammar. */
|
|
26
28
|
const grammarMap = {
|
|
27
|
-
'.
|
|
28
|
-
'.
|
|
29
|
+
'.c': 'tree-sitter-c.wasm',
|
|
30
|
+
'.dart': 'tree-sitter-dart.wasm',
|
|
31
|
+
'.go': 'tree-sitter-go.wasm',
|
|
32
|
+
'.h': 'tree-sitter-c.wasm',
|
|
33
|
+
'.java': 'tree-sitter-java.wasm',
|
|
29
34
|
'.js': 'tree-sitter-javascript.wasm',
|
|
30
35
|
'.jsx': 'tree-sitter-javascript.wasm',
|
|
31
36
|
'.py': 'tree-sitter-python.wasm',
|
|
32
37
|
'.rs': 'tree-sitter-rust.wasm',
|
|
33
|
-
'.
|
|
34
|
-
'.
|
|
35
|
-
'.h': 'tree-sitter-c.wasm',
|
|
38
|
+
'.ts': 'tree-sitter-typescript.wasm',
|
|
39
|
+
'.tsx': 'tree-sitter-tsx.wasm',
|
|
36
40
|
};
|
|
37
|
-
/** All source file extensions that lat can parse (derived from grammarMap). */
|
|
38
|
-
export const SOURCE_EXTENSIONS = new Set(Object.keys(grammarMap));
|
|
39
41
|
async function getLanguage(ext) {
|
|
40
42
|
const wasmFile = grammarMap[ext];
|
|
41
|
-
if (!wasmFile)
|
|
42
|
-
return null;
|
|
43
43
|
// Ensure WASM runtime is initialized before loading languages
|
|
44
44
|
await ensureParser();
|
|
45
45
|
if (!languages.has(wasmFile)) {
|
|
@@ -246,6 +246,314 @@ function extractPySymbols(tree) {
|
|
|
246
246
|
}
|
|
247
247
|
return symbols;
|
|
248
248
|
}
|
|
249
|
+
function dartDirectChild(node, type) {
|
|
250
|
+
return node.namedChildren.find((child) => child.type === type) ?? null;
|
|
251
|
+
}
|
|
252
|
+
function dartDefinitionName(node) {
|
|
253
|
+
const fieldName = extractName(node);
|
|
254
|
+
if (fieldName)
|
|
255
|
+
return fieldName;
|
|
256
|
+
if (node.type === 'class_definition') {
|
|
257
|
+
const alias = dartDirectChild(node, 'mixin_application_class');
|
|
258
|
+
return alias ? (dartDirectChild(alias, 'identifier')?.text ?? null) : null;
|
|
259
|
+
}
|
|
260
|
+
if (node.type === 'type_alias') {
|
|
261
|
+
return dartDirectChild(node, 'type_identifier')?.text ?? null;
|
|
262
|
+
}
|
|
263
|
+
return dartDirectChild(node, 'identifier')?.text ?? null;
|
|
264
|
+
}
|
|
265
|
+
function dartCallableNode(node) {
|
|
266
|
+
if (node.type !== 'method_signature' && node.type !== 'declaration') {
|
|
267
|
+
return node;
|
|
268
|
+
}
|
|
269
|
+
return (node.namedChildren.find((child) => [
|
|
270
|
+
'constructor_signature',
|
|
271
|
+
'factory_constructor_signature',
|
|
272
|
+
'function_signature',
|
|
273
|
+
'getter_signature',
|
|
274
|
+
'operator_signature',
|
|
275
|
+
'redirecting_factory_constructor_signature',
|
|
276
|
+
'setter_signature',
|
|
277
|
+
].includes(child.type)) ?? null);
|
|
278
|
+
}
|
|
279
|
+
function dartCallableName(node, parent) {
|
|
280
|
+
const callable = dartCallableNode(node);
|
|
281
|
+
if (!callable)
|
|
282
|
+
return null;
|
|
283
|
+
if (callable.type === 'operator_signature') {
|
|
284
|
+
const operator = callable.namedChildren.find((child) => child.type.endsWith('_operator'));
|
|
285
|
+
return operator ? `operator ${operator.text}` : null;
|
|
286
|
+
}
|
|
287
|
+
if (callable.type === 'constructor_signature' ||
|
|
288
|
+
callable.type === 'factory_constructor_signature' ||
|
|
289
|
+
callable.type === 'redirecting_factory_constructor_signature') {
|
|
290
|
+
const names = callable.namedChildren
|
|
291
|
+
.filter((child) => child.type === 'identifier')
|
|
292
|
+
.map((child) => child.text);
|
|
293
|
+
if (names.length === 0)
|
|
294
|
+
return null;
|
|
295
|
+
if (names.length === 1)
|
|
296
|
+
return names[0];
|
|
297
|
+
return names[0] === parent ? names[1] : names.at(-1);
|
|
298
|
+
}
|
|
299
|
+
return extractName(callable);
|
|
300
|
+
}
|
|
301
|
+
function dartAnnotatedStart(siblings, index) {
|
|
302
|
+
let start = siblings[index];
|
|
303
|
+
for (let i = index - 1; i >= 0 && siblings[i].type === 'annotation'; i--) {
|
|
304
|
+
start = siblings[i];
|
|
305
|
+
}
|
|
306
|
+
return start;
|
|
307
|
+
}
|
|
308
|
+
function dartDefinitionEnd(siblings, index) {
|
|
309
|
+
return siblings[index + 1]?.type === 'function_body'
|
|
310
|
+
? siblings[index + 1]
|
|
311
|
+
: siblings[index];
|
|
312
|
+
}
|
|
313
|
+
function dartSignature(sourceLines, node) {
|
|
314
|
+
return sourceLines[node.startPosition.row]?.trim() ?? '';
|
|
315
|
+
}
|
|
316
|
+
function pushDartSymbol(sourceLines, symbols, name, kind, node, options = {}) {
|
|
317
|
+
symbols.push({
|
|
318
|
+
name,
|
|
319
|
+
kind,
|
|
320
|
+
...(options.parent ? { parent: options.parent } : {}),
|
|
321
|
+
startLine: (options.start ?? node).startPosition.row + 1,
|
|
322
|
+
endLine: (options.end ?? node).endPosition.row + 1,
|
|
323
|
+
signature: dartSignature(sourceLines, node),
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
function dartVariableKind(siblings, index, container) {
|
|
327
|
+
if (container?.namedChildren.some((child) => child.type === 'const_builtin')) {
|
|
328
|
+
return 'const';
|
|
329
|
+
}
|
|
330
|
+
const row = siblings[index].startPosition.row;
|
|
331
|
+
for (let i = index - 1; i >= 0 && siblings[i].endPosition.row === row; i--) {
|
|
332
|
+
if (siblings[i].type === 'const_builtin')
|
|
333
|
+
return 'const';
|
|
334
|
+
}
|
|
335
|
+
return 'variable';
|
|
336
|
+
}
|
|
337
|
+
function extractDartVariables(sourceLines, symbols, node, kind, parent) {
|
|
338
|
+
const lists = node.type === 'initialized_identifier_list' ||
|
|
339
|
+
node.type === 'static_final_declaration_list'
|
|
340
|
+
? [node]
|
|
341
|
+
: node.namedChildren.filter((child) => child.type === 'initialized_identifier_list' ||
|
|
342
|
+
child.type === 'static_final_declaration_list');
|
|
343
|
+
for (const list of lists) {
|
|
344
|
+
for (const declaration of list.namedChildren) {
|
|
345
|
+
if (declaration.type !== 'initialized_identifier' &&
|
|
346
|
+
declaration.type !== 'static_final_declaration') {
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
const name = dartDirectChild(declaration, 'identifier')?.text;
|
|
350
|
+
if (name) {
|
|
351
|
+
pushDartSymbol(sourceLines, symbols, name, kind, node, { parent });
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function extractDartMembers(sourceLines, body, parent, symbols) {
|
|
357
|
+
const children = body.namedChildren;
|
|
358
|
+
for (let i = 0; i < children.length; i++) {
|
|
359
|
+
const node = children[i];
|
|
360
|
+
if (node.type === 'method_signature') {
|
|
361
|
+
const name = dartCallableName(node, parent);
|
|
362
|
+
if (name) {
|
|
363
|
+
pushDartSymbol(sourceLines, symbols, name, 'method', node, {
|
|
364
|
+
parent,
|
|
365
|
+
start: dartAnnotatedStart(children, i),
|
|
366
|
+
end: dartDefinitionEnd(children, i),
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
else if (node.type === 'declaration') {
|
|
371
|
+
const name = dartCallableName(node, parent);
|
|
372
|
+
if (name) {
|
|
373
|
+
pushDartSymbol(sourceLines, symbols, name, 'method', node, { parent });
|
|
374
|
+
}
|
|
375
|
+
extractDartVariables(sourceLines, symbols, node, dartVariableKind(children, i, node), parent);
|
|
376
|
+
}
|
|
377
|
+
else if (node.type === 'enum_constant') {
|
|
378
|
+
const name = extractName(node);
|
|
379
|
+
if (name) {
|
|
380
|
+
pushDartSymbol(sourceLines, symbols, name, 'const', node, { parent });
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
function extractDartSymbols(tree) {
|
|
386
|
+
const symbols = [];
|
|
387
|
+
const children = tree.rootNode.namedChildren;
|
|
388
|
+
const sourceLines = tree.rootNode.text.split('\n');
|
|
389
|
+
for (let i = 0; i < children.length; i++) {
|
|
390
|
+
const node = children[i];
|
|
391
|
+
const start = dartAnnotatedStart(children, i);
|
|
392
|
+
if (node.type === 'function_signature' ||
|
|
393
|
+
node.type === 'getter_signature' ||
|
|
394
|
+
node.type === 'setter_signature') {
|
|
395
|
+
const name = dartCallableName(node);
|
|
396
|
+
if (name) {
|
|
397
|
+
pushDartSymbol(sourceLines, symbols, name, 'function', node, {
|
|
398
|
+
start,
|
|
399
|
+
end: dartDefinitionEnd(children, i),
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
else if (node.type === 'class_definition') {
|
|
404
|
+
const name = dartDefinitionName(node);
|
|
405
|
+
if (!name)
|
|
406
|
+
continue;
|
|
407
|
+
pushDartSymbol(sourceLines, symbols, name, 'class', node, { start });
|
|
408
|
+
const body = node.childForFieldName('body');
|
|
409
|
+
if (body)
|
|
410
|
+
extractDartMembers(sourceLines, body, name, symbols);
|
|
411
|
+
}
|
|
412
|
+
else if (node.type === 'mixin_declaration') {
|
|
413
|
+
const name = dartDefinitionName(node);
|
|
414
|
+
if (!name)
|
|
415
|
+
continue;
|
|
416
|
+
pushDartSymbol(sourceLines, symbols, name, 'interface', node, { start });
|
|
417
|
+
const body = dartDirectChild(node, 'class_body');
|
|
418
|
+
if (body)
|
|
419
|
+
extractDartMembers(sourceLines, body, name, symbols);
|
|
420
|
+
}
|
|
421
|
+
else if (node.type === 'extension_declaration') {
|
|
422
|
+
const name = extractName(node);
|
|
423
|
+
if (!name)
|
|
424
|
+
continue;
|
|
425
|
+
pushDartSymbol(sourceLines, symbols, name, 'class', node, { start });
|
|
426
|
+
const body = node.childForFieldName('body');
|
|
427
|
+
if (body)
|
|
428
|
+
extractDartMembers(sourceLines, body, name, symbols);
|
|
429
|
+
}
|
|
430
|
+
else if (node.type === 'enum_declaration') {
|
|
431
|
+
const name = extractName(node);
|
|
432
|
+
if (!name)
|
|
433
|
+
continue;
|
|
434
|
+
pushDartSymbol(sourceLines, symbols, name, 'class', node, { start });
|
|
435
|
+
const body = node.childForFieldName('body');
|
|
436
|
+
if (body)
|
|
437
|
+
extractDartMembers(sourceLines, body, name, symbols);
|
|
438
|
+
}
|
|
439
|
+
else if (node.type === 'extension_type_declaration') {
|
|
440
|
+
const name = extractName(node);
|
|
441
|
+
if (!name)
|
|
442
|
+
continue;
|
|
443
|
+
pushDartSymbol(sourceLines, symbols, name, 'type', node, { start });
|
|
444
|
+
const representation = node.childForFieldName('representation');
|
|
445
|
+
const representationName = representation?.childForFieldName('name');
|
|
446
|
+
if (representation && representationName) {
|
|
447
|
+
pushDartSymbol(sourceLines, symbols, representationName.text, 'variable', representation, { parent: name });
|
|
448
|
+
}
|
|
449
|
+
const body = node.childForFieldName('body');
|
|
450
|
+
if (body)
|
|
451
|
+
extractDartMembers(sourceLines, body, name, symbols);
|
|
452
|
+
}
|
|
453
|
+
else if (node.type === 'type_alias') {
|
|
454
|
+
const name = dartDefinitionName(node);
|
|
455
|
+
if (name) {
|
|
456
|
+
pushDartSymbol(sourceLines, symbols, name, 'type', node, { start });
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
else if (node.type === 'initialized_identifier_list' ||
|
|
460
|
+
node.type === 'static_final_declaration_list') {
|
|
461
|
+
extractDartVariables(sourceLines, symbols, node, dartVariableKind(children, i));
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return symbols;
|
|
465
|
+
}
|
|
466
|
+
const javaTypeKinds = {
|
|
467
|
+
annotation_type_declaration: 'interface',
|
|
468
|
+
class_declaration: 'class',
|
|
469
|
+
enum_declaration: 'class',
|
|
470
|
+
interface_declaration: 'interface',
|
|
471
|
+
record_declaration: 'class',
|
|
472
|
+
};
|
|
473
|
+
function javaSignature(sourceLines, node) {
|
|
474
|
+
const declarator = node.namedChildren.find((child) => child.type === 'variable_declarator');
|
|
475
|
+
const name = node.childForFieldName('name') ?? declarator?.childForFieldName('name');
|
|
476
|
+
return sourceLines[(name ?? node).startPosition.row]?.trim() ?? '';
|
|
477
|
+
}
|
|
478
|
+
function pushJavaSymbol(sourceLines, symbols, name, kind, node, parent) {
|
|
479
|
+
const symbol = {
|
|
480
|
+
name,
|
|
481
|
+
kind,
|
|
482
|
+
...(parent ? { parent } : {}),
|
|
483
|
+
startLine: node.startPosition.row + 1,
|
|
484
|
+
endLine: node.endPosition.row + 1,
|
|
485
|
+
signature: javaSignature(sourceLines, node),
|
|
486
|
+
};
|
|
487
|
+
symbols.push(symbol);
|
|
488
|
+
return symbol;
|
|
489
|
+
}
|
|
490
|
+
function extractJavaVariables(sourceLines, symbols, node, parent) {
|
|
491
|
+
const kind = node.type === 'constant_declaration' ? 'const' : 'variable';
|
|
492
|
+
for (const declarator of node.namedChildren) {
|
|
493
|
+
if (declarator.type !== 'variable_declarator')
|
|
494
|
+
continue;
|
|
495
|
+
const name = extractName(declarator);
|
|
496
|
+
if (name) {
|
|
497
|
+
pushJavaSymbol(sourceLines, symbols, name, kind, node, parent);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
function collectJavaScope(sourceLines, scope, parent, symbols) {
|
|
502
|
+
for (const node of scope.namedChildren) {
|
|
503
|
+
const typeKind = javaTypeKinds[node.type];
|
|
504
|
+
if (typeKind) {
|
|
505
|
+
const name = extractName(node);
|
|
506
|
+
if (!name)
|
|
507
|
+
continue;
|
|
508
|
+
const symbol = pushJavaSymbol(sourceLines, symbols, name, typeKind, node);
|
|
509
|
+
if (parent)
|
|
510
|
+
symbols.push({ ...symbol, parent });
|
|
511
|
+
if (node.type === 'record_declaration') {
|
|
512
|
+
const parameters = node.childForFieldName('parameters');
|
|
513
|
+
for (const parameter of parameters?.namedChildren ?? []) {
|
|
514
|
+
const component = extractName(parameter);
|
|
515
|
+
if (component) {
|
|
516
|
+
pushJavaSymbol(sourceLines, symbols, component, 'variable', parameter, name);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
const body = node.childForFieldName('body');
|
|
521
|
+
if (body)
|
|
522
|
+
collectJavaScope(sourceLines, body, name, symbols);
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
if (!parent)
|
|
526
|
+
continue;
|
|
527
|
+
if (node.type === 'method_declaration' ||
|
|
528
|
+
node.type === 'constructor_declaration' ||
|
|
529
|
+
node.type === 'compact_constructor_declaration' ||
|
|
530
|
+
node.type === 'annotation_type_element_declaration') {
|
|
531
|
+
const name = extractName(node);
|
|
532
|
+
if (name) {
|
|
533
|
+
pushJavaSymbol(sourceLines, symbols, name, 'method', node, parent);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
else if (node.type === 'field_declaration' ||
|
|
537
|
+
node.type === 'constant_declaration') {
|
|
538
|
+
extractJavaVariables(sourceLines, symbols, node, parent);
|
|
539
|
+
}
|
|
540
|
+
else if (node.type === 'enum_constant') {
|
|
541
|
+
const name = extractName(node);
|
|
542
|
+
if (name) {
|
|
543
|
+
pushJavaSymbol(sourceLines, symbols, name, 'const', node, parent);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
else if (node.type === 'enum_body_declarations') {
|
|
547
|
+
collectJavaScope(sourceLines, node, parent, symbols);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
function extractJavaSymbols(tree) {
|
|
552
|
+
const symbols = [];
|
|
553
|
+
const sourceLines = tree.rootNode.text.split('\n');
|
|
554
|
+
collectJavaScope(sourceLines, tree.rootNode, undefined, symbols);
|
|
555
|
+
return symbols;
|
|
556
|
+
}
|
|
249
557
|
function extractRustSymbols(tree) {
|
|
250
558
|
const symbols = [];
|
|
251
559
|
const root = tree.rootNode;
|
|
@@ -784,72 +1092,200 @@ function firstLine(text) {
|
|
|
784
1092
|
const nl = text.indexOf('\n');
|
|
785
1093
|
return nl === -1 ? text : text.slice(0, nl);
|
|
786
1094
|
}
|
|
1095
|
+
/** Every supported source extension must declare a symbol extractor. */
|
|
1096
|
+
const symbolExtractors = {
|
|
1097
|
+
'.c': extractCSymbols,
|
|
1098
|
+
'.dart': extractDartSymbols,
|
|
1099
|
+
'.go': extractGoSymbols,
|
|
1100
|
+
'.h': extractCSymbols,
|
|
1101
|
+
'.java': extractJavaSymbols,
|
|
1102
|
+
'.js': extractTsSymbols,
|
|
1103
|
+
'.jsx': extractTsSymbols,
|
|
1104
|
+
'.py': extractPySymbols,
|
|
1105
|
+
'.rs': extractRustSymbols,
|
|
1106
|
+
'.ts': extractTsSymbols,
|
|
1107
|
+
'.tsx': extractTsSymbols,
|
|
1108
|
+
};
|
|
787
1109
|
export async function parseSourceSymbols(filePath, content) {
|
|
788
|
-
const ext = filePath
|
|
789
|
-
|
|
790
|
-
if (!lang)
|
|
1110
|
+
const ext = sourceFileExtension(filePath);
|
|
1111
|
+
if (!ext)
|
|
791
1112
|
return [];
|
|
1113
|
+
const lang = await getLanguage(ext);
|
|
792
1114
|
const p = await ensureParser();
|
|
793
1115
|
p.setLanguage(lang);
|
|
794
1116
|
const tree = p.parse(content);
|
|
795
1117
|
if (!tree)
|
|
796
1118
|
return [];
|
|
797
1119
|
try {
|
|
798
|
-
|
|
799
|
-
return extractPySymbols(tree);
|
|
800
|
-
}
|
|
801
|
-
if (ext === '.rs') {
|
|
802
|
-
return extractRustSymbols(tree);
|
|
803
|
-
}
|
|
804
|
-
if (ext === '.go') {
|
|
805
|
-
return extractGoSymbols(tree);
|
|
806
|
-
}
|
|
807
|
-
if (ext === '.c' || ext === '.h') {
|
|
808
|
-
return extractCSymbols(tree);
|
|
809
|
-
}
|
|
810
|
-
return extractTsSymbols(tree);
|
|
1120
|
+
return symbolExtractors[ext](tree);
|
|
811
1121
|
}
|
|
812
1122
|
finally {
|
|
813
1123
|
tree.delete();
|
|
814
1124
|
}
|
|
815
1125
|
}
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
const
|
|
1126
|
+
function isRecord(value) {
|
|
1127
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
1128
|
+
}
|
|
1129
|
+
const sourceSymbolKinds = new Set([
|
|
1130
|
+
'function',
|
|
1131
|
+
'class',
|
|
1132
|
+
'const',
|
|
1133
|
+
'type',
|
|
1134
|
+
'interface',
|
|
1135
|
+
'method',
|
|
1136
|
+
'variable',
|
|
1137
|
+
]);
|
|
1138
|
+
function isSourceSymbol(value) {
|
|
1139
|
+
if (!isRecord(value))
|
|
1140
|
+
return false;
|
|
1141
|
+
return (typeof value.name === 'string' &&
|
|
1142
|
+
typeof value.kind === 'string' &&
|
|
1143
|
+
sourceSymbolKinds.has(value.kind) &&
|
|
1144
|
+
(value.parent === undefined || typeof value.parent === 'string') &&
|
|
1145
|
+
Number.isInteger(value.startLine) &&
|
|
1146
|
+
value.startLine > 0 &&
|
|
1147
|
+
Number.isInteger(value.endLine) &&
|
|
1148
|
+
value.endLine >= value.startLine &&
|
|
1149
|
+
typeof value.signature === 'string');
|
|
1150
|
+
}
|
|
1151
|
+
function cachedSourceAnalysis(entry, contentHash, identity, timings) {
|
|
1152
|
+
if (!entry ||
|
|
1153
|
+
entry.version !== PARSER_CACHE_VERSION ||
|
|
1154
|
+
entry.contentHash !== contentHash ||
|
|
1155
|
+
!isRecord(entry.value) ||
|
|
1156
|
+
entry.value.path !== identity ||
|
|
1157
|
+
!Array.isArray(entry.value.symbols) ||
|
|
1158
|
+
!entry.value.symbols.every(isSourceSymbol)) {
|
|
1159
|
+
return null;
|
|
1160
|
+
}
|
|
1161
|
+
return {
|
|
1162
|
+
path: identity,
|
|
1163
|
+
symbols: entry.value.symbols,
|
|
1164
|
+
timings: {
|
|
1165
|
+
...timings,
|
|
1166
|
+
cacheStatus: 'hit',
|
|
1167
|
+
cacheWriteMs: 0,
|
|
1168
|
+
parseMs: 0,
|
|
1169
|
+
},
|
|
1170
|
+
};
|
|
1171
|
+
}
|
|
1172
|
+
/** Request-scoped owner for in-flight and completed source parser work. */
|
|
1173
|
+
export class SourceParserRuntime {
|
|
1174
|
+
analyses = new Map();
|
|
1175
|
+
symbols = new Map();
|
|
1176
|
+
clear() {
|
|
1177
|
+
this.analyses.clear();
|
|
1178
|
+
this.symbols.clear();
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
const defaultSourceParserRuntime = new SourceParserRuntime();
|
|
1182
|
+
/** Return the parser cache path for one project source file. */
|
|
1183
|
+
export function sourceAnalysisCachePath(latDir, projectRoot, absolutePath) {
|
|
1184
|
+
return parsedCachePath(latDir, parserCacheIdentity(absolutePath, projectRoot));
|
|
1185
|
+
}
|
|
1186
|
+
/** Analyze source content through the shared versioned persistent cache. */
|
|
1187
|
+
export async function analyzeSourceSymbols(filePath, content, latDir, options = {}) {
|
|
1188
|
+
const identity = (options.identity ?? filePath)
|
|
1189
|
+
.replaceAll('\\', '/')
|
|
1190
|
+
.normalize('NFC');
|
|
1191
|
+
const hashStarted = performance.now();
|
|
1192
|
+
const contentHash = hashParserContent(content);
|
|
1193
|
+
const hashMs = performance.now() - hashStarted;
|
|
1194
|
+
const cache = options.cache !== false;
|
|
1195
|
+
const cachePath = parsedCachePath(latDir, identity);
|
|
1196
|
+
const promiseKey = `${cache ? 'cache' : 'direct'}\0${cachePath}\0${contentHash}`;
|
|
1197
|
+
const runtime = options.runtime ?? defaultSourceParserRuntime;
|
|
1198
|
+
let analysis = runtime.analyses.get(promiseKey);
|
|
1199
|
+
if (!analysis) {
|
|
1200
|
+
analysis = (async () => {
|
|
1201
|
+
const cacheStarted = performance.now();
|
|
1202
|
+
const entry = cache ? await readParsedCache(cachePath) : null;
|
|
1203
|
+
const cacheReadMs = cache ? performance.now() - cacheStarted : 0;
|
|
1204
|
+
const timings = {
|
|
1205
|
+
readMs: options.readMs ?? 0,
|
|
1206
|
+
hashMs,
|
|
1207
|
+
cacheReadMs,
|
|
1208
|
+
cacheStatus: cache ? 'miss' : 'disabled',
|
|
1209
|
+
};
|
|
1210
|
+
const cached = cache
|
|
1211
|
+
? cachedSourceAnalysis(entry, contentHash, identity, timings)
|
|
1212
|
+
: null;
|
|
1213
|
+
if (cached)
|
|
1214
|
+
return cached;
|
|
1215
|
+
const parseStarted = performance.now();
|
|
1216
|
+
const symbols = await parseSourceSymbols(filePath, content);
|
|
1217
|
+
const result = {
|
|
1218
|
+
path: identity,
|
|
1219
|
+
symbols,
|
|
1220
|
+
timings: {
|
|
1221
|
+
...timings,
|
|
1222
|
+
cacheWriteMs: 0,
|
|
1223
|
+
parseMs: performance.now() - parseStarted,
|
|
1224
|
+
},
|
|
1225
|
+
};
|
|
1226
|
+
if (!cache)
|
|
1227
|
+
return result;
|
|
1228
|
+
const writeStarted = performance.now();
|
|
1229
|
+
try {
|
|
1230
|
+
await writeParsedCache(cachePath, contentHash, result);
|
|
1231
|
+
}
|
|
1232
|
+
catch {
|
|
1233
|
+
// The cache is a disposable optimization; parsing must work read-only.
|
|
1234
|
+
}
|
|
1235
|
+
result.timings.cacheWriteMs = performance.now() - writeStarted;
|
|
1236
|
+
return result;
|
|
1237
|
+
})();
|
|
1238
|
+
runtime.analyses.set(promiseKey, analysis);
|
|
1239
|
+
}
|
|
1240
|
+
return analysis;
|
|
1241
|
+
}
|
|
820
1242
|
/** Clear the symbol cache. Call between top-level operations. */
|
|
821
1243
|
export function clearSymbolCache() {
|
|
822
|
-
|
|
1244
|
+
defaultSourceParserRuntime.clear();
|
|
823
1245
|
}
|
|
824
1246
|
/**
|
|
825
1247
|
* Check whether a source file path (relative to projectRoot) has a given symbol.
|
|
826
1248
|
* Used by lat check to validate source code wiki links lazily.
|
|
827
1249
|
*/
|
|
828
|
-
export async function resolveSourceSymbol(filePath, symbolPath, projectRoot) {
|
|
1250
|
+
export async function resolveSourceSymbol(filePath, symbolPath, projectRoot, options = {}) {
|
|
829
1251
|
const absPath = join(projectRoot, filePath);
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
1252
|
+
const latDir = options.latDir ?? join(projectRoot, 'lat.md');
|
|
1253
|
+
const cacheKey = `${latDir}\0${absPath}`;
|
|
1254
|
+
const runtime = options.runtime ?? defaultSourceParserRuntime;
|
|
1255
|
+
let cachedPromise = runtime.symbols.get(cacheKey);
|
|
1256
|
+
const created = !cachedPromise;
|
|
1257
|
+
if (!cachedPromise) {
|
|
1258
|
+
cachedPromise = (async () => {
|
|
1259
|
+
const readStarted = performance.now();
|
|
1260
|
+
let content;
|
|
1261
|
+
try {
|
|
1262
|
+
content = await readFile(absPath, 'utf-8');
|
|
1263
|
+
}
|
|
1264
|
+
catch {
|
|
1265
|
+
return { symbols: [] };
|
|
1266
|
+
}
|
|
1267
|
+
const readMs = performance.now() - readStarted;
|
|
1268
|
+
try {
|
|
1269
|
+
const analysis = await analyzeSourceSymbols(filePath, content, latDir, {
|
|
1270
|
+
cache: options.cache,
|
|
1271
|
+
identity: parserCacheIdentity(absPath, projectRoot),
|
|
1272
|
+
readMs,
|
|
1273
|
+
runtime,
|
|
1274
|
+
});
|
|
1275
|
+
return { symbols: analysis.symbols, analysis };
|
|
1276
|
+
}
|
|
1277
|
+
catch (err) {
|
|
1278
|
+
return {
|
|
1279
|
+
symbols: [],
|
|
1280
|
+
error: `failed to parse "${filePath}": ${err instanceof Error ? err.message : String(err)}`,
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
1283
|
+
})();
|
|
1284
|
+
runtime.symbols.set(cacheKey, cachedPromise);
|
|
852
1285
|
}
|
|
1286
|
+
const cached = await cachedPromise;
|
|
1287
|
+
if (created && cached.analysis)
|
|
1288
|
+
options.onFileAnalyzed?.(cached.analysis);
|
|
853
1289
|
if (cached.error) {
|
|
854
1290
|
return { found: false, symbols: cached.symbols, error: cached.error };
|
|
855
1291
|
}
|
|
@@ -873,6 +1309,7 @@ export async function resolveSourceSymbol(filePath, symbolPath, projectRoot) {
|
|
|
873
1309
|
export function sourceSymbolsToSections(symbols, filePath) {
|
|
874
1310
|
const sections = [];
|
|
875
1311
|
const classMap = new Map();
|
|
1312
|
+
const parentNames = new Set(symbols.flatMap((symbol) => (symbol.parent ? [symbol.parent] : [])));
|
|
876
1313
|
for (const sym of symbols) {
|
|
877
1314
|
if (sym.parent)
|
|
878
1315
|
continue; // Handle methods after their class
|
|
@@ -888,7 +1325,7 @@ export function sourceSymbolsToSections(symbols, filePath) {
|
|
|
888
1325
|
firstParagraph: sym.signature,
|
|
889
1326
|
};
|
|
890
1327
|
sections.push(section);
|
|
891
|
-
if (sym.
|
|
1328
|
+
if (parentNames.has(sym.name)) {
|
|
892
1329
|
classMap.set(sym.name, section);
|
|
893
1330
|
}
|
|
894
1331
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|