cg-code-graph 0.23.10__tar.gz → 0.23.12__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.10/cg_code_graph.egg-info → cg_code_graph-0.23.12}/PKG-INFO +1 -1
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/__init__.py +1 -1
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/cli.py +10 -3
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/core/model.py +1 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/core/plugin.py +4 -1
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/lint_async.py +47 -10
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/mcp_server.py +5 -2
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/java/exact.py +82 -24
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/kotlin/exact.py +108 -7
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/kotlin/plugin.py +138 -10
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/swift/exact.py +23 -1
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/swift/plugin.py +34 -7
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/extractor/extract.mjs +19 -1
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/roundtrip.py +71 -7
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12/cg_code_graph.egg-info}/PKG-INFO +1 -1
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph.egg-info/SOURCES.txt +4 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_kotlin_exact.py +5 -1
- cg_code_graph-0.23.12/tests/test_kotlin_local_state.py +79 -0
- cg_code_graph-0.23.12/tests/test_kotlin_prop_exact.py +146 -0
- cg_code_graph-0.23.12/tests/test_kotlin_prop_overrides.py +57 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_lint_async.py +21 -4
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_roundtrip.py +12 -0
- cg_code_graph-0.23.12/tests/test_state_tracking_235.py +111 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_ts_fields_js_vue.py +22 -5
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/LICENSE +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/MANIFEST.in +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/README.md +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/__main__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/affected.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/agent_rules.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/agents.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/aitools.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/android_ipc.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/apple_ipc.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/apps.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/blindspots.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/bridges.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/brokers.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/cmake_sources.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/concepts.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/config.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/core/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/core/cache.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/core/detect.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/core/env.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/core/extractors.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/core/fsutil.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/core/generated.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/core/paths.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/core/redact.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/core/store.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/core/syntax_errors.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/coverage.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/dart_isolates.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/doctor.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/explore.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/external.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/graphql.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/guard_facts.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/hooks.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/indexer.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/insecure_transport.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/install_rules.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/jobs.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/link.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/local_ipc.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/local_sockets.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/mcp_graphs.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/mcp_install.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/parity.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/parity_structure.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/payload.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plans.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/platform_scan.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/platforms.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/astro/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/astro/content.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/astro/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/cfamily/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/cfamily/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/cfamily/syntax.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/bridges.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/extractor/bin/extract.dart +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/extractor/pubspec.lock +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/extractor/pubspec.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/http.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/models.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/program.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/django/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/django/extras.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/django/models.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/django/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/django/schemas.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/django/shapes.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/django/urls.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/express/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/express/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/flutter/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/flutter/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/java/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/java/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/jvm/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/jvm/interop.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/jvm/spring.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/kotlin/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/kotlin/reparse.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/laravel/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/laravel/broadcast.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/laravel/massassign.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/laravel/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/laravel/tests.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/laravel/values.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/native/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/native/gates.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/native/runner.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/native/scipread.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/native/ts.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/nest/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/nest/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/nextjs/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/nextjs/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/nuxt/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/nuxt/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/external.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/extractor/composer.json +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/extractor/composer.lock +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/extractor/extract.php +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/gating.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/http_client.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/inline_guards.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/strings.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/aitools.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/external.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/fields.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/refs.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/roots.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/socketio.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/subproc.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/tests.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/values.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/pyweb/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/pyweb/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/pyweb/values.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/rust/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/rust/cargo.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/rust/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/rust/syntax.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/scip/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/scip/importer.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/scip/scip.proto +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/scip/scip_pb2.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/stubs/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/stubs/plugins.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/swift/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/swift/baseurl.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/swift/indexstore.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/swift/packages.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/baseurl.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/extractor/fw.mjs +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/extractor/package-lock.json +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/extractor/package.json +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/extractor/rr.mjs +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/nav.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/plugin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/react_router.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/tsweb/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/tsweb/common.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/plugins/tsweb/data.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/c_cpp.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/common.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/dart.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/django-ninja.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/django.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/djangorestframework.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/express.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/java.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/kotlin.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/laravel.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/nest.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/nextjs.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/nuxt.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/php.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/python.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/react-router.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/rust.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/spring.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/swift.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/presets/typescript.yaml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/process_runs.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/protocols/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/protocols/builtin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/protocols/matchers.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/protocols/view.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/query.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/realtime.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/realtime_events.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/realtime_native.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/realtime_ws.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/routes.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/rpc.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/sdk_systems.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/sockets.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/ssrf_input.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/starters.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/surface.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/tests_index.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/udp_apps.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/update_check.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/viz/__init__.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/viz/graph.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/viz/server.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/app.css +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/app.js +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/index.html +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/layered.js +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/vendor/VERSIONS.txt +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/vendor/cose-base.js +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/vendor/cytoscape-fcose.js +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/vendor/cytoscape.min.js +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/vendor/layout-base.js +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/viz/tools/package-lock.json +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/viz/tools/package.json +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/viz/tools/shoot.mjs +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/watch.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/webhook_subs.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/webhooks.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph/xcode.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph.egg-info/dependency_links.txt +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph.egg-info/entry_points.txt +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph.egg-info/requires.txt +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/cg_code_graph.egg-info/top_level.txt +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/pyproject.toml +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/setup.cfg +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_affected.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_agents_install.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_agents_md.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_ai_tools.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_android_ipc.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_apple_ipc.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_astro.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_astro_content.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_astro_server.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_bridges.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_bridges_pigeon_monorepo.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_brokers.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_cache_clean.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_cache_invalidation.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_cache_migration.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_channels_tests.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_cli_output.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_cmake_sources.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_completeness.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_config_extras.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_coverage.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_coverage_ts_hint.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_dart_isolates.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_db_connections.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_dead_wrappers.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_dispatch_interfaces.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_dispatch_part3.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_django_flutter.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_docs_languages.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_docs_links.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_echo_ref.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_echo_wrapper.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_elysia.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_enum_constants.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_env.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_explore.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_external.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_fp_batch.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_gating.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_generated.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_graphql.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_hooks.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_impact_overrides.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_index_isolation.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_inherited_overrides.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_inline_guards.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_install_rules.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_192.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_201.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_202.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_203.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_204.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_205.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_206.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_207.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_208.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_209.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_210.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_211.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_211_used_at.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_212.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_212_langs.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_218.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_219.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_issue_222.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_java.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_java_exact.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_jobs.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_js_refs.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_js_runtime.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_kotlin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_kotlin_binding.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_kotlin_fields.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_kotlin_mixed.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_kotlin_nav_consts.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_kotlin_props.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_laravel_determinism.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_laravel_receiver_narrowing.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_laravel_resources.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_laravel_route_paths.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_link_origin.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_listing_files.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_local_ipc.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_local_sockets.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_mass_assignment.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_mcp.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_mcp_index.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_mcp_install.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_mcp_instructions.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_mcp_multi_graph.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_native_cfamily.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_native_concurrency.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_native_rust.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_nuxt_i18n.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_nuxt_import_dirs.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_nuxt_nitro.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_nuxt_rootsrc.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_nuxt_side_dirs.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_packaging.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_parity.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_parity_fields.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_parity_members.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_parity_structure.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_php_http.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_php_props.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_plain_js.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_plans.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_platform_gaps.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_platform_type_variants.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_platforms.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_platforms_apple.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_presets_config.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_process_ipc.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_process_runs.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_protocols.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_python_app_tests_module.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_python_collection_chains.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_python_compat.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_python_entry_refs.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_python_fields.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_python_infer_cycles.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_python_roots.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_python_subprocess_tests.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_python_tests.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_python_web_hosts.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_python_web_routes.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_python_web_routes_more.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_react_router.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_readers_writers_specs.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_realtime.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_realtime_native.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_redact_salt.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_request_keys.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_route_specs.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_route_tables.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_routes_search_explain.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_rpc.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_scip_health.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_sdk_external.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_sdk_external_infra.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_sdk_external_mail.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_snippet.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_sockets.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_spring.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_ssrf.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_starters_budget.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_surface.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_surface_transport.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_swift.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_swift_binding.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_swift_exact.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_swift_facts.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_swift_fields.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_swift_modules.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_swift_more.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_swift_nav_values.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_swift_parse_errors.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_swift_platform_files.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_swift_props.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_swift_sdk.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_swift_testing.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_swift_values.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_tauri_events.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_tests_scope.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_ts_fields.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_ts_file_specs.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_ts_frameworks.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_ts_node_http.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_ts_nuxt.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_ts_src_tsconfig.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_unguarded.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_update_check.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_values.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_viz.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_vue_nav.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_watch.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_webhooks.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_webhooks_152.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_webhooks_152b.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/tests/test_websockets.py +0 -0
- {cg_code_graph-0.23.10 → cg_code_graph-0.23.12}/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.12"
|
|
@@ -317,7 +317,8 @@ def main(argv=None):
|
|
|
317
317
|
p.add_argument("--json", action="store_true"); p.add_argument("--tests", action="store_true", help="include test code")
|
|
318
318
|
p = sub.add_parser("roundtrip", help="heuristic: writes of a stored property `Type.prop` through a lossy transform, "
|
|
319
319
|
"read back to seed UI state (#88)")
|
|
320
|
-
p.add_argument("spec"); p.add_argument("--db", required=True); p.add_argument("--json", action="store_true")
|
|
320
|
+
p.add_argument("spec", nargs="?"); p.add_argument("--db", required=True); p.add_argument("--json", action="store_true")
|
|
321
|
+
p.add_argument("--all", action="store_true", help="every stored property in one pass: only the round trips")
|
|
321
322
|
p.add_argument("--tests", action="store_true", help="include test code's reads and writes")
|
|
322
323
|
p = sub.add_parser("viz-plan", help="self-contained HTML overlay of a plan on the real graph")
|
|
323
324
|
p.add_argument("name"); p.add_argument("--db", required=True); p.add_argument("-o", "--out", required=True); p.add_argument("--plans-dir")
|
|
@@ -769,8 +770,14 @@ def main(argv=None):
|
|
|
769
770
|
print(json.dumps(res, indent=1) if a.json else LA.render(res))
|
|
770
771
|
elif a.cmd == "roundtrip":
|
|
771
772
|
from . import roundtrip as RT
|
|
772
|
-
|
|
773
|
-
|
|
773
|
+
if a.all or not a.spec:
|
|
774
|
+
if not a.all:
|
|
775
|
+
sys.exit("cg roundtrip: give a property `Type.prop`, or --all")
|
|
776
|
+
res = RT.roundtrip_all(st, include_tests=a.tests)
|
|
777
|
+
print(RT.to_json(res) if a.json else RT.render_all(res))
|
|
778
|
+
else:
|
|
779
|
+
res = RT.roundtrip(st, a.spec, include_tests=a.tests)
|
|
780
|
+
print(RT.to_json(res) if a.json else RT.render(res))
|
|
774
781
|
elif a.cmd in ("writers", "readers"):
|
|
775
782
|
groups = Q.access(st, a.spec, a.cmd, a.connection)
|
|
776
783
|
rows = [r for g in groups for r in g["rows"]]
|
|
@@ -71,6 +71,7 @@ EDGE_KINDS: dict[str, tuple[bool, str]] = {
|
|
|
71
71
|
"ACCESSES_FIELD": (True, "code reads/writes a struct/class field or enum variant"),
|
|
72
72
|
"READS_PROP": (True, "code reads a stored property (field node: Swift `var x`, `@State`, `@Published`)"),
|
|
73
73
|
"WRITES_PROP": (True, "code writes a stored property (assignment, compound assignment)"),
|
|
74
|
+
"SHARES_STORAGE": (False, "two stored properties persist under the same @AppStorage / @SceneStorage key"),
|
|
74
75
|
"USES_VALUE": (True, "code refers to an enum case, a constant, a static/global variable or an object-like macro"),
|
|
75
76
|
"REGISTERS_CALLBACK": (False, "function builds a callback URL for one of the app's own routes and registers it with an external party (attrs.body_key, endpoint)"),
|
|
76
77
|
"REFERENCES_FN": (True, "code/data takes a function as a value (callback, dispatch table, handler registration)"),
|
|
@@ -88,7 +88,10 @@ class GraphBuilder:
|
|
|
88
88
|
g = self.current_gate
|
|
89
89
|
if g and g.get("src") != src:
|
|
90
90
|
g = None # only references made by the gated function itself carry the gate
|
|
91
|
-
|
|
91
|
+
gate = g["gate"] if g else None
|
|
92
|
+
# a second branch of the same call on one line is its own edge (#235)
|
|
93
|
+
br = attrs.get("branch")
|
|
94
|
+
key = (src, dst, kind, file, line, gate, br) if br else (src, dst, kind, file, line, gate)
|
|
92
95
|
if key in self.edges:
|
|
93
96
|
return
|
|
94
97
|
if g:
|
|
@@ -61,6 +61,24 @@ def _input_dependent(text: str) -> bool:
|
|
|
61
61
|
t = re.sub(r"(?<![\w$])[A-Za-z_$][\w$]*\s*(?:<[^<>]*>)?\s*\(", " (", t) # call names
|
|
62
62
|
ids = re.findall(r"(?<![\w$])[A-Za-z_$][\w$]*", t)
|
|
63
63
|
return any(i.startswith("SELFREF_") or (i not in KEYWORDS and not i[0].isupper()) for i in ids)
|
|
64
|
+
_SUSP: dict = {} # file -> lines with a call of a Kotlin `suspend` function (an await point with no marker)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _load_suspend(st: GraphStore) -> None:
|
|
68
|
+
"""A plain call of a project `suspend` function inside `launch { }` (`val x = repo.load()`) suspends like
|
|
69
|
+
`.await()`: the indexed CALLS edges to nodes marked `suspend` give those lines."""
|
|
70
|
+
_SUSP.clear()
|
|
71
|
+
for r in st.q("""SELECT e.file, e.line FROM edges e JOIN nodes n ON n.id = e.dst
|
|
72
|
+
WHERE e.kind = 'CALLS' AND n.attrs LIKE '%"suspend": true%' AND e.file IS NOT NULL"""):
|
|
73
|
+
_SUSP.setdefault(r["file"], set()).add(r["line"])
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _aw(t: str, file: str | None = None, line: int | None = None) -> bool:
|
|
77
|
+
"""Is there an await point in this line of source: a marker (`await`, `.await()`, `withContext`, `delay`) or,
|
|
78
|
+
in Kotlin, a call of a `suspend` function?"""
|
|
79
|
+
return bool(AWAIT_RE.search(t)) or (line is not None and line in _SUSP.get(file, ()))
|
|
80
|
+
|
|
81
|
+
|
|
64
82
|
TEST_PATH_RE = re.compile(r"(?:^|/)(?:tests?|__tests__|spec|testing|fixtures?|factories|Tests|UITests)/|"
|
|
65
83
|
r"[._-](?:test|spec)s?\.\w+:|Tests?\.swift:|Test\.kt:|(?:^|/)test_\w+\.py:")
|
|
66
84
|
|
|
@@ -104,6 +122,7 @@ def _opener(ls: list[str], line: int, lo: int):
|
|
|
104
122
|
|
|
105
123
|
|
|
106
124
|
def stale_async(st: GraphStore, include_tests: bool = False, limit: int = 500) -> list[dict]:
|
|
125
|
+
_load_suspend(st)
|
|
107
126
|
root = st.meta().get("root")
|
|
108
127
|
cache: dict = {}
|
|
109
128
|
fields = {r["id"]: json.loads(r["attrs"] or "{}") for r in st.q("SELECT id, attrs FROM nodes WHERE kind IN ('field','property')")}
|
|
@@ -122,7 +141,8 @@ def stale_async(st: GraphStore, include_tests: bool = False, limit: int = 500) -
|
|
|
122
141
|
continue
|
|
123
142
|
kind, o = op
|
|
124
143
|
body = ls[o - 1:r["line"] - 1]
|
|
125
|
-
aw = next((o + i for i, t in enumerate(body) if
|
|
144
|
+
aw = next((o + i for i, t in enumerate(body) if _aw(t if i else t[t.find("{") + 1:] if "{" in t else t,
|
|
145
|
+
r["file"], o + i if i else None)), None)
|
|
126
146
|
if aw is None:
|
|
127
147
|
continue
|
|
128
148
|
before = "\n".join(ls[o - 1:aw - 1]) + "\n" + ls[aw - 1].split("await")[0]
|
|
@@ -131,7 +151,10 @@ def stale_async(st: GraphStore, include_tests: bool = False, limit: int = 500) -
|
|
|
131
151
|
if GUARD_RE.search(after) or SINGLE_FLIGHT_RE.search(ls[o - 1]):
|
|
132
152
|
continue
|
|
133
153
|
aw_line = ls[aw - 1]
|
|
134
|
-
k =
|
|
154
|
+
k = aw_line.find("await")
|
|
155
|
+
if k < 0: # a Kotlin suspend call: the request is the right-hand side
|
|
156
|
+
m = re.search(r"(?<![=!<>])=(?!=)", aw_line)
|
|
157
|
+
k = m.end() if m else 0
|
|
135
158
|
stmt, depth = [], 0
|
|
136
159
|
for i in range(aw - 1, min(len(ls), aw + 5)):
|
|
137
160
|
x = ls[i][k:] if i == aw - 1 else ls[i]
|
|
@@ -144,10 +167,10 @@ def stale_async(st: GraphStore, include_tests: bool = False, limit: int = 500) -
|
|
|
144
167
|
# the written value must come from the awaited result: a name bound on the await line (or derived from one
|
|
145
168
|
# after it), or the await itself on the write line; a loading flag reset after the await is not a stale result
|
|
146
169
|
res_vars = set()
|
|
147
|
-
for t in ls[aw - 1:r["line"] - 1]:
|
|
170
|
+
for j, t in enumerate(ls[aw - 1:r["line"] - 1]):
|
|
148
171
|
m = DECL_RE.search(t) or re.search(r"^\s*(?:self\.)?([A-Za-z_$][\w$]*)\s*=(?!=)", t)
|
|
149
172
|
nm = m and (m.group(1) or (m.group(2) if m.lastindex and m.lastindex >= 2 else None))
|
|
150
|
-
if nm and (
|
|
173
|
+
if nm and (_aw(t, r["file"], aw + j) or any(re.search(rf"(?<![\w$.]){re.escape(v)}\b", t.split("=", 1)[-1]) for v in res_vars)):
|
|
151
174
|
res_vars.add(nm)
|
|
152
175
|
wl = ls[r["line"] - 1]
|
|
153
176
|
if r["line"] - 1 == aw - 1:
|
|
@@ -182,7 +205,8 @@ LIFECYCLE_RE = re.compile(r"\.onAppear\b|\bonAppear\s*\(|\.task\s*[({]|\bonMount
|
|
|
182
205
|
CALLBACK_RE = re.compile(r"\.sink\s*\{|\.onReceive\s*\(|\.subscribe\s*[({]|\.collect(?:Latest)?\s*\{|\.observe\w*\s*\(|"
|
|
183
206
|
r"\bcompletion(?:Handler)?\s*:\s*\{|\{\s*\[?\s*(?:weak|unowned)\s+self\s*\]?|\.then\s*\(|\.on\s*\(\s*['\"]")
|
|
184
207
|
LITERAL_RHS_RE = re.compile(r"(?<![=!<>])=\s*(?:\[\s*\]|\[:\]|\{\s*\}|nil|null|None|undefined|0(?:\.0+)?[fFdDL]?|false|False|true|True|"
|
|
185
|
-
r"''|\"\"|emptyList\(\)|emptyMap\(\)|mutableListOf\(\)|\.init\(\)|\w+\(\)|\.\w
|
|
208
|
+
r"''|\"\"|emptyList\(\)|emptyMap\(\)|mutableListOf\(\)|\.init\(\)|\w+\(\)|\.\w+|"
|
|
209
|
+
r"[A-Z]\w*(?:\.[A-Z]\w*)+(?:\(\))?)\s*;?\s*$") # a sentinel: `AsyncData.Loading()`, `UiState.Idle`
|
|
186
210
|
LITERAL_ARG_RE = re.compile(r"\(\s*(?:nil|null|None|undefined|true|false|True|False|-?\d+(?:\.\d+)?|'[^']*'|\"[^\"]*\"|\[\s*\]|\{\s*\})\s*\)\s*;?\s*$")
|
|
187
211
|
INIT_NAMES = {"init", "__init__", "constructor", "<init>", "viewDidLoad", "onCreate", "initState", "mounted", "created", "setup"}
|
|
188
212
|
|
|
@@ -198,7 +222,7 @@ def _lifecycle(st, ls, r, node) -> str | None:
|
|
|
198
222
|
"""Is this write lifecycle code: an initializer with a real (non-default) value, or code directly inside
|
|
199
223
|
onAppear / .task (before any await) / onMounted / LaunchedEffect / useEffect / viewDidLoad?"""
|
|
200
224
|
t = ls[r["line"] - 1]
|
|
201
|
-
if
|
|
225
|
+
if _aw(t, r["file"], r["line"]):
|
|
202
226
|
return None
|
|
203
227
|
nm = ((node["name"] if node is not None else "") or "").split(".")[-1]
|
|
204
228
|
if nm in INIT_NAMES or (node is not None and node["kind"] == "class"):
|
|
@@ -212,7 +236,7 @@ def _lifecycle(st, ls, r, node) -> str | None:
|
|
|
212
236
|
lo = max(1, r["line"] - 6)
|
|
213
237
|
for i in range(r["line"], lo - 1, -1):
|
|
214
238
|
x = ls[i - 1]
|
|
215
|
-
if i < r["line"] and
|
|
239
|
+
if i < r["line"] and _aw(x, r["file"], i):
|
|
216
240
|
return None
|
|
217
241
|
m = LIFECYCLE_RE.search(x)
|
|
218
242
|
if m:
|
|
@@ -225,7 +249,8 @@ def _async_callback(ls, r, lo) -> str | None:
|
|
|
225
249
|
op = _opener(ls, r["line"], lo)
|
|
226
250
|
if op is not None:
|
|
227
251
|
body = ls[op[1] - 1:r["line"] - 1]
|
|
228
|
-
if any(
|
|
252
|
+
if any(_aw(x, r["file"], op[1] + j) for j, x in enumerate(body) if j) or \
|
|
253
|
+
(body and AWAIT_RE.search(body[0][body[0].find("{") + 1:])):
|
|
229
254
|
return f"after await in {op[0]}"
|
|
230
255
|
for i in range(r["line"] - 1, max(lo, r["line"] - 8) - 1, -1):
|
|
231
256
|
m = CALLBACK_RE.search(ls[i - 1]) if i >= 1 else None
|
|
@@ -235,6 +260,7 @@ def _async_callback(ls, r, lo) -> str | None:
|
|
|
235
260
|
|
|
236
261
|
|
|
237
262
|
def two_writers(st: GraphStore, include_tests: bool = False) -> list[dict]:
|
|
263
|
+
_load_suspend(st)
|
|
238
264
|
root = st.meta().get("root")
|
|
239
265
|
cache: dict = {}
|
|
240
266
|
rows = st.q("""SELECT e.src, e.dst, e.file, e.line, e.attrs, n.line AS fl FROM edges e JOIN nodes n ON n.id = e.src
|
|
@@ -361,6 +387,14 @@ def incomplete_cache_key(st: GraphStore, include_tests: bool = False) -> list[di
|
|
|
361
387
|
sig = "\n".join(body[:3])
|
|
362
388
|
sig = sig[sig.find("("):] if "(" in sig else ""
|
|
363
389
|
params = _idents(_split_args(sig[1:]) and ",".join(re.sub(r"[:=].*", "", a, flags=re.S) for a in _split_args(sig[1:])) or "")
|
|
390
|
+
# instance fields used without `self.` / `this.` (Swift, Kotlin): the READS_PROP edges bind them
|
|
391
|
+
own = {e["dst"].rsplit(".", 1)[-1] for e in st.q("SELECT dst, attrs FROM edges WHERE kind = 'READS_PROP' AND src = ?",
|
|
392
|
+
(fn["id"],))
|
|
393
|
+
if json.loads(e["attrs"] or "{}").get("receiver") in (None, "self", "this")}
|
|
394
|
+
text = "\n".join(body)
|
|
395
|
+
# ... unless the field is an object the function calls (`client.get(…)`, `mediaLoader.load(…)`): a dependency,
|
|
396
|
+
# not an input of the cached value
|
|
397
|
+
own = {f for f in own if not re.search(rf"(?<![\w$.]){re.escape(f)}\s*[?!]?\.\s*\w+\s*[({{]", text)}
|
|
364
398
|
assigns: dict = {}
|
|
365
399
|
for off, t in enumerate(body):
|
|
366
400
|
m = re.search(r"\b(?:let|var|val|const)\s+([A-Za-z_$][\w$]*)\s*(?::[^=]+)?=(?!=)(.*)|^\s*([a-z_$][\w$]*)\s*=(?!=)(.*)", t)
|
|
@@ -384,8 +418,10 @@ def incomplete_cache_key(st: GraphStore, include_tests: bool = False) -> list[di
|
|
|
384
418
|
vb = val.strip().rstrip(";")
|
|
385
419
|
if re.fullmatch(r"[A-Za-z_$][\w$]*", vb) and vb not in assigns:
|
|
386
420
|
continue # `put(key, value)` passes a value through; nothing is computed here
|
|
387
|
-
|
|
388
|
-
|
|
421
|
+
bare = lambda ids: {f"self_{i}" if i in own and i not in params and i not in assigns else i # noqa: E731
|
|
422
|
+
for i in ids}
|
|
423
|
+
kids = bare(_expand(_idents(key), assigns))
|
|
424
|
+
vids = bare(_expand(_idents(val), assigns)) - {vb}
|
|
389
425
|
setter = re.match(r"(?:set|put|insert|store|save|cache|add|update|write|remember|record)(?![a-z])",
|
|
390
426
|
(fn["fqn"] or "").split(".")[-1].split("(")[0])
|
|
391
427
|
inputs = {i for i in vids if (i in params and not setter and not PAYLOAD_RE.fullmatch(i.lstrip("$")))
|
|
@@ -421,6 +457,7 @@ def echo_suppression(st: GraphStore, include_tests: bool = False, patterns: list
|
|
|
421
457
|
programmatic writes of some state so the change observer, which checks the guard and returns early, does not
|
|
422
458
|
echo them back. Reports state of that pattern that is also written from an async path / callback *without*
|
|
423
459
|
setting the guard: that write reaches the observer and is sent back (a loop or a clobbered edit)."""
|
|
460
|
+
_load_suspend(st)
|
|
424
461
|
root = st.meta().get("root")
|
|
425
462
|
cache: dict = {}
|
|
426
463
|
guards = [r["id"] for r in st.q("SELECT id, name FROM nodes WHERE kind = 'field'") if GUARD_FIELD_RE.fullmatch((r["name"] or "").rsplit(".", 1)[-1].replace("_", ""))]
|
|
@@ -877,13 +877,16 @@ def _access_text(st, spec: str, what: str, limit: int, connection: str | None =
|
|
|
877
877
|
|
|
878
878
|
|
|
879
879
|
@tool
|
|
880
|
-
def roundtrip(prop: str, include_tests: bool = False) -> str:
|
|
880
|
+
def roundtrip(prop: str = "", include_tests: bool = False) -> str:
|
|
881
881
|
"""Heuristic (#88): does a stored property `Type.prop` round-trip through a lossy transform? Each write site with
|
|
882
882
|
the lossy call it passes through (clamp, min/max, round, truncating casts, `fit*`, `.cg.yaml` `lossy:` names,
|
|
883
883
|
`@cg-lossy` functions; within the function plus one hop through direct callers), each read site that seeds UI
|
|
884
884
|
state (init, onAppear, remember, useState(initial), mounted), and un-narrowed ranges drawn next to such a read.
|
|
885
|
-
Findings are heuristic evidence with file:line, not proof.
|
|
885
|
+
Findings are heuristic evidence with file:line, not proof. An empty `prop` (or `*`) checks every stored property
|
|
886
|
+
in one pass and lists only the round trips."""
|
|
886
887
|
from . import roundtrip as RT
|
|
888
|
+
if prop.strip() in ("", "*"):
|
|
889
|
+
return RT.render_all(RT.roundtrip_all(_st(), include_tests=include_tests))
|
|
887
890
|
return RT.render(RT.roundtrip(_st(), prop, include_tests=include_tests))
|
|
888
891
|
|
|
889
892
|
|
|
@@ -57,6 +57,14 @@ _ANON_SEG = re.compile(r"^\$?anon\d*$")
|
|
|
57
57
|
_ACCESSOR = re.compile(r"^(get|set|is)([A-Z]\w*)$")
|
|
58
58
|
|
|
59
59
|
|
|
60
|
+
def _accessor_kind(symbol: str) -> str | None:
|
|
61
|
+
dd = scipread.descriptors(symbol)
|
|
62
|
+
if not dd or not dd[1]:
|
|
63
|
+
return None
|
|
64
|
+
m = _ACCESSOR.fullmatch(dd[1][-1][0])
|
|
65
|
+
return m.group(1) if m else None
|
|
66
|
+
|
|
67
|
+
|
|
60
68
|
def is_anon_id(nid: str) -> bool:
|
|
61
69
|
"""True when a mapped id still contains a scip-java anonymous type segment (`$anon`)."""
|
|
62
70
|
return any(_ANON_SEG.match(part) for part in nid.split(":", 1)[-1].split("."))
|
|
@@ -105,35 +113,25 @@ def bind_java_symbol(symbol: str, nodes, file: str, line: int) -> tuple[str, str
|
|
|
105
113
|
return nid, kind
|
|
106
114
|
|
|
107
115
|
|
|
108
|
-
def
|
|
109
|
-
"""`(kotlin node id, edge kind)` for a JVM accessor call (`getX` / `setX` / `isX`).
|
|
110
|
-
|
|
111
|
-
`Widget#getName().` is `field:demo.Widget.name` with `READS_PROP`. `setX` is `WRITES_PROP`.
|
|
112
|
-
A custom accessor that is already a Kotlin method node is `CALLS`.
|
|
113
|
-
"""
|
|
114
|
-
dd = scipread.descriptors(symbol)
|
|
115
|
-
if not dd or not dd[1]:
|
|
116
|
-
return None
|
|
117
|
-
names = [n for n in dd[1] if n[1] != ")"]
|
|
118
|
-
if not names or names[-1][1] != "(":
|
|
119
|
-
return None
|
|
120
|
-
m = _ACCESSOR.fullmatch(names[-1][0])
|
|
121
|
-
if not m:
|
|
122
|
-
return None
|
|
123
|
-
kind, raw = m.group(1), m.group(2)
|
|
116
|
+
def _property_names(kind: str, raw: str) -> list[str]:
|
|
124
117
|
prop = raw[:1].lower() + raw[1:]
|
|
125
|
-
|
|
126
|
-
if not owner:
|
|
127
|
-
return None
|
|
128
|
-
props = [prop]
|
|
118
|
+
names = [prop]
|
|
129
119
|
if kind == "is":
|
|
130
|
-
|
|
131
|
-
|
|
120
|
+
names.append("is" + raw)
|
|
121
|
+
return names
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _owner_of(names: list[tuple[str, str]]) -> str:
|
|
125
|
+
return ".".join([n for n, s in names if s == "/"] + [n for n, s in names if s == "#"])
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _find_kotlin_property(nodes, owner: str, props: list[str]) -> tuple[str, str] | None:
|
|
129
|
+
"""`(node id, READS_PROP | CALLS)` for a stored field or a custom property node."""
|
|
132
130
|
for p in props:
|
|
133
131
|
fid = f"field:{owner}.{p}"
|
|
134
132
|
node = nodes.get(fid)
|
|
135
133
|
if node is not None and node.lang == "kotlin" and node.kind == "field":
|
|
136
|
-
return fid,
|
|
134
|
+
return fid, "READS_PROP"
|
|
137
135
|
for p in props:
|
|
138
136
|
for n in nodes.values():
|
|
139
137
|
if (n.lang == "kotlin" and n.attrs.get("property") and (n.fqn or "").rsplit(".", 1)[0] == owner
|
|
@@ -142,6 +140,57 @@ def kotlin_accessor_target(symbol: str, nodes) -> tuple[str, str] | None:
|
|
|
142
140
|
return None
|
|
143
141
|
|
|
144
142
|
|
|
143
|
+
def kotlin_property_ref(symbol: str, nodes, spelling: str | None = None) -> tuple[str, str] | None:
|
|
144
|
+
"""`(node id, edge kind)` for a property term (`Cart#label.`) or accessor (`getLabel().` / `setItems().` / `isReady().`).
|
|
145
|
+
|
|
146
|
+
A stored property is `READS_PROP` (`WRITES_PROP` for `setX`). A custom accessor node is `CALLS`.
|
|
147
|
+
`spelling` is the identifier at the occurrence: when it is the property (`label`, `items`) the
|
|
148
|
+
reference is a property use. When it is the accessor name itself (`getShapes`) this returns None,
|
|
149
|
+
so a declared `fun getShapes()` stays a call. Java passes no spelling and matches `getLabel`.
|
|
150
|
+
"""
|
|
151
|
+
dd = scipread.descriptors(symbol)
|
|
152
|
+
if not dd or not dd[1]:
|
|
153
|
+
return None
|
|
154
|
+
names = [n for n in dd[1] if n[1] != ")"]
|
|
155
|
+
if not names:
|
|
156
|
+
return None
|
|
157
|
+
last, suf = names[-1]
|
|
158
|
+
if suf == ".":
|
|
159
|
+
props, write = [last], False
|
|
160
|
+
elif suf == "(":
|
|
161
|
+
m = _ACCESSOR.fullmatch(last)
|
|
162
|
+
if not m:
|
|
163
|
+
return None
|
|
164
|
+
kind, raw = m.group(1), m.group(2)
|
|
165
|
+
props, write = _property_names(kind, raw), kind == "set"
|
|
166
|
+
else:
|
|
167
|
+
return None
|
|
168
|
+
if spelling is not None and spelling not in props:
|
|
169
|
+
return None
|
|
170
|
+
owner = _owner_of(names[:-1])
|
|
171
|
+
if not owner:
|
|
172
|
+
return None
|
|
173
|
+
found = _find_kotlin_property(nodes, owner, props)
|
|
174
|
+
if found is None:
|
|
175
|
+
return None
|
|
176
|
+
nid, edge = found
|
|
177
|
+
if edge == "READS_PROP" and write:
|
|
178
|
+
return nid, "WRITES_PROP"
|
|
179
|
+
return nid, edge
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def kotlin_accessor_target(symbol: str, nodes) -> tuple[str, str] | None:
|
|
183
|
+
"""`(kotlin node id, edge kind)` for a JVM accessor call (`getX` / `setX` / `isX`).
|
|
184
|
+
|
|
185
|
+
`Widget#getName().` is `field:demo.Widget.name` with `READS_PROP`. `setX` is `WRITES_PROP`.
|
|
186
|
+
A custom accessor that is already a Kotlin method node is `CALLS`.
|
|
187
|
+
"""
|
|
188
|
+
dd = scipread.descriptors(symbol)
|
|
189
|
+
if not dd or not dd[1] or dd[1][-1][1] != "(":
|
|
190
|
+
return None
|
|
191
|
+
return kotlin_property_ref(symbol, nodes)
|
|
192
|
+
|
|
193
|
+
|
|
145
194
|
class ExactLayer:
|
|
146
195
|
def __init__(self, plugin):
|
|
147
196
|
self.p = plugin
|
|
@@ -222,7 +271,16 @@ class ExactLayer:
|
|
|
222
271
|
st["scip_refs_external"] = st.get("scip_refs_external", 0) + 1
|
|
223
272
|
continue
|
|
224
273
|
if dst is None:
|
|
225
|
-
|
|
274
|
+
acc = kotlin_accessor_target(o.symbol, self.b.nodes)
|
|
275
|
+
if acc is not None:
|
|
276
|
+
src = self._owner(owners, rel, o.line + 1)
|
|
277
|
+
if src is not None and src != acc[0]:
|
|
278
|
+
extra = {"binding": "kotlin-accessor"}
|
|
279
|
+
if acc[1] == "CALLS":
|
|
280
|
+
extra["property"] = "write" if _accessor_kind(o.symbol) == "set" else "read"
|
|
281
|
+
self.b.add_edge(src, acc[0], acc[1], rel, o.line + 1, EXACT, source="scip", **extra)
|
|
282
|
+
if acc[1] == "CALLS":
|
|
283
|
+
exact.add((src, acc[0], "CALLS"))
|
|
226
284
|
continue
|
|
227
285
|
st["scip_refs_external"] = st.get("scip_refs_external", 0) + 1
|
|
228
286
|
continue
|
|
@@ -38,6 +38,7 @@ from pathlib import Path
|
|
|
38
38
|
|
|
39
39
|
from ...core.model import EXACT, HEURISTIC
|
|
40
40
|
from ...core.env import get as cg_env
|
|
41
|
+
from ..java.exact import _accessor_kind, kotlin_property_ref
|
|
41
42
|
from ..native import runner, scipread
|
|
42
43
|
|
|
43
44
|
BUILD_FILES = ("build.gradle.kts", "build.gradle", "settings.gradle.kts", "settings.gradle", "pom.xml")
|
|
@@ -443,10 +444,13 @@ class ExactLayer:
|
|
|
443
444
|
owners.update(jowners)
|
|
444
445
|
for rel, doc in list(kdocs.items()) + list(jdocs.items()):
|
|
445
446
|
java = rel in jdocs
|
|
446
|
-
# a property access `x.pets` is
|
|
447
|
-
#
|
|
447
|
+
# a property access `x.pets` is the term `C#pets.` plus synthetic `getPets().` / `setPets().` at the
|
|
448
|
+
# property's spelling. That accessor symbol collides with a declared `fun getPets()`. Map the spelling
|
|
449
|
+
# to the property node; a call that spells `getPets` stays a call (#105).
|
|
448
450
|
prop_at = {(o.line, o.col) for o in doc.occs if not (o.roles & scipread.DEFINITION)
|
|
449
451
|
and o.symbol.endswith(".") and not o.symbol.endswith(").")}
|
|
452
|
+
handled = set() if java else self._map_kotlin_properties(rel, doc, owners, st)
|
|
453
|
+
prop_at |= handled
|
|
450
454
|
for o in doc.occs:
|
|
451
455
|
if o.roles & scipread.DEFINITION:
|
|
452
456
|
continue
|
|
@@ -473,7 +477,10 @@ class ExactLayer:
|
|
|
473
477
|
if acc is not None:
|
|
474
478
|
src = self._owner(owners, rel, o.line + 1)
|
|
475
479
|
if src is not None and src != acc[0]:
|
|
476
|
-
|
|
480
|
+
extra = {"binding": "kotlin-accessor"}
|
|
481
|
+
if acc[1] == "CALLS":
|
|
482
|
+
extra["property"] = "write" if _accessor_kind(o.symbol) == "set" else "read"
|
|
483
|
+
self._mark_exact(src, acc[0], acc[1], rel, o.line + 1, **extra)
|
|
477
484
|
st["java"]["references"] += 1
|
|
478
485
|
continue
|
|
479
486
|
kind = "CALLS"
|
|
@@ -508,6 +515,7 @@ class ExactLayer:
|
|
|
508
515
|
"recall": round(agree / len(exact), 3) if exact else None,
|
|
509
516
|
# candidate edges (receiver type unknown, one per same-name method, #83) are compared on their own
|
|
510
517
|
"candidate_edges": len(self.candidates), "candidate_agree": len(self.candidates & exact)}
|
|
518
|
+
self._drop_heuristic_properties(covered)
|
|
511
519
|
rep = getattr(self.p, "file_report", None) or {}
|
|
512
520
|
seen = set(getattr(self.p, "_seen_files", None) or rep.get("seen") or covered)
|
|
513
521
|
st["scip_files"] = len({f for f in covered & seen if f.endswith(".kt")})
|
|
@@ -517,15 +525,108 @@ class ExactLayer:
|
|
|
517
525
|
from ..java.exact import kotlin_accessor_target
|
|
518
526
|
return kotlin_accessor_target(symbol, self.b.nodes)
|
|
519
527
|
|
|
520
|
-
def
|
|
521
|
-
"""
|
|
528
|
+
def _mark_exact(self, src: str, dst: str, kind: str, file: str, line: int, **attrs) -> None:
|
|
529
|
+
"""Upgrade a syntax-layer property edge, or add the exact one."""
|
|
522
530
|
key = (src, dst, kind, file, line, None)
|
|
523
531
|
e = self.b.edges.get(key)
|
|
524
532
|
if e is not None:
|
|
525
533
|
e.confidence = EXACT
|
|
526
534
|
e.attrs["source"] = "scip"
|
|
535
|
+
e.attrs.update(attrs)
|
|
527
536
|
return
|
|
528
|
-
self.b.add_edge(src, dst, kind, file, line, EXACT, source="scip",
|
|
537
|
+
self.b.add_edge(src, dst, kind, file, line, EXACT, source="scip", **attrs)
|
|
538
|
+
|
|
539
|
+
def _map_kotlin_properties(self, rel: str, doc, owners: dict, st: dict) -> set:
|
|
540
|
+
"""Property term and synthetic accessor occurrences at one spelling become exact read / write edges."""
|
|
541
|
+
buckets = defaultdict(list)
|
|
542
|
+
for o in doc.occs:
|
|
543
|
+
if o.roles & scipread.DEFINITION:
|
|
544
|
+
continue
|
|
545
|
+
buckets[(o.line, o.col)].append(o)
|
|
546
|
+
handled = set()
|
|
547
|
+
for (line, col), occs in buckets.items():
|
|
548
|
+
spell = self._spelling(rel, line, col)
|
|
549
|
+
if not spell:
|
|
550
|
+
continue
|
|
551
|
+
ref = None
|
|
552
|
+
for o in occs:
|
|
553
|
+
ref = kotlin_property_ref(o.symbol, self.b.nodes, spelling=spell)
|
|
554
|
+
if ref is not None:
|
|
555
|
+
break
|
|
556
|
+
if ref is None:
|
|
557
|
+
continue
|
|
558
|
+
src = self._owner(owners, rel, line + 1)
|
|
559
|
+
handled.add((line, col))
|
|
560
|
+
if src is None or src == ref[0]:
|
|
561
|
+
continue
|
|
562
|
+
self._emit_kotlin_property(src, ref[0], rel, line, col, spell)
|
|
563
|
+
st["scip_property_edges"] = st.get("scip_property_edges", 0) + 1
|
|
564
|
+
return handled
|
|
565
|
+
|
|
566
|
+
def _emit_kotlin_property(self, src: str, dst: str, rel: str, line: int, col: int, spell: str) -> None:
|
|
567
|
+
node = self.b.nodes.get(dst)
|
|
568
|
+
if node is None:
|
|
569
|
+
return
|
|
570
|
+
mode = self._mode_at(rel, line, col, spell)
|
|
571
|
+
if node.kind == "field":
|
|
572
|
+
kinds = {"read": ("READS_PROP",), "write": ("WRITES_PROP",),
|
|
573
|
+
"read_write": ("READS_PROP", "WRITES_PROP")}[mode]
|
|
574
|
+
for kind in kinds:
|
|
575
|
+
self._mark_exact(src, dst, kind, rel, line + 1)
|
|
576
|
+
return
|
|
577
|
+
acc = set(node.attrs.get("accessors") or [])
|
|
578
|
+
if mode == "write" and not ({"set", "delegate"} & acc):
|
|
579
|
+
mode = "read"
|
|
580
|
+
elif mode == "read_write" and not ({"set", "delegate"} & acc):
|
|
581
|
+
mode = "read"
|
|
582
|
+
self._mark_exact(src, dst, "CALLS", rel, line + 1, property=mode)
|
|
583
|
+
|
|
584
|
+
def _spelling(self, rel: str, line: int, col: int) -> str | None:
|
|
585
|
+
kf = getattr(self.p, "_kf_by_rel", {}).get(rel)
|
|
586
|
+
if kf is None or line < 0:
|
|
587
|
+
return None
|
|
588
|
+
lines = kf.src.splitlines()
|
|
589
|
+
if line >= len(lines):
|
|
590
|
+
return None
|
|
591
|
+
raw = lines[line]
|
|
592
|
+
if isinstance(raw, str):
|
|
593
|
+
raw = raw.encode()
|
|
594
|
+
if col < 0 or col >= len(raw):
|
|
595
|
+
return None
|
|
596
|
+
m = re.match(rb"[A-Za-z_][A-Za-z0-9_]*", raw[col:])
|
|
597
|
+
return m.group(0).decode() if m else None
|
|
598
|
+
|
|
599
|
+
def _mode_at(self, rel: str, line: int, col: int, spell: str) -> str:
|
|
600
|
+
"""`read`, `write` (`name =`), or `read_write` (`+=`, `++`, `--`). scip-java emits get and set together."""
|
|
601
|
+
kf = getattr(self.p, "_kf_by_rel", {}).get(rel)
|
|
602
|
+
if kf is None or line < 0:
|
|
603
|
+
return "read"
|
|
604
|
+
lines = kf.src.splitlines()
|
|
605
|
+
if line >= len(lines):
|
|
606
|
+
return "read"
|
|
607
|
+
raw = lines[line]
|
|
608
|
+
if isinstance(raw, str):
|
|
609
|
+
raw = raw.encode()
|
|
610
|
+
if col < 0 or col + len(spell) > len(raw):
|
|
611
|
+
return "read"
|
|
612
|
+
after = raw[col + len(spell):]
|
|
613
|
+
before = raw[:col]
|
|
614
|
+
if re.match(br"\s*(\+\+|--)", after) or re.search(br"(\+\+|--)\s*$", before):
|
|
615
|
+
return "read_write"
|
|
616
|
+
if re.match(br"\s*[-+*/%]=", after):
|
|
617
|
+
return "read_write"
|
|
618
|
+
if re.match(br"\s*=(?!=)", after):
|
|
619
|
+
return "write"
|
|
620
|
+
return "read"
|
|
621
|
+
|
|
622
|
+
def _drop_heuristic_properties(self, covered: set) -> None:
|
|
623
|
+
"""Covered Kotlin files keep the exact property edges, not the heuristic accessor calls."""
|
|
624
|
+
for key, e in list(self.b.edges.items()):
|
|
625
|
+
if e.confidence != HEURISTIC or e.file not in covered or not e.attrs.get("property"):
|
|
626
|
+
continue
|
|
627
|
+
n = self.b.nodes.get(e.src)
|
|
628
|
+
if n is not None and n.lang == "kotlin":
|
|
629
|
+
del self.b.edges[key]
|
|
529
630
|
|
|
530
631
|
def _jvm_name_facade(self, symbol: str, sym: dict) -> str | None:
|
|
531
632
|
"""`pkg/JvmName#fn().` → the top-level `pkg/fn().` when `JvmName` is a Kotlin file's JVM facade."""
|
|
@@ -626,7 +727,7 @@ class ExactLayer:
|
|
|
626
727
|
if e.confidence != HEURISTIC or e.file not in covered:
|
|
627
728
|
continue
|
|
628
729
|
if e.attrs.get("property"):
|
|
629
|
-
continue #
|
|
730
|
+
continue # compared on their own; exact property edges replace them after mapping (#105)
|
|
630
731
|
if e.kind == "REFERENCES_FN" and e.attrs.get("how") == "callback":
|
|
631
732
|
n = self.b.nodes.get(e.src)
|
|
632
733
|
if n is not None and n.lang == "kotlin":
|