cg-code-graph 0.23.4__tar.gz → 0.23.6__tar.gz
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.
- {cg_code_graph-0.23.4/cg_code_graph.egg-info → cg_code_graph-0.23.6}/PKG-INFO +1 -1
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/__init__.py +1 -1
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/blindspots.py +26 -6
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/cli.py +3 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/core/plugin.py +3 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/link.py +28 -5
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plans.py +3 -6
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/kotlin/plugin.py +82 -3
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/laravel/plugin.py +55 -2
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/laravel/tests.py +4 -6
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/nuxt/plugin.py +207 -11
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/php/extractor/extract.php +340 -3
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/php/plugin.py +54 -6
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/python/plugin.py +22 -3
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/swift/plugin.py +52 -1
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/ts/extractor/extract.mjs +46 -2
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/query.py +165 -10
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/routes.py +56 -3
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/webhook_subs.py +2 -3
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6/cg_code_graph.egg-info}/PKG-INFO +1 -1
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph.egg-info/SOURCES.txt +4 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_channels_tests.py +4 -4
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_external.py +1 -1
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_fp_batch.py +8 -8
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_inline_guards.py +65 -65
- cg_code_graph-0.23.6/tests/test_issue_212_langs.py +165 -0
- cg_code_graph-0.23.6/tests/test_issue_218.py +107 -0
- cg_code_graph-0.23.6/tests/test_laravel_receiver_narrowing.py +130 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_laravel_resources.py +1 -1
- cg_code_graph-0.23.6/tests/test_laravel_route_paths.py +279 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_mass_assignment.py +1 -1
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_mcp_index.py +2 -2
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_nuxt_nitro.py +54 -2
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_nuxt_rootsrc.py +2 -2
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_php_http.py +2 -2
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_plans.py +3 -3
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_request_keys.py +8 -8
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_routes_search_explain.py +14 -14
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_surface.py +5 -5
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_ts_nuxt.py +2 -2
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_unguarded.py +10 -10
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_values.py +1 -1
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_webhooks.py +5 -5
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_webhooks_152.py +10 -10
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_webhooks_152b.py +8 -8
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/LICENSE +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/MANIFEST.in +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/README.md +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/__main__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/affected.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/agent_rules.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/agents.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/aitools.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/android_ipc.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/apple_ipc.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/apps.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/bridges.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/brokers.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/concepts.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/config.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/core/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/core/cache.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/core/detect.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/core/env.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/core/extractors.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/core/fsutil.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/core/generated.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/core/model.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/core/paths.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/core/redact.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/core/store.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/core/syntax_errors.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/coverage.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/dart_isolates.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/doctor.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/explore.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/external.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/graphql.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/guard_facts.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/hooks.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/indexer.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/insecure_transport.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/install_rules.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/jobs.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/lint_async.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/local_ipc.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/local_sockets.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/mcp_graphs.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/mcp_install.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/mcp_server.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/parity.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/parity_structure.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/payload.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/platform_scan.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/platforms.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/astro/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/astro/content.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/astro/plugin.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/cfamily/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/cfamily/plugin.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/cfamily/syntax.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/dart/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/dart/bridges.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/dart/extractor/bin/extract.dart +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/dart/extractor/pubspec.lock +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/dart/extractor/pubspec.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/dart/http.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/dart/models.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/dart/plugin.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/dart/program.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/django/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/django/extras.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/django/models.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/django/plugin.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/django/schemas.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/django/shapes.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/django/urls.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/express/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/express/plugin.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/flutter/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/flutter/plugin.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/java/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/java/exact.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/java/plugin.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/jvm/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/jvm/interop.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/jvm/spring.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/kotlin/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/kotlin/exact.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/kotlin/reparse.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/laravel/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/laravel/broadcast.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/laravel/massassign.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/laravel/values.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/native/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/native/gates.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/native/runner.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/native/scipread.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/native/ts.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/nest/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/nest/plugin.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/nextjs/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/nextjs/plugin.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/nuxt/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/php/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/php/external.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/php/extractor/composer.json +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/php/extractor/composer.lock +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/php/gating.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/php/http_client.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/php/inline_guards.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/php/strings.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/python/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/python/aitools.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/python/external.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/python/fields.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/python/refs.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/python/roots.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/python/socketio.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/python/subproc.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/python/tests.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/python/values.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/pyweb/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/pyweb/plugin.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/pyweb/values.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/rust/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/rust/cargo.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/rust/plugin.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/rust/syntax.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/scip/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/scip/importer.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/scip/scip.proto +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/scip/scip_pb2.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/stubs/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/stubs/plugins.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/swift/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/swift/baseurl.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/swift/exact.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/swift/indexstore.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/swift/packages.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/ts/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/ts/baseurl.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/ts/extractor/fw.mjs +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/ts/extractor/package-lock.json +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/ts/extractor/package.json +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/ts/extractor/rr.mjs +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/ts/nav.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/ts/plugin.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/ts/react_router.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/tsweb/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/tsweb/common.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/plugins/tsweb/data.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/c_cpp.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/common.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/dart.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/django-ninja.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/django.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/djangorestframework.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/express.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/java.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/kotlin.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/laravel.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/nest.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/nextjs.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/nuxt.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/php.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/python.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/react-router.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/rust.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/spring.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/swift.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/presets/typescript.yaml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/process_runs.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/protocols/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/protocols/builtin.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/protocols/matchers.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/protocols/view.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/realtime.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/realtime_events.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/realtime_native.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/realtime_ws.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/roundtrip.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/rpc.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/sdk_systems.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/sockets.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/ssrf_input.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/starters.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/surface.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/tests_index.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/udp_apps.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/update_check.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/viz/__init__.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/viz/graph.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/viz/server.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/viz/static/app.css +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/viz/static/app.js +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/viz/static/index.html +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/viz/static/layered.js +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/viz/static/vendor/VERSIONS.txt +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/viz/static/vendor/cose-base.js +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/viz/static/vendor/cytoscape-fcose.js +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/viz/static/vendor/cytoscape.min.js +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/viz/static/vendor/layout-base.js +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/viz/tools/package-lock.json +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/viz/tools/package.json +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/viz/tools/shoot.mjs +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/watch.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/webhooks.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph/xcode.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph.egg-info/dependency_links.txt +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph.egg-info/entry_points.txt +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph.egg-info/requires.txt +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/cg_code_graph.egg-info/top_level.txt +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/pyproject.toml +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/setup.cfg +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_affected.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_agents_install.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_agents_md.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_ai_tools.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_android_ipc.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_apple_ipc.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_astro.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_astro_content.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_astro_server.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_bridges.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_bridges_pigeon_monorepo.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_brokers.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_cache_clean.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_cache_invalidation.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_cache_migration.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_cli_output.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_completeness.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_config_extras.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_coverage.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_coverage_ts_hint.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_dart_isolates.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_db_connections.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_dead_wrappers.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_dispatch_interfaces.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_django_flutter.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_docs_languages.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_docs_links.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_echo_ref.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_echo_wrapper.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_elysia.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_enum_constants.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_env.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_explore.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_gating.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_generated.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_graphql.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_hooks.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_impact_overrides.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_index_isolation.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_inherited_overrides.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_install_rules.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_issue_192.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_issue_201.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_issue_202.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_issue_203.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_issue_204.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_issue_205.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_issue_206.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_issue_207.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_issue_208.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_issue_209.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_issue_210.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_issue_211.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_issue_211_used_at.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_issue_212.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_issue_219.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_java.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_java_exact.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_jobs.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_js_refs.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_js_runtime.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_kotlin.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_kotlin_binding.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_kotlin_exact.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_kotlin_fields.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_kotlin_mixed.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_kotlin_nav_consts.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_kotlin_props.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_laravel_determinism.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_link_origin.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_lint_async.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_listing_files.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_local_ipc.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_local_sockets.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_mcp.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_mcp_install.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_mcp_instructions.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_mcp_multi_graph.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_native_cfamily.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_native_concurrency.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_native_rust.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_nuxt_i18n.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_nuxt_import_dirs.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_nuxt_side_dirs.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_packaging.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_parity.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_parity_structure.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_php_props.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_plain_js.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_platform_gaps.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_platform_type_variants.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_platforms.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_platforms_apple.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_presets_config.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_process_ipc.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_process_runs.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_protocols.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_python_app_tests_module.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_python_collection_chains.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_python_compat.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_python_entry_refs.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_python_fields.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_python_infer_cycles.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_python_roots.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_python_subprocess_tests.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_python_tests.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_python_web_hosts.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_python_web_routes.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_python_web_routes_more.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_react_router.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_readers_writers_specs.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_realtime.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_realtime_native.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_redact_salt.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_roundtrip.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_route_specs.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_route_tables.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_rpc.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_scip_health.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_sdk_external.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_sdk_external_infra.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_sdk_external_mail.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_snippet.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_sockets.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_spring.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_ssrf.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_starters_budget.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_surface_transport.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_swift.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_swift_binding.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_swift_exact.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_swift_facts.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_swift_fields.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_swift_modules.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_swift_more.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_swift_nav_values.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_swift_parse_errors.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_swift_props.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_swift_sdk.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_swift_testing.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_swift_values.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_tests_scope.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_ts_fields.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_ts_fields_js_vue.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_ts_file_specs.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_ts_frameworks.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_ts_node_http.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_ts_src_tsconfig.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_update_check.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_viz.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_vue_nav.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_watch.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_websockets.py +0 -0
- {cg_code_graph-0.23.4 → cg_code_graph-0.23.6}/tests/test_workspace_link.py +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""code-graph: deterministic code knowledge graph (beta)."""
|
|
2
|
-
__version__ = "0.23.
|
|
2
|
+
__version__ = "0.23.6"
|
|
@@ -222,11 +222,23 @@ def express_loop_routes(root: Path, files: list[str]) -> dict | None:
|
|
|
222
222
|
_PHP_LOOPS = re.compile(r"\b(?:foreach|for|while)\s*\(|->\s*(?:each|map|flatMap|eachSpread)\s*\(|\barray_(?:map|walk)\s*\(")
|
|
223
223
|
|
|
224
224
|
|
|
225
|
-
def laravel_loop_routes(root: Path, files: list[str]) -> dict | None:
|
|
226
|
-
"""Route::get(...) inside foreach / for / ->each(...) / array_map(...)
|
|
227
|
-
|
|
225
|
+
def laravel_loop_routes(root: Path, files: list[str], builder=None) -> dict | None:
|
|
226
|
+
"""Route::get(...) inside foreach / for / ->each(...) / array_map(...) that the Laravel plugin did not unroll.
|
|
227
|
+
|
|
228
|
+
Loops over literal data in route files are unrolled (#184); the plugin records every loop it saw in
|
|
229
|
+
`builder.route_loops` ({file: [{line, end, unrolled, reason}]}). The ones it could not unroll are reported with
|
|
230
|
+
their reason (`iterable not literal`); the regex below still finds loops outside route files."""
|
|
228
231
|
hits = []
|
|
232
|
+
reasons: dict[str, str] = {}
|
|
233
|
+
known = getattr(builder, "route_loops", None) or {}
|
|
234
|
+
for rel, loops in known.items():
|
|
235
|
+
for lp in loops:
|
|
236
|
+
if not lp.get("unrolled"):
|
|
237
|
+
hits.append((rel, lp["line"]))
|
|
238
|
+
if lp.get("reason"):
|
|
239
|
+
reasons[f"{rel}:{lp['line']}"] = lp["reason"]
|
|
229
240
|
for rel in files:
|
|
241
|
+
spans = [(lp["line"], lp.get("end") or lp["line"]) for lp in known.get(rel, [])]
|
|
230
242
|
src = _read(root, rel)
|
|
231
243
|
if not src or "Route::" not in src:
|
|
232
244
|
continue
|
|
@@ -237,9 +249,17 @@ def laravel_loop_routes(root: Path, files: list[str]) -> dict | None:
|
|
|
237
249
|
continue
|
|
238
250
|
if re.search(r"\bRoute::\s*(?:get|post|put|patch|delete|any|match|resource|apiResource|resources|apiResources|view|redirect)\s*\(",
|
|
239
251
|
src[b0:b1]):
|
|
240
|
-
|
|
252
|
+
ln = _line(src, start)
|
|
253
|
+
if not any(lo <= ln <= hi for lo, hi in spans):
|
|
254
|
+
hits.append((rel, ln))
|
|
241
255
|
done_until = b1
|
|
242
|
-
|
|
256
|
+
out = _finding("laravel_loop_routes", hits)
|
|
257
|
+
if out and reasons:
|
|
258
|
+
out["reasons"] = {k: reasons[k] for k in out["samples"] if k in reasons}
|
|
259
|
+
why = sorted(set(out["reasons"].values()))
|
|
260
|
+
if why:
|
|
261
|
+
out["what"] = f"{out['what']} ({'; '.join(why)})"
|
|
262
|
+
return out
|
|
243
263
|
|
|
244
264
|
|
|
245
265
|
# ------------------------------------------------------------------------------------------- Django (AST)
|
|
@@ -549,7 +569,7 @@ def detect(root: str | Path, files_by_ext: dict[str, list[str]], builder=None, p
|
|
|
549
569
|
run(nuxt_unevaluable_import_dirs, root)
|
|
550
570
|
run(vue_unresolved_navigation, builder)
|
|
551
571
|
run(ts_unrecognised_http_client, root, js, builder)
|
|
552
|
-
run(laravel_loop_routes, root, php)
|
|
572
|
+
run(laravel_loop_routes, root, php, builder)
|
|
553
573
|
py = programs.get("python")
|
|
554
574
|
if py is not None:
|
|
555
575
|
run(django_dynamic_urlpatterns, [(m.file, m.tree) for m in py.modules.values()])
|
|
@@ -826,6 +826,9 @@ def main(argv=None):
|
|
|
826
826
|
def _unknown_route(st, spec: str, as_json: bool) -> bool:
|
|
827
827
|
miss = Q.route_failure(st, spec)
|
|
828
828
|
if not miss:
|
|
829
|
+
note = Q.route_declared_note(st, spec)
|
|
830
|
+
if note:
|
|
831
|
+
print(note, file=sys.stderr)
|
|
829
832
|
return False
|
|
830
833
|
if as_json:
|
|
831
834
|
print(json.dumps({"error": miss["error"], "spec": miss["spec"], "suggestions": miss["suggestions"]}))
|
|
@@ -59,6 +59,9 @@ class GraphBuilder:
|
|
|
59
59
|
# Pigeon API definitions found by the Dart plugin ({Api: {kind: host | flutter, methods, file}}): bridges.py
|
|
60
60
|
# links their native implementations / native callers
|
|
61
61
|
self.pigeon_apis: dict = {}
|
|
62
|
+
# loops around route registrations in Laravel route files ({file: [{line, end, unrolled, reason}]}, #184):
|
|
63
|
+
# the blind-spot detector reports the ones that were not unrolled
|
|
64
|
+
self.route_loops: dict = {}
|
|
62
65
|
# keyed-hash salt for the markers that stand in for secret values (cg_code_graph/core/redact.py); the indexer
|
|
63
66
|
# sets it from the graph DB before any plugin runs
|
|
64
67
|
self.redact_salt: str | None = None
|
|
@@ -11,8 +11,11 @@ graphs (role backend, frontend or both):
|
|
|
11
11
|
Matching is deterministic (no guessing):
|
|
12
12
|
- the client path is the extractor's URL template with the origin (scheme://host or the
|
|
13
13
|
unknown server-URL placeholder) and query string removed;
|
|
14
|
-
- backend URIs are tried
|
|
15
|
-
prefix
|
|
14
|
+
- backend URIs are tried at the path the server serves them under: a Laravel route of routes/api.php is
|
|
15
|
+
stored with its API prefix (`apiPrefix` in bootstrap/app.php, a RouteServiceProvider group, `api` by
|
|
16
|
+
default) and keeps its declared path in attrs.declared_uri. When no prefix configuration was found
|
|
17
|
+
(the `api` default) the declared path is tried as well, and a route from an older graph without
|
|
18
|
+
declared_uri gets the `/api` + uri variant (see route_uri_variants);
|
|
16
19
|
- segments match when literal == literal, client placeholder <-> route {param},
|
|
17
20
|
client literal -> route {param} (resolved), or a client segment with an embedded
|
|
18
21
|
placeholder fully matches a route literal (heuristic, e.g. export.{format} ~ export.csv);
|
|
@@ -39,6 +42,28 @@ from types import SimpleNamespace
|
|
|
39
42
|
from .core.model import CONFIDENCE_RANK
|
|
40
43
|
from .core.store import GraphStore
|
|
41
44
|
|
|
45
|
+
|
|
46
|
+
_API_ROUTE_FILE = re.compile(r"(^|/)routes/api(\.php$|/)")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def route_uri_variants(file: str | None, attrs: dict) -> list[tuple[str, str]]:
|
|
50
|
+
"""(variant, uri) pairs a route answers to. `file` is the route node's file (with or without a repo prefix).
|
|
51
|
+
|
|
52
|
+
A Laravel route stores the served path (#191): attrs.uri carries the API prefix and attrs.declared_uri the
|
|
53
|
+
path as written. The declared path is also tried when the prefix is Laravel's default rather than read from
|
|
54
|
+
configuration. A route without declared_uri from routes/api.php (an older graph) gets the `/api` variant."""
|
|
55
|
+
uri = attrs.get("uri")
|
|
56
|
+
out = [("as-declared", uri)]
|
|
57
|
+
declared = attrs.get("declared_uri")
|
|
58
|
+
if declared:
|
|
59
|
+
out = [("served", uri)]
|
|
60
|
+
if attrs.get("prefix_from") == "laravel-default" and declared != uri:
|
|
61
|
+
out.append(("declared, without the default /api prefix", declared))
|
|
62
|
+
return out
|
|
63
|
+
if _API_ROUTE_FILE.search(file or "") and uri and not uri.startswith("/api/"):
|
|
64
|
+
out.append(("api-prefixed", "/api" + uri))
|
|
65
|
+
return out
|
|
66
|
+
|
|
42
67
|
PARAM = re.compile(r"^\{(\w+)(\?)?\}$")
|
|
43
68
|
CATCH_ALL = re.compile(r"^\{(\w+)\*(\?)?\}$") # {rest*} one or more segments, {rest*?} zero or more (TS routers, Next.js)
|
|
44
69
|
PH = re.compile(r"\{[^{}]*\}")
|
|
@@ -401,9 +426,7 @@ def link_many(repos: list[tuple[str, str, str]], out_db: str, *, allow: dict | N
|
|
|
401
426
|
uri, method = a.get("uri"), a.get("method")
|
|
402
427
|
if not uri or not method:
|
|
403
428
|
continue
|
|
404
|
-
uris = [
|
|
405
|
-
if (r[1] or "").startswith("routes/api.php") or (r[1] or "").startswith("routes/api/"):
|
|
406
|
-
uris.append(("api-prefixed", "/api" + uri))
|
|
429
|
+
uris = route_uri_variants(r[1], a)
|
|
407
430
|
routes.append({"id": mid(name, r[0]), "uri": uri, "method": method, "uris": uris, "server": name,
|
|
408
431
|
"file": f"{name}/{r[1]}" if r[1] else None, "line": r[3],
|
|
409
432
|
"attrs": dict(a, _file=r[1], _line=r[3])})
|
|
@@ -21,6 +21,7 @@ from . import presets
|
|
|
21
21
|
from . import query as Q
|
|
22
22
|
from .core.model import PROPAGATING
|
|
23
23
|
from .core.store import GraphStore
|
|
24
|
+
from .link import route_uri_variants
|
|
24
25
|
|
|
25
26
|
PLAN_VERSION = 1
|
|
26
27
|
STATUSES = ("draft", "agreed", "in_progress", "implemented", "abandoned")
|
|
@@ -419,10 +420,8 @@ class Ctx:
|
|
|
419
420
|
a = json.loads(r["attrs"] or "{}")
|
|
420
421
|
if not a.get("uri") or not a.get("method"):
|
|
421
422
|
continue
|
|
422
|
-
uris = [("as-declared", a["uri"])]
|
|
423
423
|
f = (r["file"] or "").split("/", 1)[-1] if self.combined else (r["file"] or "")
|
|
424
|
-
|
|
425
|
-
uris.append(("api-prefixed", "/api" + a["uri"]))
|
|
424
|
+
uris = route_uri_variants(f, a)
|
|
426
425
|
out.append({"id": r["id"], "uri": a["uri"], "method": a["method"], "uris": uris, "file": r["file"], "line": r["line"]})
|
|
427
426
|
return out
|
|
428
427
|
|
|
@@ -796,10 +795,8 @@ def snapshot_clients(st, route_ids, root: str | Path | None = None) -> list[dict
|
|
|
796
795
|
a = json.loads(r["attrs"] or "{}")
|
|
797
796
|
if not a.get("uri") or not a.get("method"):
|
|
798
797
|
continue
|
|
799
|
-
uris = [("as-declared", a["uri"])]
|
|
800
798
|
rf = (r["file"] or "").split("/", 1)[-1] if combined else (r["file"] or "")
|
|
801
|
-
|
|
802
|
-
uris.append(("api-prefixed", "/api" + a["uri"]))
|
|
799
|
+
uris = route_uri_variants(rf, a)
|
|
803
800
|
routes.append({"id": r["id"], "uri": a["uri"], "method": a["method"], "uris": uris,
|
|
804
801
|
"file": r["file"], "line": r["line"]})
|
|
805
802
|
hit = [m["route"] for m in match_endpoint(c.get("method") or "GET", base + c["path"], routes)["matched"]
|
|
@@ -305,6 +305,9 @@ class KotlinPlugin(LanguagePlugin):
|
|
|
305
305
|
self.calls: list[tuple] = []
|
|
306
306
|
self.unresolved_calls: list[tuple] = [] # (owner_id, name, receiver, line, file obj, decl)
|
|
307
307
|
self.call_branch: dict = {} # (owner_id, line, name) -> {branch, branch_line} (#88)
|
|
308
|
+
self.call_default: dict = {} # (owner_id, line, name) -> parameter whose default holds the call (#212)
|
|
309
|
+
self.call_args: dict = {} # (owner_id, line, name) -> (positional count, named labels, trailing lambda)
|
|
310
|
+
self.fn_params: dict = {} # function id -> [(name, has default, function type)]
|
|
308
311
|
# properties with a custom accessor, `by lazy` or a delegate are nodes (#89); kept out of by_name / members so
|
|
309
312
|
# a call `x()` never binds to one
|
|
310
313
|
self.props: dict[str, dict] = {} # decl id -> {"property", "accessors"}
|
|
@@ -599,11 +602,14 @@ class KotlinPlugin(LanguagePlugin):
|
|
|
599
602
|
fq = f"{owner}.{nm}" if owner else nm
|
|
600
603
|
kind = "method" if cls else "function"
|
|
601
604
|
params = next((d for d in c.children if d.type == "function_value_parameters"), None)
|
|
605
|
+
fparams = self._param_defaults(params)
|
|
602
606
|
dc = Decl(f"{kind}:{fq}{self._variant(kf, mods)}", kind, nm, fq, kf.rel, c.start_point[0] + 1,
|
|
603
607
|
c.end_point[0] + 1, cls.fqn if cls else None, [], anns, mods, recv,
|
|
604
608
|
self._params(params) if params is not None else {}, kf.test, self._name_line(c),
|
|
605
609
|
slots=self._fn_slots(params))
|
|
606
610
|
self._local_types(c, dc.types)
|
|
611
|
+
if any(dflt for _n, dflt, _f in fparams):
|
|
612
|
+
self.fn_params[dc.id] = fparams
|
|
607
613
|
self._add_decl(dc, kind)
|
|
608
614
|
self._local_fns(c, kf, dc)
|
|
609
615
|
elif ty == "enum_entry" and cls is not None:
|
|
@@ -1161,12 +1167,77 @@ class KotlinPlugin(LanguagePlugin):
|
|
|
1161
1167
|
if typ:
|
|
1162
1168
|
self.navs.append((owner, None, typ, kf.rel, line))
|
|
1163
1169
|
self.calls.append((owner, name, rtext, line, kf, decl, self._accessor(c) if owner in self.props else None))
|
|
1170
|
+
dp = self._default_param(c)
|
|
1171
|
+
if dp:
|
|
1172
|
+
self.call_default[(owner, line, name)] = dp
|
|
1173
|
+
if args is not None:
|
|
1174
|
+
vas = [x for x in args.children if x.type == "value_argument"]
|
|
1175
|
+
named = {self.t(x.children[0]) for x in vas if any(k.type == "=" for k in x.children) and x.children}
|
|
1176
|
+
spread = any(self.t(x).lstrip().startswith("*") for x in vas)
|
|
1177
|
+
self.call_args[(owner, line, name)] = (None if spread else len(vas) - len(named), named, lam is not None)
|
|
1178
|
+
elif lam is not None:
|
|
1179
|
+
self.call_args[(owner, line, name)] = (0, set(), True)
|
|
1164
1180
|
if name[:1].isupper(): # a constructor or a composable: its branch (#88)
|
|
1165
1181
|
br = self._branch(c)
|
|
1166
1182
|
if br:
|
|
1167
1183
|
self.call_branch[(owner, line, name)] = br
|
|
1168
1184
|
return False
|
|
1169
1185
|
|
|
1186
|
+
def _param_defaults(self, fvp) -> list:
|
|
1187
|
+
"""[(name, has a default value, function-typed)] per value parameter of a `function_value_parameters` node."""
|
|
1188
|
+
out = []
|
|
1189
|
+
kids = list(fvp.children) if fvp is not None else []
|
|
1190
|
+
for i, p in enumerate(kids):
|
|
1191
|
+
if p.type != "parameter":
|
|
1192
|
+
continue
|
|
1193
|
+
ids = [x for x in p.children if x.type == "identifier"]
|
|
1194
|
+
if not ids:
|
|
1195
|
+
continue
|
|
1196
|
+
ft = any(x.type == "function_type" or (x.type == "nullable_type" and "->" in self.t(x)) for x in p.children)
|
|
1197
|
+
out.append((self.t(ids[0]), i + 1 < len(kids) and kids[i + 1].type == "=", ft))
|
|
1198
|
+
return out
|
|
1199
|
+
|
|
1200
|
+
def _default_param(self, c) -> str | None:
|
|
1201
|
+
"""The parameter whose default value holds call `c` (`fun render(gamut: Int = currentGamut())`), else None."""
|
|
1202
|
+
x = c
|
|
1203
|
+
while x is not None and x.parent is not None:
|
|
1204
|
+
p = x.parent
|
|
1205
|
+
if p.type == "function_value_parameters":
|
|
1206
|
+
prev = x.prev_sibling
|
|
1207
|
+
if prev is None or prev.type != "=":
|
|
1208
|
+
return None
|
|
1209
|
+
par = prev.prev_sibling
|
|
1210
|
+
ids = [y for y in par.children if y.type == "identifier"] if par is not None and par.type == "parameter" else []
|
|
1211
|
+
return self.t(ids[0]) if ids else None
|
|
1212
|
+
if p.type in ("function_declaration", "lambda_literal", "anonymous_function", "class_body", "function_body"):
|
|
1213
|
+
return None
|
|
1214
|
+
x = p
|
|
1215
|
+
return None
|
|
1216
|
+
|
|
1217
|
+
def _omitted_defaults(self):
|
|
1218
|
+
"""A call that leaves out a defaulted argument runs the default: an edge from the caller to what the default
|
|
1219
|
+
calls, at the call site, with `omits_default` and `default_of` (#212). A call that passes it gets none."""
|
|
1220
|
+
if not self._default_edges:
|
|
1221
|
+
return
|
|
1222
|
+
n = 0
|
|
1223
|
+
for owner, tid, rel, line, key in self._default_sites:
|
|
1224
|
+
defs = self._default_edges.get(tid)
|
|
1225
|
+
params = self.fn_params.get(tid)
|
|
1226
|
+
ca = self.call_args.get(key, (0, set(), False))
|
|
1227
|
+
if not defs or not params or ca[0] is None:
|
|
1228
|
+
continue
|
|
1229
|
+
pos, named, trailing = ca
|
|
1230
|
+
given = {nm for nm, _d, _f in params[:pos]} | named
|
|
1231
|
+
if trailing and params[-1][2]:
|
|
1232
|
+
given.add(params[-1][0])
|
|
1233
|
+
left = {nm for nm, dflt, _f in params if dflt and nm not in given}
|
|
1234
|
+
for label, callee, kind in defs:
|
|
1235
|
+
if label in left and callee != owner:
|
|
1236
|
+
self.b.add_edge(owner, callee, kind, rel, line, HEURISTIC, omits_default=label, default_of=tid)
|
|
1237
|
+
n += 1
|
|
1238
|
+
if n:
|
|
1239
|
+
self.st["default_argument_sites"] = n
|
|
1240
|
+
|
|
1170
1241
|
def _branch(self, c) -> dict:
|
|
1171
1242
|
"""The innermost `if` / `else` / `when` entry around a construction or a composable call inside its function
|
|
1172
1243
|
(#88): attrs.branch (`if (loading)`, `else of if (loading)`, `when Tab.Home`, `else of when (tab)`) and
|
|
@@ -1525,6 +1596,7 @@ class KotlinPlugin(LanguagePlugin):
|
|
|
1525
1596
|
return []
|
|
1526
1597
|
|
|
1527
1598
|
def _resolve_calls(self):
|
|
1599
|
+
self._default_edges, self._default_sites = defaultdict(list), []
|
|
1528
1600
|
for owner, name, recv, line, kf, decl, acc in self.calls:
|
|
1529
1601
|
self._data_access(owner, name, recv, line, kf, decl)
|
|
1530
1602
|
self._how = self._recv = None
|
|
@@ -1543,17 +1615,24 @@ class KotlinPlugin(LanguagePlugin):
|
|
|
1543
1615
|
how["candidates"] = len(targets)
|
|
1544
1616
|
self.st["call_candidate_edges"] += len(targets)
|
|
1545
1617
|
br = self.call_branch.get((owner, line, name), {})
|
|
1618
|
+
dp = self.call_default.get((owner, line, name))
|
|
1619
|
+
da = {"default_arg": dp} if dp else {}
|
|
1546
1620
|
for t in targets[:MAX_CANDIDATES if self._how == "candidate" else 3]:
|
|
1547
1621
|
if t.kind == "class":
|
|
1548
|
-
self.b.add_edge(owner, t.id, "INSTANTIATES", kf.rel, line, HEURISTIC, **br)
|
|
1622
|
+
self.b.add_edge(owner, t.id, "INSTANTIATES", kf.rel, line, HEURISTIC, **br, **da)
|
|
1549
1623
|
ctor = [m for m in self.members.get(t.fqn, {}).get("init", [])]
|
|
1550
1624
|
self.b.add_edge(owner, t.id, "USES_TYPE", kf.rel, line, HEURISTIC, how="constructor call")
|
|
1551
1625
|
for m in ctor:
|
|
1552
|
-
self.b.add_edge(owner, m.id, "CALLS", kf.rel, line, HEURISTIC)
|
|
1626
|
+
self.b.add_edge(owner, m.id, "CALLS", kf.rel, line, HEURISTIC, **da)
|
|
1553
1627
|
else:
|
|
1554
1628
|
composable = br and any(a[0] == "Composable" for a in t.annotations)
|
|
1555
|
-
self.b.add_edge(owner, t.id, "CALLS", kf.rel, line, HEURISTIC, **how, **(br if composable else {}))
|
|
1629
|
+
self.b.add_edge(owner, t.id, "CALLS", kf.rel, line, HEURISTIC, **how, **(br if composable else {}), **da)
|
|
1630
|
+
if self._how != "candidate":
|
|
1631
|
+
self._default_sites.append((owner, t.id, kf.rel, line, (owner, line, name)))
|
|
1632
|
+
if dp:
|
|
1633
|
+
self._default_edges[owner].append((dp, t.id, "INSTANTIATES" if t.kind == "class" else "CALLS"))
|
|
1556
1634
|
self.st["calls_resolved"] += 1
|
|
1635
|
+
self._omitted_defaults()
|
|
1557
1636
|
self._resolve_reads()
|
|
1558
1637
|
self._resolve_fields()
|
|
1559
1638
|
self._resolve_copies()
|
|
@@ -180,6 +180,7 @@ class LaravelPlugin(FrameworkPlugin):
|
|
|
180
180
|
self.observers, self.listeners, self.schedules, self.bindings = [], [], [], []
|
|
181
181
|
self.seen_cols = set()
|
|
182
182
|
self.records = {r["file"]: r for r in prog.records}
|
|
183
|
+
self._apply_route_mounts()
|
|
183
184
|
self._parse_config()
|
|
184
185
|
self._parse_migrations()
|
|
185
186
|
self._parse_models()
|
|
@@ -196,6 +197,40 @@ class LaravelPlugin(FrameworkPlugin):
|
|
|
196
197
|
self.tests = LaravelTests(self, prog)
|
|
197
198
|
prog.test_fact_handlers.append(self.tests.handle_fact)
|
|
198
199
|
|
|
200
|
+
# ---- route files: served path (#191)
|
|
201
|
+
def _route_mounts(self) -> dict[str, tuple[str, str]]:
|
|
202
|
+
"""routes file -> (prefix, where it comes from): `withRouting(api:, apiPrefix:)` / `then:` groups in
|
|
203
|
+
bootstrap/app.php, `Route::prefix(..)->group(base_path(..))` in a (Laravel <= 10) RouteServiceProvider."""
|
|
204
|
+
out: dict[str, tuple[str, str]] = {}
|
|
205
|
+
order = sorted(self.records, key=lambda f: (not f.startswith("bootstrap/"), f))
|
|
206
|
+
for f in order:
|
|
207
|
+
for m in self.records[f].get("route_mounts") or []:
|
|
208
|
+
rf = m.get("file")
|
|
209
|
+
if isinstance(rf, str) and rf not in out and isinstance(m.get("prefix"), str):
|
|
210
|
+
out[rf] = (m["prefix"].strip("/"), f)
|
|
211
|
+
return out
|
|
212
|
+
|
|
213
|
+
def _apply_route_mounts(self):
|
|
214
|
+
"""Every route of routes/api.php (and routes/api/) is stored at the path Laravel serves it under: the configured
|
|
215
|
+
API prefix, `api` when nothing configures it. The declared path stays in `declared_uri`."""
|
|
216
|
+
mounts = self._route_mounts()
|
|
217
|
+
for f, r in self.records.items():
|
|
218
|
+
if not f.startswith("routes/") or not r.get("routes"):
|
|
219
|
+
continue
|
|
220
|
+
hit = mounts.get(f)
|
|
221
|
+
if hit is None and f.startswith("routes/api/"):
|
|
222
|
+
hit = mounts.get("routes/api.php")
|
|
223
|
+
if hit is None and (f == "routes/api.php" or f.startswith("routes/api/")):
|
|
224
|
+
hit = ("api", "laravel-default")
|
|
225
|
+
if hit is None or not hit[0]:
|
|
226
|
+
continue
|
|
227
|
+
prefix, src = hit
|
|
228
|
+
for rt in r["routes"]:
|
|
229
|
+
declared = rt.get("full_uri") or "/"
|
|
230
|
+
rt["declared_uri"] = declared
|
|
231
|
+
rt["full_uri"] = "/" + "/".join(p for p in (prefix.strip("/"), declared.strip("/")) if p)
|
|
232
|
+
rt["prefix_from"] = src
|
|
233
|
+
|
|
199
234
|
# ---- config/*.php
|
|
200
235
|
def _parse_config(self):
|
|
201
236
|
b = self.b
|
|
@@ -916,13 +951,20 @@ class LaravelPlugin(FrameworkPlugin):
|
|
|
916
951
|
cid = self.b.add_node("config", key, lang="php")
|
|
917
952
|
self.b.add_edge(fn.id, cid, "READS_CONFIG", fn.file, line, conf)
|
|
918
953
|
|
|
954
|
+
def _recv_of(self, c, h) -> dict:
|
|
955
|
+
"""attrs.recv for an edge into a job's handle() inherited from a base class: the job class, so the base
|
|
956
|
+
handle()'s `$this->execute()` reaches only this job's override (#148)."""
|
|
957
|
+
if c.methods.get("handle") is h or c.methods.get("__invoke") is h:
|
|
958
|
+
return {}
|
|
959
|
+
return {"recv": [f"{c.kind}:{c.fqcn}"]}
|
|
960
|
+
|
|
919
961
|
def _dispatch(self, fn, cls, line, conf):
|
|
920
962
|
c = self.prog.cls(cls)
|
|
921
963
|
if not c:
|
|
922
964
|
return
|
|
923
965
|
h = self.prog.find_method(c.fqcn, "handle") or self.prog.find_method(c.fqcn, "__invoke")
|
|
924
966
|
if self._is_job(c.fqcn) and h:
|
|
925
|
-
self.b.add_edge(fn.id, h.id, "DISPATCHES", fn.file, line, conf, via="job")
|
|
967
|
+
self.b.add_edge(fn.id, h.id, "DISPATCHES", fn.file, line, conf, via="job", **self._recv_of(c, h))
|
|
926
968
|
else:
|
|
927
969
|
eid = self.b.add_node("event", c.fqcn, name=c.fqcn.split("\\")[-1], fqn=c.fqcn, file=c.file, line=c.line,
|
|
928
970
|
module=module_of(c.file), lang="php")
|
|
@@ -1011,6 +1053,8 @@ class LaravelPlugin(FrameworkPlugin):
|
|
|
1011
1053
|
from ..php.inline_guards import for_action
|
|
1012
1054
|
n = 0
|
|
1013
1055
|
for f, r in self.records.items():
|
|
1056
|
+
if r.get("route_loops"):
|
|
1057
|
+
b.route_loops[f] = r["route_loops"]
|
|
1014
1058
|
for rt in r.get("routes") or []:
|
|
1015
1059
|
for verb in rt["methods"]:
|
|
1016
1060
|
key = f"{verb.upper()} {rt['full_uri']}"
|
|
@@ -1021,6 +1065,15 @@ class LaravelPlugin(FrameworkPlugin):
|
|
|
1021
1065
|
self.stats["route_middleware_unresolved"] = self.stats.get("route_middleware_unresolved", 0) + 1
|
|
1022
1066
|
attrs = {"name": rt.get("name") or None, "middleware": mws if rt.get("middleware") is not None else None,
|
|
1023
1067
|
"uri": rt["full_uri"], "method": verb.upper()}
|
|
1068
|
+
if rt.get("declared_uri"):
|
|
1069
|
+
attrs["declared_uri"] = rt["declared_uri"]
|
|
1070
|
+
attrs["prefix_from"] = rt.get("prefix_from")
|
|
1071
|
+
for k, ak in (("defaults", "defaults"), ("wheres", "where")):
|
|
1072
|
+
if rt.get(k):
|
|
1073
|
+
attrs[ak] = rt[k]
|
|
1074
|
+
if rt.get("unrolled_from"):
|
|
1075
|
+
u = rt["unrolled_from"]
|
|
1076
|
+
attrs["unrolled_from"] = {"file": f, "line": u.get("line"), "binding": u.get("binding") or {}}
|
|
1024
1077
|
if rt.get("webhook_client"):
|
|
1025
1078
|
attrs["webhook_client"] = rt["webhook_client"]
|
|
1026
1079
|
attrs["webhook_framework"] = "laravel-webhook-client"
|
|
@@ -1197,7 +1250,7 @@ class LaravelPlugin(FrameworkPlugin):
|
|
|
1197
1250
|
if h:
|
|
1198
1251
|
jid = b.add_node("job", c.fqcn, name=c.fqcn.split("\\")[-1], fqn=c.fqcn, file=c.file, line=c.line,
|
|
1199
1252
|
module=module_of(c.file), lang="php", entry_kind="queue_job")
|
|
1200
|
-
b.add_edge(jid, h.id, "HANDLED_BY", c.file, h.line, EXACT)
|
|
1253
|
+
b.add_edge(jid, h.id, "HANDLED_BY", c.file, h.line, EXACT, **self._recv_of(c, h))
|
|
1201
1254
|
self.stats["jobs"] += 1
|
|
1202
1255
|
if c.fqcn.startswith("App\\Listeners\\"):
|
|
1203
1256
|
h = prog.find_method(c.fqcn, "handle")
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
TEST_CALLS -> the file (beforeEach, uses(...) and other file-level setup);
|
|
8
8
|
* HTTP test calls (`$this->getJson('/api/x')`, `->actingAs($u)->post(route('x.store'))`, Pest `get('/x')`,
|
|
9
9
|
`$this->json('PATCH', '/x')`, and the same calls through project helpers such as `$this->getAs('/x')` whose URL /
|
|
10
|
-
verb are parameters) -> TEST_HTTP -> the matching route (URIs matched like cross-repo links,
|
|
11
|
-
|
|
10
|
+
verb are parameters) -> TEST_HTTP -> the matching route (URIs matched like cross-repo links, on the served path: routes/api.php routes
|
|
11
|
+
carry the API prefix Laravel adds; `route('name')` by route name).
|
|
12
12
|
|
|
13
13
|
Edges made by test code are retyped to non-propagating TEST_* kinds afterwards (cg_code_graph/tests_index.py), so
|
|
14
14
|
tests never change blast radius, caller counts or entry tagging. `cg tests <symbol|route>` walks them on purpose.
|
|
@@ -154,7 +154,7 @@ class LaravelTests:
|
|
|
154
154
|
|
|
155
155
|
# ---- after reference emission
|
|
156
156
|
def contribute(self) -> dict:
|
|
157
|
-
from ...link import match_endpoint
|
|
157
|
+
from ...link import match_endpoint, route_uri_variants
|
|
158
158
|
b, prog = self.lp.b, self.prog
|
|
159
159
|
st = defaultdict(int)
|
|
160
160
|
self._expand_helpers(st)
|
|
@@ -162,9 +162,7 @@ class LaravelTests:
|
|
|
162
162
|
for nid, n in b.nodes.items():
|
|
163
163
|
if n.kind != "route" or not n.attrs.get("uri") or not n.attrs.get("method"):
|
|
164
164
|
continue
|
|
165
|
-
uris =
|
|
166
|
-
if (n.file or "").startswith(("routes/api.php", "routes/api/")):
|
|
167
|
-
uris.append(("api-prefixed", "/api" + n.attrs["uri"]))
|
|
165
|
+
uris = route_uri_variants(n.file, n.attrs)
|
|
168
166
|
routes.append({"id": nid, "uri": n.attrs["uri"], "method": n.attrs["method"], "uris": uris})
|
|
169
167
|
if n.attrs.get("name"):
|
|
170
168
|
by_name[n.attrs["name"]].append(n)
|