@backbencher/brain 0.0.0-stage → 0.1.1
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/CHANGELOG.md +298 -0
- package/EMBEDDINGS.md +355 -0
- package/LICENSE +21 -0
- package/README.md +415 -2
- package/bin/bb +13 -0
- package/dist/analysis-exclusions-7ZJDXOVZ.js +35 -0
- package/dist/brain-index-health-Q5APTJQL.js +17 -0
- package/dist/brain-relationship-enrichment-MYR2AM4F.js +558 -0
- package/dist/brain.sql-EIM4WS4D.js +29 -0
- package/dist/chunk-22V37YTK.js +1758 -0
- package/dist/chunk-2BSKD7O3.js +40 -0
- package/dist/chunk-2DE27DVC.js +1314 -0
- package/dist/chunk-2RRBMNBQ.js +322 -0
- package/dist/chunk-2WXYNLBA.js +29 -0
- package/dist/chunk-3CTFIJJB.js +17 -0
- package/dist/chunk-3ZTOHHSW.js +2104 -0
- package/dist/chunk-4H22TLOT.js +543 -0
- package/dist/chunk-5BVAH26D.js +340 -0
- package/dist/chunk-62DHLYW6.js +3427 -0
- package/dist/chunk-7AN7U5IZ.js +371 -0
- package/dist/chunk-7DRPNVIN.js +782 -0
- package/dist/chunk-7MBYT777.js +174 -0
- package/dist/chunk-AHDWGM7Q.js +236 -0
- package/dist/chunk-B5GEAAYF.js +818 -0
- package/dist/chunk-BEIZZ73B.js +1479 -0
- package/dist/chunk-BQ3OVQ3P.js +125 -0
- package/dist/chunk-D2Q4Y47A.js +53 -0
- package/dist/chunk-DIYAGQJL.js +34 -0
- package/dist/chunk-DWKXZ6IF.js +336 -0
- package/dist/chunk-DYM4FQEE.js +90 -0
- package/dist/chunk-ENW4BTBA.js +930 -0
- package/dist/chunk-EWMWK7WN.js +75 -0
- package/dist/chunk-EY5ZZUUA.js +626 -0
- package/dist/chunk-GBI7V7KY.js +69 -0
- package/dist/chunk-GEFFO6O2.js +152 -0
- package/dist/chunk-HJEWO5EV.js +247 -0
- package/dist/chunk-HQSPJDHI.js +613 -0
- package/dist/chunk-KAET47ZL.js +125 -0
- package/dist/chunk-KCDECRJY.js +440 -0
- package/dist/chunk-L5TDYKYK.js +76 -0
- package/dist/chunk-MLKGABMK.js +9 -0
- package/dist/chunk-NO3U3FJQ.js +201 -0
- package/dist/chunk-OWISBAOF.js +61 -0
- package/dist/chunk-QKTRECYS.js +1119 -0
- package/dist/chunk-QLK6ED4Q.js +235 -0
- package/dist/chunk-R2GW4F6R.js +19 -0
- package/dist/chunk-RCMTFSEF.js +87 -0
- package/dist/chunk-RM3PY6TG.js +376 -0
- package/dist/chunk-ROMM6KMC.js +433 -0
- package/dist/chunk-SGGCSHAX.js +12050 -0
- package/dist/chunk-SK6YVHFZ.js +211 -0
- package/dist/chunk-SM7RFQRO.js +214 -0
- package/dist/chunk-UGR4QIGS.js +67 -0
- package/dist/chunk-UQNQZXHY.js +711 -0
- package/dist/chunk-UUNHHX4M.js +13 -0
- package/dist/chunk-VL52PL2T.js +71 -0
- package/dist/chunk-WIG36E67.js +196 -0
- package/dist/chunk-XHK3WWGB.js +7436 -0
- package/dist/chunk-XTQM2IP3.js +2863 -0
- package/dist/chunk-ZE2LG76D.js +1296 -0
- package/dist/chunk-ZETTGPAW.js +6950 -0
- package/dist/cli/index.js +37 -0
- package/dist/config-HZAAYDP3.js +10 -0
- package/dist/content-search-7XIP555Q.js +593 -0
- package/dist/database-76RP44JG.js +9 -0
- package/dist/doctor-ANGETYMN.js +395 -0
- package/dist/edit-engine-CG72LDZD.js +51 -0
- package/dist/engine-BKEOGN7N.js +11 -0
- package/dist/engine-VIW6NSKO.js +18 -0
- package/dist/fingerprint-OBLIMZLP.js +33 -0
- package/dist/framework-intelligence-3LORTPOX.js +860 -0
- package/dist/freshness-3K6VU5OT.js +174 -0
- package/dist/graph-engine-HBSQNPTB.js +21 -0
- package/dist/graph_request-Q6NKB6N2.js +350 -0
- package/dist/impact_request-LYP672WE.js +68 -0
- package/dist/index-space-IUUN5WYV.js +15 -0
- package/dist/index-status-7OVGYSGW.js +34 -0
- package/dist/index.js +159 -0
- package/dist/instance-FO6QZRLH.js +19 -0
- package/dist/language-detection-DFCAU5DZ.js +11 -0
- package/dist/lsp/server.js +4301 -0
- package/dist/mcp/server.js +132 -0
- package/dist/onboard-DIQZV2NW.js +161 -0
- package/dist/override-companion-pass-XR7MHTP7.js +117 -0
- package/dist/parallel-indexer-FK2XKZXY.js +88 -0
- package/dist/pool-worker.js +1153 -0
- package/dist/project-health-6XPENVAA.js +94 -0
- package/dist/project-index-5SDPHITE.js +57 -0
- package/dist/project-registry-ZJ3DVUGO.js +355 -0
- package/dist/real-bash-analyzer-EJAU5LW5.js +2201 -0
- package/dist/real-c-analyzer-HBD3FNNH.js +5942 -0
- package/dist/real-clean-analyzer-4EEZLPV5.js +3470 -0
- package/dist/real-clojure-analyzer-Q55EBOO2.js +2818 -0
- package/dist/real-cpp-analyzer-IVVOD25R.js +4101 -0
- package/dist/real-csharp-analyzer-ZBNLNJZJ.js +3298 -0
- package/dist/real-css-analyzer-6XRQLUN7.js +15 -0
- package/dist/real-dart-analyzer-OLR72EFW.js +3944 -0
- package/dist/real-elixir-analyzer-MQWGAH2I.js +2192 -0
- package/dist/real-erlang-analyzer-7BVPQEHO.js +1731 -0
- package/dist/real-fsharp-analyzer-C2UPFNOA.js +2390 -0
- package/dist/real-go-analyzer-UKGI43YS.js +4126 -0
- package/dist/real-graphql-analyzer-VE2EEFII.js +1442 -0
- package/dist/real-groovy-analyzer-W26VACFW.js +2285 -0
- package/dist/real-haskell-analyzer-5CVVAJRX.js +2533 -0
- package/dist/real-hcl-analyzer-5ZT4U43N.js +725 -0
- package/dist/real-html-analyzer-JWNX3C6I.js +1759 -0
- package/dist/real-java-analyzer-GU42VBGQ.js +4677 -0
- package/dist/real-javascript-analyzer-QA4QOJ6W.js +14 -0
- package/dist/real-json-analyzer-MPA6PRXL.js +1640 -0
- package/dist/real-julia-analyzer-22CWYQMN.js +2085 -0
- package/dist/real-kotlin-analyzer-QDZJLXXU.js +3956 -0
- package/dist/real-lua-analyzer-G7NHLYKS.js +1957 -0
- package/dist/real-makefile-analyzer-OCY3GT5N.js +920 -0
- package/dist/real-markdown-analyzer-TEJK2JXJ.js +1215 -0
- package/dist/real-matlab-analyzer-Q5SWLN7Z.js +480 -0
- package/dist/real-nim-analyzer-YLXSK563.js +3603 -0
- package/dist/real-objective-c-analyzer-D23ACC2R.js +1518 -0
- package/dist/real-perl-analyzer-WWTRHYDT.js +1865 -0
- package/dist/real-php-analyzer-JNKJHTCL.js +9368 -0
- package/dist/real-powershell-analyzer-XRSNQERV.js +2915 -0
- package/dist/real-protobuf-analyzer-3OKUCZ7T.js +867 -0
- package/dist/real-python-analyzer-VXAFWI72.js +4880 -0
- package/dist/real-r-analyzer-ZGAIDVI4.js +2596 -0
- package/dist/real-ruby-analyzer-X2KTLVBH.js +2429 -0
- package/dist/real-rust-analyzer-OFFHPL2A.js +3359 -0
- package/dist/real-scala-analyzer-TSTW27J6.js +3293 -0
- package/dist/real-scss-analyzer-AVWYPSOQ.js +1515 -0
- package/dist/real-solidity-analyzer-UCI2KWUB.js +2608 -0
- package/dist/real-sql-analyzer-F77ZMQXR.js +3840 -0
- package/dist/real-svelte-analyzer-SF7NRUO5.js +2532 -0
- package/dist/real-swift-analyzer-MN5QT3QN.js +2311 -0
- package/dist/real-toml-analyzer-66L7BDCQ.js +929 -0
- package/dist/real-typescript-analyzer-6KEMVDWQ.js +14 -0
- package/dist/real-vb-analyzer-VICVPOP7.js +3145 -0
- package/dist/real-vba-analyzer-HXLTTHKM.js +466 -0
- package/dist/real-vue-analyzer-QXR56CFV.js +2680 -0
- package/dist/real-xml-analyzer-YL465ZJW.js +2405 -0
- package/dist/real-yaml-analyzer-SUBCBNSI.js +3528 -0
- package/dist/real-zig-analyzer-HIQLZMGY.js +2430 -0
- package/dist/regex-search-NJKHMZNO.js +239 -0
- package/dist/rules-ACHPB7QU.js +152 -0
- package/dist/scoped-path-MJYWJZQX.js +11 -0
- package/dist/setup-show-NT5ZHYNE.js +15 -0
- package/dist/setup-wizard-G5YYR5T6.js +24 -0
- package/dist/symbol-search-GZJIM2J2.js +16 -0
- package/dist/taint-KXUHHPIE.js +202 -0
- package/dist/taint-analyzer-N7YLZU3N.js +163 -0
- package/dist/tool-handlers-OJDC35DI.js +72 -0
- package/dist/tool-registry-BPEJNSZG.js +17 -0
- package/dist/tool-validation-Q57YMMBX.js +32 -0
- package/dist/type-inference-QMT2RMLV.js +13 -0
- package/dist/vector-binary-LMY4QGAN.js +19 -0
- package/dist/version-ABP2TUL2.js +9 -0
- package/dist/wasm-NMWO3WXY.js +16 -0
- package/docs/EMBEDDINGS.md +132 -0
- package/docs/README.md +178 -0
- package/docs/data/m10-baseline.json +602 -0
- package/docs/data/m10-benchmark-baseline.json +57 -0
- package/docs/data/m10-benchmark-last-run.json +127 -0
- package/docs/data/m10-final-audit.json +215 -0
- package/docs/data/m12-final-audit.json +138 -0
- package/docs/data/m12-surface-matrix.json +50 -0
- package/docs/data/public-tools.json +1902 -0
- package/docs/indexing/DEAD-ASSETS.md +88 -0
- package/docs/indexing/INDEXER-REVIEW.md +634 -0
- package/docs/indexing/PERFORMANCE-FINDINGS.md +106 -0
- package/docs/indexing/README.md +427 -0
- package/docs/indexing/discovery-matrix.md +41 -0
- package/docs/indexing/embeddings.md +325 -0
- package/docs/indexing/environment-variables.md +77 -0
- package/docs/indexing/performance.md +323 -0
- package/docs/indexing/resume.md +345 -0
- package/docs/indexing/troubleshooting.md +391 -0
- package/docs/man/bb.1 +190 -0
- package/docs/tools/bb_analyze.md +147 -0
- package/docs/tools/bb_annotate.md +110 -0
- package/docs/tools/bb_annotations.md +106 -0
- package/docs/tools/bb_ask.md +101 -0
- package/docs/tools/bb_cross_language.md +103 -0
- package/docs/tools/bb_doc.md +169 -0
- package/docs/tools/bb_edit.md +185 -0
- package/docs/tools/bb_graph.md +169 -0
- package/docs/tools/bb_health.md +156 -0
- package/docs/tools/bb_impact.md +117 -0
- package/docs/tools/bb_index.md +108 -0
- package/docs/tools/bb_migrate.md +135 -0
- package/docs/tools/bb_patterns.md +140 -0
- package/docs/tools/bb_search.md +150 -0
- package/docs/tools/bb_security.md +100 -0
- package/docs/tools/bb_visualize.md +184 -0
- package/grammars/README.md +57 -0
- package/grammars/THIRD-PARTY-NOTICES.md +50 -0
- package/grammars/tree-sitter-c/LICENSE +21 -0
- package/grammars/tree-sitter-clojure/LICENSE.md +21 -0
- package/grammars/tree-sitter-cpp/LICENSE +21 -0
- package/grammars/tree-sitter-csharp/LICENSE +21 -0
- package/grammars/tree-sitter-css/LICENSE +21 -0
- package/grammars/tree-sitter-css/README.md +21 -0
- package/grammars/tree-sitter-dart/LICENSE +20 -0
- package/grammars/tree-sitter-dart-upstream/LICENSE +20 -0
- package/grammars/tree-sitter-dart-upstream/README.md +18 -0
- package/grammars/tree-sitter-elixir/LICENSE +176 -0
- package/grammars/tree-sitter-elixir/README.md +11 -0
- package/grammars/tree-sitter-fsharp/LICENSE +21 -0
- package/grammars/tree-sitter-fsharp/README.md +45 -0
- package/grammars/tree-sitter-graphql/LICENSE +21 -0
- package/grammars/tree-sitter-graphql/README.md +106 -0
- package/grammars/tree-sitter-groovy/LICENSE +21 -0
- package/grammars/tree-sitter-groovy/README.md +4 -0
- package/grammars/tree-sitter-haskell/LICENSE +21 -0
- package/grammars/tree-sitter-haskell/README.md +394 -0
- package/grammars/tree-sitter-hcl/CHANGELOG.md +102 -0
- package/grammars/tree-sitter-hcl/LICENSE +201 -0
- package/grammars/tree-sitter-hcl/README.md +39 -0
- package/grammars/tree-sitter-html/LICENSE +21 -0
- package/grammars/tree-sitter-html/README.md +21 -0
- package/grammars/tree-sitter-julia/LICENSE +21 -0
- package/grammars/tree-sitter-julia/README.md +24 -0
- package/grammars/tree-sitter-kotlin/LICENSE +9 -0
- package/grammars/tree-sitter-lua/LICENSE.md +21 -0
- package/grammars/tree-sitter-lua/README.md +29 -0
- package/grammars/tree-sitter-make/LICENSE +21 -0
- package/grammars/tree-sitter-matlab/LICENSE +19 -0
- package/grammars/tree-sitter-matlab/README.md +99 -0
- package/grammars/tree-sitter-nim/LICENSE +373 -0
- package/grammars/tree-sitter-nim/README.md +46 -0
- package/grammars/tree-sitter-objc/LICENSE +21 -0
- package/grammars/tree-sitter-objc/README.md +20 -0
- package/grammars/tree-sitter-perl/LICENSE +7 -0
- package/grammars/tree-sitter-perl/README.md +100 -0
- package/grammars/tree-sitter-powershell/LICENSE +21 -0
- package/grammars/tree-sitter-powershell/README.md +7 -0
- package/grammars/tree-sitter-proto/LICENSE +21 -0
- package/grammars/tree-sitter-proto/README.md +105 -0
- package/grammars/tree-sitter-r/LICENSE +9 -0
- package/grammars/tree-sitter-r/README.md +66 -0
- package/grammars/tree-sitter-ruby/LICENSE +22 -0
- package/grammars/tree-sitter-scss/LICENSE +21 -0
- package/grammars/tree-sitter-scss/README.md +17 -0
- package/grammars/tree-sitter-solidity/LICENSE +7 -0
- package/grammars/tree-sitter-sql/LICENSE +21 -0
- package/grammars/tree-sitter-typescript/LICENSE +21 -0
- package/grammars/tree-sitter-vba/LICENSE +21 -0
- package/grammars/tree-sitter-vba/README.md +738 -0
- package/grammars/tree-sitter-vbnet/LICENSE +21 -0
- package/grammars/tree-sitter-vbnet/README.md +322 -0
- package/grammars/tree-sitter-xml/LICENSE +19 -0
- package/grammars/tree-sitter-yaml/LICENSE +20 -0
- package/grammars/tree-sitter-yaml/README.md +21 -0
- package/package.json +184 -4
- package/wasm/dart.wasm +0 -0
- package/wasm/tree-sitter-bash.wasm +0 -0
- package/wasm/tree-sitter-c.wasm +0 -0
- package/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/wasm/tree-sitter-clean.wasm +0 -0
- package/wasm/tree-sitter-clojure.wasm +0 -0
- package/wasm/tree-sitter-core_schema.wasm +0 -0
- package/wasm/tree-sitter-cpp.wasm +0 -0
- package/wasm/tree-sitter-css.wasm +0 -0
- package/wasm/tree-sitter-dart.wasm +0 -0
- package/wasm/tree-sitter-elisp.wasm +0 -0
- package/wasm/tree-sitter-elixir.wasm +0 -0
- package/wasm/tree-sitter-elm.wasm +0 -0
- package/wasm/tree-sitter-embedded_template.wasm +0 -0
- package/wasm/tree-sitter-erlang.wasm +0 -0
- package/wasm/tree-sitter-fsharp.wasm +0 -0
- package/wasm/tree-sitter-fsharp_signature.wasm +0 -0
- package/wasm/tree-sitter-go.wasm +0 -0
- package/wasm/tree-sitter-graphql.wasm +0 -0
- package/wasm/tree-sitter-groovy.wasm +0 -0
- package/wasm/tree-sitter-haskell.wasm +0 -0
- package/wasm/tree-sitter-hcl.wasm +0 -0
- package/wasm/tree-sitter-html.wasm +0 -0
- package/wasm/tree-sitter-java.wasm +0 -0
- package/wasm/tree-sitter-javascript.wasm +0 -0
- package/wasm/tree-sitter-json.wasm +0 -0
- package/wasm/tree-sitter-json_schema.wasm +0 -0
- package/wasm/tree-sitter-julia.wasm +0 -0
- package/wasm/tree-sitter-kotlin.wasm +0 -0
- package/wasm/tree-sitter-lua.wasm +0 -0
- package/wasm/tree-sitter-make.wasm +0 -0
- package/wasm/tree-sitter-markdown.wasm +0 -0
- package/wasm/tree-sitter-markdown_inline.wasm +0 -0
- package/wasm/tree-sitter-matlab.wasm +0 -0
- package/wasm/tree-sitter-nim.wasm +0 -0
- package/wasm/tree-sitter-objc.wasm +0 -0
- package/wasm/tree-sitter-ocaml.wasm +0 -0
- package/wasm/tree-sitter-perl.wasm +0 -0
- package/wasm/tree-sitter-php.wasm +0 -0
- package/wasm/tree-sitter-php_only.wasm +0 -0
- package/wasm/tree-sitter-powershell.wasm +0 -0
- package/wasm/tree-sitter-protobuf.wasm +0 -0
- package/wasm/tree-sitter-python.wasm +0 -0
- package/wasm/tree-sitter-ql.wasm +0 -0
- package/wasm/tree-sitter-r.wasm +0 -0
- package/wasm/tree-sitter-rescript.wasm +0 -0
- package/wasm/tree-sitter-ruby.wasm +0 -0
- package/wasm/tree-sitter-rust.wasm +0 -0
- package/wasm/tree-sitter-scala.wasm +0 -0
- package/wasm/tree-sitter-scss.wasm +0 -0
- package/wasm/tree-sitter-solidity.wasm +0 -0
- package/wasm/tree-sitter-sql.wasm +0 -0
- package/wasm/tree-sitter-svelte.wasm +0 -0
- package/wasm/tree-sitter-swift.wasm +0 -0
- package/wasm/tree-sitter-systemrdl.wasm +0 -0
- package/wasm/tree-sitter-terraform.wasm +0 -0
- package/wasm/tree-sitter-tlaplus.wasm +0 -0
- package/wasm/tree-sitter-toml.wasm +0 -0
- package/wasm/tree-sitter-tsx.wasm +0 -0
- package/wasm/tree-sitter-typescript.wasm +0 -0
- package/wasm/tree-sitter-vba.wasm +0 -0
- package/wasm/tree-sitter-vbnet.wasm +0 -0
- package/wasm/tree-sitter-vue.wasm +0 -0
- package/wasm/tree-sitter-xml.wasm +0 -0
- package/wasm/tree-sitter-yaml.wasm +0 -0
- package/wasm/tree-sitter-zig.wasm +0 -0
- package/wasm/tree-sitter.wasm +0 -0
- package/wasm/tsx.wasm +0 -0
- package/wasm/typescript.wasm +0 -0
|
@@ -0,0 +1,867 @@
|
|
|
1
|
+
import {
|
|
2
|
+
dirOf,
|
|
3
|
+
fileClaimForTarget
|
|
4
|
+
} from "./chunk-EWMWK7WN.js";
|
|
5
|
+
import {
|
|
6
|
+
ASTEngine
|
|
7
|
+
} from "./chunk-3ZTOHHSW.js";
|
|
8
|
+
import "./chunk-BQ3OVQ3P.js";
|
|
9
|
+
import "./chunk-SK6YVHFZ.js";
|
|
10
|
+
import "./chunk-2BSKD7O3.js";
|
|
11
|
+
import "./chunk-KAET47ZL.js";
|
|
12
|
+
import "./chunk-KCDECRJY.js";
|
|
13
|
+
import "./chunk-MLKGABMK.js";
|
|
14
|
+
|
|
15
|
+
// src/ast/real-protobuf-analyzer.ts
|
|
16
|
+
import * as path from "path";
|
|
17
|
+
var hasJsWhitespace = (c) => c === 9 || c === 10 || c === 11 || c === 12 || c === 13 || c === 32 || c === 160 || c === 5760 || c >= 8192 && c <= 8202 || c === 8232 || c === 8233 || c === 8239 || c === 8287 || c === 12288 || c === 65279;
|
|
18
|
+
var stripPackagePrefix = (s) => {
|
|
19
|
+
let i = 0;
|
|
20
|
+
while (i < s.length && hasJsWhitespace(s.charCodeAt(i))) i++;
|
|
21
|
+
if (!s.startsWith("package", i)) return s;
|
|
22
|
+
i += 7;
|
|
23
|
+
if (i >= s.length || !hasJsWhitespace(s.charCodeAt(i))) return s;
|
|
24
|
+
while (i < s.length && hasJsWhitespace(s.charCodeAt(i))) i++;
|
|
25
|
+
return s.slice(i);
|
|
26
|
+
};
|
|
27
|
+
var stripTrailingSemicolon = (s) => {
|
|
28
|
+
let e = s.length;
|
|
29
|
+
while (e > 0 && hasJsWhitespace(s.charCodeAt(e - 1))) e--;
|
|
30
|
+
if (e > 0 && s.charCodeAt(e - 1) === 59) e--;
|
|
31
|
+
return s.slice(0, e);
|
|
32
|
+
};
|
|
33
|
+
var stripOneTrailingSlash = (s) => s.endsWith("/") ? s.slice(0, -1) : s;
|
|
34
|
+
var hasPathSeparator = (s) => s.includes("/") || s.includes("\\");
|
|
35
|
+
var hasUriSchemePrefix = (s) => {
|
|
36
|
+
const isLetter = (c) => c >= 65 && c <= 90 || c >= 97 && c <= 122;
|
|
37
|
+
if (s.length === 0 || !isLetter(s.charCodeAt(0))) return false;
|
|
38
|
+
for (let i = 1; i < s.length; i++) {
|
|
39
|
+
const c = s.charCodeAt(i);
|
|
40
|
+
if (c === 58) return true;
|
|
41
|
+
if (!isLetter(c) && !(c >= 48 && c <= 57) && c !== 43 && c !== 46 && c !== 45) return false;
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
};
|
|
45
|
+
var PROTOBUF_DECLARATION_SPEC = {
|
|
46
|
+
typeNodes: { message: "class", enum: "enum", service: "interface" },
|
|
47
|
+
memberNodes: [],
|
|
48
|
+
baseNodes: [],
|
|
49
|
+
nameResolver: (n) => {
|
|
50
|
+
const children = (n.namedChildren ?? []).filter((c) => c !== null && c !== void 0);
|
|
51
|
+
const own = children.find((c) => String(c.type).endsWith("_name"))?.text ?? n.childForFieldName("name")?.text ?? "";
|
|
52
|
+
if (own.length === 0) return "";
|
|
53
|
+
let root = n;
|
|
54
|
+
while (root.parent !== null && root.parent !== void 0) root = root.parent;
|
|
55
|
+
const rootChildren = (root.namedChildren ?? []).filter((c) => c !== null && c !== void 0);
|
|
56
|
+
const packages = [];
|
|
57
|
+
for (const c of rootChildren) {
|
|
58
|
+
if (String(c.type) !== "package") continue;
|
|
59
|
+
const text = stripTrailingSemicolon(stripPackagePrefix(String(c.text ?? ""))).trim();
|
|
60
|
+
if (text.length > 0) packages.push(text);
|
|
61
|
+
}
|
|
62
|
+
return packages.length > 0 ? `${packages.join(".")}.${own}` : own;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
var PROTOBUF_EXTERNAL_NAMESPACES = [
|
|
66
|
+
"google.protobuf",
|
|
67
|
+
"google.api",
|
|
68
|
+
// `google.rpc` is the Google API's error-code/status surface (`google.rpc.Status`,
|
|
69
|
+
// `google.rpc.Code`, `google/rpc/error_details.proto`), and it was missing from a list whose
|
|
70
|
+
// job is exactly the runtime namespaces no admitted file declares FOR THE PROJECT THAT READS
|
|
71
|
+
// THEM. MEASURED whole population before adding it
|
|
72
|
+
// (validation/m14/fixtures/protobuf/measurements/claim-pricing.mts §A): the entry attaches to
|
|
73
|
+
// 30 `uses` edges — 17 read in projects that do NOT ship `google/rpc` (docker 6,
|
|
74
|
+
// waypoint 10, kubernetes 1) and are `unresolved` today, 13 read in `pb-googleapis`, which
|
|
75
|
+
// DOES ship `google/rpc/status.proto` and where the edges resolve today. The 13 are the
|
|
76
|
+
// `resolved -> extOK` shape §8.2 of `FOUR-CLAUSE-protobuf.md` already pre-authorized for
|
|
77
|
+
// `google.protobuf` (415 such moves): a per-file analyzer cannot know which project it is in,
|
|
78
|
+
// so a namespace claim is a statement about the LIST and the arbiter checks it against the
|
|
79
|
+
// list — never the symbol table. Widening an array is a visible, reviewable act, which is
|
|
80
|
+
// what makes the 13 acceptable in exchange for closing 17.
|
|
81
|
+
"google.rpc",
|
|
82
|
+
"gogoproto",
|
|
83
|
+
"protoc-gen-openapiv2"
|
|
84
|
+
];
|
|
85
|
+
function protobufExternalNamespaceOf(target) {
|
|
86
|
+
if (target.length === 0) return null;
|
|
87
|
+
const segs = target.split(".");
|
|
88
|
+
for (let n = segs.length; n >= 1; n--) {
|
|
89
|
+
const cand = segs.slice(0, n).join(".");
|
|
90
|
+
if (PROTOBUF_EXTERNAL_NAMESPACES.includes(cand)) return cand;
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
var RealProtobufAnalyzer = class {
|
|
95
|
+
analyze(rootNode, content, filePath, context) {
|
|
96
|
+
const symbols = [];
|
|
97
|
+
const relationships = [];
|
|
98
|
+
const imports = [];
|
|
99
|
+
const typeCache = /* @__PURE__ */ new Map();
|
|
100
|
+
const idOf = (n) => n.id ?? -1;
|
|
101
|
+
const typeOf = (n) => {
|
|
102
|
+
const id = idOf(n);
|
|
103
|
+
const hit = typeCache.get(id);
|
|
104
|
+
if (hit !== void 0) return hit;
|
|
105
|
+
const t = n.type;
|
|
106
|
+
typeCache.set(id, t);
|
|
107
|
+
return t;
|
|
108
|
+
};
|
|
109
|
+
const kids = (n) => {
|
|
110
|
+
const out = [];
|
|
111
|
+
for (const c of n.children) if (c && c.isNamed) out.push(c);
|
|
112
|
+
return out;
|
|
113
|
+
};
|
|
114
|
+
const firstOfType = (n, t) => {
|
|
115
|
+
for (const c of kids(n)) if (typeOf(c) === t) return c;
|
|
116
|
+
return null;
|
|
117
|
+
};
|
|
118
|
+
const lineOf = (n) => n ? n.startPosition.row + 1 : 0;
|
|
119
|
+
const lineOfOf = (startIndex) => {
|
|
120
|
+
let row = 1;
|
|
121
|
+
for (let i = 0; i < startIndex && i < content.length; i++) if (content.charCodeAt(i) === 10) row++;
|
|
122
|
+
return row;
|
|
123
|
+
};
|
|
124
|
+
const unquote = (s) => {
|
|
125
|
+
if (!s || s.length < 2) return s ?? "";
|
|
126
|
+
const a = s[0];
|
|
127
|
+
const b = s[s.length - 1];
|
|
128
|
+
if ((a === '"' || a === "'") && a === b) return s.slice(1, -1);
|
|
129
|
+
return s;
|
|
130
|
+
};
|
|
131
|
+
const prevSiblingOf = (parent, child) => {
|
|
132
|
+
const all = parent.children;
|
|
133
|
+
for (let i = 0; i < all.length; i++) {
|
|
134
|
+
const c = all[i];
|
|
135
|
+
if (c && c.startIndex === child.startIndex && c.endIndex === child.endIndex) {
|
|
136
|
+
return i > 0 ? all[i - 1] : null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
};
|
|
141
|
+
const docComments = /* @__PURE__ */ new Map();
|
|
142
|
+
{
|
|
143
|
+
const lineStarts = [0];
|
|
144
|
+
for (let i = 0; i < content.length; i++) {
|
|
145
|
+
if (content.charCodeAt(i) === 10) lineStarts.push(i + 1);
|
|
146
|
+
}
|
|
147
|
+
const onOwnLine = (n) => {
|
|
148
|
+
const s = lineStarts[n.startPosition.row];
|
|
149
|
+
if (s === void 0 || s > n.startIndex) return true;
|
|
150
|
+
for (let i = s; i < n.startIndex; i++) {
|
|
151
|
+
const c = content.charCodeAt(i);
|
|
152
|
+
if (c !== 32 && c !== 9 && c !== 13) return false;
|
|
153
|
+
}
|
|
154
|
+
return true;
|
|
155
|
+
};
|
|
156
|
+
const stack2 = [rootNode];
|
|
157
|
+
while (stack2.length) {
|
|
158
|
+
const n = stack2.pop();
|
|
159
|
+
let pending = [];
|
|
160
|
+
for (const c of n.children) {
|
|
161
|
+
if (!c) continue;
|
|
162
|
+
if (typeOf(c) === "comment") {
|
|
163
|
+
if (onOwnLine(c)) pending.push(c.text.trim());
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (pending.length && c.isNamed) {
|
|
167
|
+
docComments.set(idOf(c), pending);
|
|
168
|
+
pending = [];
|
|
169
|
+
}
|
|
170
|
+
stack2.push(c);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
const nodeToRange = (node) => {
|
|
175
|
+
let anchor = node;
|
|
176
|
+
for (const c of node.children) {
|
|
177
|
+
if (!c) continue;
|
|
178
|
+
if (typeOf(c) === "comment") continue;
|
|
179
|
+
anchor = c;
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
startLine: anchor.startPosition.row + 1,
|
|
184
|
+
startColumn: anchor.startPosition.column + 1,
|
|
185
|
+
endLine: node.endPosition.row + 1,
|
|
186
|
+
endColumn: node.endPosition.column + 1,
|
|
187
|
+
startIndex: anchor.startIndex,
|
|
188
|
+
endIndex: node.endIndex
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
const fileDecls = kids(rootNode);
|
|
192
|
+
let pkg = "";
|
|
193
|
+
let syntax = null;
|
|
194
|
+
let edition = null;
|
|
195
|
+
const fileOptions = [];
|
|
196
|
+
const importDirs = /* @__PURE__ */ new Set();
|
|
197
|
+
for (const d of fileDecls) {
|
|
198
|
+
if (typeOf(d) !== "import") continue;
|
|
199
|
+
const mod = unquote(String(d.childForFieldName("path")?.text ?? ""));
|
|
200
|
+
if (mod.length === 0) continue;
|
|
201
|
+
const cut = mod.lastIndexOf("/");
|
|
202
|
+
importDirs.add(cut > 0 ? mod.slice(0, cut) : "");
|
|
203
|
+
}
|
|
204
|
+
const projectNames = context?.projectIndex?.symbolNames instanceof Set ? context.projectIndex.symbolNames : void 0;
|
|
205
|
+
for (const d of fileDecls) {
|
|
206
|
+
const t = typeOf(d);
|
|
207
|
+
if (t === "package") pkg = firstOfType(d, "full_ident")?.text ?? "";
|
|
208
|
+
else if (t === "syntax") {
|
|
209
|
+
const all = d.children;
|
|
210
|
+
let value = null;
|
|
211
|
+
for (let i = 0; i < all.length; i++) {
|
|
212
|
+
const c = all[i];
|
|
213
|
+
if (c && !c.isNamed && c.text === "=") {
|
|
214
|
+
const nxt = all[i + 1];
|
|
215
|
+
if (nxt) value = unquote(nxt.text);
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
syntax = value;
|
|
220
|
+
} else if (t === "edition") {
|
|
221
|
+
edition = unquote(d.childForFieldName("value")?.text) || unquote(firstOfType(d, "string")?.text) || null;
|
|
222
|
+
} else if (t === "option") {
|
|
223
|
+
const k = kids(d);
|
|
224
|
+
fileOptions.push({
|
|
225
|
+
name: k[0]?.text ?? "",
|
|
226
|
+
value: k[1]?.text ?? "",
|
|
227
|
+
line: lineOf(d)
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const SymbolKind = ASTEngine.SymbolKind;
|
|
232
|
+
const qualify = (owner, name) => owner ? `${owner}.${name}` : name;
|
|
233
|
+
const declaredIds = /* @__PURE__ */ new Set();
|
|
234
|
+
const usedIds = /* @__PURE__ */ new Set();
|
|
235
|
+
const metaOf = /* @__PURE__ */ new Map();
|
|
236
|
+
const uniqueId = (base, kind) => {
|
|
237
|
+
if (!usedIds.has(base)) return base;
|
|
238
|
+
let n = 0;
|
|
239
|
+
let cand = `${base}#${kind}`;
|
|
240
|
+
while (usedIds.has(cand)) {
|
|
241
|
+
n++;
|
|
242
|
+
cand = `${base}#${kind}${n}`;
|
|
243
|
+
}
|
|
244
|
+
return cand;
|
|
245
|
+
};
|
|
246
|
+
const declaredTypeIds = /* @__PURE__ */ new Set();
|
|
247
|
+
const slotClaims = /* @__PURE__ */ new Map();
|
|
248
|
+
const isTypeDeclaring = (kind) => kind === ASTEngine.SymbolKind.Class || kind === ASTEngine.SymbolKind.Enum;
|
|
249
|
+
const addSymbol = (id, s) => {
|
|
250
|
+
const real = uniqueId(id, String(s.kind));
|
|
251
|
+
const fieldNumber = s.metadata && s.metadata.fieldNumber !== void 0 ? s.metadata.fieldNumber : null;
|
|
252
|
+
if (s.kind === ASTEngine.SymbolKind.Property && fieldNumber !== null) {
|
|
253
|
+
const slotKey = `${String(s.ownerName ?? "")}\0${fieldNumber}`;
|
|
254
|
+
const prev = slotClaims.get(slotKey);
|
|
255
|
+
if (prev) {
|
|
256
|
+
const later = (s.range.startIndex ?? 0) > prev.startIndex;
|
|
257
|
+
const srcStart = later ? s.range.startIndex ?? 0 : prev.startIndex;
|
|
258
|
+
if (!collectOnly) {
|
|
259
|
+
addRel(
|
|
260
|
+
later ? real : prev.id,
|
|
261
|
+
later ? prev.id : real,
|
|
262
|
+
RelationshipTypeOverrides,
|
|
263
|
+
lineOfOf(srcStart),
|
|
264
|
+
{ role: "fieldSlot", fieldNumber }
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
slotClaims.set(slotKey, { id: real, startIndex: s.range.startIndex ?? 0, name: String(s.name) });
|
|
269
|
+
}
|
|
270
|
+
usedIds.add(real);
|
|
271
|
+
declaredIds.add(real);
|
|
272
|
+
if (isTypeDeclaring(s.kind)) declaredTypeIds.add(real);
|
|
273
|
+
if (collectOnly) return real;
|
|
274
|
+
s.metadata = { ...s.metadata, id: real, qualifiedName: real };
|
|
275
|
+
s.qualifiedName = real;
|
|
276
|
+
metaOf.set(real, s.metadata);
|
|
277
|
+
symbols.push(s);
|
|
278
|
+
return real;
|
|
279
|
+
};
|
|
280
|
+
const ownerMeta = (id, fn) => {
|
|
281
|
+
const m = metaOf.get(id);
|
|
282
|
+
if (m) fn(m);
|
|
283
|
+
};
|
|
284
|
+
const fileRanges = [];
|
|
285
|
+
let collectOnly = false;
|
|
286
|
+
const evidenceClassFor = (type) => {
|
|
287
|
+
if (type === ASTEngine.RelationshipType.Imports) return "import_based";
|
|
288
|
+
if (type === ASTEngine.RelationshipType.Exports) return "structural";
|
|
289
|
+
return "structural";
|
|
290
|
+
};
|
|
291
|
+
const addRel = (source, target, type, line, metadata = {}) => {
|
|
292
|
+
if (collectOnly) return;
|
|
293
|
+
relationships.push({
|
|
294
|
+
source,
|
|
295
|
+
target,
|
|
296
|
+
type,
|
|
297
|
+
relationshipType: type,
|
|
298
|
+
line_number: line,
|
|
299
|
+
confidence: 1,
|
|
300
|
+
metadata: {
|
|
301
|
+
evidenceClass: evidenceClassFor(type),
|
|
302
|
+
// THE NAMESPACE CLAIM (task-19). Attached ONLY where this edge is a TYPE REFERENCE that
|
|
303
|
+
// this file does not declare AND whose namespace is one of the declared runtime
|
|
304
|
+
// namespaces above — i.e. exactly the class that used to read `unresolved` with no claim
|
|
305
|
+
// at all. The `declaredTypeIds` guard is what keeps the lane from certifying a reference
|
|
306
|
+
// its own file already answers; it is also why this adoption moves no `resolved` edge.
|
|
307
|
+
...type === ASTEngine.RelationshipType.References && !declaredTypeIds.has(target) && protobufExternalNamespaceOf(target) !== null ? { languageNamespace: [...PROTOBUF_EXTERNAL_NAMESPACES] } : {},
|
|
308
|
+
...metadata
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
};
|
|
312
|
+
const resolveRef = (text, scope) => {
|
|
313
|
+
if (text.startsWith(".")) return text.slice(1);
|
|
314
|
+
const chain = [];
|
|
315
|
+
if (scope) {
|
|
316
|
+
const segs = scope.split(".");
|
|
317
|
+
for (let i = segs.length; i > 0; i--) {
|
|
318
|
+
const cand = segs.slice(0, i).join(".");
|
|
319
|
+
if (!pkg || cand === pkg || cand.startsWith(pkg + ".")) chain.push(cand);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
if (pkg) chain.push(pkg);
|
|
323
|
+
chain.push(null);
|
|
324
|
+
for (const base of chain) {
|
|
325
|
+
const cand = base ? `${base}.${text}` : text;
|
|
326
|
+
if (declaredTypeIds.has(cand)) return cand;
|
|
327
|
+
}
|
|
328
|
+
if (text.includes(".")) {
|
|
329
|
+
const hit = resolveViaImports(text, scope);
|
|
330
|
+
if (hit !== null) return hit;
|
|
331
|
+
return text;
|
|
332
|
+
}
|
|
333
|
+
const bare = resolveBareViaImports(text, scope);
|
|
334
|
+
if (bare !== null) return bare;
|
|
335
|
+
return qualify(pkg || null, text);
|
|
336
|
+
};
|
|
337
|
+
const resolveBareViaImports = (text, scope) => {
|
|
338
|
+
if (importDirs.size === 0) return null;
|
|
339
|
+
const chain = specScopeChain(scope);
|
|
340
|
+
for (const base of chain) {
|
|
341
|
+
if (base.length === 0) continue;
|
|
342
|
+
const dir = base.split(".").join("/");
|
|
343
|
+
if (!importDirs.has(dir)) continue;
|
|
344
|
+
for (const other of chain) {
|
|
345
|
+
if (other.length === 0) continue;
|
|
346
|
+
const otherDir = other.split(".").join("/");
|
|
347
|
+
if (otherDir !== dir && otherDir.endsWith(dir)) return null;
|
|
348
|
+
}
|
|
349
|
+
return `${base}.${text}`;
|
|
350
|
+
}
|
|
351
|
+
return null;
|
|
352
|
+
};
|
|
353
|
+
const specScopeChain = (scope) => {
|
|
354
|
+
const chain = [];
|
|
355
|
+
const push = (v) => {
|
|
356
|
+
if (!chain.includes(v)) chain.push(v);
|
|
357
|
+
};
|
|
358
|
+
if (scope) {
|
|
359
|
+
const segs = scope.split(".");
|
|
360
|
+
for (let i = segs.length; i > 0; i--) push(segs.slice(0, i).join("."));
|
|
361
|
+
}
|
|
362
|
+
if (pkg) {
|
|
363
|
+
const segs = pkg.split(".");
|
|
364
|
+
for (let i = segs.length; i > 0; i--) push(segs.slice(0, i).join("."));
|
|
365
|
+
}
|
|
366
|
+
push("");
|
|
367
|
+
return chain;
|
|
368
|
+
};
|
|
369
|
+
const resolveViaImports = (text, scope) => {
|
|
370
|
+
if (importDirs.size === 0) return null;
|
|
371
|
+
const lastDot = text.lastIndexOf(".");
|
|
372
|
+
if (lastDot <= 0) return null;
|
|
373
|
+
const rootedAt = text.slice(0, lastDot);
|
|
374
|
+
const typeName = text.slice(lastDot + 1);
|
|
375
|
+
const chain = specScopeChain(scope);
|
|
376
|
+
for (const base of chain) {
|
|
377
|
+
const packageOf = base.length > 0 ? `${base}.${rootedAt}` : rootedAt;
|
|
378
|
+
const dir = packageOf.split(".").join("/");
|
|
379
|
+
if (!importDirs.has(dir)) {
|
|
380
|
+
const candidate = `${packageOf}.${typeName}`;
|
|
381
|
+
if (projectNames !== void 0 && projectNames.has(candidate)) return candidate;
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
for (const other of chain) {
|
|
385
|
+
const otherPackage = other.length > 0 ? `${other}.${rootedAt}` : rootedAt;
|
|
386
|
+
const otherDir = otherPackage.split(".").join("/");
|
|
387
|
+
if (otherDir !== dir && otherDir.endsWith(dir)) return null;
|
|
388
|
+
}
|
|
389
|
+
return `${packageOf}.${typeName}`;
|
|
390
|
+
}
|
|
391
|
+
return null;
|
|
392
|
+
};
|
|
393
|
+
const refTypeOf = (typeNode) => {
|
|
394
|
+
if (!typeNode) return null;
|
|
395
|
+
const inner = firstOfType(typeNode, "message_or_enum_type");
|
|
396
|
+
return inner ? inner.text : null;
|
|
397
|
+
};
|
|
398
|
+
const idOwner = (ctx) => ctx.viaExtension ? ctx.scope : ctx.owner;
|
|
399
|
+
const addFieldLike = (node, nameNode, ctx, extra) => {
|
|
400
|
+
const name = nameNode.text;
|
|
401
|
+
if (!name) return null;
|
|
402
|
+
const meta = { ...extra };
|
|
403
|
+
if (ctx.oneof) meta.oneof = ctx.oneof;
|
|
404
|
+
if (ctx.viaExtension) meta.viaExtension = true;
|
|
405
|
+
const id = addSymbol(qualify(idOwner(ctx), name), {
|
|
406
|
+
name,
|
|
407
|
+
kind: SymbolKind.Property,
|
|
408
|
+
range: nodeToRange(node),
|
|
409
|
+
ownerName: ctx.owner ?? void 0,
|
|
410
|
+
ownerKind: ctx.ownerKind ?? void 0,
|
|
411
|
+
metadata: meta
|
|
412
|
+
});
|
|
413
|
+
if (ctx.owner) {
|
|
414
|
+
addRel(ctx.owner, id, RelationshipTypeContains, lineOf(node), {
|
|
415
|
+
member: "field",
|
|
416
|
+
// `viaExtension` on the EDGE as well as on the symbol. It was on the
|
|
417
|
+
// symbol only, so a consumer reading `google.protobuf.MessageOptions
|
|
418
|
+
// -contains-> audit_ticket` could not tell an extension field added in
|
|
419
|
+
// another file from a field declared in the message's own body — and the
|
|
420
|
+
// header's claim that the edge carries it was false. Measured over the
|
|
421
|
+
// corpus before this change: 0 of the extension-derived `contains` edges
|
|
422
|
+
// carried `viaExtension`, because `addFieldLike` set it on the symbol's
|
|
423
|
+
// metadata object and the `addRel` call passed only `member`.
|
|
424
|
+
...ctx.viaExtension ? { viaExtension: true } : {}
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
return id;
|
|
428
|
+
};
|
|
429
|
+
const RelationshipTypeContains = ASTEngine.RelationshipType.Contains;
|
|
430
|
+
const RelationshipTypeReferences = ASTEngine.RelationshipType.References;
|
|
431
|
+
const RelationshipTypeImports = ASTEngine.RelationshipType.Imports;
|
|
432
|
+
const RelationshipTypeExports = ASTEngine.RelationshipType.Exports;
|
|
433
|
+
const RelationshipTypeOverrides = ASTEngine.RelationshipType.Overrides;
|
|
434
|
+
const emitField = (node, ctx) => {
|
|
435
|
+
const typeNode = firstOfType(node, "type");
|
|
436
|
+
const body = firstOfType(node, "message_body");
|
|
437
|
+
const numNode = firstOfType(node, "field_number");
|
|
438
|
+
const label = (node.children ?? []).filter((c) => c && !c.isNamed).map((c) => c.text).find((t) => t === "optional" || t === "required" || t === "repeated");
|
|
439
|
+
if (!typeNode && body) {
|
|
440
|
+
const gname = node.childForFieldName("name")?.text ?? firstOfType(node, "identifier")?.text;
|
|
441
|
+
if (gname) {
|
|
442
|
+
const typeOwner = idOwner(ctx);
|
|
443
|
+
const typeId = addSymbol(qualify(typeOwner, gname), {
|
|
444
|
+
name: gname,
|
|
445
|
+
kind: SymbolKind.Class,
|
|
446
|
+
range: nodeToRange(node),
|
|
447
|
+
ownerName: typeOwner ?? void 0,
|
|
448
|
+
// Inside an `extend`, `ctx.ownerKind` is the EXTENDEE's kind, which is
|
|
449
|
+
// not the kind of the scope the type is being declared in, so it is
|
|
450
|
+
// omitted rather than asserted. Outside an `extend` the two agree and it
|
|
451
|
+
// is carried through unchanged.
|
|
452
|
+
...ctx.viaExtension ? {} : { ownerKind: ctx.ownerKind ?? void 0 },
|
|
453
|
+
// `isGroupType` and nothing else: a type declared at the block's own
|
|
454
|
+
// scope is not an extension member, so it does not carry `viaExtension`.
|
|
455
|
+
// The group's FIELD below still does.
|
|
456
|
+
metadata: { isGroupType: true }
|
|
457
|
+
});
|
|
458
|
+
if (typeOwner) addRel(typeOwner, typeId, RelationshipTypeContains, lineOf(node), { member: "groupType" });
|
|
459
|
+
const fieldId2 = addSymbol(qualify(idOwner(ctx), gname), {
|
|
460
|
+
name: gname,
|
|
461
|
+
kind: SymbolKind.Property,
|
|
462
|
+
range: nodeToRange(node),
|
|
463
|
+
ownerName: ctx.owner ?? void 0,
|
|
464
|
+
ownerKind: ctx.ownerKind ?? void 0,
|
|
465
|
+
metadata: {
|
|
466
|
+
type: gname,
|
|
467
|
+
isGroup: true,
|
|
468
|
+
fieldNumber: numNode?.text ?? null,
|
|
469
|
+
...label ? { label } : {},
|
|
470
|
+
...ctx.viaExtension ? { viaExtension: true } : {}
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
if (ctx.owner) addRel(ctx.owner, fieldId2, RelationshipTypeContains, lineOf(node), { member: "field", ...ctx.viaExtension ? { viaExtension: true } : {} });
|
|
474
|
+
addRel(fieldId2, typeId, RelationshipTypeReferences, lineOf(node), { role: "groupType" });
|
|
475
|
+
const inner = {
|
|
476
|
+
...ctx,
|
|
477
|
+
owner: typeId,
|
|
478
|
+
scope: typeId,
|
|
479
|
+
ownerKind: SymbolKind.Class,
|
|
480
|
+
oneof: null,
|
|
481
|
+
viaExtension: false
|
|
482
|
+
};
|
|
483
|
+
pushAll(kids(body), inner);
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
const nameNode = firstOfType(node, "identifier");
|
|
488
|
+
if (!nameNode) return;
|
|
489
|
+
const ref = refTypeOf(typeNode);
|
|
490
|
+
const fieldId = addFieldLike(node, nameNode, ctx, {
|
|
491
|
+
type: ref ?? typeNode?.text ?? null,
|
|
492
|
+
...ref ? {} : { scalar: true },
|
|
493
|
+
fieldNumber: numNode?.text ?? null,
|
|
494
|
+
...label ? { label } : {}
|
|
495
|
+
});
|
|
496
|
+
if (fieldId && ref) {
|
|
497
|
+
addRel(fieldId, resolveRef(ref, ctx.scope), RelationshipTypeReferences, lineOf(node), { role: "fieldType" });
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
const emitMapField = (node, ctx) => {
|
|
501
|
+
const nameNode = firstOfType(node, "identifier");
|
|
502
|
+
if (!nameNode) return;
|
|
503
|
+
const keyNode = firstOfType(node, "key_type");
|
|
504
|
+
const valType = firstOfType(node, "type");
|
|
505
|
+
const valRef = refTypeOf(valType);
|
|
506
|
+
const numNode = firstOfType(node, "field_number");
|
|
507
|
+
const fieldId = addFieldLike(node, nameNode, ctx, {
|
|
508
|
+
isMap: true,
|
|
509
|
+
mapKey: keyNode?.text ?? null,
|
|
510
|
+
mapValue: valRef ?? valType?.text ?? null,
|
|
511
|
+
...valRef ? {} : { valueIsScalar: true },
|
|
512
|
+
fieldNumber: numNode?.text ?? null
|
|
513
|
+
});
|
|
514
|
+
if (fieldId && valRef) {
|
|
515
|
+
addRel(fieldId, resolveRef(valRef, ctx.scope), RelationshipTypeReferences, lineOf(node), {
|
|
516
|
+
role: "mapValueType"
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
const emitOneofField = (node, ctx) => {
|
|
521
|
+
const nameNode = firstOfType(node, "identifier");
|
|
522
|
+
if (!nameNode) return;
|
|
523
|
+
const typeNode = firstOfType(node, "type");
|
|
524
|
+
const ref = refTypeOf(typeNode);
|
|
525
|
+
const fieldId = addFieldLike(node, nameNode, ctx, {
|
|
526
|
+
type: ref ?? typeNode?.text ?? null,
|
|
527
|
+
...ref ? {} : { scalar: true },
|
|
528
|
+
fieldNumber: firstOfType(node, "field_number")?.text ?? null
|
|
529
|
+
});
|
|
530
|
+
if (fieldId && ref) {
|
|
531
|
+
addRel(fieldId, resolveRef(ref, ctx.scope), RelationshipTypeReferences, lineOf(node), { role: "oneofFieldType" });
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
const emitEnumField = (node, ctx) => {
|
|
535
|
+
const nameNode = firstOfType(node, "identifier");
|
|
536
|
+
if (!nameNode) return;
|
|
537
|
+
const name = nameNode.text;
|
|
538
|
+
const id = addSymbol(qualify(idOwner(ctx), name), {
|
|
539
|
+
name,
|
|
540
|
+
kind: SymbolKind.EnumMember,
|
|
541
|
+
range: nodeToRange(node),
|
|
542
|
+
ownerName: ctx.owner ?? void 0,
|
|
543
|
+
ownerKind: SymbolKind.Enum,
|
|
544
|
+
metadata: {
|
|
545
|
+
value: firstOfType(node, "int_lit")?.text ?? null,
|
|
546
|
+
...ctx.viaExtension ? { viaExtension: true } : {}
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
if (ctx.owner) addRel(ctx.owner, id, RelationshipTypeContains, lineOf(node), { member: "enumValue", ...ctx.viaExtension ? { viaExtension: true } : {} });
|
|
550
|
+
};
|
|
551
|
+
const emitRpc = (node, ctx) => {
|
|
552
|
+
const nameNode = firstOfType(node, "rpc_name");
|
|
553
|
+
if (!nameNode) return;
|
|
554
|
+
const name = nameNode.text;
|
|
555
|
+
const types = kids(node).filter((c) => typeOf(c) === "message_or_enum_type");
|
|
556
|
+
const request = types[0]?.text ?? null;
|
|
557
|
+
const response = types[1]?.text ?? null;
|
|
558
|
+
const isStreaming = (t) => {
|
|
559
|
+
if (!t) return false;
|
|
560
|
+
const p = prevSiblingOf(node, t);
|
|
561
|
+
return !!p && !p.isNamed && p.text === "stream";
|
|
562
|
+
};
|
|
563
|
+
const clientStreaming = isStreaming(types[0]);
|
|
564
|
+
const serverStreaming = isStreaming(types[1]);
|
|
565
|
+
const id = addSymbol(qualify(ctx.owner, name), {
|
|
566
|
+
name,
|
|
567
|
+
kind: SymbolKind.Method,
|
|
568
|
+
range: nodeToRange(node),
|
|
569
|
+
ownerName: ctx.owner ?? void 0,
|
|
570
|
+
ownerKind: SymbolKind.Interface,
|
|
571
|
+
...request ? { parameters: [{ name: "request", type: request }] } : {},
|
|
572
|
+
...response ? { returnType: response } : {},
|
|
573
|
+
metadata: {
|
|
574
|
+
...request ? { requestType: request } : {},
|
|
575
|
+
...response ? { responseType: response } : {},
|
|
576
|
+
clientStreaming,
|
|
577
|
+
serverStreaming
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
if (ctx.owner) addRel(ctx.owner, id, RelationshipTypeContains, lineOf(node), { member: "rpc", ...ctx.viaExtension ? { viaExtension: true } : {} });
|
|
581
|
+
if (request) addRel(id, resolveRef(request, ctx.scope), RelationshipTypeReferences, lineOf(node), { role: "rpcRequest" });
|
|
582
|
+
if (response) addRel(id, resolveRef(response, ctx.scope), RelationshipTypeReferences, lineOf(node), { role: "rpcResponse" });
|
|
583
|
+
};
|
|
584
|
+
const stack = [];
|
|
585
|
+
const pushAll = (children, ctx) => {
|
|
586
|
+
for (const c of children) stack.push({ node: c, ctx });
|
|
587
|
+
};
|
|
588
|
+
const visit = (node, ctx) => {
|
|
589
|
+
switch (typeOf(node)) {
|
|
590
|
+
case "message": {
|
|
591
|
+
const nameNode = firstOfType(node, "message_name");
|
|
592
|
+
if (!nameNode) return;
|
|
593
|
+
const name = nameNode.text;
|
|
594
|
+
const id = addSymbol(qualify(ctx.owner, name), {
|
|
595
|
+
name,
|
|
596
|
+
kind: SymbolKind.Class,
|
|
597
|
+
range: nodeToRange(node),
|
|
598
|
+
...docComments.has(idOf(node)) ? { comments: docComments.get(idOf(node)) } : {},
|
|
599
|
+
ownerName: ctx.owner ?? void 0,
|
|
600
|
+
ownerKind: ctx.ownerKind ?? void 0,
|
|
601
|
+
metadata: { isMessage: true, ...ctx.viaExtension ? { viaExtension: true } : {} }
|
|
602
|
+
});
|
|
603
|
+
if (ctx.owner) addRel(ctx.owner, id, RelationshipTypeContains, lineOf(node), { member: "nestedType", ...ctx.viaExtension ? { viaExtension: true } : {} });
|
|
604
|
+
const body = firstOfType(node, "message_body");
|
|
605
|
+
if (body) {
|
|
606
|
+
const inner = { ...ctx, owner: id, scope: id, ownerKind: SymbolKind.Class, oneof: null };
|
|
607
|
+
pushAll(kids(body), inner);
|
|
608
|
+
}
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
case "enum": {
|
|
612
|
+
const nameNode = firstOfType(node, "enum_name");
|
|
613
|
+
if (!nameNode) return;
|
|
614
|
+
const name = nameNode.text;
|
|
615
|
+
const id = addSymbol(qualify(ctx.owner, name), {
|
|
616
|
+
name,
|
|
617
|
+
kind: SymbolKind.Enum,
|
|
618
|
+
range: nodeToRange(node),
|
|
619
|
+
...docComments.has(idOf(node)) ? { comments: docComments.get(idOf(node)) } : {},
|
|
620
|
+
ownerName: ctx.owner ?? void 0,
|
|
621
|
+
ownerKind: ctx.ownerKind ?? void 0,
|
|
622
|
+
metadata: { isEnum: true, ...ctx.viaExtension ? { viaExtension: true } : {} }
|
|
623
|
+
});
|
|
624
|
+
if (ctx.owner) addRel(ctx.owner, id, RelationshipTypeContains, lineOf(node), { member: "nestedType", ...ctx.viaExtension ? { viaExtension: true } : {} });
|
|
625
|
+
const body = firstOfType(node, "enum_body");
|
|
626
|
+
if (body) {
|
|
627
|
+
const inner = { ...ctx, owner: id, scope: id, ownerKind: SymbolKind.Enum, oneof: null };
|
|
628
|
+
pushAll(kids(body), inner);
|
|
629
|
+
}
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
case "service": {
|
|
633
|
+
const nameNode = firstOfType(node, "service_name");
|
|
634
|
+
if (!nameNode) return;
|
|
635
|
+
const name = nameNode.text;
|
|
636
|
+
const id = addSymbol(qualify(ctx.owner, name), {
|
|
637
|
+
name,
|
|
638
|
+
kind: SymbolKind.Interface,
|
|
639
|
+
range: nodeToRange(node),
|
|
640
|
+
...docComments.has(idOf(node)) ? { comments: docComments.get(idOf(node)) } : {},
|
|
641
|
+
ownerName: ctx.owner ?? void 0,
|
|
642
|
+
ownerKind: ctx.ownerKind ?? void 0,
|
|
643
|
+
metadata: { isService: true, ...ctx.viaExtension ? { viaExtension: true } : {} }
|
|
644
|
+
});
|
|
645
|
+
if (ctx.owner) addRel(ctx.owner, id, RelationshipTypeContains, lineOf(node), { member: "nestedType", ...ctx.viaExtension ? { viaExtension: true } : {} });
|
|
646
|
+
const inner = { ...ctx, owner: id, scope: id, ownerKind: SymbolKind.Interface, oneof: null };
|
|
647
|
+
pushAll(
|
|
648
|
+
kids(node).filter((c) => typeOf(c) !== "service_name"),
|
|
649
|
+
inner
|
|
650
|
+
);
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
case "extend": {
|
|
654
|
+
const target = firstOfType(node, "full_ident")?.text ?? firstOfType(node, "message_or_enum_type")?.text;
|
|
655
|
+
const body = firstOfType(node, "message_body");
|
|
656
|
+
if (!target || !body) return;
|
|
657
|
+
const resolved = resolveRef(target, ctx.scope);
|
|
658
|
+
const inner = {
|
|
659
|
+
...ctx,
|
|
660
|
+
owner: resolved,
|
|
661
|
+
// `scope` is DELIBERATELY NOT `resolved`. The block's members belong
|
|
662
|
+
// to the extended type, but a type written inside the block is
|
|
663
|
+
// looked up from where the block is WRITTEN, because `extend` does
|
|
664
|
+
// not open a scope. Inheriting `ctx.scope` unchanged is what makes a
|
|
665
|
+
// nested `extend` resolve against the enclosing messages; setting it
|
|
666
|
+
// to `resolved` would resolve against a type the language never made
|
|
667
|
+
// a scope of, and the walk would find nothing.
|
|
668
|
+
scope: ctx.scope,
|
|
669
|
+
ownerKind: SymbolKind.Class,
|
|
670
|
+
oneof: null,
|
|
671
|
+
viaExtension: true
|
|
672
|
+
};
|
|
673
|
+
pushAll(kids(body), inner);
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
case "oneof": {
|
|
677
|
+
const kn = kids(node);
|
|
678
|
+
const nameNode = kn.find((c) => typeOf(c) === "identifier");
|
|
679
|
+
if (!nameNode) return;
|
|
680
|
+
const name = nameNode.text;
|
|
681
|
+
const id = addSymbol(qualify(ctx.owner, name), {
|
|
682
|
+
name,
|
|
683
|
+
kind: SymbolKind.Union,
|
|
684
|
+
range: nodeToRange(node),
|
|
685
|
+
...docComments.has(idOf(node)) ? { comments: docComments.get(idOf(node)) } : {},
|
|
686
|
+
ownerName: ctx.owner ?? void 0,
|
|
687
|
+
ownerKind: ctx.ownerKind ?? void 0,
|
|
688
|
+
metadata: { isOneof: true }
|
|
689
|
+
});
|
|
690
|
+
if (ctx.owner) addRel(ctx.owner, id, RelationshipTypeContains, lineOf(node), { member: "oneof", ...ctx.viaExtension ? { viaExtension: true } : {} });
|
|
691
|
+
const inner = { ...ctx, oneof: id };
|
|
692
|
+
pushAll(kids(node), inner);
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
case "reserved":
|
|
696
|
+
case "extensions": {
|
|
697
|
+
const what = typeOf(node) === "reserved" ? "reserved" : "extensions";
|
|
698
|
+
const ranges = kids(node).filter((c) => typeOf(c) === "ranges").flatMap((r) => kids(r).filter((c) => typeOf(c) === "range").map((c) => c.text));
|
|
699
|
+
const names = kids(node).filter((c) => typeOf(c) === "field_names").flatMap((f) => kids(f).map((c) => unquote(c.text)));
|
|
700
|
+
if (ctx.owner) ownerMeta(ctx.owner, (m) => {
|
|
701
|
+
const list = m[what] ?? [];
|
|
702
|
+
list.push(...ranges.length ? ranges.map((t) => ({ range: t })) : names.map((t) => ({ name: t })));
|
|
703
|
+
m[what] = list;
|
|
704
|
+
});
|
|
705
|
+
else
|
|
706
|
+
fileRanges.push(
|
|
707
|
+
...ranges.length ? ranges.map((t) => ({ kind: what, range: t })) : names.map((t) => ({ kind: what, name: t }))
|
|
708
|
+
);
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
case "field":
|
|
712
|
+
emitField(node, ctx);
|
|
713
|
+
return;
|
|
714
|
+
case "map_field":
|
|
715
|
+
emitMapField(node, ctx);
|
|
716
|
+
return;
|
|
717
|
+
case "oneof_field":
|
|
718
|
+
emitOneofField(node, ctx);
|
|
719
|
+
return;
|
|
720
|
+
case "enum_field":
|
|
721
|
+
emitEnumField(node, ctx);
|
|
722
|
+
return;
|
|
723
|
+
case "rpc":
|
|
724
|
+
emitRpc(node, ctx);
|
|
725
|
+
return;
|
|
726
|
+
default:
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
};
|
|
730
|
+
const root = { pkg, owner: pkg || null, scope: pkg || null, ownerKind: null, oneof: null, viaExtension: false };
|
|
731
|
+
const drain = () => {
|
|
732
|
+
while (stack.length) {
|
|
733
|
+
const item = stack.pop();
|
|
734
|
+
const d = item.node;
|
|
735
|
+
const t = typeOf(d);
|
|
736
|
+
if (t === "import") {
|
|
737
|
+
const raw = d.childForFieldName("path")?.text ?? firstOfType(d, "string")?.text ?? "";
|
|
738
|
+
const path2 = unquote(raw);
|
|
739
|
+
let modifier = null;
|
|
740
|
+
for (const c of d.children) {
|
|
741
|
+
if (!c || c.isNamed) continue;
|
|
742
|
+
if (c.text === "public" || c.text === "weak" || c.text === "option") {
|
|
743
|
+
modifier = c.text;
|
|
744
|
+
break;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
if (!collectOnly) {
|
|
748
|
+
imports.push({
|
|
749
|
+
module: path2,
|
|
750
|
+
path: path2,
|
|
751
|
+
items: [],
|
|
752
|
+
isDefaultImport: false,
|
|
753
|
+
isNamespaceImport: false,
|
|
754
|
+
range: nodeToRange(d),
|
|
755
|
+
metadata: { ...modifier ? { modifier } : {} }
|
|
756
|
+
});
|
|
757
|
+
if (path2) {
|
|
758
|
+
const selfMod = pkg.length > 0 ? pkg : filePath.split("/").pop() || filePath;
|
|
759
|
+
const moduleMeta = { modulePath: path2, filePath, ...pkg.length > 0 ? { moduleOwner: "package" } : { moduleOwner: "basename" } };
|
|
760
|
+
if (modifier === "public") {
|
|
761
|
+
addRel(selfMod, path2, RelationshipTypeExports, lineOf(d), {
|
|
762
|
+
...moduleMeta,
|
|
763
|
+
viaPublicImport: true
|
|
764
|
+
});
|
|
765
|
+
addRel(selfMod, path2, RelationshipTypeImports, lineOf(d), {
|
|
766
|
+
...moduleMeta,
|
|
767
|
+
...modifier ? { modifier } : {},
|
|
768
|
+
viaPublicImport: true
|
|
769
|
+
});
|
|
770
|
+
} else {
|
|
771
|
+
addRel(selfMod, path2, RelationshipTypeImports, lineOf(d), {
|
|
772
|
+
...moduleMeta,
|
|
773
|
+
...modifier ? { modifier } : {},
|
|
774
|
+
// The editions FEATURE import resolves an option's definition
|
|
775
|
+
// rather than a message, which is why it is not a re-export even
|
|
776
|
+
// though it names a file this one depends on.
|
|
777
|
+
...modifier === "option" ? { isFeatureImport: true } : {}
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
continue;
|
|
783
|
+
}
|
|
784
|
+
if (t === "package") {
|
|
785
|
+
addSymbol(pkg, {
|
|
786
|
+
name: pkg,
|
|
787
|
+
kind: SymbolKind.Namespace,
|
|
788
|
+
range: nodeToRange(d),
|
|
789
|
+
metadata: { isProtoPackage: true }
|
|
790
|
+
});
|
|
791
|
+
continue;
|
|
792
|
+
}
|
|
793
|
+
visit(d, item.ctx);
|
|
794
|
+
}
|
|
795
|
+
};
|
|
796
|
+
collectOnly = true;
|
|
797
|
+
pushAll(fileDecls, root);
|
|
798
|
+
drain();
|
|
799
|
+
collectOnly = false;
|
|
800
|
+
usedIds.clear();
|
|
801
|
+
metaOf.clear();
|
|
802
|
+
slotClaims.clear();
|
|
803
|
+
fileRanges.length = 0;
|
|
804
|
+
stack.length = 0;
|
|
805
|
+
pushAll(fileDecls, root);
|
|
806
|
+
drain();
|
|
807
|
+
const claimRoot = typeof context?.projectRoot === "string" && context.projectRoot.length > 0 ? context.projectRoot : null;
|
|
808
|
+
if (claimRoot !== null) {
|
|
809
|
+
for (const r of relationships) {
|
|
810
|
+
if (r.type !== ASTEngine.RelationshipType.Imports && r.type !== ASTEngine.RelationshipType.Exports) continue;
|
|
811
|
+
const md = r.metadata;
|
|
812
|
+
if (!md || typeof md.importProjectFile === "string") continue;
|
|
813
|
+
const written = String(r.target ?? "");
|
|
814
|
+
const extraCandidates = [];
|
|
815
|
+
const target = written.trim();
|
|
816
|
+
if (target.length > 0 && !target.includes("://") && !target.startsWith("/")) {
|
|
817
|
+
const fileRel = path.relative(path.resolve(claimRoot), filePath).split(path.sep).join("/");
|
|
818
|
+
let rel = stripOneTrailingSlash(dirOf(fileRel));
|
|
819
|
+
while (rel.length > 0) {
|
|
820
|
+
extraCandidates.push(`${rel}/${target}`);
|
|
821
|
+
rel = stripOneTrailingSlash(dirOf(rel));
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
const claim = fileClaimForTarget({
|
|
825
|
+
projectRoot: claimRoot,
|
|
826
|
+
filePath,
|
|
827
|
+
written,
|
|
828
|
+
admittedExtensions: ["proto"],
|
|
829
|
+
extraCandidates
|
|
830
|
+
});
|
|
831
|
+
if (claim === null) {
|
|
832
|
+
const src = String(r.target ?? "");
|
|
833
|
+
if (hasPathSeparator(src) || hasUriSchemePrefix(src)) md.sourcePathClaim = [src];
|
|
834
|
+
continue;
|
|
835
|
+
}
|
|
836
|
+
md.importProjectFile = claim;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
return {
|
|
840
|
+
symbols,
|
|
841
|
+
relationships,
|
|
842
|
+
imports,
|
|
843
|
+
metadata: {
|
|
844
|
+
...syntax ? { syntax } : {},
|
|
845
|
+
...edition ? { edition } : {},
|
|
846
|
+
...pkg ? { protoPackage: pkg } : {},
|
|
847
|
+
...fileOptions.length ? { fileOptions } : {},
|
|
848
|
+
...fileRanges.length ? { fileRanges } : {},
|
|
849
|
+
// A COUNTED work measure, not a duration. `typeCache.size` is the number
|
|
850
|
+
// of distinct nodes the walk actually read, which is what a linearity
|
|
851
|
+
// claim needs: it is deterministic and load-independent, where a wall
|
|
852
|
+
// clock on a shared machine moved this lane's own ratio between 0.94 and
|
|
853
|
+
// 2.05 across runs of identical code, and exceeded its bound only when
|
|
854
|
+
// other lanes were running. A gate whose verdict depends on what else the
|
|
855
|
+
// machine is doing is not a gate.
|
|
856
|
+
visitedNodes: typeCache.size,
|
|
857
|
+
filePath,
|
|
858
|
+
symbolCount: symbols.length,
|
|
859
|
+
relationshipCount: relationships.length
|
|
860
|
+
}
|
|
861
|
+
};
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
export {
|
|
865
|
+
PROTOBUF_DECLARATION_SPEC,
|
|
866
|
+
RealProtobufAnalyzer
|
|
867
|
+
};
|