@quolu/lattice 0.70.0 → 0.71.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/bin/lattice.mjs +21 -0
- package/package.json +1 -1
- package/sensor/dist/bin/lattice-sensor.js +746 -323
- package/sensor/dist/bin/viewer-gate.d.ts +17 -0
- package/sensor/dist/bin/viewer-gate.d.ts.map +1 -0
- package/sensor/dist/bin/viewer-gate.js +31 -0
- package/sensor/dist/bin/viewer-gate.js.map +1 -0
- package/sensor/dist/context/formatter.d.ts +7 -1
- package/sensor/dist/context/formatter.d.ts.map +1 -1
- package/sensor/dist/context/formatter.js +12 -6
- package/sensor/dist/context/formatter.js.map +1 -1
- package/sensor/dist/context/index.d.ts +12 -0
- package/sensor/dist/context/index.d.ts.map +1 -1
- package/sensor/dist/context/index.js +103 -16
- package/sensor/dist/context/index.js.map +1 -1
- package/sensor/dist/db/index.d.ts +23 -2
- package/sensor/dist/db/index.d.ts.map +1 -1
- package/sensor/dist/db/index.js +109 -31
- package/sensor/dist/db/index.js.map +1 -1
- package/sensor/dist/db/migrations.d.ts +1 -1
- package/sensor/dist/db/migrations.d.ts.map +1 -1
- package/sensor/dist/db/migrations.js +68 -1
- package/sensor/dist/db/migrations.js.map +1 -1
- package/sensor/dist/db/queries.d.ts +583 -6
- package/sensor/dist/db/queries.d.ts.map +1 -1
- package/sensor/dist/db/queries.js +1425 -57
- package/sensor/dist/db/queries.js.map +1 -1
- package/sensor/dist/db/schema.sql +27 -4
- package/sensor/dist/db/sqlite-adapter.d.ts +2 -0
- package/sensor/dist/db/sqlite-adapter.d.ts.map +1 -1
- package/sensor/dist/db/sqlite-adapter.js +56 -7
- package/sensor/dist/db/sqlite-adapter.js.map +1 -1
- package/sensor/dist/db/synthesis-stage.d.ts +12 -0
- package/sensor/dist/db/synthesis-stage.d.ts.map +1 -0
- package/sensor/dist/db/synthesis-stage.js +93 -0
- package/sensor/dist/db/synthesis-stage.js.map +1 -0
- package/sensor/dist/db/wal-valve.d.ts +32 -12
- package/sensor/dist/db/wal-valve.d.ts.map +1 -1
- package/sensor/dist/db/wal-valve.js +65 -22
- package/sensor/dist/db/wal-valve.js.map +1 -1
- package/sensor/dist/db/wsl-shared-index.d.ts +53 -0
- package/sensor/dist/db/wsl-shared-index.d.ts.map +1 -0
- package/sensor/dist/db/wsl-shared-index.js +121 -0
- package/sensor/dist/db/wsl-shared-index.js.map +1 -0
- package/sensor/dist/directory.d.ts +126 -2
- package/sensor/dist/directory.d.ts.map +1 -1
- package/sensor/dist/directory.js +285 -16
- package/sensor/dist/directory.js.map +1 -1
- package/sensor/dist/errors.d.ts +14 -0
- package/sensor/dist/errors.d.ts.map +1 -1
- package/sensor/dist/errors.js +16 -1
- package/sensor/dist/errors.js.map +1 -1
- package/sensor/dist/extraction/cfml-extractor.d.ts +1 -0
- package/sensor/dist/extraction/cfml-extractor.d.ts.map +1 -1
- package/sensor/dist/extraction/cfml-extractor.js +15 -3
- package/sensor/dist/extraction/cfml-extractor.js.map +1 -1
- package/sensor/dist/extraction/dfm-extractor.d.ts.map +1 -1
- package/sensor/dist/extraction/dfm-extractor.js +14 -10
- package/sensor/dist/extraction/dfm-extractor.js.map +1 -1
- package/sensor/dist/extraction/extraction-version.d.ts +1 -1
- package/sensor/dist/extraction/extraction-version.d.ts.map +1 -1
- package/sensor/dist/extraction/extraction-version.js +3 -1
- package/sensor/dist/extraction/extraction-version.js.map +1 -1
- package/sensor/dist/extraction/function-ref.d.ts +6 -4
- package/sensor/dist/extraction/function-ref.d.ts.map +1 -1
- package/sensor/dist/extraction/function-ref.js +35 -14
- package/sensor/dist/extraction/function-ref.js.map +1 -1
- package/sensor/dist/extraction/generated-detection.d.ts +48 -12
- package/sensor/dist/extraction/generated-detection.d.ts.map +1 -1
- package/sensor/dist/extraction/generated-detection.js +176 -11
- package/sensor/dist/extraction/generated-detection.js.map +1 -1
- package/sensor/dist/extraction/grammars.d.ts +38 -0
- package/sensor/dist/extraction/grammars.d.ts.map +1 -1
- package/sensor/dist/extraction/grammars.js +115 -3
- package/sensor/dist/extraction/grammars.js.map +1 -1
- package/sensor/dist/extraction/index.d.ts +218 -14
- package/sensor/dist/extraction/index.d.ts.map +1 -1
- package/sensor/dist/extraction/index.js +887 -175
- package/sensor/dist/extraction/index.js.map +1 -1
- package/sensor/dist/extraction/languages/c-cpp.d.ts +58 -0
- package/sensor/dist/extraction/languages/c-cpp.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/c-cpp.js +310 -19
- package/sensor/dist/extraction/languages/c-cpp.js.map +1 -1
- package/sensor/dist/extraction/languages/dart.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/dart.js +8 -3
- package/sensor/dist/extraction/languages/dart.js.map +1 -1
- package/sensor/dist/extraction/languages/erlang.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/erlang.js +58 -22
- package/sensor/dist/extraction/languages/erlang.js.map +1 -1
- package/sensor/dist/extraction/languages/javascript.js +1 -1
- package/sensor/dist/extraction/languages/javascript.js.map +1 -1
- package/sensor/dist/extraction/languages/kotlin.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/kotlin.js +169 -36
- package/sensor/dist/extraction/languages/kotlin.js.map +1 -1
- package/sensor/dist/extraction/languages/lua.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/lua.js +4 -1
- package/sensor/dist/extraction/languages/lua.js.map +1 -1
- package/sensor/dist/extraction/languages/objc.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/objc.js +4 -0
- package/sensor/dist/extraction/languages/objc.js.map +1 -1
- package/sensor/dist/extraction/languages/python.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/python.js +71 -0
- package/sensor/dist/extraction/languages/python.js.map +1 -1
- package/sensor/dist/extraction/languages/rust.d.ts +20 -0
- package/sensor/dist/extraction/languages/rust.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/rust.js +50 -20
- package/sensor/dist/extraction/languages/rust.js.map +1 -1
- package/sensor/dist/extraction/languages/scala.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/scala.js +18 -3
- package/sensor/dist/extraction/languages/scala.js.map +1 -1
- package/sensor/dist/extraction/languages/swift.d.ts +15 -0
- package/sensor/dist/extraction/languages/swift.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/swift.js +50 -0
- package/sensor/dist/extraction/languages/swift.js.map +1 -1
- package/sensor/dist/extraction/languages/typescript.d.ts.map +1 -1
- package/sensor/dist/extraction/languages/typescript.js +9 -2
- package/sensor/dist/extraction/languages/typescript.js.map +1 -1
- package/sensor/dist/extraction/liquid-extractor.d.ts +18 -0
- package/sensor/dist/extraction/liquid-extractor.d.ts.map +1 -1
- package/sensor/dist/extraction/liquid-extractor.js +98 -22
- package/sensor/dist/extraction/liquid-extractor.js.map +1 -1
- package/sensor/dist/extraction/mybatis-extractor.d.ts.map +1 -1
- package/sensor/dist/extraction/mybatis-extractor.js +6 -4
- package/sensor/dist/extraction/mybatis-extractor.js.map +1 -1
- package/sensor/dist/extraction/parse-pool.d.ts +7 -0
- package/sensor/dist/extraction/parse-pool.d.ts.map +1 -1
- package/sensor/dist/extraction/parse-pool.js +20 -1
- package/sensor/dist/extraction/parse-pool.js.map +1 -1
- package/sensor/dist/extraction/syntax-tokens.d.ts +103 -0
- package/sensor/dist/extraction/syntax-tokens.d.ts.map +1 -0
- package/sensor/dist/extraction/syntax-tokens.js +381 -0
- package/sensor/dist/extraction/syntax-tokens.js.map +1 -0
- package/sensor/dist/extraction/tree-sitter-helpers.d.ts +5 -0
- package/sensor/dist/extraction/tree-sitter-helpers.d.ts.map +1 -1
- package/sensor/dist/extraction/tree-sitter-helpers.js +17 -0
- package/sensor/dist/extraction/tree-sitter-helpers.js.map +1 -1
- package/sensor/dist/extraction/tree-sitter-types.d.ts +31 -3
- package/sensor/dist/extraction/tree-sitter-types.d.ts.map +1 -1
- package/sensor/dist/extraction/tree-sitter.d.ts +101 -18
- package/sensor/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/sensor/dist/extraction/tree-sitter.js +928 -134
- package/sensor/dist/extraction/tree-sitter.js.map +1 -1
- package/sensor/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
- package/sensor/dist/file-limits.d.ts +40 -0
- package/sensor/dist/file-limits.d.ts.map +1 -0
- package/sensor/dist/file-limits.js +147 -0
- package/sensor/dist/file-limits.js.map +1 -0
- package/sensor/dist/graph/branch-guards.d.ts +265 -0
- package/sensor/dist/graph/branch-guards.d.ts.map +1 -0
- package/sensor/dist/graph/branch-guards.js +2325 -0
- package/sensor/dist/graph/branch-guards.js.map +1 -0
- package/sensor/dist/graph/dead-code.d.ts +251 -0
- package/sensor/dist/graph/dead-code.d.ts.map +1 -0
- package/sensor/dist/graph/dead-code.js +776 -0
- package/sensor/dist/graph/dead-code.js.map +1 -0
- package/sensor/dist/graph/dynamic-boundary-report.d.ts +121 -0
- package/sensor/dist/graph/dynamic-boundary-report.d.ts.map +1 -0
- package/sensor/dist/graph/dynamic-boundary-report.js +283 -0
- package/sensor/dist/graph/dynamic-boundary-report.js.map +1 -0
- package/sensor/dist/graph/index.d.ts +4 -0
- package/sensor/dist/graph/index.d.ts.map +1 -1
- package/sensor/dist/graph/index.js +16 -1
- package/sensor/dist/graph/index.js.map +1 -1
- package/sensor/dist/graph/named-symbol-flow.d.ts +125 -0
- package/sensor/dist/graph/named-symbol-flow.d.ts.map +1 -0
- package/sensor/dist/graph/named-symbol-flow.js +552 -0
- package/sensor/dist/graph/named-symbol-flow.js.map +1 -0
- package/sensor/dist/graph/queries.d.ts.map +1 -1
- package/sensor/dist/graph/queries.js +2 -0
- package/sensor/dist/graph/queries.js.map +1 -1
- package/sensor/dist/graph/symbol-lookup.d.ts +83 -0
- package/sensor/dist/graph/symbol-lookup.d.ts.map +1 -0
- package/sensor/dist/graph/symbol-lookup.js +181 -0
- package/sensor/dist/graph/symbol-lookup.js.map +1 -0
- package/sensor/dist/graph/traversal.d.ts +9 -0
- package/sensor/dist/graph/traversal.d.ts.map +1 -1
- package/sensor/dist/graph/traversal.js +62 -36
- package/sensor/dist/graph/traversal.js.map +1 -1
- package/sensor/dist/graph/type-hierarchy.d.ts +155 -0
- package/sensor/dist/graph/type-hierarchy.d.ts.map +1 -0
- package/sensor/dist/graph/type-hierarchy.js +382 -0
- package/sensor/dist/graph/type-hierarchy.js.map +1 -0
- package/sensor/dist/index.d.ts +272 -10
- package/sensor/dist/index.d.ts.map +1 -1
- package/sensor/dist/index.js +510 -34
- package/sensor/dist/index.js.map +1 -1
- package/sensor/dist/mcp/answer-freshness.d.ts +10 -0
- package/sensor/dist/mcp/answer-freshness.d.ts.map +1 -0
- package/sensor/dist/mcp/answer-freshness.js +68 -0
- package/sensor/dist/mcp/answer-freshness.js.map +1 -0
- package/sensor/dist/mcp/daemon-manager.d.ts +1 -1
- package/sensor/dist/mcp/daemon-manager.d.ts.map +1 -1
- package/sensor/dist/mcp/daemon-manager.js +17 -1
- package/sensor/dist/mcp/daemon-manager.js.map +1 -1
- package/sensor/dist/mcp/daemon-paths.d.ts +8 -0
- package/sensor/dist/mcp/daemon-paths.d.ts.map +1 -1
- package/sensor/dist/mcp/daemon-paths.js +65 -2
- package/sensor/dist/mcp/daemon-paths.js.map +1 -1
- package/sensor/dist/mcp/daemon-registry.d.ts +17 -4
- package/sensor/dist/mcp/daemon-registry.d.ts.map +1 -1
- package/sensor/dist/mcp/daemon-registry.js +133 -23
- package/sensor/dist/mcp/daemon-registry.js.map +1 -1
- package/sensor/dist/mcp/daemon.d.ts +26 -13
- package/sensor/dist/mcp/daemon.d.ts.map +1 -1
- package/sensor/dist/mcp/daemon.js +126 -32
- package/sensor/dist/mcp/daemon.js.map +1 -1
- package/sensor/dist/mcp/dynamic-boundaries.d.ts +1 -10
- package/sensor/dist/mcp/dynamic-boundaries.d.ts.map +1 -1
- package/sensor/dist/mcp/dynamic-boundaries.js +46 -42
- package/sensor/dist/mcp/dynamic-boundaries.js.map +1 -1
- package/sensor/dist/mcp/engine.d.ts +31 -9
- package/sensor/dist/mcp/engine.d.ts.map +1 -1
- package/sensor/dist/mcp/engine.js +190 -79
- package/sensor/dist/mcp/engine.js.map +1 -1
- package/sensor/dist/mcp/explore-dedup.d.ts +140 -0
- package/sensor/dist/mcp/explore-dedup.d.ts.map +1 -0
- package/sensor/dist/mcp/explore-dedup.js +239 -0
- package/sensor/dist/mcp/explore-dedup.js.map +1 -0
- package/sensor/dist/mcp/explore-diagnostics.d.ts +289 -0
- package/sensor/dist/mcp/explore-diagnostics.d.ts.map +1 -0
- package/sensor/dist/mcp/explore-diagnostics.js +558 -0
- package/sensor/dist/mcp/explore-diagnostics.js.map +1 -0
- package/sensor/dist/mcp/explore-session-state.d.ts +217 -0
- package/sensor/dist/mcp/explore-session-state.d.ts.map +1 -0
- package/sensor/dist/mcp/explore-session-state.js +322 -0
- package/sensor/dist/mcp/explore-session-state.js.map +1 -0
- package/sensor/dist/mcp/index-freshness-worker.d.ts +2 -0
- package/sensor/dist/mcp/index-freshness-worker.d.ts.map +1 -0
- package/sensor/dist/mcp/index-freshness-worker.js +30 -0
- package/sensor/dist/mcp/index-freshness-worker.js.map +1 -0
- package/sensor/dist/mcp/index-freshness.d.ts +7 -0
- package/sensor/dist/mcp/index-freshness.d.ts.map +1 -0
- package/sensor/dist/mcp/index-freshness.js +94 -0
- package/sensor/dist/mcp/index-freshness.js.map +1 -0
- package/sensor/dist/mcp/index.d.ts +3 -1
- package/sensor/dist/mcp/index.d.ts.map +1 -1
- package/sensor/dist/mcp/index.js +109 -12
- package/sensor/dist/mcp/index.js.map +1 -1
- package/sensor/dist/mcp/liveness-watchdog.d.ts +4 -1
- package/sensor/dist/mcp/liveness-watchdog.d.ts.map +1 -1
- package/sensor/dist/mcp/liveness-watchdog.js +11 -2
- package/sensor/dist/mcp/liveness-watchdog.js.map +1 -1
- package/sensor/dist/mcp/project-lifecycle.d.ts +9 -0
- package/sensor/dist/mcp/project-lifecycle.d.ts.map +1 -0
- package/sensor/dist/mcp/project-lifecycle.js +182 -0
- package/sensor/dist/mcp/project-lifecycle.js.map +1 -0
- package/sensor/dist/mcp/proxy.d.ts.map +1 -1
- package/sensor/dist/mcp/proxy.js +15 -1
- package/sensor/dist/mcp/proxy.js.map +1 -1
- package/sensor/dist/mcp/query-pool.d.ts +2 -2
- package/sensor/dist/mcp/query-pool.d.ts.map +1 -1
- package/sensor/dist/mcp/query-pool.js +9 -7
- package/sensor/dist/mcp/query-pool.js.map +1 -1
- package/sensor/dist/mcp/query-worker.js +2 -2
- package/sensor/dist/mcp/query-worker.js.map +1 -1
- package/sensor/dist/mcp/server-instructions.d.ts +2 -2
- package/sensor/dist/mcp/server-instructions.d.ts.map +1 -1
- package/sensor/dist/mcp/server-instructions.js +13 -6
- package/sensor/dist/mcp/server-instructions.js.map +1 -1
- package/sensor/dist/mcp/session.d.ts +16 -0
- package/sensor/dist/mcp/session.d.ts.map +1 -1
- package/sensor/dist/mcp/session.js +36 -13
- package/sensor/dist/mcp/session.js.map +1 -1
- package/sensor/dist/mcp/startup-handshake.d.ts +3 -1
- package/sensor/dist/mcp/startup-handshake.d.ts.map +1 -1
- package/sensor/dist/mcp/startup-handshake.js +10 -2
- package/sensor/dist/mcp/startup-handshake.js.map +1 -1
- package/sensor/dist/mcp/tools.d.ts +496 -38
- package/sensor/dist/mcp/tools.d.ts.map +1 -1
- package/sensor/dist/mcp/tools.js +4021 -772
- package/sensor/dist/mcp/tools.js.map +1 -1
- package/sensor/dist/mcp/writer-lock.d.ts +61 -0
- package/sensor/dist/mcp/writer-lock.d.ts.map +1 -0
- package/sensor/dist/mcp/writer-lock.js +260 -0
- package/sensor/dist/mcp/writer-lock.js.map +1 -0
- package/sensor/dist/project-config.d.ts +23 -0
- package/sensor/dist/project-config.d.ts.map +1 -1
- package/sensor/dist/project-config.js +39 -2
- package/sensor/dist/project-config.js.map +1 -1
- package/sensor/dist/resolution/alias-binding.d.ts +56 -0
- package/sensor/dist/resolution/alias-binding.d.ts.map +1 -0
- package/sensor/dist/resolution/alias-binding.js +127 -0
- package/sensor/dist/resolution/alias-binding.js.map +1 -0
- package/sensor/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
- package/sensor/dist/resolution/c-fnptr-synthesizer.js +21 -19
- package/sensor/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
- package/sensor/dist/resolution/callback-synthesizer.d.ts +23 -1
- package/sensor/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/sensor/dist/resolution/callback-synthesizer.js +356 -155
- package/sensor/dist/resolution/callback-synthesizer.js.map +1 -1
- package/sensor/dist/resolution/cpp-constructor.d.ts +4 -0
- package/sensor/dist/resolution/cpp-constructor.d.ts.map +1 -0
- package/sensor/dist/resolution/cpp-constructor.js +123 -0
- package/sensor/dist/resolution/cpp-constructor.js.map +1 -0
- package/sensor/dist/resolution/cpp-macro-visibility.d.ts +12 -0
- package/sensor/dist/resolution/cpp-macro-visibility.d.ts.map +1 -0
- package/sensor/dist/resolution/cpp-macro-visibility.js +342 -0
- package/sensor/dist/resolution/cpp-macro-visibility.js.map +1 -0
- package/sensor/dist/resolution/expo-router-synthesizer.d.ts +32 -0
- package/sensor/dist/resolution/expo-router-synthesizer.d.ts.map +1 -0
- package/sensor/dist/resolution/expo-router-synthesizer.js +189 -0
- package/sensor/dist/resolution/expo-router-synthesizer.js.map +1 -0
- package/sensor/dist/resolution/frameworks/csharp.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/csharp.js +96 -2
- package/sensor/dist/resolution/frameworks/csharp.js.map +1 -1
- package/sensor/dist/resolution/frameworks/expo-router.d.ts +189 -0
- package/sensor/dist/resolution/frameworks/expo-router.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/expo-router.js +785 -0
- package/sensor/dist/resolution/frameworks/expo-router.js.map +1 -0
- package/sensor/dist/resolution/frameworks/express.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/express.js +251 -16
- package/sensor/dist/resolution/frameworks/express.js.map +1 -1
- package/sensor/dist/resolution/frameworks/index.d.ts +5 -0
- package/sensor/dist/resolution/frameworks/index.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/index.js +29 -1
- package/sensor/dist/resolution/frameworks/index.js.map +1 -1
- package/sensor/dist/resolution/frameworks/java.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/java.js +79 -47
- package/sensor/dist/resolution/frameworks/java.js.map +1 -1
- package/sensor/dist/resolution/frameworks/laravel.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/laravel.js +294 -4
- package/sensor/dist/resolution/frameworks/laravel.js.map +1 -1
- package/sensor/dist/resolution/frameworks/nestjs.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/nestjs.js +6 -14
- package/sensor/dist/resolution/frameworks/nestjs.js.map +1 -1
- package/sensor/dist/resolution/frameworks/nextjs.d.ts +76 -0
- package/sensor/dist/resolution/frameworks/nextjs.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/nextjs.js +328 -0
- package/sensor/dist/resolution/frameworks/nextjs.js.map +1 -0
- package/sensor/dist/resolution/frameworks/object-literal.d.ts +32 -0
- package/sensor/dist/resolution/frameworks/object-literal.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/object-literal.js +139 -0
- package/sensor/dist/resolution/frameworks/object-literal.js.map +1 -0
- package/sensor/dist/resolution/frameworks/package-deps.d.ts +14 -0
- package/sensor/dist/resolution/frameworks/package-deps.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/package-deps.js +78 -0
- package/sensor/dist/resolution/frameworks/package-deps.js.map +1 -0
- package/sensor/dist/resolution/frameworks/python.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/python.js +166 -0
- package/sensor/dist/resolution/frameworks/python.js.map +1 -1
- package/sensor/dist/resolution/frameworks/react-native.d.ts +26 -0
- package/sensor/dist/resolution/frameworks/react-native.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/react-native.js +153 -14
- package/sensor/dist/resolution/frameworks/react-native.js.map +1 -1
- package/sensor/dist/resolution/frameworks/react-router.d.ts +46 -0
- package/sensor/dist/resolution/frameworks/react-router.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/react-router.js +187 -0
- package/sensor/dist/resolution/frameworks/react-router.js.map +1 -0
- package/sensor/dist/resolution/frameworks/react.d.ts +2 -1
- package/sensor/dist/resolution/frameworks/react.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/react.js +188 -139
- package/sensor/dist/resolution/frameworks/react.js.map +1 -1
- package/sensor/dist/resolution/frameworks/svelte.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/svelte.js +6 -1
- package/sensor/dist/resolution/frameworks/svelte.js.map +1 -1
- package/sensor/dist/resolution/frameworks/sveltekit-router.d.ts +36 -0
- package/sensor/dist/resolution/frameworks/sveltekit-router.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/sveltekit-router.js +156 -0
- package/sensor/dist/resolution/frameworks/sveltekit-router.js.map +1 -0
- package/sensor/dist/resolution/frameworks/swift.d.ts.map +1 -1
- package/sensor/dist/resolution/frameworks/swift.js +140 -99
- package/sensor/dist/resolution/frameworks/swift.js.map +1 -1
- package/sensor/dist/resolution/frameworks/tanstack-router.d.ts +84 -0
- package/sensor/dist/resolution/frameworks/tanstack-router.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/tanstack-router.js +437 -0
- package/sensor/dist/resolution/frameworks/tanstack-router.js.map +1 -0
- package/sensor/dist/resolution/frameworks/vue-router.d.ts +82 -0
- package/sensor/dist/resolution/frameworks/vue-router.d.ts.map +1 -0
- package/sensor/dist/resolution/frameworks/vue-router.js +377 -0
- package/sensor/dist/resolution/frameworks/vue-router.js.map +1 -0
- package/sensor/dist/resolution/import-resolver.d.ts +38 -0
- package/sensor/dist/resolution/import-resolver.d.ts.map +1 -1
- package/sensor/dist/resolution/import-resolver.js +394 -28
- package/sensor/dist/resolution/import-resolver.js.map +1 -1
- package/sensor/dist/resolution/index.d.ts +89 -25
- package/sensor/dist/resolution/index.d.ts.map +1 -1
- package/sensor/dist/resolution/index.js +573 -148
- package/sensor/dist/resolution/index.js.map +1 -1
- package/sensor/dist/resolution/js-builtins.d.ts +13 -0
- package/sensor/dist/resolution/js-builtins.d.ts.map +1 -0
- package/sensor/dist/resolution/js-builtins.js +46 -0
- package/sensor/dist/resolution/js-builtins.js.map +1 -0
- package/sensor/dist/resolution/name-matcher.d.ts +99 -22
- package/sensor/dist/resolution/name-matcher.d.ts.map +1 -1
- package/sensor/dist/resolution/name-matcher.js +2220 -86
- package/sensor/dist/resolution/name-matcher.js.map +1 -1
- package/sensor/dist/resolution/next-router-synthesizer.d.ts +27 -0
- package/sensor/dist/resolution/next-router-synthesizer.d.ts.map +1 -0
- package/sensor/dist/resolution/next-router-synthesizer.js +113 -0
- package/sensor/dist/resolution/next-router-synthesizer.js.map +1 -0
- package/sensor/dist/resolution/path-aliases.d.ts +6 -4
- package/sensor/dist/resolution/path-aliases.d.ts.map +1 -1
- package/sensor/dist/resolution/path-aliases.js +125 -17
- package/sensor/dist/resolution/path-aliases.js.map +1 -1
- package/sensor/dist/resolution/react-router-synthesizer.d.ts +33 -0
- package/sensor/dist/resolution/react-router-synthesizer.d.ts.map +1 -0
- package/sensor/dist/resolution/react-router-synthesizer.js +126 -0
- package/sensor/dist/resolution/react-router-synthesizer.js.map +1 -0
- package/sensor/dist/resolution/resolver-pool.d.ts +2 -0
- package/sensor/dist/resolution/resolver-pool.d.ts.map +1 -1
- package/sensor/dist/resolution/resolver-pool.js +4 -0
- package/sensor/dist/resolution/resolver-pool.js.map +1 -1
- package/sensor/dist/resolution/strip-comments.d.ts +6 -0
- package/sensor/dist/resolution/strip-comments.d.ts.map +1 -1
- package/sensor/dist/resolution/strip-comments.js +58 -0
- package/sensor/dist/resolution/strip-comments.js.map +1 -1
- package/sensor/dist/resolution/sveltekit-synthesizer.d.ts +58 -0
- package/sensor/dist/resolution/sveltekit-synthesizer.d.ts.map +1 -0
- package/sensor/dist/resolution/sveltekit-synthesizer.js +173 -0
- package/sensor/dist/resolution/sveltekit-synthesizer.js.map +1 -0
- package/sensor/dist/resolution/swift-type-visibility.d.ts +52 -0
- package/sensor/dist/resolution/swift-type-visibility.d.ts.map +1 -0
- package/sensor/dist/resolution/swift-type-visibility.js +328 -0
- package/sensor/dist/resolution/swift-type-visibility.js.map +1 -0
- package/sensor/dist/resolution/synth-utils.d.ts +26 -0
- package/sensor/dist/resolution/synth-utils.d.ts.map +1 -0
- package/sensor/dist/resolution/synth-utils.js +75 -0
- package/sensor/dist/resolution/synth-utils.js.map +1 -0
- package/sensor/dist/resolution/tanstack-router-synthesizer.d.ts +31 -0
- package/sensor/dist/resolution/tanstack-router-synthesizer.d.ts.map +1 -0
- package/sensor/dist/resolution/tanstack-router-synthesizer.js +114 -0
- package/sensor/dist/resolution/tanstack-router-synthesizer.js.map +1 -0
- package/sensor/dist/resolution/tier-synthesizer.d.ts +54 -0
- package/sensor/dist/resolution/tier-synthesizer.d.ts.map +1 -0
- package/sensor/dist/resolution/tier-synthesizer.js +1294 -0
- package/sensor/dist/resolution/tier-synthesizer.js.map +1 -0
- package/sensor/dist/resolution/types.d.ts +78 -2
- package/sensor/dist/resolution/types.d.ts.map +1 -1
- package/sensor/dist/resolution/types.js +64 -0
- package/sensor/dist/resolution/types.js.map +1 -1
- package/sensor/dist/resolution/vue-router-synthesizer.d.ts +30 -0
- package/sensor/dist/resolution/vue-router-synthesizer.d.ts.map +1 -0
- package/sensor/dist/resolution/vue-router-synthesizer.js +115 -0
- package/sensor/dist/resolution/vue-router-synthesizer.js.map +1 -0
- package/sensor/dist/search/identifier-segments.d.ts +10 -0
- package/sensor/dist/search/identifier-segments.d.ts.map +1 -1
- package/sensor/dist/search/identifier-segments.js +29 -0
- package/sensor/dist/search/identifier-segments.js.map +1 -1
- package/sensor/dist/search/query-paths.d.ts +106 -0
- package/sensor/dist/search/query-paths.d.ts.map +1 -0
- package/sensor/dist/search/query-paths.js +513 -0
- package/sensor/dist/search/query-paths.js.map +1 -0
- package/sensor/dist/search/query-utils.d.ts +22 -2
- package/sensor/dist/search/query-utils.d.ts.map +1 -1
- package/sensor/dist/search/query-utils.js +56 -16
- package/sensor/dist/search/query-utils.js.map +1 -1
- package/sensor/dist/sync/watch-policy.d.ts +14 -0
- package/sensor/dist/sync/watch-policy.d.ts.map +1 -1
- package/sensor/dist/sync/watch-policy.js +19 -0
- package/sensor/dist/sync/watch-policy.js.map +1 -1
- package/sensor/dist/sync/watcher.d.ts +74 -35
- package/sensor/dist/sync/watcher.d.ts.map +1 -1
- package/sensor/dist/sync/watcher.js +281 -99
- package/sensor/dist/sync/watcher.js.map +1 -1
- package/sensor/dist/telemetry/index.d.ts +4 -2
- package/sensor/dist/telemetry/index.d.ts.map +1 -1
- package/sensor/dist/telemetry/index.js +92 -41
- package/sensor/dist/telemetry/index.js.map +1 -1
- package/sensor/dist/types.d.ts +18 -2
- package/sensor/dist/types.d.ts.map +1 -1
- package/sensor/dist/types.js +2 -0
- package/sensor/dist/types.js.map +1 -1
- package/sensor/dist/ui-server/api/deadcode.d.ts +84 -0
- package/sensor/dist/ui-server/api/deadcode.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/deadcode.js +136 -0
- package/sensor/dist/ui-server/api/deadcode.js.map +1 -0
- package/sensor/dist/ui-server/api/effects.d.ts +94 -0
- package/sensor/dist/ui-server/api/effects.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/effects.js +527 -0
- package/sensor/dist/ui-server/api/effects.js.map +1 -0
- package/sensor/dist/ui-server/api/entrypoints.d.ts +92 -0
- package/sensor/dist/ui-server/api/entrypoints.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/entrypoints.js +361 -0
- package/sensor/dist/ui-server/api/entrypoints.js.map +1 -0
- package/sensor/dist/ui-server/api/events.d.ts +183 -0
- package/sensor/dist/ui-server/api/events.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/events.js +430 -0
- package/sensor/dist/ui-server/api/events.js.map +1 -0
- package/sensor/dist/ui-server/api/file.d.ts +66 -0
- package/sensor/dist/ui-server/api/file.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/file.js +235 -0
- package/sensor/dist/ui-server/api/file.js.map +1 -0
- package/sensor/dist/ui-server/api/filecode.d.ts +126 -0
- package/sensor/dist/ui-server/api/filecode.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/filecode.js +205 -0
- package/sensor/dist/ui-server/api/filecode.js.map +1 -0
- package/sensor/dist/ui-server/api/flow.d.ts +226 -0
- package/sensor/dist/ui-server/api/flow.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/flow.js +612 -0
- package/sensor/dist/ui-server/api/flow.js.map +1 -0
- package/sensor/dist/ui-server/api/hierarchy.d.ts +81 -0
- package/sensor/dist/ui-server/api/hierarchy.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/hierarchy.js +92 -0
- package/sensor/dist/ui-server/api/hierarchy.js.map +1 -0
- package/sensor/dist/ui-server/api/index.d.ts +90 -0
- package/sensor/dist/ui-server/api/index.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/index.js +332 -0
- package/sensor/dist/ui-server/api/index.js.map +1 -0
- package/sensor/dist/ui-server/api/map.d.ts +256 -0
- package/sensor/dist/ui-server/api/map.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/map.js +760 -0
- package/sensor/dist/ui-server/api/map.js.map +1 -0
- package/sensor/dist/ui-server/api/node.d.ts +81 -0
- package/sensor/dist/ui-server/api/node.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/node.js +388 -0
- package/sensor/dist/ui-server/api/node.js.map +1 -0
- package/sensor/dist/ui-server/api/nodes.d.ts +25 -0
- package/sensor/dist/ui-server/api/nodes.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/nodes.js +45 -0
- package/sensor/dist/ui-server/api/nodes.js.map +1 -0
- package/sensor/dist/ui-server/api/program.d.ts +139 -0
- package/sensor/dist/ui-server/api/program.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/program.js +315 -0
- package/sensor/dist/ui-server/api/program.js.map +1 -0
- package/sensor/dist/ui-server/api/respond.d.ts +76 -0
- package/sensor/dist/ui-server/api/respond.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/respond.js +186 -0
- package/sensor/dist/ui-server/api/respond.js.map +1 -0
- package/sensor/dist/ui-server/api/route-roots.d.ts +39 -0
- package/sensor/dist/ui-server/api/route-roots.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/route-roots.js +96 -0
- package/sensor/dist/ui-server/api/route-roots.js.map +1 -0
- package/sensor/dist/ui-server/api/routes.d.ts +59 -0
- package/sensor/dist/ui-server/api/routes.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/routes.js +108 -0
- package/sensor/dist/ui-server/api/routes.js.map +1 -0
- package/sensor/dist/ui-server/api/screens.d.ts +117 -0
- package/sensor/dist/ui-server/api/screens.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/screens.js +611 -0
- package/sensor/dist/ui-server/api/screens.js.map +1 -0
- package/sensor/dist/ui-server/api/search.d.ts +29 -0
- package/sensor/dist/ui-server/api/search.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/search.js +232 -0
- package/sensor/dist/ui-server/api/search.js.map +1 -0
- package/sensor/dist/ui-server/api/session.d.ts +52 -0
- package/sensor/dist/ui-server/api/session.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/session.js +196 -0
- package/sensor/dist/ui-server/api/session.js.map +1 -0
- package/sensor/dist/ui-server/api/source.d.ts +200 -0
- package/sensor/dist/ui-server/api/source.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/source.js +422 -0
- package/sensor/dist/ui-server/api/source.js.map +1 -0
- package/sensor/dist/ui-server/api/stats.d.ts +27 -0
- package/sensor/dist/ui-server/api/stats.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/stats.js +164 -0
- package/sensor/dist/ui-server/api/stats.js.map +1 -0
- package/sensor/dist/ui-server/api/steps.d.ts +274 -0
- package/sensor/dist/ui-server/api/steps.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/steps.js +1544 -0
- package/sensor/dist/ui-server/api/steps.js.map +1 -0
- package/sensor/dist/ui-server/api/trail-store.d.ts +142 -0
- package/sensor/dist/ui-server/api/trail-store.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/trail-store.js +325 -0
- package/sensor/dist/ui-server/api/trail-store.js.map +1 -0
- package/sensor/dist/ui-server/api/trails.d.ts +163 -0
- package/sensor/dist/ui-server/api/trails.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/trails.js +369 -0
- package/sensor/dist/ui-server/api/trails.js.map +1 -0
- package/sensor/dist/ui-server/api/when.d.ts +133 -0
- package/sensor/dist/ui-server/api/when.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/when.js +275 -0
- package/sensor/dist/ui-server/api/when.js.map +1 -0
- package/sensor/dist/ui-server/api/wire.d.ts +179 -0
- package/sensor/dist/ui-server/api/wire.d.ts.map +1 -0
- package/sensor/dist/ui-server/api/wire.js +231 -0
- package/sensor/dist/ui-server/api/wire.js.map +1 -0
- package/sensor/dist/ui-server/assets.d.ts +40 -0
- package/sensor/dist/ui-server/assets.d.ts.map +1 -0
- package/sensor/dist/ui-server/assets.js +110 -0
- package/sensor/dist/ui-server/assets.js.map +1 -0
- package/sensor/dist/ui-server/constants.d.ts +32 -0
- package/sensor/dist/ui-server/constants.d.ts.map +1 -0
- package/sensor/dist/ui-server/constants.js +35 -0
- package/sensor/dist/ui-server/constants.js.map +1 -0
- package/sensor/dist/ui-server/highlight/index.d.ts +113 -0
- package/sensor/dist/ui-server/highlight/index.d.ts.map +1 -0
- package/sensor/dist/ui-server/highlight/index.js +307 -0
- package/sensor/dist/ui-server/highlight/index.js.map +1 -0
- package/sensor/dist/ui-server/highlight/languages.d.ts +36 -0
- package/sensor/dist/ui-server/highlight/languages.d.ts.map +1 -0
- package/sensor/dist/ui-server/highlight/languages.js +50 -0
- package/sensor/dist/ui-server/highlight/languages.js.map +1 -0
- package/sensor/dist/ui-server/index.d.ts +92 -0
- package/sensor/dist/ui-server/index.d.ts.map +1 -0
- package/sensor/dist/ui-server/index.js +399 -0
- package/sensor/dist/ui-server/index.js.map +1 -0
- package/sensor/dist/ui-server/open-browser.d.ts +31 -0
- package/sensor/dist/ui-server/open-browser.d.ts.map +1 -0
- package/sensor/dist/ui-server/open-browser.js +79 -0
- package/sensor/dist/ui-server/open-browser.js.map +1 -0
- package/sensor/dist/ui-server/security.d.ts +127 -0
- package/sensor/dist/ui-server/security.d.ts.map +1 -0
- package/sensor/dist/ui-server/security.js +332 -0
- package/sensor/dist/ui-server/security.js.map +1 -0
- package/sensor/dist/ui-server/static.d.ts +45 -0
- package/sensor/dist/ui-server/static.d.ts.map +1 -0
- package/sensor/dist/ui-server/static.js +165 -0
- package/sensor/dist/ui-server/static.js.map +1 -0
- package/sensor/dist/utils.d.ts +14 -2
- package/sensor/dist/utils.d.ts.map +1 -1
- package/sensor/dist/utils.js +25 -10
- package/sensor/dist/utils.js.map +1 -1
- package/src/sensor-adapter.mjs +5 -1
|
@@ -45,21 +45,41 @@ exports.ReferenceResolver = void 0;
|
|
|
45
45
|
exports.createResolver = createResolver;
|
|
46
46
|
const fs = __importStar(require("fs"));
|
|
47
47
|
const path = __importStar(require("path"));
|
|
48
|
+
const synthesis_stage_1 = require("../db/synthesis-stage");
|
|
49
|
+
const types_1 = require("./types");
|
|
48
50
|
const name_matcher_1 = require("./name-matcher");
|
|
51
|
+
const cpp_macro_visibility_1 = require("./cpp-macro-visibility");
|
|
52
|
+
const cpp_constructor_1 = require("./cpp-constructor");
|
|
53
|
+
const swift_type_visibility_1 = require("./swift-type-visibility");
|
|
49
54
|
const import_resolver_1 = require("./import-resolver");
|
|
50
55
|
const resolver_pool_1 = require("./resolver-pool");
|
|
56
|
+
const alias_binding_1 = require("./alias-binding");
|
|
51
57
|
const frameworks_1 = require("./frameworks");
|
|
52
58
|
const callback_synthesizer_1 = require("./callback-synthesizer");
|
|
53
59
|
const cooperative_yield_1 = require("./cooperative-yield");
|
|
60
|
+
const file_limits_1 = require("../file-limits");
|
|
54
61
|
const path_aliases_1 = require("./path-aliases");
|
|
55
62
|
const go_module_1 = require("./go-module");
|
|
56
63
|
const workspace_packages_1 = require("./workspace-packages");
|
|
57
64
|
const errors_1 = require("../errors");
|
|
65
|
+
const utils_1 = require("../utils");
|
|
58
66
|
const lru_cache_1 = require("./lru-cache");
|
|
67
|
+
const js_builtins_1 = require("./js-builtins");
|
|
59
68
|
/** Node kinds that can declare supertypes (extends/implements). */
|
|
60
69
|
const SUPERTYPE_BEARING_KINDS = new Set([
|
|
61
70
|
'class', 'struct', 'interface', 'trait', 'protocol', 'enum',
|
|
62
71
|
]);
|
|
72
|
+
/**
|
|
73
|
+
* The only edges resolving a reference reads (getSupertypes' walk). The batch
|
|
74
|
+
* loop commits a batch that made any of these before the next batch fans out;
|
|
75
|
+
* its other edges land while that batch resolves. A resolution strategy that
|
|
76
|
+
* reads another edge kind must be added here.
|
|
77
|
+
*/
|
|
78
|
+
const RESOLUTION_READ_EDGE_KINDS = ['implements', 'extends'];
|
|
79
|
+
// SUPERTYPE_TARGET_KINDS (the kinds an extends/implements edge may TARGET)
|
|
80
|
+
// lives in ./types — the name-matcher needs the same set to restrict its
|
|
81
|
+
// candidate pool before ranking. It is deliberately wider than
|
|
82
|
+
// SUPERTYPE_BEARING_KINDS above, which is about the DECLARING side.
|
|
63
83
|
/**
|
|
64
84
|
* Languages whose chained static-factory/fluent calls defer to the conformance
|
|
65
85
|
* second pass. Dotted-receiver languages resolve via matchDottedCallChain; the
|
|
@@ -109,13 +129,6 @@ function resolveCacheLimit() {
|
|
|
109
129
|
// Re-export types
|
|
110
130
|
__exportStar(require("./types"), exports);
|
|
111
131
|
// Pre-built Sets for O(1) built-in lookups (allocated once, shared across all instances)
|
|
112
|
-
const JS_BUILT_INS = new Set([
|
|
113
|
-
'console', 'window', 'document', 'global', 'process',
|
|
114
|
-
'Promise', 'Array', 'Object', 'String', 'Number', 'Boolean',
|
|
115
|
-
'Date', 'Math', 'JSON', 'RegExp', 'Error', 'Map', 'Set',
|
|
116
|
-
'setTimeout', 'setInterval', 'clearTimeout', 'clearInterval',
|
|
117
|
-
'fetch', 'require', 'module', 'exports', '__dirname', '__filename',
|
|
118
|
-
]);
|
|
119
132
|
const REACT_HOOKS = new Set([
|
|
120
133
|
'useState', 'useEffect', 'useContext', 'useReducer', 'useCallback',
|
|
121
134
|
'useMemo', 'useRef', 'useLayoutEffect', 'useImperativeHandle', 'useDebugValue',
|
|
@@ -236,8 +249,9 @@ class ReferenceResolver {
|
|
|
236
249
|
context;
|
|
237
250
|
frameworks = [];
|
|
238
251
|
// Chained static-factory/fluent call refs the first pass couldn't resolve,
|
|
239
|
-
// collected in-memory
|
|
240
|
-
//
|
|
252
|
+
// collected in-memory and left pending in the DB until the post-pass
|
|
253
|
+
// finishes, so a restart can recover the queue (#1577). Drained by
|
|
254
|
+
// resolveChainedCallsViaConformance
|
|
241
255
|
// once implements/extends edges exist, to resolve methods on a supertype the
|
|
242
256
|
// receiver conforms to (#750).
|
|
243
257
|
deferredChainRefs = [];
|
|
@@ -246,6 +260,7 @@ class ReferenceResolver {
|
|
|
246
260
|
// same reason as deferredChainRefs and drained by
|
|
247
261
|
// resolveDeferredThisMemberRefs once implements/extends edges exist (#808).
|
|
248
262
|
deferredThisMemberRefs = [];
|
|
263
|
+
deferredRowIds = new Set();
|
|
249
264
|
// Per-`.razor`/`.cshtml`-file `@using` namespace set (own directives + folder
|
|
250
265
|
// `_Imports.razor`, cascading to the project root). Used to disambiguate a
|
|
251
266
|
// markup type ref to the right C# namespace.
|
|
@@ -261,6 +276,12 @@ class ReferenceResolver {
|
|
|
261
276
|
lowerNameCache; // lower(name) → nodes cache
|
|
262
277
|
qualifiedNameCache; // qualified_name → nodes cache
|
|
263
278
|
fileLinesCache; // file → split lines cache
|
|
279
|
+
// id → node for the resolver's own point reads. Every resolved reference
|
|
280
|
+
// re-reads its target a few times (kind gate, language gate, alias
|
|
281
|
+
// following, edge creation) and targets recur ~5× on large repos; the query
|
|
282
|
+
// layer's cache is too small for that working set. Same stable window as the
|
|
283
|
+
// name caches above; absent ids are not cached.
|
|
284
|
+
nodeByIdCache;
|
|
264
285
|
methodMatchCache; // lang\0Type::method → matching method nodes
|
|
265
286
|
// Per-(language, methodName) owner index for getMethodMatches: buckets a
|
|
266
287
|
// method name's candidates by their qualifiedName's last two segments so a
|
|
@@ -297,6 +318,8 @@ class ReferenceResolver {
|
|
|
297
318
|
// resolution pass (same lifetime assumption as nameCache); clearCaches() resets
|
|
298
319
|
// it between passes. Callers must treat the returned array as read-only.
|
|
299
320
|
nodesByKindCache = new Map();
|
|
321
|
+
// Filesystem existence probes behind context.fileExists (paths not in knownFiles).
|
|
322
|
+
fileExistsMemo = new Map();
|
|
300
323
|
knownNames = null; // all known symbol names for fast pre-filtering
|
|
301
324
|
knownFiles = null;
|
|
302
325
|
cachesWarmed = false;
|
|
@@ -325,6 +348,7 @@ class ReferenceResolver {
|
|
|
325
348
|
// Split-lines arrays are heavier than content strings; refs arrive
|
|
326
349
|
// file-ordered, so a small cache still hits nearly always.
|
|
327
350
|
this.fileLinesCache = new lru_cache_1.LRUCache(contentLimit);
|
|
351
|
+
this.nodeByIdCache = new lru_cache_1.LRUCache(Math.max(limit * 4, 20_000));
|
|
328
352
|
this.methodMatchCache = new lru_cache_1.LRUCache(limit);
|
|
329
353
|
this.context = this.createContext();
|
|
330
354
|
}
|
|
@@ -403,6 +427,16 @@ class ReferenceResolver {
|
|
|
403
427
|
this.knownNames = names;
|
|
404
428
|
this.cachesWarmed = true;
|
|
405
429
|
}
|
|
430
|
+
/** `queries.getNodeById` through the resolver's own id → node cache. */
|
|
431
|
+
nodeById(id) {
|
|
432
|
+
const cached = this.nodeByIdCache.get(id);
|
|
433
|
+
if (cached !== undefined)
|
|
434
|
+
return cached;
|
|
435
|
+
const node = this.queries.getNodeById(id);
|
|
436
|
+
if (node)
|
|
437
|
+
this.nodeByIdCache.set(id, node);
|
|
438
|
+
return node;
|
|
439
|
+
}
|
|
406
440
|
/**
|
|
407
441
|
* Clear internal caches
|
|
408
442
|
*/
|
|
@@ -415,11 +449,13 @@ class ReferenceResolver {
|
|
|
415
449
|
this.lowerNameCache.clear();
|
|
416
450
|
this.qualifiedNameCache.clear();
|
|
417
451
|
this.fileLinesCache.clear();
|
|
452
|
+
this.nodeByIdCache.clear();
|
|
418
453
|
this.methodMatchCache.clear();
|
|
419
454
|
this.methodOwnerIndexCache.clear();
|
|
420
455
|
this.supertypeMemo.clear();
|
|
421
456
|
this.supertypeGen++;
|
|
422
457
|
this.nodesByKindCache.clear();
|
|
458
|
+
this.fileExistsMemo.clear();
|
|
423
459
|
this.knownNames = null;
|
|
424
460
|
this.knownFiles = null;
|
|
425
461
|
this.cachesWarmed = false;
|
|
@@ -428,6 +464,8 @@ class ReferenceResolver {
|
|
|
428
464
|
if (this.context) {
|
|
429
465
|
(0, import_resolver_1.clearImportResolverMemos)(this.context);
|
|
430
466
|
(0, name_matcher_1.clearNameMatcherMemos)(this.context);
|
|
467
|
+
(0, cpp_macro_visibility_1.clearCppMacroVisibility)(this.context);
|
|
468
|
+
(0, swift_type_visibility_1.clearSwiftTypeVisibility)(this.context);
|
|
431
469
|
}
|
|
432
470
|
}
|
|
433
471
|
/** `readFile` through the LRU content cache (null = read failed, also cached). */
|
|
@@ -437,6 +475,14 @@ class ReferenceResolver {
|
|
|
437
475
|
}
|
|
438
476
|
const fullPath = path.join(this.projectRoot, filePath);
|
|
439
477
|
try {
|
|
478
|
+
// Import resolvers may follow package metadata to an archive (`file:*.har`,
|
|
479
|
+
// for example). Reject anything extraction would not accept before UTF-8
|
|
480
|
+
// decoding can multiply a large binary blob into gigabytes of V8 heap.
|
|
481
|
+
const stats = fs.statSync(fullPath);
|
|
482
|
+
if (!stats.isFile() || stats.size > file_limits_1.MAX_SOURCE_FILE_SIZE_BYTES) {
|
|
483
|
+
this.fileCache.set(filePath, null);
|
|
484
|
+
return null;
|
|
485
|
+
}
|
|
440
486
|
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
441
487
|
this.fileCache.set(filePath, content);
|
|
442
488
|
return content;
|
|
@@ -447,17 +493,49 @@ class ReferenceResolver {
|
|
|
447
493
|
return null;
|
|
448
494
|
}
|
|
449
495
|
}
|
|
496
|
+
/**
|
|
497
|
+
* `readFileCached(filePath)?.includes(needle)` for an ASCII needle, searched
|
|
498
|
+
* in the raw bytes: an ASCII byte sequence survives UTF-8 decoding
|
|
499
|
+
* unchanged, and decoding is most of reading a file nobody keeps.
|
|
500
|
+
*/
|
|
501
|
+
fileContains(filePath, needle) {
|
|
502
|
+
if (this.fileCache.has(filePath))
|
|
503
|
+
return this.fileCache.get(filePath)?.includes(needle) ?? false;
|
|
504
|
+
const fullPath = path.join(this.projectRoot, filePath);
|
|
505
|
+
try {
|
|
506
|
+
const stats = fs.statSync(fullPath);
|
|
507
|
+
if (!stats.isFile() || stats.size > file_limits_1.MAX_SOURCE_FILE_SIZE_BYTES)
|
|
508
|
+
return false;
|
|
509
|
+
return fs.readFileSync(fullPath).includes(needle);
|
|
510
|
+
}
|
|
511
|
+
catch {
|
|
512
|
+
return false;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
450
515
|
/**
|
|
451
516
|
* Create the resolution context
|
|
452
517
|
*/
|
|
453
518
|
createContext() {
|
|
454
519
|
return {
|
|
520
|
+
resolveImport: (ref) => (0, import_resolver_1.resolveViaImport)(ref, this.context),
|
|
455
521
|
getNodesInFile: (filePath) => {
|
|
456
522
|
if (!this.nodeCache.has(filePath)) {
|
|
457
523
|
this.nodeCache.set(filePath, this.queries.getNodesByFile(filePath));
|
|
458
524
|
}
|
|
459
525
|
return this.nodeCache.get(filePath);
|
|
460
526
|
},
|
|
527
|
+
fileHasExportedNode: (filePath) => {
|
|
528
|
+
const cached = this.nodeCache.get(filePath);
|
|
529
|
+
return cached !== undefined ? cached.some((n) => n.isExported) : this.queries.fileHasExportedNode(filePath);
|
|
530
|
+
},
|
|
531
|
+
getExportedNodesInFile: (filePath) => {
|
|
532
|
+
const cached = this.nodeCache.get(filePath);
|
|
533
|
+
return cached !== undefined ? cached.filter((n) => n.isExported) : this.queries.getExportedNodesByFile(filePath);
|
|
534
|
+
},
|
|
535
|
+
getNodesInFileNamed: (filePath, name) => {
|
|
536
|
+
const cached = this.nodeCache.get(filePath);
|
|
537
|
+
return cached !== undefined ? cached.filter((n) => n.name === name) : this.queries.getNodesByFileAndName(filePath, name);
|
|
538
|
+
},
|
|
461
539
|
getNodesByName: (name) => {
|
|
462
540
|
const cached = this.nameCache.get(name);
|
|
463
541
|
if (cached !== undefined)
|
|
@@ -488,7 +566,7 @@ class ReferenceResolver {
|
|
|
488
566
|
for (const m of candidates) {
|
|
489
567
|
if (m.kind !== 'method')
|
|
490
568
|
continue;
|
|
491
|
-
if (m.language
|
|
569
|
+
if (!(0, name_matcher_1.sameLanguageFamily)(m.language, language))
|
|
492
570
|
continue;
|
|
493
571
|
const qn = m.qualifiedName;
|
|
494
572
|
if (qn === want || qn.endsWith(`::${want}`))
|
|
@@ -515,7 +593,7 @@ class ReferenceResolver {
|
|
|
515
593
|
for (const m of candidates) {
|
|
516
594
|
if (m.kind !== 'method')
|
|
517
595
|
continue;
|
|
518
|
-
if (m.language
|
|
596
|
+
if (!(0, name_matcher_1.sameLanguageFamily)(m.language, language))
|
|
519
597
|
continue;
|
|
520
598
|
const qn = m.qualifiedName;
|
|
521
599
|
const i2 = qn.lastIndexOf('::');
|
|
@@ -565,17 +643,40 @@ class ReferenceResolver {
|
|
|
565
643
|
return true;
|
|
566
644
|
}
|
|
567
645
|
}
|
|
568
|
-
// Fall back to filesystem for files not yet indexed
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
646
|
+
// Fall back to filesystem for files not yet indexed. `path.join` does
|
|
647
|
+
// not clamp, and relative-import resolution hands us paths carrying
|
|
648
|
+
// `../` segments, so the probe has to be contained (#1631): a path
|
|
649
|
+
// outside the root can never be an indexed project file, and the
|
|
650
|
+
// `knownFiles` check above already answered for everything that is.
|
|
651
|
+
// Lexical containment only: this is a per-candidate hot path, and the
|
|
652
|
+
// symlink half of `validatePathWithinRoot` costs two `realpathSync`
|
|
653
|
+
// calls per probe (~70x slower here). It would also be wrong to apply
|
|
654
|
+
// — indexing deliberately follows in-root symlinks whose targets live
|
|
655
|
+
// outside the root (#935), so only the `../` escape is refused.
|
|
656
|
+
// Memoized: import resolution probes the same candidate paths (every
|
|
657
|
+
// extension of a specifier) from every file that imports it, and the
|
|
658
|
+
// tree does not change within a resolution pass (same window as the
|
|
659
|
+
// file-content cache; dropped by clearCaches).
|
|
660
|
+
const probed = this.fileExistsMemo.get(filePath);
|
|
661
|
+
if (probed !== undefined)
|
|
662
|
+
return probed;
|
|
663
|
+
const fullPath = (0, utils_1.lexicalPathWithinRoot)(this.projectRoot, filePath);
|
|
664
|
+
let exists = false;
|
|
665
|
+
if (fullPath !== null) {
|
|
666
|
+
try {
|
|
667
|
+
exists = fs.existsSync(fullPath);
|
|
668
|
+
}
|
|
669
|
+
catch (error) {
|
|
670
|
+
(0, errors_1.logDebug)('Error checking file existence', { filePath, error: String(error) });
|
|
671
|
+
}
|
|
576
672
|
}
|
|
673
|
+
if (this.fileExistsMemo.size >= 200_000)
|
|
674
|
+
this.fileExistsMemo.clear();
|
|
675
|
+
this.fileExistsMemo.set(filePath, exists);
|
|
676
|
+
return exists;
|
|
577
677
|
},
|
|
578
678
|
readFile: (filePath) => this.readFileCached(filePath),
|
|
679
|
+
fileContains: (filePath, needle) => this.fileContains(filePath, needle),
|
|
579
680
|
getFileLines: (filePath) => {
|
|
580
681
|
const cached = this.fileLinesCache.get(filePath);
|
|
581
682
|
if (cached !== undefined)
|
|
@@ -616,7 +717,7 @@ class ReferenceResolver {
|
|
|
616
717
|
return result;
|
|
617
718
|
},
|
|
618
719
|
getNodeById: (id) => {
|
|
619
|
-
return this.
|
|
720
|
+
return this.nodeById(id);
|
|
620
721
|
},
|
|
621
722
|
getSupertypes: (typeName, language) => {
|
|
622
723
|
// Union the `implements`/`extends` targets of every same-named type node.
|
|
@@ -633,7 +734,9 @@ class ReferenceResolver {
|
|
|
633
734
|
return hit.supers;
|
|
634
735
|
const typeNodes = this.context
|
|
635
736
|
.getNodesByName(typeName)
|
|
636
|
-
|
|
737
|
+
// Scala singletons can inherit members even though they cannot be parents.
|
|
738
|
+
.filter((n) => n.language === language && (SUPERTYPE_BEARING_KINDS.has(n.kind) ||
|
|
739
|
+
(n.language === 'scala' && n.kind === 'module')));
|
|
637
740
|
let supers;
|
|
638
741
|
if (typeNodes.length === 0) {
|
|
639
742
|
supers = [];
|
|
@@ -641,11 +744,20 @@ class ReferenceResolver {
|
|
|
641
744
|
else {
|
|
642
745
|
const supertypes = new Set();
|
|
643
746
|
for (const tn of typeNodes) {
|
|
644
|
-
for (const edge of this.queries.getOutgoingEdges(tn.id,
|
|
645
|
-
const target = this.
|
|
747
|
+
for (const edge of this.queries.getOutgoingEdges(tn.id, RESOLUTION_READ_EDGE_KINDS)) {
|
|
748
|
+
const target = this.nodeById(edge.target);
|
|
646
749
|
if (target?.name && target.name !== typeName)
|
|
647
750
|
supertypes.add(target.name);
|
|
648
751
|
}
|
|
752
|
+
// A Swift conformance to a type the project only extends (SwiftUI's
|
|
753
|
+
// `View`) resolves to nothing — the extension is not the type — yet
|
|
754
|
+
// the members its extensions add are still the conformer's.
|
|
755
|
+
if (language === 'swift') {
|
|
756
|
+
for (const name of (0, swift_type_visibility_1.swiftExtendedConformances)(tn, this.context)) {
|
|
757
|
+
if (name !== typeName)
|
|
758
|
+
supertypes.add(name);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
649
761
|
}
|
|
650
762
|
supers = [...supertypes];
|
|
651
763
|
}
|
|
@@ -716,6 +828,7 @@ class ReferenceResolver {
|
|
|
716
828
|
resolveAll(unresolvedRefs, onProgress) {
|
|
717
829
|
// Pre-load all nodes into memory for fast lookups
|
|
718
830
|
this.warmCaches();
|
|
831
|
+
this.advanceSupertypeGeneration();
|
|
719
832
|
const resolved = [];
|
|
720
833
|
const unresolved = [];
|
|
721
834
|
const byMethod = {};
|
|
@@ -863,9 +976,48 @@ class ReferenceResolver {
|
|
|
863
976
|
return false;
|
|
864
977
|
}
|
|
865
978
|
/**
|
|
866
|
-
* Resolve a single reference
|
|
979
|
+
* Resolve a single reference.
|
|
980
|
+
*
|
|
981
|
+
* Thin decorator over `resolveOneInner` so every strategy — framework,
|
|
982
|
+
* import, name-match, chain, CFML component path — passes through the
|
|
983
|
+
* inheritance target-kind gate at ONE seam. Filtering inside the
|
|
984
|
+
* name-matcher would have covered `matchByExactName` only.
|
|
985
|
+
* Calls that land on an alias binding then forward once to the callable
|
|
986
|
+
* the alias names (see ./alias-binding), regardless of the strategy.
|
|
867
987
|
*/
|
|
868
988
|
resolveOne(ref) {
|
|
989
|
+
// A C/C++ "call" whose name is a function-like macro visible in this
|
|
990
|
+
// translation unit is a macro expansion, not a call — it must never bind
|
|
991
|
+
// to a same-named function in another file (#1838).
|
|
992
|
+
if ((0, cpp_macro_visibility_1.isVisibleCppMacro)(ref, this.context))
|
|
993
|
+
return null;
|
|
994
|
+
// A Swift type reference never lands on an `extension X {}` node, nor on a
|
|
995
|
+
// nested type it cannot name bare (see ./swift-type-visibility).
|
|
996
|
+
const candidate = (0, swift_type_visibility_1.gateSwiftTypeTarget)(this.gateTargetKind(this.resolveOneInner(ref), ref), ref, this.context);
|
|
997
|
+
const resolved = candidate?.resolvedBy === 'framework'
|
|
998
|
+
? this.gateFrameworkLanguage(candidate, ref)
|
|
999
|
+
: this.gateLanguage(candidate, ref);
|
|
1000
|
+
if (!resolved || ref.referenceKind !== 'calls')
|
|
1001
|
+
return resolved;
|
|
1002
|
+
const target = this.nodeById(resolved.targetNodeId);
|
|
1003
|
+
if (!target)
|
|
1004
|
+
return resolved;
|
|
1005
|
+
const dot = ref.referenceName.lastIndexOf('.');
|
|
1006
|
+
const memberName = dot >= 0 ? ref.referenceName.slice(dot + 1) : null;
|
|
1007
|
+
const forwarded = (0, alias_binding_1.resolveAliasBinding)(target, memberName, this.context);
|
|
1008
|
+
if (!forwarded || forwarded.id === resolved.targetNodeId)
|
|
1009
|
+
return resolved;
|
|
1010
|
+
return this.gateLanguage({
|
|
1011
|
+
...resolved,
|
|
1012
|
+
targetNodeId: forwarded.id,
|
|
1013
|
+
confidence: Math.min(resolved.confidence, 0.85),
|
|
1014
|
+
}, ref);
|
|
1015
|
+
}
|
|
1016
|
+
resolveOneInner(ref) {
|
|
1017
|
+
// A local C++ object construction (`T obj(args)`, ref `ns::T::T/1`)
|
|
1018
|
+
// resolves ONLY to a constructor of the lexically nearest `T` (#1839).
|
|
1019
|
+
if ((0, cpp_constructor_1.isCppConstructorRef)(ref))
|
|
1020
|
+
return (0, cpp_constructor_1.matchCppConstructor)(ref, this.context);
|
|
869
1021
|
// Skip built-in/external references
|
|
870
1022
|
if (this.isBuiltInOrExternal(ref)) {
|
|
871
1023
|
return null;
|
|
@@ -895,9 +1047,13 @@ class ReferenceResolver {
|
|
|
895
1047
|
// indexed under the bare name, so the existence check strips the dot.
|
|
896
1048
|
// Nix static path imports (`import ./x.nix`) name a FILE, not a symbol —
|
|
897
1049
|
// they bypass the symbol-existence check and resolve via resolveViaImport.
|
|
898
|
-
|
|
1050
|
+
let existenceName = ref.language === 'arkts' && ref.referenceName.startsWith('.')
|
|
899
1051
|
? ref.referenceName.slice(1)
|
|
900
1052
|
: ref.referenceName;
|
|
1053
|
+
// Erlang refs carry the call-site arity (`f/1`, `mod::f/2` — #1610); the
|
|
1054
|
+
// name index stores bare names, so existence is checked arity-less.
|
|
1055
|
+
if (ref.language === 'erlang')
|
|
1056
|
+
existenceName = existenceName.replace(/\/\d{1,3}$/, '');
|
|
901
1057
|
const tPre = this.profileStages ? process.hrtime.bigint() : 0n;
|
|
902
1058
|
const preFilterPass = (0, import_resolver_1.isNixPathImportRef)(ref) ||
|
|
903
1059
|
this.hasAnyPossibleMatch(existenceName) ||
|
|
@@ -906,7 +1062,7 @@ class ReferenceResolver {
|
|
|
906
1062
|
if (this.profileStages)
|
|
907
1063
|
this.stageAdd('preFilter', ref, preFilterPass, tPre);
|
|
908
1064
|
if (!preFilterPass) {
|
|
909
|
-
return
|
|
1065
|
+
return this.gateLanguage((0, name_matcher_1.matchJsStoreBindingCall)(ref, this.context), ref);
|
|
910
1066
|
}
|
|
911
1067
|
// Function-as-value refs (#756) get a dedicated, strictly-gated path:
|
|
912
1068
|
// import-based resolution first (an imported callback resolves through its
|
|
@@ -919,9 +1075,12 @@ class ReferenceResolver {
|
|
|
919
1075
|
if (ref.referenceName.startsWith('this.')) {
|
|
920
1076
|
return this.gateLanguage(this.resolveThisMemberFnRef(ref), ref);
|
|
921
1077
|
}
|
|
1078
|
+
if ((ref.language === 'python' || ref.language === 'go') && ref.referenceName.includes('.')) {
|
|
1079
|
+
return this.gateLanguage((0, name_matcher_1.matchFunctionRef)(ref, this.context), ref);
|
|
1080
|
+
}
|
|
922
1081
|
const viaImport = this.gateLanguage((0, import_resolver_1.resolveViaImport)(ref, this.context), ref);
|
|
923
1082
|
if (viaImport) {
|
|
924
|
-
const target = this.
|
|
1083
|
+
const target = this.nodeById(viaImport.targetNodeId);
|
|
925
1084
|
if (target &&
|
|
926
1085
|
(target.kind === 'function' ||
|
|
927
1086
|
target.kind === 'method' ||
|
|
@@ -963,12 +1122,16 @@ class ReferenceResolver {
|
|
|
963
1122
|
if (razorResult)
|
|
964
1123
|
return razorResult;
|
|
965
1124
|
}
|
|
1125
|
+
// An explicit PHP class import owns its static calls, including an
|
|
1126
|
+
// unavailable method. Do not let same-name fallbacks change the receiver
|
|
1127
|
+
// to an unrelated Service/Repository type (#1545).
|
|
1128
|
+
const phpStaticImport = (0, import_resolver_1.resolvePhpImportedStaticCall)(ref, this.context);
|
|
1129
|
+
if (phpStaticImport !== undefined)
|
|
1130
|
+
return this.gateLanguage(phpStaticImport, ref);
|
|
966
1131
|
const candidates = [];
|
|
967
1132
|
// Strategy 1: Try framework-specific resolution. Cross-language bridges
|
|
968
1133
|
// are deliberately preserved (Drupal `routing.yml` → PHP controller, RN
|
|
969
|
-
// JS → native `calls`)
|
|
970
|
-
// edge between two KNOWN families (see its doc), never a `calls` bridge or
|
|
971
|
-
// a config↔code edge.
|
|
1134
|
+
// JS → native `calls`); other code references obey the shared family gate.
|
|
972
1135
|
const tFw = this.profileStages ? process.hrtime.bigint() : 0n;
|
|
973
1136
|
let fwEarly = null;
|
|
974
1137
|
for (const framework of this.frameworks) {
|
|
@@ -985,7 +1148,21 @@ class ReferenceResolver {
|
|
|
985
1148
|
this.stageAdd('frameworks', ref, fwEarly !== null, tFw);
|
|
986
1149
|
if (fwEarly)
|
|
987
1150
|
return fwEarly;
|
|
1151
|
+
// A retained untyped chain supplies effect/call-site evidence only. In
|
|
1152
|
+
// particular, importing its root does not make the root its call target.
|
|
1153
|
+
if ((0, name_matcher_1.isUnresolvedJsMemberCall)(ref))
|
|
1154
|
+
return null;
|
|
988
1155
|
// Strategy 2: Try import-based resolution
|
|
1156
|
+
// A TS/JS/Python call-receiver chain (`useStore.getState().reset`, #1683)
|
|
1157
|
+
// names the ROOT's import, not the method's: letting resolveViaImport see
|
|
1158
|
+
// it binds the call to the imported store constant and the method is
|
|
1159
|
+
// never looked up. The name-matcher owns the chain shape for these
|
|
1160
|
+
// languages — the Java/Kotlin/C++ chains keep their existing path.
|
|
1161
|
+
if (ref.referenceKind === 'calls' &&
|
|
1162
|
+
CHAIN_SHAPE.test(ref.referenceName) &&
|
|
1163
|
+
(ref.language === 'typescript' || ref.language === 'javascript' || ref.language === 'tsx' || ref.language === 'jsx' || ref.language === 'python')) {
|
|
1164
|
+
return this.gateLanguage((0, name_matcher_1.matchReference)(ref, this.context), ref);
|
|
1165
|
+
}
|
|
989
1166
|
const tImp = this.profileStages ? process.hrtime.bigint() : 0n;
|
|
990
1167
|
const importResult = this.gateLanguage((0, import_resolver_1.resolveViaImport)(ref, this.context), ref);
|
|
991
1168
|
if (this.profileStages)
|
|
@@ -1022,8 +1199,15 @@ class ReferenceResolver {
|
|
|
1022
1199
|
// matcher would link each `mkOption` call to whichever file's inherit
|
|
1023
1200
|
// binding it happened to pick. Same-file matches only.
|
|
1024
1201
|
if (nameResult) {
|
|
1025
|
-
const target = this.
|
|
1026
|
-
|
|
1202
|
+
const target = this.nodeById(nameResult.targetNodeId);
|
|
1203
|
+
// A definition its language makes file-local — a C `static`, a Kotlin
|
|
1204
|
+
// `private fun`, a Go unexported name in another package, a Rust
|
|
1205
|
+
// non-`pub` item outside its module subtree — cannot be what a name in
|
|
1206
|
+
// another file means, whichever strategy chose it (#1730).
|
|
1207
|
+
if (target && !(0, name_matcher_1.isVisibleAcrossFiles)(target, ref, this.context)) {
|
|
1208
|
+
nameResult = null;
|
|
1209
|
+
}
|
|
1210
|
+
else if (ref.language === 'nix') {
|
|
1027
1211
|
if (!target || target.filePath !== ref.filePath) {
|
|
1028
1212
|
nameResult = null;
|
|
1029
1213
|
}
|
|
@@ -1071,7 +1255,7 @@ class ReferenceResolver {
|
|
|
1071
1255
|
if (ref.referenceKind === 'calls' &&
|
|
1072
1256
|
CHAIN_LANGUAGES.has(ref.language) &&
|
|
1073
1257
|
CHAIN_SHAPE.test(ref.referenceName)) {
|
|
1074
|
-
this.
|
|
1258
|
+
this.deferReference(ref, this.deferredChainRefs);
|
|
1075
1259
|
}
|
|
1076
1260
|
else if (
|
|
1077
1261
|
// PHP `$this->prop->method()` (encoded `this->prop.method`): its method
|
|
@@ -1080,7 +1264,7 @@ class ReferenceResolver {
|
|
|
1080
1264
|
ref.referenceKind === 'calls' &&
|
|
1081
1265
|
ref.language === 'php' &&
|
|
1082
1266
|
PHP_PROP_SHAPE.test(ref.referenceName)) {
|
|
1083
|
-
this.
|
|
1267
|
+
this.deferReference(ref, this.deferredChainRefs);
|
|
1084
1268
|
}
|
|
1085
1269
|
return null;
|
|
1086
1270
|
}
|
|
@@ -1091,43 +1275,53 @@ class ReferenceResolver {
|
|
|
1091
1275
|
* Create edges from resolved references
|
|
1092
1276
|
*/
|
|
1093
1277
|
createEdges(resolved) {
|
|
1094
|
-
return resolved.
|
|
1278
|
+
return resolved.flatMap((ref) => {
|
|
1095
1279
|
// `function_ref` (#756) is internal-only: it persists as a `references`
|
|
1096
1280
|
// edge (the registration site depends on the callback), distinguishable
|
|
1097
1281
|
// by metadata.resolvedBy === 'function-ref'. callers/impact already
|
|
1098
1282
|
// traverse `references`, so registration sites surface with no
|
|
1099
1283
|
// graph-layer changes.
|
|
1100
|
-
let kind = ref.
|
|
1284
|
+
let kind = ref.edgeKind ??
|
|
1285
|
+
(ref.original.referenceKind === 'function_ref' ? 'references' : ref.original.referenceKind);
|
|
1101
1286
|
// Promote "extends" to "implements" when a class/struct targets an interface
|
|
1102
1287
|
if (kind === 'extends') {
|
|
1103
|
-
const targetNode = this.
|
|
1288
|
+
const targetNode = this.nodeById(ref.targetNodeId);
|
|
1104
1289
|
if (targetNode && (targetNode.kind === 'interface' || targetNode.kind === 'protocol')) {
|
|
1105
|
-
const sourceNode = this.
|
|
1290
|
+
const sourceNode = this.nodeById(ref.original.fromNodeId);
|
|
1106
1291
|
if (sourceNode && sourceNode.kind !== 'interface' && sourceNode.kind !== 'protocol') {
|
|
1107
1292
|
kind = 'implements';
|
|
1108
1293
|
}
|
|
1109
1294
|
}
|
|
1110
1295
|
}
|
|
1111
1296
|
// Promote "calls" to "instantiates" when the resolved target is a
|
|
1112
|
-
// class/struct. Languages without a `new` keyword (Python, Ruby)
|
|
1297
|
+
// class/struct/union. Languages without a `new` keyword (Python, Ruby)
|
|
1113
1298
|
// express instantiation as `Foo()` — extraction can't tell that
|
|
1114
1299
|
// apart from a function call without symbol info, but resolution
|
|
1115
1300
|
// can: if `Foo` resolves to a class, the call IS an instantiation.
|
|
1116
1301
|
if (kind === 'calls') {
|
|
1117
|
-
const targetNode = this.
|
|
1118
|
-
if (targetNode &&
|
|
1302
|
+
const targetNode = this.nodeById(ref.targetNodeId);
|
|
1303
|
+
if (targetNode &&
|
|
1304
|
+
(targetNode.kind === 'class' || targetNode.kind === 'struct' || targetNode.kind === 'union')) {
|
|
1119
1305
|
kind = 'instantiates';
|
|
1120
1306
|
}
|
|
1121
1307
|
}
|
|
1122
|
-
|
|
1308
|
+
// One reference can name several targets — a navigation whose
|
|
1309
|
+
// destination is a conditional reaches every arm. Each becomes its own
|
|
1310
|
+
// edge, sharing this resolution's kind and confidence.
|
|
1311
|
+
const targets = [
|
|
1312
|
+
{ targetNodeId: ref.targetNodeId, metadata: ref.metadata },
|
|
1313
|
+
...(ref.alsoTargets ?? []),
|
|
1314
|
+
];
|
|
1315
|
+
return targets.map((t) => ({
|
|
1123
1316
|
source: ref.original.fromNodeId,
|
|
1124
|
-
target:
|
|
1317
|
+
target: t.targetNodeId,
|
|
1125
1318
|
kind,
|
|
1126
1319
|
line: ref.original.line,
|
|
1127
1320
|
column: ref.original.column,
|
|
1128
1321
|
confidence: ref.confidence,
|
|
1129
1322
|
resolvedBy: ref.resolvedBy,
|
|
1130
1323
|
metadata: {
|
|
1324
|
+
...(t.metadata ?? {}),
|
|
1131
1325
|
confidence: ref.confidence,
|
|
1132
1326
|
resolvedBy: ref.resolvedBy,
|
|
1133
1327
|
// The ORIGINAL reference text (and kind, when edge-kind promotion
|
|
@@ -1153,7 +1347,7 @@ class ReferenceResolver {
|
|
|
1153
1347
|
...(ref.original.bindingForm !== undefined ? { binding: ref.original.bindingForm } : {}),
|
|
1154
1348
|
...(ref.original.importedName !== undefined ? { importedName: ref.original.importedName } : {}),
|
|
1155
1349
|
},
|
|
1156
|
-
};
|
|
1350
|
+
}));
|
|
1157
1351
|
});
|
|
1158
1352
|
}
|
|
1159
1353
|
/**
|
|
@@ -1202,10 +1396,25 @@ class ReferenceResolver {
|
|
|
1202
1396
|
}
|
|
1203
1397
|
return { byRowId, legacyKeys };
|
|
1204
1398
|
}
|
|
1399
|
+
/** A deferred attempt is unfinished work, not a final failure (#1577). */
|
|
1400
|
+
nonDeferredFailures(unresolved) {
|
|
1401
|
+
return unresolved.filter((ref) => ref.rowId == null || !this.deferredRowIds.has(ref.rowId));
|
|
1402
|
+
}
|
|
1403
|
+
deferReference(ref, queue) {
|
|
1404
|
+
queue.push(ref);
|
|
1405
|
+
if (ref.rowId != null)
|
|
1406
|
+
this.deferredRowIds.add(ref.rowId);
|
|
1407
|
+
}
|
|
1205
1408
|
/**
|
|
1206
1409
|
* Resolve and persist edges to database
|
|
1207
1410
|
*/
|
|
1208
1411
|
resolveAndPersist(unresolvedRefs, onProgress) {
|
|
1412
|
+
const prerequisites = unresolvedRefs.filter(ReferenceResolver.isPrerequisite);
|
|
1413
|
+
if (prerequisites.length > 0 && prerequisites.length < unresolvedRefs.length) {
|
|
1414
|
+
const first = this.resolveAndPersist(prerequisites, (current) => onProgress?.(current, unresolvedRefs.length));
|
|
1415
|
+
const rest = this.resolveAndPersist(unresolvedRefs.filter((ref) => !ReferenceResolver.isPrerequisite(ref)), (current) => onProgress?.(prerequisites.length + current, unresolvedRefs.length));
|
|
1416
|
+
return ReferenceResolver.mergeResults(first, rest);
|
|
1417
|
+
}
|
|
1209
1418
|
const result = this.resolveAll(unresolvedRefs, onProgress);
|
|
1210
1419
|
// Create edges from resolved references
|
|
1211
1420
|
const edges = this.createEdges(result.resolved);
|
|
@@ -1229,7 +1438,7 @@ class ReferenceResolver {
|
|
|
1229
1438
|
// is still 'pending', so any pending row at rest belongs to an
|
|
1230
1439
|
// interrupted run and the sweep can key off the pending count.
|
|
1231
1440
|
if (result.unresolved.length > 0) {
|
|
1232
|
-
const { byRowId, legacyKeys } = ReferenceResolver.partitionFailedCleanup(result.unresolved);
|
|
1441
|
+
const { byRowId, legacyKeys } = ReferenceResolver.partitionFailedCleanup(this.nonDeferredFailures(result.unresolved));
|
|
1233
1442
|
this.queries.markReferencesFailedByRowIds(byRowId);
|
|
1234
1443
|
this.queries.markReferencesFailed(legacyKeys);
|
|
1235
1444
|
}
|
|
@@ -1245,8 +1454,18 @@ class ReferenceResolver {
|
|
|
1245
1454
|
* a large edit lands many popular symbol names at once.
|
|
1246
1455
|
*/
|
|
1247
1456
|
async resolveAndPersistListYielding(refs) {
|
|
1457
|
+
const prerequisites = refs.filter(ReferenceResolver.isPrerequisite);
|
|
1458
|
+
if (prerequisites.length > 0 && prerequisites.length < refs.length) {
|
|
1459
|
+
const first = await this.resolveAndPersistListYielding(prerequisites);
|
|
1460
|
+
const rest = await this.resolveAndPersistListYielding(refs.filter((ref) => !ReferenceResolver.isPrerequisite(ref)));
|
|
1461
|
+
return ReferenceResolver.mergeResults(first, rest);
|
|
1462
|
+
}
|
|
1248
1463
|
const maybeYield = (0, cooperative_yield_1.createYielder)();
|
|
1249
1464
|
const result = await this.resolveBatchYielding(refs, maybeYield);
|
|
1465
|
+
await this.persistResolutionResult(result, maybeYield);
|
|
1466
|
+
return result;
|
|
1467
|
+
}
|
|
1468
|
+
async persistResolutionResult(result, maybeYield) {
|
|
1250
1469
|
const PERSIST_CHUNK = 1000;
|
|
1251
1470
|
const edges = this.createEdges(result.resolved);
|
|
1252
1471
|
for (let i = 0; i < edges.length; i += PERSIST_CHUNK) {
|
|
@@ -1262,7 +1481,7 @@ class ReferenceResolver {
|
|
|
1262
1481
|
this.queries.deleteSpecificResolvedReferences(resolvedCleanup.legacyKeys.slice(i, i + PERSIST_CHUNK));
|
|
1263
1482
|
await maybeYield();
|
|
1264
1483
|
}
|
|
1265
|
-
const failedCleanup = ReferenceResolver.partitionFailedCleanup(result.unresolved);
|
|
1484
|
+
const failedCleanup = ReferenceResolver.partitionFailedCleanup(this.nonDeferredFailures(result.unresolved));
|
|
1266
1485
|
for (let i = 0; i < failedCleanup.byRowId.length; i += PERSIST_CHUNK) {
|
|
1267
1486
|
this.queries.markReferencesFailedByRowIds(failedCleanup.byRowId.slice(i, i + PERSIST_CHUNK));
|
|
1268
1487
|
await maybeYield();
|
|
@@ -1271,7 +1490,43 @@ class ReferenceResolver {
|
|
|
1271
1490
|
this.queries.markReferencesFailed(failedCleanup.legacyKeys.slice(i, i + PERSIST_CHUNK));
|
|
1272
1491
|
await maybeYield();
|
|
1273
1492
|
}
|
|
1274
|
-
return
|
|
1493
|
+
return edges.length;
|
|
1494
|
+
}
|
|
1495
|
+
/** Finalize the durable queue only AFTER its edges have been inserted. */
|
|
1496
|
+
async persistDeferredReferences(deferred, resolved) {
|
|
1497
|
+
for (const ref of deferred)
|
|
1498
|
+
if (ref.rowId != null)
|
|
1499
|
+
this.deferredRowIds.delete(ref.rowId);
|
|
1500
|
+
const matched = new Set(resolved.map((ref) => ref.original));
|
|
1501
|
+
const unresolved = deferred.filter((ref) => !matched.has(ref));
|
|
1502
|
+
const count = await this.persistResolutionResult({
|
|
1503
|
+
resolved,
|
|
1504
|
+
unresolved,
|
|
1505
|
+
stats: { total: deferred.length, resolved: resolved.length, unresolved: unresolved.length, byMethod: {} },
|
|
1506
|
+
}, (0, cooperative_yield_1.createYielder)());
|
|
1507
|
+
if (count > 0)
|
|
1508
|
+
this.clearCaches();
|
|
1509
|
+
return count;
|
|
1510
|
+
}
|
|
1511
|
+
/** Same two phases as the bounded DB reader: persist wiring before calls. */
|
|
1512
|
+
static isPrerequisite(ref) {
|
|
1513
|
+
return ref.referenceKind === 'imports' || ref.referenceKind === 'extends' || ref.referenceKind === 'implements';
|
|
1514
|
+
}
|
|
1515
|
+
static mergeResults(first, rest) {
|
|
1516
|
+
const byMethod = { ...first.stats.byMethod };
|
|
1517
|
+
for (const [method, count] of Object.entries(rest.stats.byMethod)) {
|
|
1518
|
+
byMethod[method] = (byMethod[method] ?? 0) + count;
|
|
1519
|
+
}
|
|
1520
|
+
return {
|
|
1521
|
+
resolved: first.resolved.concat(rest.resolved),
|
|
1522
|
+
unresolved: first.unresolved.concat(rest.unresolved),
|
|
1523
|
+
stats: {
|
|
1524
|
+
total: first.stats.total + rest.stats.total,
|
|
1525
|
+
resolved: first.stats.resolved + rest.stats.resolved,
|
|
1526
|
+
unresolved: first.stats.unresolved + rest.stats.unresolved,
|
|
1527
|
+
byMethod,
|
|
1528
|
+
},
|
|
1529
|
+
};
|
|
1275
1530
|
}
|
|
1276
1531
|
/**
|
|
1277
1532
|
* Second resolution pass for chained static-factory / fluent calls whose
|
|
@@ -1315,14 +1570,7 @@ class ReferenceResolver {
|
|
|
1315
1570
|
resolved.push(match);
|
|
1316
1571
|
await maybeYield();
|
|
1317
1572
|
}
|
|
1318
|
-
|
|
1319
|
-
return 0;
|
|
1320
|
-
const edges = this.createEdges(resolved);
|
|
1321
|
-
if (edges.length > 0) {
|
|
1322
|
-
this.queries.insertEdges(edges);
|
|
1323
|
-
this.clearCaches();
|
|
1324
|
-
}
|
|
1325
|
-
return edges.length;
|
|
1573
|
+
return this.persistDeferredReferences(deferred, resolved);
|
|
1326
1574
|
}
|
|
1327
1575
|
/**
|
|
1328
1576
|
* Resolve one batch with a yield checkpoint between EVERY ref so the #850
|
|
@@ -1478,6 +1726,7 @@ class ReferenceResolver {
|
|
|
1478
1726
|
unresolved.push(ref);
|
|
1479
1727
|
}
|
|
1480
1728
|
}
|
|
1729
|
+
this.deferredRowIds.clear(); // the admission side now owns both queues
|
|
1481
1730
|
return {
|
|
1482
1731
|
resolved,
|
|
1483
1732
|
unresolved,
|
|
@@ -1500,8 +1749,10 @@ class ReferenceResolver {
|
|
|
1500
1749
|
* would have.
|
|
1501
1750
|
*/
|
|
1502
1751
|
appendDeferredFromWorkers(deferredChain, deferredThisMember) {
|
|
1503
|
-
|
|
1504
|
-
|
|
1752
|
+
for (const ref of deferredChain)
|
|
1753
|
+
this.deferReference(ref, this.deferredChainRefs);
|
|
1754
|
+
for (const ref of deferredThisMember)
|
|
1755
|
+
this.deferReference(ref, this.deferredThisMemberRefs);
|
|
1505
1756
|
}
|
|
1506
1757
|
/**
|
|
1507
1758
|
* Resolve and persist in batches to keep memory bounded.
|
|
@@ -1520,7 +1771,7 @@ class ReferenceResolver {
|
|
|
1520
1771
|
// the valve's timer-driven passive passes stay perpetually partial against
|
|
1521
1772
|
// the pool's continuous reads, which is how a kernel-scale resolution grew
|
|
1522
1773
|
// a 22GB WAL on a 4.6GB DB (migration plan §7a.1).
|
|
1523
|
-
parallel) {
|
|
1774
|
+
parallel, synthesize = true) {
|
|
1524
1775
|
// Resolution runs on the indexer's MAIN thread, and the #850 liveness
|
|
1525
1776
|
// watchdog SIGKILLs a process whose event loop stalls past its window (60s
|
|
1526
1777
|
// by default). A single dense batch's resolveAll — or the synthesis pass
|
|
@@ -1675,8 +1926,26 @@ class ReferenceResolver {
|
|
|
1675
1926
|
}
|
|
1676
1927
|
try {
|
|
1677
1928
|
try {
|
|
1929
|
+
// Orphans retain interruption/re-extraction order, not clean-index order.
|
|
1930
|
+
// A caller can precede its imports or supertypes by many batches (#1577).
|
|
1931
|
+
// Drain those prerequisites first, then start a fresh keyset cursor over
|
|
1932
|
+
// the remaining kinds. The disjoint filters let us prefetch across the
|
|
1933
|
+
// phase boundary before cleanup without re-reading the current batch.
|
|
1934
|
+
let prerequisites = true;
|
|
1935
|
+
let afterRowId = 0;
|
|
1936
|
+
const readNextBatch = () => {
|
|
1937
|
+
let next = this.queries.getUnresolvedReferencesBatchAfter(afterRowId, batchSize, prerequisites);
|
|
1938
|
+
if (next.length === 0 && prerequisites) {
|
|
1939
|
+
prerequisites = false;
|
|
1940
|
+
afterRowId = 0;
|
|
1941
|
+
next = this.queries.getUnresolvedReferencesBatchAfter(afterRowId, batchSize, prerequisites);
|
|
1942
|
+
}
|
|
1943
|
+
if (next.length > 0)
|
|
1944
|
+
afterRowId = next[next.length - 1].rowId;
|
|
1945
|
+
return next;
|
|
1946
|
+
};
|
|
1678
1947
|
tLp = Date.now();
|
|
1679
|
-
let batch =
|
|
1948
|
+
let batch = readNextBatch();
|
|
1680
1949
|
lp('read', tLp);
|
|
1681
1950
|
let inFlight = batch.length > 0 ? beginBatch(batch) : null;
|
|
1682
1951
|
while (batch.length > 0 && inFlight) {
|
|
@@ -1686,7 +1955,7 @@ class ReferenceResolver {
|
|
|
1686
1955
|
// enumeration yields the following batch (keyset — OFFSET re-walked the
|
|
1687
1956
|
// accumulated failed prefix every read, 54.6s at kernel scale, §7a.2).
|
|
1688
1957
|
tLp = Date.now();
|
|
1689
|
-
const nextBatch =
|
|
1958
|
+
const nextBatch = readNextBatch();
|
|
1690
1959
|
lp('read', tLp);
|
|
1691
1960
|
const tBatch = Date.now();
|
|
1692
1961
|
const result = await settleBatch(inFlight, batch);
|
|
@@ -1759,27 +2028,36 @@ class ReferenceResolver {
|
|
|
1759
2028
|
// the remainder idempotently on the next run/sweep (#1187).
|
|
1760
2029
|
const PERSIST_CHUNK = 1000;
|
|
1761
2030
|
const tPersist = Date.now();
|
|
1762
|
-
//
|
|
1763
|
-
//
|
|
1764
|
-
//
|
|
1765
|
-
// receiver typed as a subclass only reaches a
|
|
1766
|
-
// base class if those edges are visible.
|
|
1767
|
-
// out first downgraded exactly those
|
|
1768
|
-
// the 0.9 typed-receiver path to the
|
|
2031
|
+
// A batch that made `extends`/`implements` edges persists them BEFORE
|
|
2032
|
+
// fanning out the next batch: later batches read them —
|
|
2033
|
+
// resolveMethodOnType walks supertype chains over edges that earlier
|
|
2034
|
+
// batches resolved, so a receiver typed as a subclass only reaches a
|
|
2035
|
+
// method declared on its base class if those edges are visible.
|
|
2036
|
+
// (Validated on dubbo: fanning out first downgraded exactly those
|
|
2037
|
+
// supertype-method resolutions from the 0.9 typed-receiver path to the
|
|
2038
|
+
// 0.65 word-overlap fallback.) They are the only edges resolution reads
|
|
2039
|
+
// (RESOLUTION_READ_EDGE_KINDS), so a batch that made none — every batch
|
|
2040
|
+
// after the prerequisite phase readNextBatch drains first — fans the
|
|
2041
|
+
// next batch out now and inserts while it resolves: the same writes in
|
|
2042
|
+
// the same order, and nothing the workers read differs.
|
|
1769
2043
|
tLp = Date.now();
|
|
1770
2044
|
const edges = this.createEdges(result.resolved);
|
|
1771
2045
|
lp('createEdges', tLp);
|
|
2046
|
+
const readEdge = edges.some((e) => RESOLUTION_READ_EDGE_KINDS.includes(e.kind));
|
|
2047
|
+
let nextInFlight = !readEdge && nextBatch.length > 0 ? beginBatch(nextBatch) : null;
|
|
1772
2048
|
tLp = Date.now();
|
|
1773
2049
|
for (let i = 0; i < edges.length; i += PERSIST_CHUNK) {
|
|
1774
2050
|
this.queries.insertEdges(edges.slice(i, i + PERSIST_CHUNK));
|
|
1775
2051
|
await maybeYield();
|
|
1776
2052
|
}
|
|
1777
2053
|
lp('insertEdges', tLp);
|
|
1778
|
-
// NOW fan the next batch out — workers see exactly the
|
|
1779
|
-
// sequential baseline would (every batch ≤ this one
|
|
1780
|
-
// the main thread spends the REST of the persist (ref
|
|
1781
|
-
// parking below) overlapped with their resolution —
|
|
1782
|
-
|
|
2054
|
+
// NOW fan the next batch out (if not already) — workers see exactly the
|
|
2055
|
+
// edge state the sequential baseline would (every batch ≤ this one
|
|
2056
|
+
// committed), while the main thread spends the REST of the persist (ref
|
|
2057
|
+
// deletes + failed parking below) overlapped with their resolution —
|
|
2058
|
+
// the double-buffer.
|
|
2059
|
+
if (!nextInFlight && nextBatch.length > 0)
|
|
2060
|
+
nextInFlight = beginBatch(nextBatch);
|
|
1783
2061
|
// Clean up resolved refs so they don't appear in the next batch —
|
|
1784
2062
|
// by row id, so a same-key sibling ref in a LATER batch (same caller
|
|
1785
2063
|
// calling the same callee at another line) is left pending for its own
|
|
@@ -1801,7 +2079,9 @@ class ReferenceResolver {
|
|
|
1801
2079
|
// only see pending rows) but stay retryable when a later sync adds a
|
|
1802
2080
|
// symbol that could satisfy them (#1240).
|
|
1803
2081
|
tLp = Date.now();
|
|
1804
|
-
const
|
|
2082
|
+
const failures = this.nonDeferredFailures(result.unresolved);
|
|
2083
|
+
const deferredCount = result.unresolved.length - failures.length;
|
|
2084
|
+
const failedCleanup = ReferenceResolver.partitionFailedCleanup(failures);
|
|
1805
2085
|
for (let i = 0; i < failedCleanup.byRowId.length; i += PERSIST_CHUNK) {
|
|
1806
2086
|
removedThisBatch += this.queries.markReferencesFailedByRowIds(failedCleanup.byRowId.slice(i, i + PERSIST_CHUNK));
|
|
1807
2087
|
await maybeYield();
|
|
@@ -1831,17 +2111,11 @@ class ReferenceResolver {
|
|
|
1831
2111
|
// first 5000 refs are all external/stdlib calls, resolution stopped at
|
|
1832
2112
|
// batch one and left the rest of the table as permanent orphans (#1187).
|
|
1833
2113
|
// The count-based guard below catches the true no-progress case.
|
|
1834
|
-
// Non-progress guard (defense-in-depth).
|
|
1835
|
-
// the
|
|
1836
|
-
//
|
|
1837
|
-
//
|
|
1838
|
-
//
|
|
1839
|
-
// `original.referenceName` differs from the stored row, so the keyed
|
|
1840
|
-
// delete/update no-ops, and we'd re-read + re-resolve + re-insert the
|
|
1841
|
-
// same rows forever (the runaway that grew a 99-file repo to 5M edges /
|
|
1842
|
-
// 1.4 GB before the Go-fallback fix). Stop rather than grow the graph
|
|
1843
|
-
// without bound. (An in-flight prefetched batch is abandoned unsettled —
|
|
1844
|
-
// fan-out has no side effects until settleBatch appends its results.)
|
|
2114
|
+
// Non-progress guard (defense-in-depth). Ordinary attempts must leave
|
|
2115
|
+
// the pending set; a mismatched original reference can make legacy-key
|
|
2116
|
+
// cleanup a no-op. Keep the guard against that broken persistence even
|
|
2117
|
+
// though keyset pagination now advances independently of row cleanup.
|
|
2118
|
+
// An abandoned prefetched batch has no side effects until settleBatch.
|
|
1845
2119
|
// Non-progress signal, now O(1): `changes` summed across this batch's
|
|
1846
2120
|
// deletes + failed-parks is the DIRECT evidence the guard's old count
|
|
1847
2121
|
// diff inferred — a resolver returning a mismatched name makes the keyed
|
|
@@ -1851,7 +2125,9 @@ class ReferenceResolver {
|
|
|
1851
2125
|
// runs only on the suspicious path (claimed-work batch removed nothing —
|
|
1852
2126
|
// e.g. every row was a sibling a legacy-key sweep already consumed),
|
|
1853
2127
|
// where it arbitrates stop-vs-continue exactly as before.
|
|
1854
|
-
|
|
2128
|
+
// Deferred refs legitimately remain pending for the post-pass. The
|
|
2129
|
+
// keyset cursor advances past them; they must not trigger this guard.
|
|
2130
|
+
if (removedThisBatch + deferredCount <= 0 && batch.length > 0) {
|
|
1855
2131
|
tLp = Date.now();
|
|
1856
2132
|
const remaining = this.queries.getUnresolvedReferencesCount();
|
|
1857
2133
|
lp('countGuard', tLp);
|
|
@@ -1888,6 +2164,21 @@ class ReferenceResolver {
|
|
|
1888
2164
|
await bp;
|
|
1889
2165
|
}
|
|
1890
2166
|
}
|
|
2167
|
+
// Indexes the bulk-edge window's end deferred: built once, while the pool
|
|
2168
|
+
// is busy with synthesis when it is, and in any case before this returns.
|
|
2169
|
+
let deferredBuilt = !bulkEdgesActive || !parallel?.bulkEdgeLoad?.deferred;
|
|
2170
|
+
const buildDeferredIndexes = () => {
|
|
2171
|
+
if (deferredBuilt)
|
|
2172
|
+
return;
|
|
2173
|
+
deferredBuilt = true;
|
|
2174
|
+
const tDeferred = Date.now();
|
|
2175
|
+
try {
|
|
2176
|
+
parallel.bulkEdgeLoad.deferred();
|
|
2177
|
+
}
|
|
2178
|
+
catch { /* healed by schema.sql on the next open, like a crash in the window */ }
|
|
2179
|
+
if (process.env.LATTICE_SENSOR_SYNTH_TIMINGS)
|
|
2180
|
+
console.error(`[phase-timing] deferred-edge-index: ${Date.now() - tDeferred}ms`);
|
|
2181
|
+
};
|
|
1891
2182
|
// Dynamic-edge synthesis: now that all base `calls` edges are persisted,
|
|
1892
2183
|
// synthesize observer/callback dispatch edges (dispatcher → registered
|
|
1893
2184
|
// callbacks) that static parsing leaves out. Best-effort — never fail the
|
|
@@ -1897,11 +2188,13 @@ class ReferenceResolver {
|
|
|
1897
2188
|
// loop. See docs/design/callback-edge-synthesis.md.
|
|
1898
2189
|
const tSynth = Date.now();
|
|
1899
2190
|
try {
|
|
1900
|
-
|
|
2191
|
+
if (synthesize)
|
|
2192
|
+
aggregateStats.byMethod['callback-synthesis'] = await (0, callback_synthesizer_1.synthesizeCallbackEdges)(this.queries, this.context, onSynthesisProgress, pool, parallel?.backpressure, buildDeferredIndexes);
|
|
1901
2193
|
}
|
|
1902
2194
|
catch {
|
|
1903
2195
|
// synthesis is additive and optional; ignore failures
|
|
1904
2196
|
}
|
|
2197
|
+
buildDeferredIndexes();
|
|
1905
2198
|
if (process.env.LATTICE_SENSOR_SYNTH_TIMINGS)
|
|
1906
2199
|
console.error(`[phase-timing] callback-synthesis: ${Date.now() - tSynth}ms`);
|
|
1907
2200
|
}
|
|
@@ -1920,12 +2213,63 @@ class ReferenceResolver {
|
|
|
1920
2213
|
stats: aggregateStats,
|
|
1921
2214
|
};
|
|
1922
2215
|
}
|
|
2216
|
+
/** Replace synthesis only after every base-resolution pass has finished. */
|
|
2217
|
+
async refreshSynthesis(dbPath, onProgress, backpressure) {
|
|
2218
|
+
this.clearCaches();
|
|
2219
|
+
const stage = new synthesis_stage_1.SynthesisStage(dbPath);
|
|
2220
|
+
try {
|
|
2221
|
+
const fresh = new ReferenceResolver(this.projectRoot, stage.queries);
|
|
2222
|
+
const count = await (0, callback_synthesizer_1.synthesizeCallbackEdges)(stage.queries, fresh.context, onProgress, null, backpressure);
|
|
2223
|
+
await stage.publish(backpressure);
|
|
2224
|
+
return count;
|
|
2225
|
+
}
|
|
2226
|
+
finally {
|
|
2227
|
+
stage.close();
|
|
2228
|
+
this.clearCaches();
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
1923
2231
|
/**
|
|
1924
2232
|
* Get detected frameworks
|
|
1925
2233
|
*/
|
|
1926
2234
|
getDetectedFrameworks() {
|
|
1927
2235
|
return this.frameworks.map((f) => f.name);
|
|
1928
2236
|
}
|
|
2237
|
+
/**
|
|
2238
|
+
* True when `receiver` is a local name bound by an import that resolves to a
|
|
2239
|
+
* file IN THIS PROJECT — the only case where letting a python
|
|
2240
|
+
* built-in-method name through the filter is safe (#1681).
|
|
2241
|
+
*
|
|
2242
|
+
* Asking only whether SOME import bound the local name is not enough: every
|
|
2243
|
+
* import produces a mapping, stdlib and PyPI included, so that would also be
|
|
2244
|
+
* true for `os`, `requests`, `np`. Opening the filter for them lets
|
|
2245
|
+
* resolveViaImport find no project file, fall through to bare-name matching,
|
|
2246
|
+
* and bind `os.remove(p)` to whatever project method happens to be named
|
|
2247
|
+
* `remove` — reintroducing, through its own escape hatch, the fabricated-edge
|
|
2248
|
+
* class this filter exists to prevent.
|
|
2249
|
+
*
|
|
2250
|
+
* Resolving the specifier is the same question resolveViaImport will ask
|
|
2251
|
+
* next, so a receiver that passes here is one the qualified path can actually
|
|
2252
|
+
* serve; anything else stays a silent miss rather than a wrong edge.
|
|
2253
|
+
*/
|
|
2254
|
+
isPythonProjectModule(ref, receiver) {
|
|
2255
|
+
for (const imp of this.context.getImportMappings(ref.filePath, ref.language)) {
|
|
2256
|
+
if (imp.localName !== receiver)
|
|
2257
|
+
continue;
|
|
2258
|
+
// `import pkg.mod` / `import pkg.mod as m` binds the module `source`
|
|
2259
|
+
// names. `from pkg import mod` binds `pkg.mod`, and `from . import mod`
|
|
2260
|
+
// binds `.mod` — join without doubling the dot that makes `.` mean the
|
|
2261
|
+
// current package.
|
|
2262
|
+
const specifier = imp.isNamespace
|
|
2263
|
+
? imp.source
|
|
2264
|
+
: imp.source.endsWith('.')
|
|
2265
|
+
? `${imp.source}${imp.exportedName}`
|
|
2266
|
+
: `${imp.source}.${imp.exportedName}`;
|
|
2267
|
+
if ((0, import_resolver_1.resolveImportPath)(specifier, ref.filePath, ref.language, this.context)) {
|
|
2268
|
+
return true;
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
return false;
|
|
2272
|
+
}
|
|
1929
2273
|
/**
|
|
1930
2274
|
* Check if reference is to a built-in or external symbol
|
|
1931
2275
|
*/
|
|
@@ -1934,7 +2278,7 @@ class ReferenceResolver {
|
|
|
1934
2278
|
const isJsTs = ref.language === 'typescript' || ref.language === 'javascript'
|
|
1935
2279
|
|| ref.language === 'tsx' || ref.language === 'jsx' || ref.language === 'arkts';
|
|
1936
2280
|
// JavaScript/TypeScript built-ins
|
|
1937
|
-
if (isJsTs && JS_BUILT_INS.has(name)) {
|
|
2281
|
+
if (isJsTs && js_builtins_1.JS_BUILT_INS.has(name)) {
|
|
1938
2282
|
return true;
|
|
1939
2283
|
}
|
|
1940
2284
|
// ArkTS resource-reference intrinsics — `$r('app.string.x')` /
|
|
@@ -1968,10 +2312,27 @@ class ReferenceResolver {
|
|
|
1968
2312
|
}
|
|
1969
2313
|
// Filter built-in methods on non-class receivers
|
|
1970
2314
|
// (e.g., items.append where items is a local list variable)
|
|
1971
|
-
// But allow if the capitalized receiver matches a known codebase class
|
|
2315
|
+
// But allow if the capitalized receiver matches a known codebase class,
|
|
2316
|
+
// OR the receiver is itself an imported project module — a module can
|
|
2317
|
+
// export a top-level function sharing a common collection-method name
|
|
2318
|
+
// (`ledger.append`, `from . import ledger`), and that call is a real
|
|
2319
|
+
// project dependency, not `list.append` (#1681). Without this, the
|
|
2320
|
+
// qualified ref never reaches resolveViaImport / resolvePythonModuleMember.
|
|
1972
2321
|
if (PYTHON_BUILT_IN_METHODS.has(method)) {
|
|
2322
|
+
// A module-scope collection binding is stronger evidence than a
|
|
2323
|
+
// coincidentally matching class name (#1652). Only use this file's
|
|
2324
|
+
// binding: an unrelated module may reuse the receiver for a collection.
|
|
2325
|
+
const isCollection = this.context.getNodesByName(receiver).some((node) => node.language === 'python' && node.filePath === ref.filePath &&
|
|
2326
|
+
(node.kind === 'variable' || node.kind === 'constant') &&
|
|
2327
|
+
node.qualifiedName === receiver &&
|
|
2328
|
+
/^=\s*(?:[\[{]|(?:dict|list|set|tuple|frozenset)\s*\(|\(\s*\)|\([^()]*,)/.test(node.signature ?? ''));
|
|
2329
|
+
if (isCollection)
|
|
2330
|
+
return true;
|
|
1973
2331
|
const capitalized = receiver.charAt(0).toUpperCase() + receiver.slice(1);
|
|
1974
|
-
|
|
2332
|
+
const isKnownClass = this.context.getNodesByName(capitalized).some((node) => node.language === 'python' &&
|
|
2333
|
+
(node.kind === 'class' || node.kind === 'struct' || node.kind === 'interface'));
|
|
2334
|
+
const isProjectModule = !isKnownClass && this.isPythonProjectModule(ref, receiver);
|
|
2335
|
+
if (!isKnownClass && !isProjectModule) {
|
|
1975
2336
|
return true;
|
|
1976
2337
|
}
|
|
1977
2338
|
}
|
|
@@ -1979,9 +2340,8 @@ class ReferenceResolver {
|
|
|
1979
2340
|
// A bare name colliding with a builtin method (index, get, update, count…)
|
|
1980
2341
|
// is only a builtin when NOTHING in the codebase declares it. A declared
|
|
1981
2342
|
// symbol with that exact name — e.g. a Flask/FastAPI view `def index()` or
|
|
1982
|
-
// `def get()` — is a real reference target.
|
|
1983
|
-
//
|
|
1984
|
-
// method silently loses its route→handler edge.
|
|
2343
|
+
// `def get()` — is a real reference target. Without this guard, every
|
|
2344
|
+
// handler named after a builtin method silently loses its route→handler edge.
|
|
1985
2345
|
if (PYTHON_BUILT_IN_METHODS.has(name) && !this.knownNames?.has(name)) {
|
|
1986
2346
|
return true;
|
|
1987
2347
|
}
|
|
@@ -2032,28 +2392,16 @@ class ReferenceResolver {
|
|
|
2032
2392
|
* Get file path from node ID
|
|
2033
2393
|
*/
|
|
2034
2394
|
getFilePathFromNodeId(nodeId) {
|
|
2035
|
-
const node = this.
|
|
2395
|
+
const node = this.nodeById(nodeId);
|
|
2036
2396
|
return node?.filePath || '';
|
|
2037
2397
|
}
|
|
2038
2398
|
/**
|
|
2039
2399
|
* Get language from node ID
|
|
2040
2400
|
*/
|
|
2041
2401
|
getLanguageFromNodeId(nodeId) {
|
|
2042
|
-
const node = this.
|
|
2402
|
+
const node = this.nodeById(nodeId);
|
|
2043
2403
|
return node?.language || 'unknown';
|
|
2044
2404
|
}
|
|
2045
|
-
/**
|
|
2046
|
-
* Drop an import/name-strategy resolution that crosses a language family.
|
|
2047
|
-
* Two regimes (mirrors `applyLanguageGate`'s candidate filter):
|
|
2048
|
-
* - `references` (type usage): STRICT — a `Type.member` static read names a
|
|
2049
|
-
* same-family type, never a coincidentally same-named symbol in another
|
|
2050
|
-
* language. Drops any non-same-family target.
|
|
2051
|
-
* - `imports` (import binding / `#include`): both-known — a C++ `#include
|
|
2052
|
-
* "X.h"` must not resolve to a same-named ObjC header on another platform
|
|
2053
|
-
* (basename collision), but a singleton-family / SFC language (`vue` →
|
|
2054
|
-
* `.ts`) importing across is left alone.
|
|
2055
|
-
* Applies to the import (strategy 2) + name-match (strategy 3) results.
|
|
2056
|
-
*/
|
|
2057
2405
|
/**
|
|
2058
2406
|
* Collect the `@using` namespaces in scope for a `.razor`/`.cshtml` file: its
|
|
2059
2407
|
* own `@using` directives plus every `_Imports.razor` from the file's folder up
|
|
@@ -2211,7 +2559,7 @@ class ReferenceResolver {
|
|
|
2211
2559
|
const member = ref.referenceName.slice('this.'.length);
|
|
2212
2560
|
if (!member)
|
|
2213
2561
|
return null;
|
|
2214
|
-
const fromNode = this.
|
|
2562
|
+
const fromNode = this.nodeById(ref.fromNodeId);
|
|
2215
2563
|
if (!fromNode)
|
|
2216
2564
|
return null;
|
|
2217
2565
|
// A hook declared at class-body level (Ruby `before_action :authenticate`)
|
|
@@ -2236,7 +2584,7 @@ class ReferenceResolver {
|
|
|
2236
2584
|
// Not on the class itself — possibly INHERITED. implements/extends
|
|
2237
2585
|
// edges don't exist yet in this pass, so retry in the supertype pass
|
|
2238
2586
|
// (resolveDeferredThisMemberRefs) instead of giving up.
|
|
2239
|
-
this.
|
|
2587
|
+
this.deferReference(ref, this.deferredThisMemberRefs);
|
|
2240
2588
|
return null;
|
|
2241
2589
|
}
|
|
2242
2590
|
const target = candidates.reduce((a, b) => (a.startLine <= b.startLine ? a : b));
|
|
@@ -2267,10 +2615,41 @@ class ReferenceResolver {
|
|
|
2267
2615
|
// periodically so the #850 liveness watchdog heartbeat can fire (#1091).
|
|
2268
2616
|
const maybeYield = (0, cooperative_yield_1.createYielder)();
|
|
2269
2617
|
const resolved = [];
|
|
2618
|
+
// Refs share supertypes (every `this.dispose` walks the same chain), and
|
|
2619
|
+
// nothing is written until the loop ends: read each type's supertype
|
|
2620
|
+
// edges, and each supertype's callable members by name, once.
|
|
2621
|
+
const supertypeEdges = new Map();
|
|
2622
|
+
const callableMembers = new Map();
|
|
2623
|
+
const supertypesOf = (id) => {
|
|
2624
|
+
let edges = supertypeEdges.get(id);
|
|
2625
|
+
if (!edges) {
|
|
2626
|
+
edges = this.queries.getOutgoingEdges(id, ['implements', 'extends']);
|
|
2627
|
+
supertypeEdges.set(id, edges);
|
|
2628
|
+
}
|
|
2629
|
+
return edges;
|
|
2630
|
+
};
|
|
2631
|
+
const callableMembersOf = (id) => {
|
|
2632
|
+
let byName = callableMembers.get(id);
|
|
2633
|
+
if (!byName) {
|
|
2634
|
+
byName = new Map();
|
|
2635
|
+
for (const c of this.queries.getOutgoingEdges(id, ['contains'])) {
|
|
2636
|
+
const m = this.nodeById(c.target);
|
|
2637
|
+
if (!m || (m.kind !== 'function' && m.kind !== 'method'))
|
|
2638
|
+
continue;
|
|
2639
|
+
const list = byName.get(m.name);
|
|
2640
|
+
if (list)
|
|
2641
|
+
list.push(m);
|
|
2642
|
+
else
|
|
2643
|
+
byName.set(m.name, [m]);
|
|
2644
|
+
}
|
|
2645
|
+
callableMembers.set(id, byName);
|
|
2646
|
+
}
|
|
2647
|
+
return byName;
|
|
2648
|
+
};
|
|
2270
2649
|
for (const ref of deferred) {
|
|
2271
2650
|
await maybeYield();
|
|
2272
2651
|
const member = ref.referenceName.slice('this.'.length);
|
|
2273
|
-
const fromNode = this.
|
|
2652
|
+
const fromNode = this.nodeById(ref.fromNodeId);
|
|
2274
2653
|
if (!fromNode || !member)
|
|
2275
2654
|
continue;
|
|
2276
2655
|
// Class-body-level hooks (Ruby) attribute to the CLASS node itself.
|
|
@@ -2310,24 +2689,18 @@ class ReferenceResolver {
|
|
|
2310
2689
|
for (let depth = 0; depth < 5 && frontierNodes.length > 0 && !target; depth++) {
|
|
2311
2690
|
const next = [];
|
|
2312
2691
|
for (const typeNode of frontierNodes) {
|
|
2313
|
-
for (const edge of
|
|
2314
|
-
const superNode = this.
|
|
2692
|
+
for (const edge of supertypesOf(typeNode.id)) {
|
|
2693
|
+
const superNode = this.nodeById(edge.target);
|
|
2315
2694
|
if (!superNode || seenNodes.has(superNode.id))
|
|
2316
2695
|
continue;
|
|
2317
2696
|
seenNodes.add(superNode.id);
|
|
2318
2697
|
if (!SUPERTYPE_BEARING_KINDS.has(superNode.kind))
|
|
2319
2698
|
continue;
|
|
2320
2699
|
// Member lookup anchored on the supertype's contains edges.
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
m.
|
|
2325
|
-
(m.kind === 'function' || m.kind === 'method') &&
|
|
2326
|
-
(0, name_matcher_1.sameLanguageFamily)(m.language, ref.language)) {
|
|
2327
|
-
target = m;
|
|
2328
|
-
break;
|
|
2329
|
-
}
|
|
2330
|
-
}
|
|
2700
|
+
target =
|
|
2701
|
+
callableMembersOf(superNode.id)
|
|
2702
|
+
.get(member)
|
|
2703
|
+
?.find((m) => (0, name_matcher_1.sameLanguageFamily)(m.language, ref.language)) ?? null;
|
|
2331
2704
|
if (target)
|
|
2332
2705
|
break;
|
|
2333
2706
|
next.push(superNode);
|
|
@@ -2346,47 +2719,99 @@ class ReferenceResolver {
|
|
|
2346
2719
|
});
|
|
2347
2720
|
}
|
|
2348
2721
|
}
|
|
2349
|
-
|
|
2350
|
-
return 0;
|
|
2351
|
-
const edges = this.createEdges(resolved);
|
|
2352
|
-
if (edges.length > 0) {
|
|
2353
|
-
this.queries.insertEdges(edges);
|
|
2354
|
-
this.clearCaches();
|
|
2355
|
-
}
|
|
2356
|
-
return edges.length;
|
|
2722
|
+
return this.persistDeferredReferences(deferred, resolved);
|
|
2357
2723
|
}
|
|
2358
|
-
|
|
2724
|
+
/**
|
|
2725
|
+
* Drop a resolution whose target cannot be what the reference names.
|
|
2726
|
+
* Applied at the `resolveOne` seam so it covers every strategy uniformly —
|
|
2727
|
+
* framework, import, name-match, chain, CFML component path.
|
|
2728
|
+
*
|
|
2729
|
+
* For `imports`: the target must be importable. A member that only exists
|
|
2730
|
+
* inside a type never is.
|
|
2731
|
+
*
|
|
2732
|
+
* For `extends`/`implements`, it cannot be describing a real supertype when:
|
|
2733
|
+
*
|
|
2734
|
+
* 1. The target's kind can never be a supertype (an enum member, a method,
|
|
2735
|
+
* a variable). `matchByExactName` additionally narrows its candidate
|
|
2736
|
+
* pool by the same set, so a legitimate supertype outranks a same-named
|
|
2737
|
+
* non-type rather than merely losing its edge.
|
|
2738
|
+
* 2. The name is imported from outside the repo, so NO local node is the
|
|
2739
|
+
* referent. Without this, filtering by kind alone just relocates the
|
|
2740
|
+
* false edge onto the next same-named local type.
|
|
2741
|
+
*
|
|
2742
|
+
* One exception to (1): a TypeScript VALUE that shares its name with a type
|
|
2743
|
+
* in the same file. `export const IFoo = createDecorator<IFoo>('foo')` beside
|
|
2744
|
+
* `export interface IFoo` is how VS Code declares every service, and an
|
|
2745
|
+
* import of `IFoo` resolves to the file with both — a strategy that takes the
|
|
2746
|
+
* first export of that name gets the value. The strategy found the right
|
|
2747
|
+
* file and name; the type declared there is the supertype, so the edge moves
|
|
2748
|
+
* to it rather than being dropped (dropping it lost ~900 `implements` edges
|
|
2749
|
+
* on vscode).
|
|
2750
|
+
*
|
|
2751
|
+
* Otherwise this only ever REMOVES an edge, never adds one. A dropped ref
|
|
2752
|
+
* stays in `unresolved_refs` as `failed`, which is the honest record for a
|
|
2753
|
+
* supertype that lives outside the repo — silent beats wrong.
|
|
2754
|
+
*/
|
|
2755
|
+
gateTargetKind(result, ref) {
|
|
2359
2756
|
if (!result)
|
|
2360
2757
|
return result;
|
|
2361
|
-
|
|
2362
|
-
|
|
2758
|
+
// A `#define` is a value, never a callee (#1838): a macro defined only in
|
|
2759
|
+
// an unrelated file is not what `NAME(x)` here expands to either.
|
|
2760
|
+
if (ref.referenceKind === 'calls') {
|
|
2761
|
+
const target = this.nodeById(result.targetNodeId);
|
|
2762
|
+
if (target?.kind === 'constant' && types_1.CPP_DEFINE_SIGNATURE.test(target.signature ?? ''))
|
|
2763
|
+
return null;
|
|
2764
|
+
}
|
|
2765
|
+
// An `imports` reference names something importable — never a member that
|
|
2766
|
+
// only exists inside a type.
|
|
2767
|
+
if (ref.referenceKind === 'imports') {
|
|
2768
|
+
const target = this.nodeById(result.targetNodeId);
|
|
2769
|
+
return target && !(0, types_1.isImportableKind)(target.kind) ? null : result;
|
|
2770
|
+
}
|
|
2771
|
+
if (!(0, types_1.isInheritanceRef)(ref))
|
|
2363
2772
|
return result;
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2773
|
+
const target = this.nodeById(result.targetNodeId);
|
|
2774
|
+
if (target && !(0, types_1.isSupertypeTarget)(target)) {
|
|
2775
|
+
const type = this.sameNamedTypeOfValue(target);
|
|
2776
|
+
if (!type)
|
|
2777
|
+
return null;
|
|
2778
|
+
result = { ...result, targetNodeId: type.id };
|
|
2779
|
+
}
|
|
2780
|
+
if ((0, import_resolver_1.isBoundToOutOfRepoImport)(ref, this.context))
|
|
2367
2781
|
return null;
|
|
2368
2782
|
return result;
|
|
2369
2783
|
}
|
|
2784
|
+
/** The one supertype-kind node a TypeScript value shares its name and file with. */
|
|
2785
|
+
sameNamedTypeOfValue(value) {
|
|
2786
|
+
if (value.kind !== 'constant' && value.kind !== 'variable')
|
|
2787
|
+
return null;
|
|
2788
|
+
if (value.language !== 'typescript' && value.language !== 'tsx')
|
|
2789
|
+
return null;
|
|
2790
|
+
const types = this.context
|
|
2791
|
+
.getNodesInFile(value.filePath)
|
|
2792
|
+
.filter((n) => n.name === value.name && (0, types_1.isSupertypeTarget)(n));
|
|
2793
|
+
return types.length === 1 ? types[0] : null;
|
|
2794
|
+
}
|
|
2795
|
+
gateLanguage(result, ref) {
|
|
2796
|
+
if (!result)
|
|
2797
|
+
return result;
|
|
2798
|
+
return (0, name_matcher_1.gateLanguageMatch)(result, ref, this.context);
|
|
2799
|
+
}
|
|
2370
2800
|
/**
|
|
2371
|
-
*
|
|
2372
|
-
*
|
|
2373
|
-
*
|
|
2374
|
-
* bridges, but those legitimate bridges are either `calls` edges (RN/Expo
|
|
2375
|
-
* JS → native) or config↔code edges whose config side (`yaml`/`blade`/…) is
|
|
2376
|
-
* not a known programming-language family. A `references`/`imports` edge
|
|
2377
|
-
* between two *known* families is always a coincidental name collision — the
|
|
2378
|
-
* React/Svelte/Vue PascalCase component resolvers name-match `getNodesByName`
|
|
2379
|
-
* without a language check, so a TS `<TestRunner>` ref happily matched a
|
|
2380
|
-
* Kotlin `class TestRunner`. Gating only the both-known-cross-family case
|
|
2381
|
-
* lets config bridges and `calls` bridges through untouched.
|
|
2801
|
+
* Framework calls carry bridge evidence (RN/Expo JS → native). Other
|
|
2802
|
+
* framework results obey the same code-family boundary as name matches;
|
|
2803
|
+
* markup/config transitions remain open.
|
|
2382
2804
|
*/
|
|
2383
2805
|
gateFrameworkLanguage(result, ref) {
|
|
2384
2806
|
if (!result)
|
|
2385
2807
|
return result;
|
|
2386
|
-
if (ref.referenceKind
|
|
2808
|
+
if (ref.referenceKind === 'calls')
|
|
2387
2809
|
return result;
|
|
2388
2810
|
const tgt = this.getLanguageFromNodeId(result.targetNodeId);
|
|
2389
|
-
|
|
2811
|
+
// Package imports cannot target prose found by a framework's name lookup.
|
|
2812
|
+
if (ref.referenceKind === 'imports' && tgt === 'markdown' && ref.language !== 'markdown')
|
|
2813
|
+
return null;
|
|
2814
|
+
if (tgt && ref.language && (0, name_matcher_1.crossesCodeBoundary)(tgt, ref.language))
|
|
2390
2815
|
return null;
|
|
2391
2816
|
return result;
|
|
2392
2817
|
}
|