codebase-onboarder 0.5.0 → 0.7.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.
- package/README.md +196 -47
- package/bin/build-if-source.js +23 -0
- package/cli/commands.d.ts +26 -0
- package/cli/commands.js +836 -811
- package/cli/commands.js.map +1 -0
- package/cli/explorer/advanced.d.ts +14 -0
- package/cli/explorer/advanced.js +449 -0
- package/cli/explorer/advanced.js.map +1 -0
- package/cli/explorer/app.d.ts +1 -0
- package/cli/explorer/app.js +396 -229
- package/cli/explorer/app.js.map +1 -0
- package/cli/explorer/assistant.d.ts +9 -0
- package/cli/explorer/assistant.js +58 -0
- package/cli/explorer/assistant.js.map +1 -0
- package/cli/explorer/commands.d.ts +17 -0
- package/cli/explorer/commands.js +400 -162
- package/cli/explorer/commands.js.map +1 -0
- package/cli/explorer/featureViews.d.ts +124 -0
- package/cli/explorer/featureViews.js +179 -0
- package/cli/explorer/featureViews.js.map +1 -0
- package/cli/explorer/github.d.ts +21 -0
- package/cli/explorer/github.js +73 -0
- package/cli/explorer/github.js.map +1 -0
- package/cli/explorer/graphs.d.ts +7 -0
- package/cli/explorer/graphs.js +173 -0
- package/cli/explorer/graphs.js.map +1 -0
- package/cli/explorer/picker.d.ts +22 -0
- package/cli/explorer/picker.js +150 -0
- package/cli/explorer/picker.js.map +1 -0
- package/cli/explorer/report.d.ts +85 -0
- package/cli/explorer/report.js +60 -0
- package/cli/explorer/report.js.map +1 -0
- package/cli/explorer/session.d.ts +449 -0
- package/cli/explorer/session.js +184 -95
- package/cli/explorer/session.js.map +1 -0
- package/cli/explorer/views.d.ts +19 -0
- package/cli/explorer/views.js +496 -412
- package/cli/explorer/views.js.map +1 -0
- package/cli/explorer/wrap.d.ts +1 -0
- package/cli/explorer/wrap.js +33 -0
- package/cli/explorer/wrap.js.map +1 -0
- package/cli/main.d.ts +1 -0
- package/cli/main.js +235 -138
- package/cli/main.js.map +1 -0
- package/cli/prompt.d.ts +5 -0
- package/cli/prompt.js +84 -80
- package/cli/prompt.js.map +1 -0
- package/cli/scanOptions.d.ts +2 -0
- package/cli/scanOptions.js +11 -0
- package/cli/scanOptions.js.map +1 -0
- package/cli/ui.d.ts +33 -0
- package/cli/ui.js +55 -35
- package/cli/ui.js.map +1 -0
- package/cli/wizard.d.ts +187 -0
- package/cli/wizard.js +304 -284
- package/cli/wizard.js.map +1 -0
- package/package.json +15 -4
- package/public/app.d.ts +1 -0
- package/public/app.js +1057 -1009
- package/public/app.js.map +1 -0
- package/public/browser.d.ts +68 -0
- package/public/browser.js +2 -0
- package/public/browser.js.map +1 -0
- package/public/index.html +30 -13
- package/public/js/about.d.ts +6 -0
- package/public/js/about.js +165 -172
- package/public/js/about.js.map +1 -0
- package/public/js/aiDraft.d.ts +3 -0
- package/public/js/aiDraft.js +116 -124
- package/public/js/aiDraft.js.map +1 -0
- package/public/js/analysisPanel.d.ts +7 -0
- package/public/js/analysisPanel.js +166 -166
- package/public/js/analysisPanel.js.map +1 -0
- package/public/js/analysisReport.d.ts +38 -0
- package/public/js/analysisReport.js +105 -110
- package/public/js/analysisReport.js.map +1 -0
- package/public/js/api.d.ts +26 -0
- package/public/js/api.js +176 -167
- package/public/js/api.js.map +1 -0
- package/public/js/atlas.d.ts +6 -0
- package/public/js/atlas.js +50 -58
- package/public/js/atlas.js.map +1 -0
- package/public/js/blameView.d.ts +2 -0
- package/public/js/blameView.js +36 -37
- package/public/js/blameView.js.map +1 -0
- package/public/js/codeTab.d.ts +3 -0
- package/public/js/codeTab.js +175 -180
- package/public/js/codeTab.js.map +1 -0
- package/public/js/codeViewer.d.ts +5 -0
- package/public/js/codeViewer.js +162 -150
- package/public/js/codeViewer.js.map +1 -0
- package/public/js/components/FileChip.d.ts +9 -0
- package/public/js/components/FileChip.js +45 -49
- package/public/js/components/FileChip.js.map +1 -0
- package/public/js/components/MetricSparkline.d.ts +7 -0
- package/public/js/components/MetricSparkline.js +35 -44
- package/public/js/components/MetricSparkline.js.map +1 -0
- package/public/js/components/RiskBadge.d.ts +9 -0
- package/public/js/components/RiskBadge.js +55 -63
- package/public/js/components/RiskBadge.js.map +1 -0
- package/public/js/deepAnalysisView.d.ts +99 -0
- package/public/js/deepAnalysisView.js +282 -302
- package/public/js/deepAnalysisView.js.map +1 -0
- package/public/js/diagramPane.d.ts +8 -0
- package/public/js/diagramPane.js +133 -135
- package/public/js/diagramPane.js.map +1 -0
- package/public/js/diffView.d.ts +6 -0
- package/public/js/diffView.js +222 -209
- package/public/js/diffView.js.map +1 -0
- package/public/js/docsView.d.ts +2 -0
- package/public/js/docsView.js +441 -442
- package/public/js/docsView.js.map +1 -0
- package/public/js/dom.d.ts +189 -0
- package/public/js/dom.js +5 -0
- package/public/js/dom.js.map +1 -0
- package/public/js/fileSourceBrowser.d.ts +5 -0
- package/public/js/fileSourceBrowser.js +33 -41
- package/public/js/fileSourceBrowser.js.map +1 -0
- package/public/js/flameGraph.d.ts +5 -0
- package/public/js/flameGraph.js +62 -72
- package/public/js/flameGraph.js.map +1 -0
- package/public/js/forceGraph.d.ts +10 -0
- package/public/js/forceGraph.js +581 -556
- package/public/js/forceGraph.js.map +1 -0
- package/public/js/heatmap.d.ts +4 -0
- package/public/js/heatmap.js +142 -164
- package/public/js/heatmap.js.map +1 -0
- package/public/js/highlight.d.ts +2 -0
- package/public/js/highlight.js +116 -107
- package/public/js/highlight.js.map +1 -0
- package/public/js/html.d.ts +2 -0
- package/public/js/html.js +14 -44
- package/public/js/html.js.map +1 -0
- package/public/js/insightsView.d.ts +5 -0
- package/public/js/insightsView.js +93 -111
- package/public/js/insightsView.js.map +1 -0
- package/public/js/inspector.d.ts +37 -0
- package/public/js/inspector.js +416 -445
- package/public/js/inspector.js.map +1 -0
- package/public/js/llm.d.ts +113 -0
- package/public/js/llm.js +233 -272
- package/public/js/llm.js.map +1 -0
- package/public/js/mapView.d.ts +3 -0
- package/public/js/mapView.js +121 -120
- package/public/js/mapView.js.map +1 -0
- package/public/js/markdown.d.ts +3 -0
- package/public/js/markdown.js +84 -91
- package/public/js/markdown.js.map +1 -0
- package/public/js/mindmap.d.ts +32 -0
- package/public/js/mindmap.js +244 -259
- package/public/js/mindmap.js.map +1 -0
- package/public/js/mobilePanels.d.ts +5 -0
- package/public/js/mobilePanels.js +50 -0
- package/public/js/mobilePanels.js.map +1 -0
- package/public/js/repoFiles.d.ts +12 -0
- package/public/js/repoFiles.js +28 -27
- package/public/js/repoFiles.js.map +1 -0
- package/public/js/reviewView.d.ts +28 -0
- package/public/js/reviewView.js +256 -0
- package/public/js/reviewView.js.map +1 -0
- package/public/js/sbomView.d.ts +3 -0
- package/public/js/sbomView.js +59 -67
- package/public/js/sbomView.js.map +1 -0
- package/public/js/scanCache.d.ts +16 -0
- package/public/js/scanCache.js +67 -65
- package/public/js/scanCache.js.map +1 -0
- package/public/js/search.d.ts +7 -0
- package/public/js/search.js +868 -800
- package/public/js/search.js.map +1 -0
- package/public/js/searchLocal.d.ts +42 -0
- package/public/js/searchLocal.js +87 -0
- package/public/js/searchLocal.js.map +1 -0
- package/public/js/serverSettings.d.ts +5 -0
- package/public/js/serverSettings.js +153 -164
- package/public/js/serverSettings.js.map +1 -0
- package/public/js/state.d.ts +798 -0
- package/public/js/state.js +114 -122
- package/public/js/state.js.map +1 -0
- package/public/js/tour.d.ts +6 -0
- package/public/js/tour.js +5 -7
- package/public/js/tour.js.map +1 -0
- package/public/js/transitions.d.ts +2 -0
- package/public/js/transitions.js +9 -10
- package/public/js/transitions.js.map +1 -0
- package/public/js/tree.d.ts +12 -0
- package/public/js/tree.js +157 -154
- package/public/js/tree.js.map +1 -0
- package/public/js/workflowsView.d.ts +3 -0
- package/public/js/workflowsView.js +15 -22
- package/public/js/workflowsView.js.map +1 -0
- package/public/search.css +495 -0
- package/public/styles.css +163 -346
- package/public/workbench.css +166 -0
- package/server/apiAuth.d.ts +3 -0
- package/server/apiAuth.js +18 -20
- package/server/apiAuth.js.map +1 -0
- package/server/apiDiff.d.ts +2 -0
- package/server/apiDiff.js +20 -18
- package/server/apiDiff.js.map +1 -0
- package/server/apiDocs.d.ts +2 -0
- package/server/apiDocs.js +38 -40
- package/server/apiDocs.js.map +1 -0
- package/server/apiFile.d.ts +1 -0
- package/server/apiFile.js +14 -17
- package/server/apiFile.js.map +1 -0
- package/server/apiGitBlame.d.ts +2 -0
- package/server/apiGitBlame.js +50 -51
- package/server/apiGitBlame.js.map +1 -0
- package/server/apiMcp.d.ts +4 -0
- package/server/apiMcp.js +64 -66
- package/server/apiMcp.js.map +1 -0
- package/server/apiReview.d.ts +2 -0
- package/server/apiReview.js +45 -0
- package/server/apiReview.js.map +1 -0
- package/server/apiScan.d.ts +5 -0
- package/server/apiScan.js +90 -71
- package/server/apiScan.js.map +1 -0
- package/server/apiSearch.d.ts +33 -0
- package/server/apiSearch.js +184 -200
- package/server/apiSearch.js.map +1 -0
- package/server/apiSettings.d.ts +4 -0
- package/server/apiSettings.js +84 -85
- package/server/apiSettings.js.map +1 -0
- package/server/apiTools.d.ts +3 -0
- package/server/apiTools.js +55 -56
- package/server/apiTools.js.map +1 -0
- package/server/auth.d.ts +5 -0
- package/server/auth.js +54 -51
- package/server/auth.js.map +1 -0
- package/server/config.d.ts +42 -0
- package/server/config.js +189 -194
- package/server/config.js.map +1 -0
- package/server/daemon.d.ts +12 -0
- package/server/daemon.js +124 -114
- package/server/daemon.js.map +1 -0
- package/server/fileSourceNode.d.ts +2 -0
- package/server/fileSourceNode.js +34 -36
- package/server/fileSourceNode.js.map +1 -0
- package/server/gitClone.d.ts +9 -0
- package/server/gitClone.js +59 -61
- package/server/gitClone.js.map +1 -0
- package/server/gitDiff.d.ts +36 -0
- package/server/gitDiff.js +271 -169
- package/server/gitDiff.js.map +1 -0
- package/server/gitHistory.d.ts +12 -0
- package/server/gitHistory.js +80 -80
- package/server/gitHistory.js.map +1 -0
- package/server/gitRemote.d.ts +12 -0
- package/server/gitRemote.js +60 -0
- package/server/gitRemote.js.map +1 -0
- package/server/htmlText.d.ts +4 -0
- package/server/htmlText.js +16 -23
- package/server/htmlText.js.map +1 -0
- package/server/http.d.ts +5 -0
- package/server/http.js +27 -30
- package/server/http.js.map +1 -0
- package/server/httpGuards.d.ts +2 -0
- package/server/httpGuards.js +47 -43
- package/server/httpGuards.js.map +1 -0
- package/server/https.d.ts +34 -0
- package/server/https.js +121 -111
- package/server/https.js.map +1 -0
- package/server/index.d.ts +40 -0
- package/server/index.js +139 -147
- package/server/index.js.map +1 -0
- package/server/layout.d.ts +26 -0
- package/server/layout.js +59 -37
- package/server/layout.js.map +1 -0
- package/server/llmProxy.d.ts +3 -0
- package/server/llmProxy.js +137 -135
- package/server/llmProxy.js.map +1 -0
- package/server/logger.d.ts +38 -0
- package/server/logger.js +198 -211
- package/server/logger.js.map +1 -0
- package/server/mcp/analysis.d.ts +29 -0
- package/server/mcp/analysis.js +99 -120
- package/server/mcp/analysis.js.map +1 -0
- package/server/mcp/http.d.ts +9 -0
- package/server/mcp/http.js +128 -137
- package/server/mcp/http.js.map +1 -0
- package/server/mcp/runner.d.ts +68 -0
- package/server/mcp/runner.js +208 -218
- package/server/mcp/runner.js.map +1 -0
- package/server/mcp/server.d.ts +29 -0
- package/server/mcp/server.js +166 -179
- package/server/mcp/server.js.map +1 -0
- package/server/mcp/standalone.d.ts +1 -0
- package/server/mcp/standalone.js +8 -10
- package/server/mcp/standalone.js.map +1 -0
- package/server/mcp/tools.d.ts +2020 -0
- package/server/mcp/tools.js +523 -574
- package/server/mcp/tools.js.map +1 -0
- package/server/paths.d.ts +3 -0
- package/server/paths.js +17 -15
- package/server/paths.js.map +1 -0
- package/server/pidfile.d.ts +9 -0
- package/server/pidfile.js +43 -45
- package/server/pidfile.js.map +1 -0
- package/server/review.d.ts +5 -0
- package/server/review.js +35 -0
- package/server/review.js.map +1 -0
- package/server/router.d.ts +33 -0
- package/server/router.js +191 -197
- package/server/router.js.map +1 -0
- package/server/scanRequest.d.ts +3 -0
- package/server/scanRequest.js +36 -0
- package/server/scanRequest.js.map +1 -0
- package/server/searchIndex.d.ts +17 -0
- package/server/searchIndex.js +83 -80
- package/server/searchIndex.js.map +1 -0
- package/server/sessions.d.ts +14 -0
- package/server/sessions.js +62 -70
- package/server/sessions.js.map +1 -0
- package/server/startup.d.ts +118 -0
- package/server/startup.js +143 -148
- package/server/startup.js.map +1 -0
- package/server/static.d.ts +6 -0
- package/server/static.js +28 -31
- package/server/static.js.map +1 -0
- package/server/tools/install.d.ts +4 -0
- package/server/tools/install.js +176 -185
- package/server/tools/install.js.map +1 -0
- package/server/tools/parse.d.ts +8 -0
- package/server/tools/parse.js +112 -114
- package/server/tools/parse.js.map +1 -0
- package/server/tools/platform.d.ts +9 -0
- package/server/tools/platform.js +49 -47
- package/server/tools/platform.js.map +1 -0
- package/server/tools/registry.d.ts +137 -0
- package/server/tools/registry.js +173 -172
- package/server/tools/registry.js.map +1 -0
- package/server/tools/scan.d.ts +34 -0
- package/server/tools/scan.js +89 -98
- package/server/tools/scan.js.map +1 -0
- package/server/tools.d.ts +34 -0
- package/server/tools.js +94 -107
- package/server/tools.js.map +1 -0
- package/server/tunnel.d.ts +29 -0
- package/server/tunnel.js +61 -66
- package/server/tunnel.js.map +1 -0
- package/shared/analyzer/docs.d.ts +16 -0
- package/shared/analyzer/docs.js +99 -93
- package/shared/analyzer/docs.js.map +1 -0
- package/shared/analyzer/explainLocal.d.ts +4 -0
- package/shared/analyzer/explainLocal.js +122 -142
- package/shared/analyzer/explainLocal.js.map +1 -0
- package/shared/analyzer/github.d.ts +37 -0
- package/shared/analyzer/github.js +79 -0
- package/shared/analyzer/github.js.map +1 -0
- package/shared/analyzer/graph.d.ts +41 -0
- package/shared/analyzer/graph.js +393 -400
- package/shared/analyzer/graph.js.map +1 -0
- package/shared/analyzer/health.d.ts +33 -0
- package/shared/analyzer/health.js +197 -193
- package/shared/analyzer/health.js.map +1 -0
- package/shared/analyzer/history.d.ts +29 -0
- package/shared/analyzer/history.js +110 -111
- package/shared/analyzer/history.js.map +1 -0
- package/shared/analyzer/jsonConfig.d.ts +2 -0
- package/shared/analyzer/jsonConfig.js +61 -0
- package/shared/analyzer/jsonConfig.js.map +1 -0
- package/shared/analyzer/languages/csharp.d.ts +26 -0
- package/shared/analyzer/languages/csharp.js +83 -88
- package/shared/analyzer/languages/csharp.js.map +1 -0
- package/shared/analyzer/languages/generic.d.ts +23 -0
- package/shared/analyzer/languages/generic.js +94 -105
- package/shared/analyzer/languages/generic.js.map +1 -0
- package/shared/analyzer/languages/go.d.ts +24 -0
- package/shared/analyzer/languages/go.js +45 -54
- package/shared/analyzer/languages/go.js.map +1 -0
- package/shared/analyzer/languages/index.d.ts +6 -0
- package/shared/analyzer/languages/index.js +19 -20
- package/shared/analyzer/languages/index.js.map +1 -0
- package/shared/analyzer/languages/java.d.ts +20 -0
- package/shared/analyzer/languages/java.js +73 -78
- package/shared/analyzer/languages/java.js.map +1 -0
- package/shared/analyzer/languages/javascript.d.ts +12 -0
- package/shared/analyzer/languages/javascript.js +258 -209
- package/shared/analyzer/languages/javascript.js.map +1 -0
- package/shared/analyzer/languages/python.d.ts +23 -0
- package/shared/analyzer/languages/python.js +92 -100
- package/shared/analyzer/languages/python.js.map +1 -0
- package/shared/analyzer/languages/rust.d.ts +17 -0
- package/shared/analyzer/languages/rust.js +96 -98
- package/shared/analyzer/languages/rust.js.map +1 -0
- package/shared/analyzer/languages/typescript.d.ts +11 -0
- package/shared/analyzer/languages/typescript.js +117 -116
- package/shared/analyzer/languages/typescript.js.map +1 -0
- package/shared/analyzer/licenses.d.ts +18 -0
- package/shared/analyzer/licenses.js +130 -133
- package/shared/analyzer/licenses.js.map +1 -0
- package/shared/analyzer/metrics.d.ts +20 -0
- package/shared/analyzer/metrics.js +112 -104
- package/shared/analyzer/metrics.js.map +1 -0
- package/shared/analyzer/pathUtil.d.ts +10 -0
- package/shared/analyzer/pathUtil.js +29 -35
- package/shared/analyzer/pathUtil.js.map +1 -0
- package/shared/analyzer/patterns.d.ts +11 -0
- package/shared/analyzer/patterns.js +231 -253
- package/shared/analyzer/patterns.js.map +1 -0
- package/shared/analyzer/scan.d.ts +62 -0
- package/shared/analyzer/scan.js +451 -442
- package/shared/analyzer/scan.js.map +1 -0
- package/shared/analyzer/scanControl.d.ts +11 -0
- package/shared/analyzer/scanControl.js +62 -0
- package/shared/analyzer/scanControl.js.map +1 -0
- package/shared/analyzer/security.d.ts +18 -0
- package/shared/analyzer/security.js +159 -159
- package/shared/analyzer/security.js.map +1 -0
- package/shared/analyzer/services.d.ts +5 -0
- package/shared/analyzer/services.js +141 -138
- package/shared/analyzer/services.js.map +1 -0
- package/shared/analyzer/stack.d.ts +6 -0
- package/shared/analyzer/stack.js +134 -141
- package/shared/analyzer/stack.js.map +1 -0
- package/shared/analyzer/tour.d.ts +2 -0
- package/shared/analyzer/tour.js +45 -53
- package/shared/analyzer/tour.js.map +1 -0
- package/shared/analyzer/util.d.ts +8 -0
- package/shared/analyzer/util.js +130 -76
- package/shared/analyzer/util.js.map +1 -0
- package/shared/analyzer/workflows.d.ts +8 -0
- package/shared/analyzer/workflows.js +139 -134
- package/shared/analyzer/workflows.js.map +1 -0
- package/shared/contracts.d.ts +250 -0
- package/shared/contracts.js +2 -0
- package/shared/contracts.js.map +1 -0
- package/shared/diagram/aiFacts.d.ts +35 -0
- package/shared/diagram/aiFacts.js +102 -105
- package/shared/diagram/aiFacts.js.map +1 -0
- package/shared/diagram/aiMermaid.d.ts +5 -0
- package/shared/diagram/aiMermaid.js +46 -45
- package/shared/diagram/aiMermaid.js.map +1 -0
- package/shared/diagram/atlas.d.ts +16 -0
- package/shared/diagram/atlas.js +51 -60
- package/shared/diagram/atlas.js.map +1 -0
- package/shared/diagram/mermaid.d.ts +43 -0
- package/shared/diagram/mermaid.js +348 -370
- package/shared/diagram/mermaid.js.map +1 -0
- package/shared/review/contracts.d.ts +95 -0
- package/shared/review/contracts.js +2 -0
- package/shared/review/contracts.js.map +1 -0
- package/shared/review/review.d.ts +10 -0
- package/shared/review/review.js +184 -0
- package/shared/review/review.js.map +1 -0
- package/shared/search/query.d.ts +32 -0
- package/shared/search/query.js +395 -388
- package/shared/search/query.js.map +1 -0
|
@@ -1,120 +1,112 @@
|
|
|
1
1
|
// Python. Line-oriented, indentation-aware enough for our purposes.
|
|
2
|
-
|
|
3
2
|
import { blankComments, lineCounter, uniqueBy, callsWithin, declarationOrder } from '../util.js';
|
|
4
3
|
import { dirOf, joinPath } from '../pathUtil.js';
|
|
5
|
-
|
|
6
4
|
export const extensions = ['.py'];
|
|
7
|
-
|
|
8
5
|
const IMPORT_FROM_RE = /^[ \t]*from\s+([.\w]+)\s+import\s+/gm;
|
|
9
6
|
const IMPORT_PLAIN_RE = /^[ \t]*import\s+([\w.,\s]+?)\s*(?:#.*)?$/gm;
|
|
10
7
|
const DEF_RE = /^([ \t]*)(?:async\s+)?def\s+([\w]+)\s*\(/gm;
|
|
11
8
|
const CLASS_RE = /^([ \t]*)class\s+([\w]+)/gm;
|
|
12
|
-
|
|
13
9
|
export function analyze(source, path) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
imports.push({ spec: m[1], kind: 'from', line: lineAt(m.index) });
|
|
20
|
-
}
|
|
21
|
-
for (const m of clean.matchAll(IMPORT_PLAIN_RE)) {
|
|
22
|
-
for (let part of m[1].split(',')) {
|
|
23
|
-
part = part.trim().split(/\s+as\s+/)[0].trim();
|
|
24
|
-
if (part) imports.push({ spec: part, kind: 'import', line: lineAt(m.index) });
|
|
10
|
+
const clean = blankComments(source, { block: false, lineChar: '#' });
|
|
11
|
+
const lineAt = lineCounter(clean);
|
|
12
|
+
const imports = [];
|
|
13
|
+
for (const m of clean.matchAll(IMPORT_FROM_RE)) {
|
|
14
|
+
imports.push({ spec: m[1], kind: 'from', line: lineAt(m.index) });
|
|
25
15
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
16
|
+
for (const m of clean.matchAll(IMPORT_PLAIN_RE)) {
|
|
17
|
+
for (let part of m[1].split(',')) {
|
|
18
|
+
part = part.trim().split(/\s+as\s+/)[0].trim();
|
|
19
|
+
if (part)
|
|
20
|
+
imports.push({ spec: part, kind: 'import', line: lineAt(m.index) });
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const functions = [];
|
|
24
|
+
for (const m of clean.matchAll(DEF_RE)) {
|
|
25
|
+
const indent = m[1].length;
|
|
26
|
+
functions.push({
|
|
27
|
+
name: m[2],
|
|
28
|
+
kind: indent > 0 ? 'method' : 'function',
|
|
29
|
+
line: lineAt(m.index),
|
|
30
|
+
indent,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const classes = [];
|
|
34
|
+
for (const m of clean.matchAll(CLASS_RE)) {
|
|
35
|
+
classes.push({ name: m[2], line: lineAt(m.index) });
|
|
36
|
+
}
|
|
37
|
+
// Calls: a function's body is the run of lines more indented than its def.
|
|
38
|
+
const lines = clean.split('\n');
|
|
39
|
+
const calls = [];
|
|
40
|
+
const topLevel = functions.filter((f) => f.kind === 'function');
|
|
41
|
+
const names = new Set(functions.map((f) => f.name));
|
|
42
|
+
const declaredAt = declarationOrder(functions);
|
|
43
|
+
for (const fn of functions) {
|
|
44
|
+
const body = indentedBody(lines, fn.line - 1, fn.indent);
|
|
45
|
+
if (!body)
|
|
46
|
+
continue;
|
|
47
|
+
const called = callsWithin(body, names)
|
|
48
|
+
.filter((name) => name !== fn.name)
|
|
49
|
+
.sort((a, b) => declaredAt.get(a) - declaredAt.get(b));
|
|
50
|
+
for (const name of called)
|
|
51
|
+
calls.push({ from: fn.name, to: name });
|
|
52
|
+
}
|
|
53
|
+
const exports = topLevel
|
|
54
|
+
.filter((f) => !f.name.startsWith('_'))
|
|
55
|
+
.map((f) => ({ name: f.name, kind: 'function' }))
|
|
56
|
+
.concat(classes.filter((c) => !c.name.startsWith('_')).map((c) => ({ name: c.name, kind: 'class' })));
|
|
57
|
+
const hasMain = /__name__\s*==\s*['"]__main__['"]/.test(clean);
|
|
58
|
+
return {
|
|
59
|
+
imports: uniqueBy(imports, (i) => i.spec + ':' + i.line),
|
|
60
|
+
exports: uniqueBy(exports, (e) => e.name),
|
|
61
|
+
functions: functions.map(({ indent, ...rest }) => rest),
|
|
62
|
+
classes,
|
|
63
|
+
calls: uniqueBy(calls, (c) => c.from + '->' + c.to),
|
|
64
|
+
hasMain,
|
|
65
|
+
};
|
|
74
66
|
}
|
|
75
|
-
|
|
76
67
|
function indentedBody(lines, defLineIdx, indent) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
68
|
+
const out = [];
|
|
69
|
+
for (let i = defLineIdx + 1; i < lines.length; i++) {
|
|
70
|
+
const line = lines[i];
|
|
71
|
+
if (line.trim() === '') {
|
|
72
|
+
out.push('');
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const lead = line.length - line.trimStart().length;
|
|
76
|
+
if (lead <= indent)
|
|
77
|
+
break;
|
|
78
|
+
out.push(line);
|
|
83
79
|
}
|
|
84
|
-
|
|
85
|
-
if (lead <= indent) break;
|
|
86
|
-
out.push(line);
|
|
87
|
-
}
|
|
88
|
-
return out.join('\n');
|
|
80
|
+
return out.join('\n');
|
|
89
81
|
}
|
|
90
|
-
|
|
91
82
|
export function packageNameOf(spec) {
|
|
92
|
-
|
|
83
|
+
return spec.replace(/^\.+/, '').split('.')[0] || spec;
|
|
93
84
|
}
|
|
94
|
-
|
|
95
85
|
export function resolveImport(spec, fromPath, has, context = {}) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
86
|
+
const fromDir = dirOf(fromPath);
|
|
87
|
+
if (spec.startsWith('.')) {
|
|
88
|
+
// Relative import: one dot = current package, two = parent, and so on.
|
|
89
|
+
const dots = spec.match(/^\.+/)[0].length;
|
|
90
|
+
let base = fromDir;
|
|
91
|
+
for (let i = 1; i < dots; i++)
|
|
92
|
+
base = dirOf(base);
|
|
93
|
+
const rest = spec.slice(dots).replace(/\./g, '/');
|
|
94
|
+
const target = rest ? joinPath(base, rest) : base;
|
|
95
|
+
for (const cand of [target + '.py', target + '/__init__.py']) {
|
|
96
|
+
if (has(cand))
|
|
97
|
+
return { path: cand };
|
|
98
|
+
}
|
|
99
|
+
return { unresolved: spec };
|
|
107
100
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (has(cand)) return { path: cand };
|
|
101
|
+
// Absolute import: try from repo root, then relative to the file (a common
|
|
102
|
+
// layout in small scripts), then give up and call it external.
|
|
103
|
+
const rel = spec.replace(/\./g, '/');
|
|
104
|
+
for (const root of ['', fromDir]) {
|
|
105
|
+
for (const cand of [joinPath(root, rel) + '.py', joinPath(root, rel) + '/__init__.py']) {
|
|
106
|
+
if (has(cand))
|
|
107
|
+
return { path: cand };
|
|
108
|
+
}
|
|
117
109
|
}
|
|
118
|
-
|
|
119
|
-
return { external: spec.split('.')[0] };
|
|
110
|
+
return { external: spec.split('.')[0] };
|
|
120
111
|
}
|
|
112
|
+
//# sourceMappingURL=python.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python.js","sourceRoot":"","sources":["../../../src/shared/analyzer/languages/python.ts"],"names":[],"mappings":"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","sourcesContent":["// Python. Line-oriented, indentation-aware enough for our purposes.\n\nimport { blankComments, lineCounter, uniqueBy, callsWithin, declarationOrder } from '../util.js';\nimport { dirOf, joinPath } from '../pathUtil.js';\n\nexport const extensions = ['.py'];\n\nconst IMPORT_FROM_RE = /^[ \\t]*from\\s+([.\\w]+)\\s+import\\s+/gm;\nconst IMPORT_PLAIN_RE = /^[ \\t]*import\\s+([\\w.,\\s]+?)\\s*(?:#.*)?$/gm;\nconst DEF_RE = /^([ \\t]*)(?:async\\s+)?def\\s+([\\w]+)\\s*\\(/gm;\nconst CLASS_RE = /^([ \\t]*)class\\s+([\\w]+)/gm;\n\nexport function analyze(source, path) {\n const clean = blankComments(source, { block: false, lineChar: '#' });\n const lineAt = lineCounter(clean);\n\n const imports = [];\n for (const m of clean.matchAll(IMPORT_FROM_RE)) {\n imports.push({ spec: m[1], kind: 'from', line: lineAt(m.index) });\n }\n for (const m of clean.matchAll(IMPORT_PLAIN_RE)) {\n for (let part of m[1].split(',')) {\n part = part.trim().split(/\\s+as\\s+/)[0].trim();\n if (part) imports.push({ spec: part, kind: 'import', line: lineAt(m.index) });\n }\n }\n\n const functions = [];\n for (const m of clean.matchAll(DEF_RE)) {\n const indent = m[1].length;\n functions.push({\n name: m[2],\n kind: indent > 0 ? 'method' : 'function',\n line: lineAt(m.index),\n indent,\n });\n }\n\n const classes = [];\n for (const m of clean.matchAll(CLASS_RE)) {\n classes.push({ name: m[2], line: lineAt(m.index) });\n }\n\n // Calls: a function's body is the run of lines more indented than its def.\n const lines = clean.split('\\n');\n const calls = [];\n const topLevel = functions.filter((f) => f.kind === 'function');\n const names = new Set(functions.map((f) => f.name));\n const declaredAt = declarationOrder(functions);\n for (const fn of functions) {\n const body = indentedBody(lines, fn.line - 1, fn.indent);\n if (!body) continue;\n const called = callsWithin(body, names)\n .filter((name) => name !== fn.name)\n .sort((a, b) => declaredAt.get(a) - declaredAt.get(b));\n for (const name of called) calls.push({ from: fn.name, to: name });\n }\n\n const exports = topLevel\n .filter((f) => !f.name.startsWith('_'))\n .map((f) => ({ name: f.name, kind: 'function' }))\n .concat(classes.filter((c) => !c.name.startsWith('_')).map((c) => ({ name: c.name, kind: 'class' })));\n\n const hasMain = /__name__\\s*==\\s*['\"]__main__['\"]/.test(clean);\n\n return {\n imports: uniqueBy(imports, (i) => i.spec + ':' + i.line),\n exports: uniqueBy(exports, (e) => e.name),\n functions: functions.map(({ indent, ...rest }) => rest),\n classes,\n calls: uniqueBy(calls, (c) => c.from + '->' + c.to),\n hasMain,\n };\n}\n\nfunction indentedBody(lines, defLineIdx, indent) {\n const out = [];\n for (let i = defLineIdx + 1; i < lines.length; i++) {\n const line = lines[i];\n if (line.trim() === '') {\n out.push('');\n continue;\n }\n const lead = line.length - line.trimStart().length;\n if (lead <= indent) break;\n out.push(line);\n }\n return out.join('\\n');\n}\n\nexport function packageNameOf(spec) {\n return spec.replace(/^\\.+/, '').split('.')[0] || spec;\n}\n\nexport function resolveImport(spec, fromPath, has, context: Record<string, any> = {}) {\n const fromDir = dirOf(fromPath);\n\n if (spec.startsWith('.')) {\n // Relative import: one dot = current package, two = parent, and so on.\n const dots = spec.match(/^\\.+/)[0].length;\n let base = fromDir;\n for (let i = 1; i < dots; i++) base = dirOf(base);\n const rest = spec.slice(dots).replace(/\\./g, '/');\n const target = rest ? joinPath(base, rest) : base;\n for (const cand of [target + '.py', target + '/__init__.py']) {\n if (has(cand)) return { path: cand };\n }\n return { unresolved: spec };\n }\n\n // Absolute import: try from repo root, then relative to the file (a common\n // layout in small scripts), then give up and call it external.\n const rel = spec.replace(/\\./g, '/');\n for (const root of ['', fromDir]) {\n for (const cand of [joinPath(root, rel) + '.py', joinPath(root, rel) + '/__init__.py']) {\n if (has(cand)) return { path: cand };\n }\n }\n return { external: spec.split('.')[0] };\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const extensions: string[];
|
|
2
|
+
export declare function analyze(source: any, path: any): {
|
|
3
|
+
imports: any[];
|
|
4
|
+
exports: any[];
|
|
5
|
+
functions: any[];
|
|
6
|
+
classes: any[];
|
|
7
|
+
hasMain: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare function crateRootFor(fromPath: any): string;
|
|
10
|
+
export declare function moduleDirFor(fromPath: any): string;
|
|
11
|
+
export declare function resolveImport(spec: any, fromPath: any, has: any, context?: Record<string, any>, meta?: Record<string, any>): {
|
|
12
|
+
unresolved: any;
|
|
13
|
+
path?: undefined;
|
|
14
|
+
} | {
|
|
15
|
+
unresolved?: undefined;
|
|
16
|
+
path: string;
|
|
17
|
+
};
|
|
@@ -14,62 +14,56 @@
|
|
|
14
14
|
// dependency from Cargo.toml — stays unresolved, because inventing a file would
|
|
15
15
|
// be a node in the graph that does not exist.
|
|
16
16
|
import { blankComments, lineCounter, uniqueBy } from '../util.js';
|
|
17
|
-
|
|
18
17
|
export const extensions = ['.rs'];
|
|
19
|
-
|
|
20
18
|
export function analyze(source, path) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
hasMain
|
|
53
|
-
};
|
|
19
|
+
const clean = blankComments(source);
|
|
20
|
+
const lineAt = lineCounter(clean);
|
|
21
|
+
const imports = [];
|
|
22
|
+
// `use foo::bar;` and `mod foo;` are both dependencies on a file, and both are
|
|
23
|
+
// worth an edge. `pub use` is a re-export — still a real dependency.
|
|
24
|
+
for (const m of clean.matchAll(/\b(?:pub\s+)?(?:use|mod)\s+([a-zA-Z0-9_:]+)/g)) {
|
|
25
|
+
imports.push({ spec: m[1], line: lineAt(m.index) });
|
|
26
|
+
}
|
|
27
|
+
const functions = [];
|
|
28
|
+
for (const m of clean.matchAll(/\b(pub\s+)?fn\s+([a-zA-Z0-9_]+)/g)) {
|
|
29
|
+
functions.push({ name: m[2], pub: !!m[1], line: lineAt(m.index) });
|
|
30
|
+
}
|
|
31
|
+
const classes = [];
|
|
32
|
+
for (const m of clean.matchAll(/\b(pub\s+)?(?:struct|enum|trait)\s+([a-zA-Z0-9_]+)/g)) {
|
|
33
|
+
classes.push({ name: m[2], pub: !!m[1], line: lineAt(m.index) });
|
|
34
|
+
}
|
|
35
|
+
const exports = [];
|
|
36
|
+
for (const f of functions)
|
|
37
|
+
if (f.pub)
|
|
38
|
+
exports.push({ name: f.name, kind: 'function' });
|
|
39
|
+
for (const c of classes)
|
|
40
|
+
if (c.pub)
|
|
41
|
+
exports.push({ name: c.name, kind: 'class' });
|
|
42
|
+
const hasMain = /\bfn\s+main\s*\(/.test(clean);
|
|
43
|
+
return {
|
|
44
|
+
imports: uniqueBy(imports, i => i.spec + ':' + i.line),
|
|
45
|
+
exports,
|
|
46
|
+
functions,
|
|
47
|
+
classes,
|
|
48
|
+
hasMain
|
|
49
|
+
};
|
|
54
50
|
}
|
|
55
|
-
|
|
56
51
|
const dirOfPath = (p) => {
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
const at = String(p).lastIndexOf('/');
|
|
53
|
+
return at < 0 ? '' : String(p).slice(0, at + 1);
|
|
59
54
|
};
|
|
60
|
-
|
|
61
55
|
// The crate root: the `src/` directory, wherever it sits. `src/lib.rs` → `src/`;
|
|
62
56
|
// `crates/foo/src/main.rs` → `crates/foo/src/`. A crate with no `src/` (a flat
|
|
63
57
|
// `lib.rs` in the repo root) is rooted at that file's own directory, which is the
|
|
64
58
|
// same rule with one fewer component to find.
|
|
65
59
|
export function crateRootFor(fromPath) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
60
|
+
const normalized = String(fromPath).replace(/\\/g, '/');
|
|
61
|
+
const segments = normalized.split('/');
|
|
62
|
+
const at = segments.lastIndexOf('src');
|
|
63
|
+
if (at < 0)
|
|
64
|
+
return dirOfPath(normalized);
|
|
65
|
+
return segments.slice(0, at + 1).join('/') + '/';
|
|
71
66
|
}
|
|
72
|
-
|
|
73
67
|
// The directory that holds the *children* of the module this file defines.
|
|
74
68
|
//
|
|
75
69
|
// This is not simply the dirname, and getting it wrong breaks every `self::`.
|
|
@@ -81,64 +75,68 @@ export function crateRootFor(fromPath) {
|
|
|
81
75
|
// after the crate, not after their module, so stripping `.rs` from `src/lib.rs`
|
|
82
76
|
// would invent a module called `lib`.
|
|
83
77
|
export function moduleDirFor(fromPath) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
78
|
+
const normalized = String(fromPath).replace(/\\/g, '/');
|
|
79
|
+
const dir = dirOfPath(normalized);
|
|
80
|
+
const name = normalized.slice(dir.length);
|
|
81
|
+
if (name === 'mod.rs' || name === 'lib.rs' || name === 'main.rs')
|
|
82
|
+
return dir;
|
|
83
|
+
return normalized.replace(/\.rs$/, '') + '/';
|
|
89
84
|
}
|
|
90
|
-
|
|
91
85
|
// A module named by a path is either `path.rs` or `path/mod.rs`. Both are
|
|
92
86
|
// idiomatic Rust, so both are tried and the first that exists wins.
|
|
93
87
|
function moduleCandidates(path) {
|
|
94
|
-
|
|
88
|
+
return [path + '.rs', path + '/mod.rs'];
|
|
95
89
|
}
|
|
96
|
-
|
|
97
90
|
export function resolveImport(spec, fromPath, has, context = {}, meta = {}) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
91
|
+
const from = String(fromPath).replace(/\\/g, '/');
|
|
92
|
+
const raw = String(spec);
|
|
93
|
+
// `::foo::Bar` is a 2018 absolute path — another crate, not this one.
|
|
94
|
+
if (raw.startsWith('::'))
|
|
95
|
+
return { unresolved: spec };
|
|
96
|
+
const segments = raw.split('::').filter(Boolean);
|
|
97
|
+
if (!segments.length)
|
|
98
|
+
return { unresolved: spec };
|
|
99
|
+
// Where the path starts. `crate::` is the crate root; `self::` and a bare
|
|
100
|
+
// `mod foo;` are the current file's own module; `super::` is one level up.
|
|
101
|
+
const head = segments[0];
|
|
102
|
+
let base;
|
|
103
|
+
let rest;
|
|
104
|
+
if (head === 'crate') {
|
|
105
|
+
base = crateRootFor(from);
|
|
106
|
+
rest = segments.slice(1);
|
|
107
|
+
}
|
|
108
|
+
else if (head === 'super') {
|
|
109
|
+
// `dirOfPath` already ends in a separator, so do not add another — `src/a//`
|
|
110
|
+
// never matches a real path, and the miss would be silent.
|
|
111
|
+
base = dirOfPath(moduleDirFor(from).replace(/\/$/, ''));
|
|
112
|
+
rest = segments.slice(1);
|
|
113
|
+
}
|
|
114
|
+
else if (head === 'self') {
|
|
115
|
+
base = moduleDirFor(from);
|
|
116
|
+
rest = segments.slice(1);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// A bare `mod foo;` declares a module beside the current one. A bare
|
|
120
|
+
// `use foo::Bar;` means an *external crate* in Rust 2018, so it will not be
|
|
121
|
+
// found here and stays unresolved — which is the right answer for
|
|
122
|
+
// `serde::Serialize` and every other dependency.
|
|
123
|
+
base = moduleDirFor(from);
|
|
124
|
+
rest = segments;
|
|
125
|
+
}
|
|
126
|
+
if (!rest.length)
|
|
127
|
+
return { unresolved: spec };
|
|
128
|
+
// `crate::a::b::T` means T is declared *in* the module `a::b`, so the answer is
|
|
129
|
+
// the module file for the longest prefix that exists. Trying the deepest path
|
|
130
|
+
// first costs one lookup and covers the flat `mod a;` → `a.rs` case.
|
|
131
|
+
for (let end = rest.length; end > 0; end -= 1) {
|
|
132
|
+
const candidate = base + rest.slice(0, end).join('/');
|
|
133
|
+
for (const file of moduleCandidates(candidate)) {
|
|
134
|
+
if (has(file))
|
|
135
|
+
return { path: file };
|
|
136
|
+
}
|
|
138
137
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
// the honest answer, and scan.js reports these by name.
|
|
143
|
-
return { unresolved: spec };
|
|
138
|
+
// `std`, `serde`, anything from Cargo.toml: outside this crate. Unresolved is
|
|
139
|
+
// the honest answer, and scan.js reports these by name.
|
|
140
|
+
return { unresolved: spec };
|
|
144
141
|
}
|
|
142
|
+
//# sourceMappingURL=rust.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rust.js","sourceRoot":"","sources":["../../../src/shared/analyzer/languages/rust.ts"],"names":[],"mappings":"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","sourcesContent":["// Rust analyzer\n//\n// Rust has no `import` in the Java sense: a crate is a module tree, and `use`\n// names a path *into* that tree. The mapping is still real, though, and it is\n// what gives a Rust repo a graph:\n//\n// crate root src/lib.rs, src/main.rs, or crates/<name>/src/lib.rs\n// module `a` src/a.rs or src/a/mod.rs\n// `crate::a::T` T is declared in src/a.rs (or src/a/mod.rs)\n//\n// So a `use` resolves to the *module file* that owns the item, and the leading\n// `crate` is just the crate root. `self::` and `super::` are relative to the\n// current file's module directory. Anything outside the crate — `std`, a\n// dependency from Cargo.toml — stays unresolved, because inventing a file would\n// be a node in the graph that does not exist.\nimport { blankComments, lineCounter, uniqueBy } from '../util.js';\n\nexport const extensions = ['.rs'];\n\nexport function analyze(source, path) {\n const clean = blankComments(source);\n const lineAt = lineCounter(clean);\n\n const imports = [];\n // `use foo::bar;` and `mod foo;` are both dependencies on a file, and both are\n // worth an edge. `pub use` is a re-export — still a real dependency.\n for (const m of clean.matchAll(/\\b(?:pub\\s+)?(?:use|mod)\\s+([a-zA-Z0-9_:]+)/g)) {\n imports.push({ spec: m[1], line: lineAt(m.index) });\n }\n\n const functions = [];\n for (const m of clean.matchAll(/\\b(pub\\s+)?fn\\s+([a-zA-Z0-9_]+)/g)) {\n functions.push({ name: m[2], pub: !!m[1], line: lineAt(m.index) });\n }\n\n const classes = [];\n for (const m of clean.matchAll(/\\b(pub\\s+)?(?:struct|enum|trait)\\s+([a-zA-Z0-9_]+)/g)) {\n classes.push({ name: m[2], pub: !!m[1], line: lineAt(m.index) });\n }\n\n const exports = [];\n for (const f of functions) if (f.pub) exports.push({ name: f.name, kind: 'function' });\n for (const c of classes) if (c.pub) exports.push({ name: c.name, kind: 'class' });\n\n const hasMain = /\\bfn\\s+main\\s*\\(/.test(clean);\n\n return {\n imports: uniqueBy(imports, i => i.spec + ':' + i.line),\n exports,\n functions,\n classes,\n hasMain\n };\n}\n\nconst dirOfPath = (p) => {\n const at = String(p).lastIndexOf('/');\n return at < 0 ? '' : String(p).slice(0, at + 1);\n};\n\n// The crate root: the `src/` directory, wherever it sits. `src/lib.rs` → `src/`;\n// `crates/foo/src/main.rs` → `crates/foo/src/`. A crate with no `src/` (a flat\n// `lib.rs` in the repo root) is rooted at that file's own directory, which is the\n// same rule with one fewer component to find.\nexport function crateRootFor(fromPath) {\n const normalized = String(fromPath).replace(/\\\\/g, '/');\n const segments = normalized.split('/');\n const at = segments.lastIndexOf('src');\n if (at < 0) return dirOfPath(normalized);\n return segments.slice(0, at + 1).join('/') + '/';\n}\n\n// The directory that holds the *children* of the module this file defines.\n//\n// This is not simply the dirname, and getting it wrong breaks every `self::`.\n// src/lib.rs → `src/` the crate root's children sit in src/\n// src/a/b.rs → `src/a/b/` the module is `a::b`, so `self::x` is a/b/x.rs\n// src/a/b/mod.rs → `src/a/b/` the same module, declared the directory way\n//\n// The lib/main special case is the one that is easy to miss: they are named\n// after the crate, not after their module, so stripping `.rs` from `src/lib.rs`\n// would invent a module called `lib`.\nexport function moduleDirFor(fromPath) {\n const normalized = String(fromPath).replace(/\\\\/g, '/');\n const dir = dirOfPath(normalized);\n const name = normalized.slice(dir.length);\n if (name === 'mod.rs' || name === 'lib.rs' || name === 'main.rs') return dir;\n return normalized.replace(/\\.rs$/, '') + '/';\n}\n\n// A module named by a path is either `path.rs` or `path/mod.rs`. Both are\n// idiomatic Rust, so both are tried and the first that exists wins.\nfunction moduleCandidates(path) {\n return [path + '.rs', path + '/mod.rs'];\n}\n\nexport function resolveImport(spec, fromPath, has, context: Record<string, any> = {}, meta: Record<string, any> = {}) {\n const from = String(fromPath).replace(/\\\\/g, '/');\n const raw = String(spec);\n // `::foo::Bar` is a 2018 absolute path — another crate, not this one.\n if (raw.startsWith('::')) return { unresolved: spec };\n const segments = raw.split('::').filter(Boolean);\n if (!segments.length) return { unresolved: spec };\n\n // Where the path starts. `crate::` is the crate root; `self::` and a bare\n // `mod foo;` are the current file's own module; `super::` is one level up.\n const head = segments[0];\n let base;\n let rest;\n if (head === 'crate') {\n base = crateRootFor(from);\n rest = segments.slice(1);\n } else if (head === 'super') {\n // `dirOfPath` already ends in a separator, so do not add another — `src/a//`\n // never matches a real path, and the miss would be silent.\n base = dirOfPath(moduleDirFor(from).replace(/\\/$/, ''));\n rest = segments.slice(1);\n } else if (head === 'self') {\n base = moduleDirFor(from);\n rest = segments.slice(1);\n } else {\n // A bare `mod foo;` declares a module beside the current one. A bare\n // `use foo::Bar;` means an *external crate* in Rust 2018, so it will not be\n // found here and stays unresolved — which is the right answer for\n // `serde::Serialize` and every other dependency.\n base = moduleDirFor(from);\n rest = segments;\n }\n if (!rest.length) return { unresolved: spec };\n\n // `crate::a::b::T` means T is declared *in* the module `a::b`, so the answer is\n // the module file for the longest prefix that exists. Trying the deepest path\n // first costs one lookup and covers the flat `mod a;` → `a.rs` case.\n for (let end = rest.length; end > 0; end -= 1) {\n const candidate = base + rest.slice(0, end).join('/');\n for (const file of moduleCandidates(candidate)) {\n if (has(file)) return { path: file };\n }\n }\n\n // `std`, `serde`, anything from Cargo.toml: outside this crate. Unresolved is\n // the honest answer, and scan.js reports these by name.\n return { unresolved: spec };\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { resolveImport, packageNameOf } from './javascript.js';
|
|
2
|
+
export declare const extensions: string[];
|
|
3
|
+
export declare function analyze(source: any, path: any): {
|
|
4
|
+
imports: any[];
|
|
5
|
+
exports: any[];
|
|
6
|
+
functions: any[];
|
|
7
|
+
classes: any[];
|
|
8
|
+
interfaces: any[];
|
|
9
|
+
hasMain: boolean;
|
|
10
|
+
};
|
|
11
|
+
export { resolveImport, packageNameOf };
|