cg-code-graph 0.23.6__tar.gz → 0.23.8__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.6/cg_code_graph.egg-info → cg_code_graph-0.23.8}/PKG-INFO +1 -1
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/__init__.py +1 -1
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/bridges.py +165 -8
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/cli.py +9 -5
- cg_code_graph-0.23.8/cg_code_graph/cmake_sources.py +322 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/config.py +37 -5
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/coverage.py +2 -2
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/mcp_server.py +5 -4
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/parity.py +77 -9
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/parity_structure.py +119 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/platforms.py +125 -3
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/ts/extractor/extract.mjs +59 -4
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8/cg_code_graph.egg-info}/PKG-INFO +1 -1
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph.egg-info/SOURCES.txt +5 -0
- cg_code_graph-0.23.8/tests/test_cmake_sources.py +129 -0
- cg_code_graph-0.23.8/tests/test_issue_222.py +168 -0
- cg_code_graph-0.23.8/tests/test_parity_fields.py +125 -0
- cg_code_graph-0.23.8/tests/test_tauri_events.py +128 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/LICENSE +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/MANIFEST.in +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/README.md +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/__main__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/affected.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/agent_rules.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/agents.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/aitools.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/android_ipc.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/apple_ipc.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/apps.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/blindspots.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/brokers.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/concepts.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/core/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/core/cache.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/core/detect.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/core/env.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/core/extractors.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/core/fsutil.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/core/generated.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/core/model.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/core/paths.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/core/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/core/redact.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/core/store.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/core/syntax_errors.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/dart_isolates.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/doctor.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/explore.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/external.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/graphql.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/guard_facts.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/hooks.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/indexer.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/insecure_transport.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/install_rules.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/jobs.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/link.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/lint_async.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/local_ipc.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/local_sockets.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/mcp_graphs.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/mcp_install.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/payload.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plans.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/platform_scan.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/astro/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/astro/content.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/astro/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/cfamily/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/cfamily/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/cfamily/syntax.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/dart/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/dart/bridges.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/dart/extractor/bin/extract.dart +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/dart/extractor/pubspec.lock +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/dart/extractor/pubspec.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/dart/http.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/dart/models.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/dart/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/dart/program.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/django/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/django/extras.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/django/models.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/django/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/django/schemas.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/django/shapes.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/django/urls.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/express/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/express/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/flutter/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/flutter/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/java/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/java/exact.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/java/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/jvm/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/jvm/interop.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/jvm/spring.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/kotlin/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/kotlin/exact.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/kotlin/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/kotlin/reparse.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/laravel/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/laravel/broadcast.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/laravel/massassign.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/laravel/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/laravel/tests.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/laravel/values.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/native/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/native/gates.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/native/runner.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/native/scipread.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/native/ts.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/nest/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/nest/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/nextjs/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/nextjs/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/nuxt/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/nuxt/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/php/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/php/external.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/php/extractor/composer.json +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/php/extractor/composer.lock +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/php/extractor/extract.php +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/php/gating.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/php/http_client.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/php/inline_guards.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/php/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/php/strings.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/python/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/python/aitools.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/python/external.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/python/fields.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/python/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/python/refs.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/python/roots.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/python/socketio.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/python/subproc.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/python/tests.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/python/values.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/pyweb/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/pyweb/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/pyweb/values.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/rust/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/rust/cargo.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/rust/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/rust/syntax.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/scip/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/scip/importer.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/scip/scip.proto +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/scip/scip_pb2.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/stubs/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/stubs/plugins.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/swift/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/swift/baseurl.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/swift/exact.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/swift/indexstore.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/swift/packages.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/swift/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/ts/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/ts/baseurl.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/ts/extractor/fw.mjs +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/ts/extractor/package-lock.json +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/ts/extractor/package.json +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/ts/extractor/rr.mjs +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/ts/nav.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/ts/plugin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/ts/react_router.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/tsweb/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/tsweb/common.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/plugins/tsweb/data.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/c_cpp.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/common.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/dart.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/django-ninja.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/django.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/djangorestframework.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/express.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/java.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/kotlin.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/laravel.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/nest.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/nextjs.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/nuxt.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/php.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/python.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/react-router.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/rust.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/spring.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/swift.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/presets/typescript.yaml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/process_runs.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/protocols/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/protocols/builtin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/protocols/matchers.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/protocols/view.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/query.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/realtime.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/realtime_events.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/realtime_native.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/realtime_ws.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/roundtrip.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/routes.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/rpc.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/sdk_systems.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/sockets.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/ssrf_input.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/starters.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/surface.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/tests_index.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/udp_apps.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/update_check.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/viz/__init__.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/viz/graph.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/viz/server.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/viz/static/app.css +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/viz/static/app.js +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/viz/static/index.html +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/viz/static/layered.js +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/viz/static/vendor/VERSIONS.txt +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/viz/static/vendor/cose-base.js +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/viz/static/vendor/cytoscape-fcose.js +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/viz/static/vendor/cytoscape.min.js +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/viz/static/vendor/layout-base.js +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/viz/tools/package-lock.json +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/viz/tools/package.json +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/viz/tools/shoot.mjs +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/watch.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/webhook_subs.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/webhooks.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph/xcode.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph.egg-info/dependency_links.txt +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph.egg-info/entry_points.txt +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph.egg-info/requires.txt +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/cg_code_graph.egg-info/top_level.txt +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/pyproject.toml +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/setup.cfg +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_affected.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_agents_install.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_agents_md.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_ai_tools.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_android_ipc.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_apple_ipc.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_astro.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_astro_content.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_astro_server.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_bridges.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_bridges_pigeon_monorepo.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_brokers.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_cache_clean.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_cache_invalidation.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_cache_migration.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_channels_tests.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_cli_output.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_completeness.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_config_extras.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_coverage.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_coverage_ts_hint.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_dart_isolates.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_db_connections.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_dead_wrappers.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_dispatch_interfaces.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_django_flutter.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_docs_languages.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_docs_links.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_echo_ref.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_echo_wrapper.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_elysia.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_enum_constants.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_env.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_explore.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_external.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_fp_batch.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_gating.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_generated.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_graphql.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_hooks.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_impact_overrides.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_index_isolation.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_inherited_overrides.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_inline_guards.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_install_rules.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_192.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_201.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_202.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_203.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_204.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_205.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_206.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_207.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_208.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_209.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_210.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_211.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_211_used_at.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_212.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_212_langs.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_218.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_issue_219.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_java.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_java_exact.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_jobs.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_js_refs.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_js_runtime.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_kotlin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_kotlin_binding.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_kotlin_exact.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_kotlin_fields.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_kotlin_mixed.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_kotlin_nav_consts.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_kotlin_props.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_laravel_determinism.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_laravel_receiver_narrowing.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_laravel_resources.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_laravel_route_paths.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_link_origin.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_lint_async.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_listing_files.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_local_ipc.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_local_sockets.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_mass_assignment.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_mcp.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_mcp_index.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_mcp_install.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_mcp_instructions.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_mcp_multi_graph.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_native_cfamily.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_native_concurrency.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_native_rust.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_nuxt_i18n.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_nuxt_import_dirs.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_nuxt_nitro.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_nuxt_rootsrc.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_nuxt_side_dirs.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_packaging.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_parity.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_parity_structure.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_php_http.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_php_props.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_plain_js.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_plans.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_platform_gaps.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_platform_type_variants.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_platforms.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_platforms_apple.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_presets_config.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_process_ipc.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_process_runs.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_protocols.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_python_app_tests_module.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_python_collection_chains.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_python_compat.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_python_entry_refs.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_python_fields.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_python_infer_cycles.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_python_roots.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_python_subprocess_tests.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_python_tests.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_python_web_hosts.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_python_web_routes.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_python_web_routes_more.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_react_router.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_readers_writers_specs.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_realtime.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_realtime_native.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_redact_salt.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_request_keys.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_roundtrip.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_route_specs.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_route_tables.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_routes_search_explain.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_rpc.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_scip_health.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_sdk_external.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_sdk_external_infra.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_sdk_external_mail.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_snippet.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_sockets.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_spring.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_ssrf.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_starters_budget.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_surface.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_surface_transport.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_swift.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_swift_binding.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_swift_exact.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_swift_facts.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_swift_fields.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_swift_modules.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_swift_more.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_swift_nav_values.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_swift_parse_errors.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_swift_props.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_swift_sdk.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_swift_testing.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_swift_values.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_tests_scope.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_ts_fields.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_ts_fields_js_vue.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_ts_file_specs.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_ts_frameworks.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_ts_node_http.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_ts_nuxt.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_ts_src_tsconfig.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_unguarded.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_update_check.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_values.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_viz.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_vue_nav.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_watch.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_webhooks.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_webhooks_152.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_webhooks_152b.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/tests/test_websockets.py +0 -0
- {cg_code_graph-0.23.6 → cg_code_graph-0.23.8}/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.8"
|
|
@@ -31,6 +31,9 @@ Process protocols (one app, two processes; receivers carry attrs.process instead
|
|
|
31
31
|
tauri endpoint:tauri:<command> (plugin commands: endpoint:tauri:plugin:<name>|<command>, external
|
|
32
32
|
tauri-plugin-<name> unless the plugin crate is in the repo); invoke('cmd') from @tauri-apps/api ->
|
|
33
33
|
#[tauri::command] fn in the Rust core; check unregistered: not listed in generate_handler!
|
|
34
|
+
tauri-event endpoint:tauri-event:<name>; emit / emit_to / emit_str / emit_filter with a literal name (Rust
|
|
35
|
+
`app.emit("x", ..)`, webview `emit('x')`, `getCurrentWindow().emit('x')`, `emitTo(label, 'x')`)
|
|
36
|
+
-> listen / listen_any / once (Rust closures, webview callbacks); `tauri://` names are Tauri's own
|
|
34
37
|
no_receiver for these: the other side is in the repo (some channel / command is received) but not this one.
|
|
35
38
|
"""
|
|
36
39
|
from __future__ import annotations
|
|
@@ -55,6 +58,8 @@ PROTOCOLS = {
|
|
|
55
58
|
"ipcRenderer.on)",
|
|
56
59
|
"electron-preload": "Electron context bridge member (window.<key>.<member>() -> contextBridge.exposeInMainWorld)",
|
|
57
60
|
"tauri": "Tauri command (invoke('cmd') -> #[tauri::command] fn cmd registered in generate_handler!)",
|
|
61
|
+
"tauri-event": "Tauri event (emit / emit_to('name') in Rust or the webview -> listen / once('name') on the other "
|
|
62
|
+
"side; `tauri://` events are emitted by Tauri itself)",
|
|
58
63
|
"react-native-event": "React Native event (native sendEvent / RCTDeviceEventEmitter.emit / sendEventWithName / Expo "
|
|
59
64
|
"sendEvent -> NativeEventEmitter / DeviceEventEmitter addListener in JS)",
|
|
60
65
|
"capacitor-event": "Capacitor plugin event (native notifyListeners('evt') -> Plugin.addListener('evt') in JS)",
|
|
@@ -64,8 +69,8 @@ PROTOCOLS = {
|
|
|
64
69
|
# native -> app events: the JS listener is the receiver; no_sender only where the repo sends some event natively
|
|
65
70
|
EVENT_PROTOCOLS = ("react-native-event", "capacitor-event")
|
|
66
71
|
# protocols between processes of one app (no per-platform receivers)
|
|
67
|
-
PROCESS_PROTOCOLS = ("electron-ipc", "electron-preload", "tauri")
|
|
68
|
-
TRANSPORT = {"electron-ipc": "ipc", "tauri": "ipc", "electron-preload": "local"}
|
|
72
|
+
PROCESS_PROTOCOLS = ("electron-ipc", "electron-preload", "tauri", "tauri-event")
|
|
73
|
+
TRANSPORT = {"electron-ipc": "ipc", "tauri": "ipc", "tauri-event": "ipc", "electron-preload": "local"}
|
|
69
74
|
MOBILE = ("android", "ios", "macos")
|
|
70
75
|
APP_LANGS = ("dart", "ts") # the app side of a bridge (receivers there: a native -> app call)
|
|
71
76
|
# Capacitor Plugin / CAPPlugin base-class methods: handled by the bridge on every platform unless a plugin overrides them
|
|
@@ -1162,11 +1167,134 @@ def tauri_receivers(project, builder) -> dict:
|
|
|
1162
1167
|
return {"commands": n, "registered": len(registered)} if n else {}
|
|
1163
1168
|
|
|
1164
1169
|
|
|
1170
|
+
TAURI_EV_RS_SEND = re.compile(r"\.\s*(emit|emit_str|emit_all)\s*\(\s*\"([^\"]+)\"|"
|
|
1171
|
+
r"\.\s*(emit_to|emit_str_to|emit_filter|emit_str_filter)\s*\(\s*(?:[^,()]|\([^()]*\))+,\s*\"([^\"]+)\"")
|
|
1172
|
+
TAURI_EV_RS_RECV = re.compile(r"\.\s*(listen|listen_any|once|once_any)\s*\(\s*\"([^\"]+)\"\s*,\s*(?:move\s*)?(\|[^|]*\||[A-Za-z_][\w:]*)?")
|
|
1173
|
+
TAURI_EV_JS_SEND = re.compile(r"""(?<![\w$])(?:\.\s*)?(emit)\s*\(\s*(['"`])([^'"`$\n]+)\2|"""
|
|
1174
|
+
r"""(?<![\w$])(?:\.\s*)?(emitTo)\s*\(\s*[^,()]+,\s*(['"`])([^'"`$\n]+)\5""")
|
|
1175
|
+
TAURI_EV_JS_RECV = re.compile(r"""(?<![\w$])(?:\.\s*)?(listen|once)\s*(?:<[^>()]*>)?\s*\(\s*(['"`])([^'"`$\n]+)\2\s*,\s*([A-Za-z_$][\w$]*)?""")
|
|
1176
|
+
TAURI_EV_DYN_SEND = re.compile(r"""(?<![\w$])(?:\.\s*)?(?:emit|emit_str|emit_all)\s*\(\s*&?[A-Za-z_$][\w$.]*\s*[,)]""")
|
|
1177
|
+
TAURI_EV_DYN_RECV = re.compile(r"""(?<![\w$])(?:\.\s*)?(?:listen|listen_any|once)\s*(?:<[^>()]*>)?\s*\(\s*&?[A-Za-z_$][\w$.]*\s*,""")
|
|
1178
|
+
_JS_TOKEN = re.compile(r"""'(?:\\.|[^'\\\n])*'|"(?:\\.|[^"\\\n])*"|`(?:\\.|[^`\\])*`|//[^\n]*|/\*.*?\*/""", re.S)
|
|
1179
|
+
JS_LIKE = (".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".vue", ".svelte")
|
|
1180
|
+
|
|
1181
|
+
|
|
1182
|
+
def _innermost(builder, by_file: dict, rel: str, line: int) -> str | None:
|
|
1183
|
+
"""The innermost function / method / component node of `rel` around `line`, else its module / file node."""
|
|
1184
|
+
best, size = None, None
|
|
1185
|
+
for n in by_file.get(rel, ()):
|
|
1186
|
+
if n.line is None or n.line > line or (n.end_line or n.line) < line:
|
|
1187
|
+
continue
|
|
1188
|
+
sz = (n.end_line or n.line) - n.line
|
|
1189
|
+
if size is None or sz < size:
|
|
1190
|
+
best, size = n.id, sz
|
|
1191
|
+
return best
|
|
1192
|
+
|
|
1193
|
+
|
|
1194
|
+
def _uses_tauri(root: Path, depth: int = 4) -> bool:
|
|
1195
|
+
"""A Cargo.toml depending on tauri or a package.json depending on @tauri-apps/* within `depth` directories."""
|
|
1196
|
+
from . import presets
|
|
1197
|
+
skip = presets.skip_dirs("common")
|
|
1198
|
+
for dp, dn, fn in os.walk(root):
|
|
1199
|
+
rel = Path(dp).relative_to(root)
|
|
1200
|
+
dn[:] = [] if len(rel.parts) >= depth else [d for d in dn if d not in skip and not d.startswith(".")]
|
|
1201
|
+
for name, rx in (("Cargo.toml", r"^\s*tauri\s*="), ("package.json", r'"@tauri-apps/')):
|
|
1202
|
+
if name in fn:
|
|
1203
|
+
try:
|
|
1204
|
+
if re.search(rx, (Path(dp) / name).read_text(encoding="utf-8", errors="replace"), re.M):
|
|
1205
|
+
return True
|
|
1206
|
+
except OSError:
|
|
1207
|
+
pass
|
|
1208
|
+
return False
|
|
1209
|
+
|
|
1210
|
+
|
|
1211
|
+
def tauri_events(project, builder) -> dict:
|
|
1212
|
+
"""Tauri events (#111): a literal event name emitted on one side (Rust core or webview) and listened to on the
|
|
1213
|
+
other -> SENDS_TO / RECEIVED_BY over endpoint:tauri-event:<name>. The receiver is the named callback when the
|
|
1214
|
+
listener passes a function by name, else the function that registers the listener. Names built at run time
|
|
1215
|
+
(`window.emit(event_name, ..)`) are not followed."""
|
|
1216
|
+
root = Path(project.root)
|
|
1217
|
+
if not _uses_tauri(root):
|
|
1218
|
+
return {}
|
|
1219
|
+
by_file: dict[str, list] = defaultdict(list)
|
|
1220
|
+
kinds = ("function", "method", "component", "page", "layout", "module", "file", "closure")
|
|
1221
|
+
for n in builder.nodes.values():
|
|
1222
|
+
if n.file and n.kind in kinds:
|
|
1223
|
+
by_file[n.file].append(n)
|
|
1224
|
+
named: dict[str, dict[str, str]] = defaultdict(dict)
|
|
1225
|
+
for f, ns in by_file.items():
|
|
1226
|
+
for n in ns:
|
|
1227
|
+
if n.kind in ("function", "method"):
|
|
1228
|
+
named[f].setdefault(n.name.rsplit("::", 1)[-1].rsplit(".", 1)[-1], n.id)
|
|
1229
|
+
sent = recv = 0
|
|
1230
|
+
dyn = {"send": 0, "recv": 0} # names passed in a variable: a helper forwards them (`listen(eventName, ..)`)
|
|
1231
|
+
eps = set()
|
|
1232
|
+
for rel in sorted(by_file):
|
|
1233
|
+
is_rs = rel.endswith(".rs")
|
|
1234
|
+
if not (is_rs or rel.endswith(JS_LIKE)) or rel.endswith(".d.ts"):
|
|
1235
|
+
continue
|
|
1236
|
+
try:
|
|
1237
|
+
raw = (root / rel).read_text(encoding="utf-8", errors="replace")
|
|
1238
|
+
except OSError:
|
|
1239
|
+
continue
|
|
1240
|
+
if is_rs:
|
|
1241
|
+
if "emit" not in raw and "listen" not in raw and "once" not in raw:
|
|
1242
|
+
continue
|
|
1243
|
+
src = strip_comments(raw)
|
|
1244
|
+
if not re.search(r"\btauri\b", src):
|
|
1245
|
+
continue
|
|
1246
|
+
else:
|
|
1247
|
+
if "@tauri-apps/api" not in raw and "__TAURI__" not in raw:
|
|
1248
|
+
continue
|
|
1249
|
+
src = _JS_TOKEN.sub(lambda m: m.group(0) if m.group(0)[0] in "'\"`" else re.sub(r"[^\n]", " ", m.group(0)), raw)
|
|
1250
|
+
side = "core" if is_rs else "webview"
|
|
1251
|
+
lines = lambda pos: src.count("\n", 0, pos) + 1 # noqa: E731
|
|
1252
|
+
dyn["send"] += len(TAURI_EV_DYN_SEND.findall(src))
|
|
1253
|
+
dyn["recv"] += len(TAURI_EV_DYN_RECV.findall(src))
|
|
1254
|
+
for m in (TAURI_EV_RS_SEND if is_rs else TAURI_EV_JS_SEND).finditer(src):
|
|
1255
|
+
name = (m.group(2) or m.group(4)) if is_rs else (m.group(3) or m.group(6))
|
|
1256
|
+
ln = lines(m.start())
|
|
1257
|
+
who = _innermost(builder, by_file, rel, ln)
|
|
1258
|
+
if not who or not name:
|
|
1259
|
+
continue
|
|
1260
|
+
nid = protocol_send(builder, "tauri-event", name, None, who, rel, ln, "exact", process=side,
|
|
1261
|
+
via=(m.group(1) or m.group(3)) if is_rs else (m.group(1) or m.group(4)))
|
|
1262
|
+
if name.startswith("tauri://"):
|
|
1263
|
+
builder.nodes[nid].attrs["builtin"] = True
|
|
1264
|
+
eps.add(nid)
|
|
1265
|
+
sent += 1
|
|
1266
|
+
for m in (TAURI_EV_RS_RECV if is_rs else TAURI_EV_JS_RECV).finditer(src):
|
|
1267
|
+
name = m.group(2) if is_rs else m.group(3)
|
|
1268
|
+
cb = (m.group(3) or "") if is_rs else (m.group(4) or "")
|
|
1269
|
+
ln = lines(m.start())
|
|
1270
|
+
h = named[rel].get(cb.rsplit("::", 1)[-1]) if cb and not cb.startswith("|") else None
|
|
1271
|
+
h = h or _innermost(builder, by_file, rel, ln)
|
|
1272
|
+
if not h:
|
|
1273
|
+
continue
|
|
1274
|
+
nid = protocol_receive(builder, "tauri-event", name, None, h, rel, ln, "exact", process=side,
|
|
1275
|
+
via=m.group(1))
|
|
1276
|
+
if name.startswith("tauri://"):
|
|
1277
|
+
builder.nodes[nid].attrs["builtin"] = True
|
|
1278
|
+
eps.add(nid)
|
|
1279
|
+
recv += 1
|
|
1280
|
+
if dyn["send"] or dyn["recv"]:
|
|
1281
|
+
# the other side may be one of those: no no_receiver / no_sender claim for the literal names
|
|
1282
|
+
for nid in eps:
|
|
1283
|
+
builder.nodes[nid].attrs["dynamic_names"] = dict(dyn)
|
|
1284
|
+
out = {"event_sends": sent, "event_listeners": recv}
|
|
1285
|
+
if dyn["send"] or dyn["recv"]:
|
|
1286
|
+
out["event_dynamic_names"] = dyn
|
|
1287
|
+
return out if sent or recv else {}
|
|
1288
|
+
|
|
1289
|
+
|
|
1165
1290
|
def apply(project, builder, scanned=None, sends_only: bool = False) -> dict:
|
|
1166
1291
|
"""Index pass: native receivers of every bridge protocol -> RECEIVED_BY edges (+ stub nodes for Java / ObjC) and
|
|
1167
1292
|
platform marks on their files. Returns the bridges stats (empty when there is no bridge code)."""
|
|
1168
1293
|
from .platforms import BIG, Cond, _plat_atom, mark
|
|
1169
1294
|
tauri = tauri_receivers(project, builder)
|
|
1295
|
+
ev = tauri_events(project, builder)
|
|
1296
|
+
if ev:
|
|
1297
|
+
tauri = {**(tauri or {}), **ev}
|
|
1170
1298
|
st0 = {"tauri": tauri} if tauri else {}
|
|
1171
1299
|
st = _apply(project, builder, scanned, sends_only, mark, BIG, Cond, _plat_atom)
|
|
1172
1300
|
if st0 or st:
|
|
@@ -1406,9 +1534,31 @@ def project_targets(project, builder) -> list[str]:
|
|
|
1406
1534
|
return []
|
|
1407
1535
|
|
|
1408
1536
|
|
|
1409
|
-
def
|
|
1537
|
+
def _declared_role(declared: dict, f: str | None) -> str | None:
|
|
1538
|
+
if not f or not declared:
|
|
1539
|
+
return None
|
|
1540
|
+
return next((r for g, r in declared.items() if fnmatch.fnmatch(f, g)), None)
|
|
1541
|
+
|
|
1542
|
+
|
|
1543
|
+
def _process_roles(builder, eps, recv, send, declared: dict | None = None) -> None:
|
|
1410
1544
|
"""Electron / Tauri: process role of each file taking part in IPC (attrs.process on its module node): main,
|
|
1411
|
-
preload (exposes a context bridge), renderer (Electron), webview / core (Tauri).
|
|
1545
|
+
preload (exposes a context bridge), renderer (Electron), webview / core (Tauri). `.cg.yaml`
|
|
1546
|
+
platforms.processes (glob -> role) wins over the inferred role, for the module and for each send / receive edge
|
|
1547
|
+
in its files (attrs.process_from: config)."""
|
|
1548
|
+
declared = declared or {}
|
|
1549
|
+
if declared:
|
|
1550
|
+
for nid, n in eps.items():
|
|
1551
|
+
if n.attrs.get("protocol") not in PROCESS_PROTOCOLS:
|
|
1552
|
+
continue
|
|
1553
|
+
for e in recv[nid]:
|
|
1554
|
+
dn = builder.nodes.get(e.dst)
|
|
1555
|
+
r = _declared_role(declared, dn.file if dn else None)
|
|
1556
|
+
if r:
|
|
1557
|
+
e.attrs = {**(e.attrs or {}), "process": r, "process_from": "config"}
|
|
1558
|
+
for e in send[nid]:
|
|
1559
|
+
r = _declared_role(declared, e.file)
|
|
1560
|
+
if r:
|
|
1561
|
+
e.attrs = {**(e.attrs or {}), "process": r, "process_from": "config"}
|
|
1412
1562
|
roles = defaultdict(set)
|
|
1413
1563
|
for nid, n in eps.items():
|
|
1414
1564
|
if n.attrs.get("protocol") not in PROCESS_PROTOCOLS:
|
|
@@ -1421,10 +1571,16 @@ def _process_roles(builder, eps, recv, send) -> None:
|
|
|
1421
1571
|
sn = builder.nodes.get(e.src)
|
|
1422
1572
|
if sn and sn.file and e.attrs.get("process"):
|
|
1423
1573
|
roles[sn.file].add(e.attrs["process"])
|
|
1424
|
-
if not roles:
|
|
1574
|
+
if not roles and not declared:
|
|
1425
1575
|
return
|
|
1426
1576
|
for n in builder.nodes.values():
|
|
1427
|
-
if n.kind in ("module", "file", "mod", "crate")
|
|
1577
|
+
if n.kind not in ("module", "file", "mod", "crate", "component"):
|
|
1578
|
+
continue
|
|
1579
|
+
d = _declared_role(declared, n.file)
|
|
1580
|
+
if d:
|
|
1581
|
+
# declared: also files that take no part in IPC themselves (the renderer's components, the core's services)
|
|
1582
|
+
n.attrs["process"], n.attrs["process_from"] = d, "config"
|
|
1583
|
+
elif n.file in roles and n.kind != "component":
|
|
1428
1584
|
r = roles[n.file]
|
|
1429
1585
|
n.attrs["process"] = "preload" if "preload" in r else next(iter(r)) if len(r) == 1 else "+".join(sorted(r))
|
|
1430
1586
|
|
|
@@ -1457,7 +1613,7 @@ def finalize(project, builder, st: dict, targets: list[str] | None) -> dict:
|
|
|
1457
1613
|
proto_recv = defaultdict(set)
|
|
1458
1614
|
for nid in recv:
|
|
1459
1615
|
proto_recv[eps[nid].attrs["protocol"]].add(None)
|
|
1460
|
-
_process_roles(builder, eps, recv, send)
|
|
1616
|
+
_process_roles(builder, eps, recv, send, ((project.options.get("config") or {}).get("platforms") or {}).get("processes"))
|
|
1461
1617
|
# macOS counts only where some bridge module is implemented for it (a Flutter macos/ runner)
|
|
1462
1618
|
used = {e.attrs.get("platform") for es in recv.values() for e in es}
|
|
1463
1619
|
mobile = [p for p in (targets or []) if p in ("android", "ios") or (p == "macos" and p in used)]
|
|
@@ -1487,7 +1643,8 @@ def finalize(project, builder, st: dict, targets: list[str] | None) -> dict:
|
|
|
1487
1643
|
# one app, two processes: a receiver-less channel is a miss when the other side is in the repo at all
|
|
1488
1644
|
ext_pkg = any(e.attrs.get("external") for e in send[nid] + tsend[nid])
|
|
1489
1645
|
impl = None if ext_pkg else (proto_recv.get(a["protocol"]) or None)
|
|
1490
|
-
base = a.get("method") in BASE_METHODS.get(a["protocol"], ())
|
|
1646
|
+
base = (a.get("method") in BASE_METHODS.get(a["protocol"], ()) or bool(a.get("builtin"))
|
|
1647
|
+
or bool(a.get("dynamic_names")))
|
|
1491
1648
|
if base:
|
|
1492
1649
|
a["base_method"] = True # the framework's base class implements it on every platform; a module may override
|
|
1493
1650
|
if a["protocol"] in EVENT_PROTOCOLS and (send[nid] or tsend[nid]) and not recv[nid]:
|
|
@@ -186,8 +186,9 @@ def main(argv=None):
|
|
|
186
186
|
"(variants missing a target, API differences, references to code missing on a target)")
|
|
187
187
|
p.add_argument("action", nargs="?", default="summary", choices=["summary", "divergence"])
|
|
188
188
|
p.add_argument("--db", required=True); p.add_argument("--target", help="divergence: only findings that affect this target")
|
|
189
|
-
p.add_argument("--kind", choices=["variants", "api_surface", "missing_callee", "missing_callee_tests"],
|
|
190
|
-
help="divergence: one finding kind (missing_callee_tests: from test code on the project-default platforms
|
|
189
|
+
p.add_argument("--kind", choices=["variants", "api_surface", "missing_callee", "missing_callee_tests", "dead_branch"],
|
|
190
|
+
help="divergence: one finding kind (missing_callee_tests: from test code on the project-default platforms; "
|
|
191
|
+
"dead_branch: nested conditions no target meets together)")
|
|
191
192
|
p.add_argument("--max-items", type=int, default=40); p.add_argument("--json", action="store_true")
|
|
192
193
|
p = sub.add_parser("resolutions", help="every place a concept (e.g. timezone) is resolved, with fallback chains and divergence")
|
|
193
194
|
p.add_argument("concept"); p.add_argument("--db", required=True); p.add_argument("--within", help="substring filter on the owning function fqn (e.g. Report)")
|
|
@@ -300,9 +301,12 @@ def main(argv=None):
|
|
|
300
301
|
p.add_argument("--strip-prefix", action="append", default=[], help="a name prefix one side adds (`Vault` in "
|
|
301
302
|
"VaultAddEditState for AddEditState), ignored when matching (repeatable)")
|
|
302
303
|
p.add_argument("--structure", action="store_true", help="also pair symbols whose names differ by what they use: "
|
|
303
|
-
"shared strings, localization keys, endpoints and already-paired callees,
|
|
304
|
-
"from the pairs found (#93); matches carry their
|
|
304
|
+
"shared strings, localization keys, resources, endpoints and already-paired callees, then types by "
|
|
305
|
+
"their declared fields, plus rename rules learned from the pairs found (#93); matches carry their "
|
|
306
|
+
"evidence")
|
|
305
307
|
p.add_argument("--no-learn", action="store_true", help="with --structure: no learned rename rules")
|
|
308
|
+
p.add_argument("--both-sides", action="store_true", help="also list the matched pairs and what only --against "
|
|
309
|
+
"has (target symbols no source symbol matched)")
|
|
306
310
|
p.add_argument("--write-map", help="with --structure: write the inferred pairs as a --map JSON file to review")
|
|
307
311
|
p.add_argument("--json", action="store_true"); p.add_argument("--max-items", type=int, default=200)
|
|
308
312
|
p = sub.add_parser("lint", help="heuristic lints (#88): `lint async-state` flags stale async results, state with "
|
|
@@ -573,7 +577,7 @@ def main(argv=None):
|
|
|
573
577
|
from . import parity as PA
|
|
574
578
|
mapping = json.loads(open(a.map, encoding="utf-8").read()) if a.map else None
|
|
575
579
|
res = PA.parity(a.db, a.against, mapping=mapping, fuzzy=not a.no_fuzzy, strip_prefixes=a.strip_prefix,
|
|
576
|
-
structure=a.structure, learn=not a.no_learn)
|
|
580
|
+
structure=a.structure, learn=not a.no_learn, both_sides=a.both_sides)
|
|
577
581
|
if a.write_map:
|
|
578
582
|
with open(a.write_map, "w", encoding="utf-8") as fh:
|
|
579
583
|
json.dump(PA.rename_map(res), fh, indent=1, sort_keys=True)
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
"""Per-platform C / C++ source lists from CMake (#111): `if(WIN32) list(APPEND srcs src/win/fs.c)`,
|
|
2
|
+
`if(CMAKE_SYSTEM_NAME MATCHES "Android|Linux") ...`, `target_sources(...)` under a condition. A source file that every
|
|
3
|
+
CMakeLists.txt mentions only under platform conditions is built only where one of them holds; that is the build's own
|
|
4
|
+
answer, so it replaces the directory / file-name guess (src/unix/, linux.c) for that file.
|
|
5
|
+
|
|
6
|
+
Read without running CMake: `if` / `elseif` / `else` / `endif` over WIN32, APPLE, UNIX, ANDROID, IOS, EMSCRIPTEN,
|
|
7
|
+
MSVC, MINGW, CYGWIN and `CMAKE_SYSTEM_NAME STREQUAL / MATCHES`, with NOT / AND / OR and parentheses. Anything else (an
|
|
8
|
+
option, a version check) is unknown and keeps the file live. Files are named in `list(APPEND|PREPEND ...)`, `set(...)`,
|
|
9
|
+
`target_sources(...)`, `add_library(...)` and `add_executable(...)`, relative to the CMakeLists.txt (a
|
|
10
|
+
`${CMAKE_CURRENT_SOURCE_DIR}/` prefix is understood); names built from other variables are not followed.
|
|
11
|
+
|
|
12
|
+
compile_db_membership: `.cg.yaml` platforms.compile_commands, one compile_commands.json per target build, is the exact
|
|
13
|
+
answer and wins over the CMake lists."""
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import os
|
|
17
|
+
import re
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
from . import presets
|
|
21
|
+
|
|
22
|
+
SYSTEM_NAME = {"windows": "Windows", "linux": "Linux", "macos": "Darwin", "ios": "iOS", "android": "Android",
|
|
23
|
+
"web": "Emscripten", "tvos": "tvOS", "watchos": "watchOS", "visionos": "visionOS"}
|
|
24
|
+
# operating systems outside the known targets, to tell whether a source list also builds the file there
|
|
25
|
+
OTHER = tuple("other:" + n for n in ("FreeBSD", "OpenBSD", "NetBSD", "DragonFly", "AIX", "SunOS", "OS390", "QNX",
|
|
26
|
+
"Haiku", "CYGWIN", "MSYS", "GNU", "OS400"))
|
|
27
|
+
BSDS = {"other:FreeBSD", "other:OpenBSD", "other:NetBSD", "other:DragonFly"}
|
|
28
|
+
SRC = re.compile(r"\.(c|cc|cpp|cxx|m|mm|h|hh|hpp|hxx)$", re.I)
|
|
29
|
+
LISTS = {"list", "set", "target_sources", "add_library", "add_executable"}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _strip_comments(text: str) -> str:
|
|
33
|
+
text = re.sub(r"#\[(=*)\[.*?\]\1\]", " ", text, flags=re.S) # bracket comments
|
|
34
|
+
out = []
|
|
35
|
+
for line in text.split("\n"):
|
|
36
|
+
q = False
|
|
37
|
+
for i, ch in enumerate(line):
|
|
38
|
+
if ch == '"':
|
|
39
|
+
q = not q
|
|
40
|
+
elif ch == "#" and not q:
|
|
41
|
+
line = line[:i]
|
|
42
|
+
break
|
|
43
|
+
out.append(line)
|
|
44
|
+
return "\n".join(out)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _commands(text: str):
|
|
48
|
+
"""(name, args text, line) for every command call, args with nested parentheses."""
|
|
49
|
+
i, n = 0, len(text)
|
|
50
|
+
rx = re.compile(r"([A-Za-z_]\w*)\s*\(")
|
|
51
|
+
while True:
|
|
52
|
+
m = rx.search(text, i)
|
|
53
|
+
if not m:
|
|
54
|
+
return
|
|
55
|
+
depth, j, q = 1, m.end(), False
|
|
56
|
+
while j < n and depth:
|
|
57
|
+
ch = text[j]
|
|
58
|
+
if ch == '"':
|
|
59
|
+
q = not q
|
|
60
|
+
elif not q and ch == "(":
|
|
61
|
+
depth += 1
|
|
62
|
+
elif not q and ch == ")":
|
|
63
|
+
depth -= 1
|
|
64
|
+
j += 1
|
|
65
|
+
yield m.group(1).lower(), text[m.end():j - 1], text.count("\n", 0, m.start()) + 1
|
|
66
|
+
i = j
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _tokens(args: str) -> list[str]:
|
|
70
|
+
return [a[1:-1] if a.startswith('"') else a for a in re.findall(r'"[^"]*"|\(|\)|[^\s()"]+', args)]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# ------------------------------------------------------------------ three-valued condition evaluation per target
|
|
74
|
+
def _var(name: str, p: str):
|
|
75
|
+
name = re.sub(r"^\$\{(.*)\}$", r"\1", name)
|
|
76
|
+
u = name.upper()
|
|
77
|
+
if p.startswith("other:"):
|
|
78
|
+
if u in ("WIN32", "APPLE", "ANDROID", "IOS", "EMSCRIPTEN", "MSVC", "MINGW", "CMAKE_CL_64", "LINUX"):
|
|
79
|
+
return False
|
|
80
|
+
if u == "UNIX":
|
|
81
|
+
return True
|
|
82
|
+
if u in ("CYGWIN", "MSYS"):
|
|
83
|
+
return p == "other:" + u
|
|
84
|
+
if u == "BSD":
|
|
85
|
+
return p in BSDS
|
|
86
|
+
if u == "WIN32":
|
|
87
|
+
return p == "windows"
|
|
88
|
+
if u == "APPLE":
|
|
89
|
+
return p in ("macos", "ios", "tvos", "watchos", "visionos")
|
|
90
|
+
if u == "UNIX":
|
|
91
|
+
return p != "windows"
|
|
92
|
+
if u == "ANDROID":
|
|
93
|
+
return p == "android"
|
|
94
|
+
if u == "IOS":
|
|
95
|
+
return p == "ios"
|
|
96
|
+
if u == "EMSCRIPTEN":
|
|
97
|
+
return p == "web"
|
|
98
|
+
if u in ("MSVC", "MINGW", "CMAKE_CL_64"):
|
|
99
|
+
return None if p == "windows" else False
|
|
100
|
+
if u in ("CYGWIN", "MSYS", "BSD"):
|
|
101
|
+
return False
|
|
102
|
+
if u == "LINUX":
|
|
103
|
+
return p == "linux"
|
|
104
|
+
if u in ("ON", "TRUE", "YES", "Y") or (u.isdigit() and u != "0"):
|
|
105
|
+
return True
|
|
106
|
+
if u in ("OFF", "FALSE", "NO", "N", "0", "IGNORE", "NOTFOUND", ""):
|
|
107
|
+
return False
|
|
108
|
+
return None
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _system(tok: str) -> bool:
|
|
112
|
+
return re.sub(r"^\$\{(.*)\}$", r"\1", tok) == "CMAKE_SYSTEM_NAME"
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class _Cond:
|
|
116
|
+
def __init__(self, toks: list[str]):
|
|
117
|
+
self.t, self.i = toks, 0
|
|
118
|
+
|
|
119
|
+
def peek(self):
|
|
120
|
+
return self.t[self.i] if self.i < len(self.t) else None
|
|
121
|
+
|
|
122
|
+
def take(self):
|
|
123
|
+
self.i += 1
|
|
124
|
+
return self.t[self.i - 1]
|
|
125
|
+
|
|
126
|
+
def parse(self, p: str):
|
|
127
|
+
self.i = 0
|
|
128
|
+
try:
|
|
129
|
+
v = self.p_or(p)
|
|
130
|
+
except (IndexError, re.error):
|
|
131
|
+
return None
|
|
132
|
+
return v if self.i >= len(self.t) else None
|
|
133
|
+
|
|
134
|
+
def p_or(self, p):
|
|
135
|
+
v = self.p_and(p)
|
|
136
|
+
while self.peek() == "OR":
|
|
137
|
+
self.take()
|
|
138
|
+
w = self.p_and(p)
|
|
139
|
+
v = True if (v is True or w is True) else (False if (v is False and w is False) else None)
|
|
140
|
+
return v
|
|
141
|
+
|
|
142
|
+
def p_and(self, p):
|
|
143
|
+
v = self.p_not(p)
|
|
144
|
+
while self.peek() == "AND":
|
|
145
|
+
self.take()
|
|
146
|
+
w = self.p_not(p)
|
|
147
|
+
v = False if (v is False or w is False) else (True if (v is True and w is True) else None)
|
|
148
|
+
return v
|
|
149
|
+
|
|
150
|
+
def p_not(self, p):
|
|
151
|
+
if self.peek() == "NOT":
|
|
152
|
+
self.take()
|
|
153
|
+
v = self.p_not(p)
|
|
154
|
+
return None if v is None else not v
|
|
155
|
+
return self.p_bin(p)
|
|
156
|
+
|
|
157
|
+
def p_bin(self, p):
|
|
158
|
+
tok = self.take()
|
|
159
|
+
if tok == "(":
|
|
160
|
+
v = self.p_or(p)
|
|
161
|
+
if self.take() != ")":
|
|
162
|
+
raise IndexError
|
|
163
|
+
return v
|
|
164
|
+
if tok in ("DEFINED", "EXISTS", "COMMAND", "TARGET", "POLICY", "IS_DIRECTORY", "IS_ABSOLUTE"):
|
|
165
|
+
self.take()
|
|
166
|
+
return None
|
|
167
|
+
op = self.peek()
|
|
168
|
+
if op in ("STREQUAL", "MATCHES", "EQUAL", "STRLESS", "STRGREATER", "LESS", "GREATER", "IN_LIST",
|
|
169
|
+
"VERSION_LESS", "VERSION_GREATER", "VERSION_EQUAL", "VERSION_GREATER_EQUAL", "VERSION_LESS_EQUAL",
|
|
170
|
+
"LESS_EQUAL", "GREATER_EQUAL", "STRLESS_EQUAL", "STRGREATER_EQUAL"):
|
|
171
|
+
self.take()
|
|
172
|
+
rhs = self.take()
|
|
173
|
+
sysname = SYSTEM_NAME.get(p) or p.split(":", 1)[-1]
|
|
174
|
+
if _system(tok) and op == "STREQUAL":
|
|
175
|
+
return sysname == rhs
|
|
176
|
+
if _system(tok) and op == "MATCHES":
|
|
177
|
+
return re.search(rhs, sysname) is not None
|
|
178
|
+
return None
|
|
179
|
+
return _var(tok, p)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def _values(toks: list[str]) -> dict:
|
|
183
|
+
from .platforms import KNOWN
|
|
184
|
+
c = _Cond(toks)
|
|
185
|
+
return {p: c.parse(p) for p in KNOWN + OTHER}
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def _and(a: dict, b: dict) -> dict:
|
|
189
|
+
return {p: False if (a[p] is False or b[p] is False) else (True if (a[p] is True and b[p] is True) else None) for p in a}
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def _not(a: dict) -> dict:
|
|
193
|
+
return {p: None if v is None else not v for p, v in a.items()}
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _or(a: dict, b: dict) -> dict:
|
|
197
|
+
return {p: True if (a[p] is True or b[p] is True) else (False if (a[p] is False and b[p] is False) else None) for p in a}
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
# ------------------------------------------------------------------ source membership
|
|
201
|
+
def membership(root: Path, files: set[str]) -> dict[str, dict]:
|
|
202
|
+
"""rel file -> {"values": {target: True / False / None}, "text": first condition, "at": "CMakeLists.txt:12",
|
|
203
|
+
"mentions": n, "elsewhere": also built on another OS} for the indexed files the CMake lists mention only under
|
|
204
|
+
platform conditions."""
|
|
205
|
+
from .platforms import KNOWN
|
|
206
|
+
root = Path(root)
|
|
207
|
+
every = {p: True for p in KNOWN + OTHER}
|
|
208
|
+
skip = presets.skip_dirs("common")
|
|
209
|
+
seen: dict[str, dict] = {}
|
|
210
|
+
for d, dirs, names in os.walk(root):
|
|
211
|
+
dirs[:] = [x for x in dirs if x not in skip and not x.startswith(".")]
|
|
212
|
+
if "CMakeLists.txt" not in names and not any(n.endswith(".cmake") for n in names):
|
|
213
|
+
continue
|
|
214
|
+
for name in sorted(n for n in names if n == "CMakeLists.txt" or n.endswith(".cmake")):
|
|
215
|
+
path = Path(d) / name
|
|
216
|
+
try:
|
|
217
|
+
text = _strip_comments(path.read_text(encoding="utf-8", errors="replace"))
|
|
218
|
+
except OSError:
|
|
219
|
+
continue
|
|
220
|
+
base = Path(d).relative_to(root).as_posix()
|
|
221
|
+
rel_cm = path.relative_to(root).as_posix()
|
|
222
|
+
stack: list[list] = [] # [current branch values, values of previous branches, text]
|
|
223
|
+
body = 0 # inside function() / macro(): the lists are built where it is called
|
|
224
|
+
for cmd, args, line in _commands(text):
|
|
225
|
+
if cmd in ("function", "macro"):
|
|
226
|
+
body += 1
|
|
227
|
+
continue
|
|
228
|
+
if cmd in ("endfunction", "endmacro"):
|
|
229
|
+
body = max(0, body - 1)
|
|
230
|
+
continue
|
|
231
|
+
if body:
|
|
232
|
+
continue
|
|
233
|
+
if cmd == "if":
|
|
234
|
+
v = _values(_tokens(args))
|
|
235
|
+
stack.append([v, [v], f"if({args.strip()})"[:120]])
|
|
236
|
+
elif cmd == "elseif" and stack:
|
|
237
|
+
v = _values(_tokens(args))
|
|
238
|
+
prev = stack[-1][1]
|
|
239
|
+
cur = v
|
|
240
|
+
for pv in prev:
|
|
241
|
+
cur = _and(cur, _not(pv))
|
|
242
|
+
stack[-1] = [cur, prev + [v], f"elseif({args.strip()})"[:120]]
|
|
243
|
+
elif cmd == "else" and stack:
|
|
244
|
+
cur = dict(every)
|
|
245
|
+
for pv in stack[-1][1]:
|
|
246
|
+
cur = _and(cur, _not(pv))
|
|
247
|
+
stack[-1] = [cur, stack[-1][1], "else() of " + stack[-1][2]]
|
|
248
|
+
elif cmd == "endif" and stack:
|
|
249
|
+
stack.pop()
|
|
250
|
+
elif cmd in LISTS:
|
|
251
|
+
cond = dict(every)
|
|
252
|
+
for v, _, _ in stack:
|
|
253
|
+
cond = _and(cond, v)
|
|
254
|
+
for tok in _tokens(args):
|
|
255
|
+
tok = re.sub(r"^\$\{(?:CMAKE_CURRENT_SOURCE_DIR|CMAKE_CURRENT_LIST_DIR)\}/", "", tok)
|
|
256
|
+
if "$" in tok or not SRC.search(tok) or tok.startswith("/"):
|
|
257
|
+
continue
|
|
258
|
+
rel = os.path.normpath(os.path.join(base, tok)).replace(os.sep, "/") if base != "." else os.path.normpath(tok).replace(os.sep, "/")
|
|
259
|
+
if rel not in files:
|
|
260
|
+
continue
|
|
261
|
+
s = seen.get(rel)
|
|
262
|
+
text_c = " && ".join(t for _, _, t in stack) or "unconditional"
|
|
263
|
+
if s is None:
|
|
264
|
+
seen[rel] = {"values": cond, "text": text_c, "at": f"{rel_cm}:{line}", "mentions": 1}
|
|
265
|
+
else:
|
|
266
|
+
s["values"] = _or(s["values"], cond)
|
|
267
|
+
s["mentions"] += 1
|
|
268
|
+
out = {}
|
|
269
|
+
for f, s in seen.items():
|
|
270
|
+
vals = {p: s["values"][p] for p in KNOWN}
|
|
271
|
+
if any(v is False for v in vals.values()):
|
|
272
|
+
# also built on an OS outside the known targets (a BSD, AIX, Cygwin): its #else branches are live there
|
|
273
|
+
out[f] = {**s, "values": vals, "elsewhere": any(s["values"][p] is not False for p in OTHER)}
|
|
274
|
+
return out
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def tree(values: dict):
|
|
278
|
+
"""A platforms.Cond tree with these per-target values: True where it holds, unknown where it may."""
|
|
279
|
+
parts = [("atom", "platform", p) for p, v in values.items() if v is True]
|
|
280
|
+
parts += [("atom", "unknown_on", p) for p, v in values.items() if v is None]
|
|
281
|
+
if not parts:
|
|
282
|
+
return ("atom", "never", None)
|
|
283
|
+
return parts[0] if len(parts) == 1 else ("any", parts)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
# ------------------------------------------------------------------ compile databases per target
|
|
287
|
+
def compile_db_membership(root: Path, dbs: dict[str, str], files: set[str]) -> dict[str, dict]:
|
|
288
|
+
"""`.cg.yaml` platforms.compile_commands (target -> compile_commands.json of that target's build): a source file
|
|
289
|
+
is built on the targets whose database compiles it, not on the other listed targets, and unknown on targets
|
|
290
|
+
without a database. Headers are not compiled on their own and are left out."""
|
|
291
|
+
from .platforms import KNOWN
|
|
292
|
+
root = Path(root).resolve()
|
|
293
|
+
compiled: dict[str, set[str]] = {}
|
|
294
|
+
for target, path in dbs.items():
|
|
295
|
+
p = (root / path) if not os.path.isabs(path) else Path(path)
|
|
296
|
+
try:
|
|
297
|
+
entries = __import__("json").loads(p.read_text(encoding="utf-8", errors="replace"))
|
|
298
|
+
except (OSError, ValueError):
|
|
299
|
+
continue
|
|
300
|
+
got = set()
|
|
301
|
+
for e in entries if isinstance(entries, list) else ():
|
|
302
|
+
f = e.get("file") if isinstance(e, dict) else None
|
|
303
|
+
if not f:
|
|
304
|
+
continue
|
|
305
|
+
fp = Path(f) if os.path.isabs(f) else Path(e.get("directory") or root) / f
|
|
306
|
+
try:
|
|
307
|
+
rel = Path(os.path.normpath(fp)).resolve().relative_to(root).as_posix()
|
|
308
|
+
except (ValueError, OSError):
|
|
309
|
+
continue
|
|
310
|
+
got.add(rel)
|
|
311
|
+
compiled[target] = got
|
|
312
|
+
if not compiled:
|
|
313
|
+
return {}
|
|
314
|
+
out = {}
|
|
315
|
+
for f in files:
|
|
316
|
+
if not re.search(r"\.(c|cc|cpp|cxx|c\+\+|m|mm)$", f, re.I):
|
|
317
|
+
continue
|
|
318
|
+
vals = {p: (f in compiled[p]) if p in compiled else None for p in KNOWN}
|
|
319
|
+
if any(v is False for v in vals.values()):
|
|
320
|
+
on = [p for p in KNOWN if vals[p]]
|
|
321
|
+
out[f] = {"values": vals, "text": f"compile_commands ({', '.join(on) or 'no listed target'})"}
|
|
322
|
+
return out
|