cg-code-graph 0.10.1__tar.gz → 0.11.0__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.10.1/cg_code_graph.egg-info → cg_code_graph-0.11.0}/PKG-INFO +7 -6
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/README.md +5 -4
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0/cg_code_graph.egg-info}/PKG-INFO +7 -6
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/cg_code_graph.egg-info/SOURCES.txt +5 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/cg_code_graph.egg-info/requires.txt +1 -1
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/__init__.py +1 -1
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/cli.py +5 -2
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/coverage.py +19 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/indexer.py +12 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/mcp_server.py +4 -3
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/platforms.py +3 -2
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/cfamily/plugin.py +26 -1
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/cfamily/syntax.py +104 -2
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/kotlin/exact.py +10 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/kotlin/plugin.py +248 -32
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/native/scipread.py +9 -1
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/aitools.py +31 -1
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/external.py +36 -7
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/rust/plugin.py +44 -5
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/rust/syntax.py +74 -3
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/ts/extractor/extract.mjs +128 -1
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/ts/extractor/fw.mjs +314 -2
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/ts/plugin.py +115 -1
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/tsweb/data.py +3 -1
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/protocols/builtin.py +25 -1
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/protocols/view.py +33 -4
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/query.py +17 -4
- cg_code_graph-0.11.0/codegraph/rpc.py +1217 -0
- cg_code_graph-0.11.0/codegraph/sockets.py +1144 -0
- cg_code_graph-0.11.0/codegraph/udp_apps.py +389 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/pyproject.toml +1 -1
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_ai_tools.py +103 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_coverage_ts_hint.py +27 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_external.py +113 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_kotlin.py +31 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_kotlin_mixed.py +24 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_native_cfamily.py +77 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_native_rust.py +36 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_process_runs.py +38 -5
- cg_code_graph-0.11.0/tests/test_rpc.py +185 -0
- cg_code_graph-0.11.0/tests/test_sockets.py +169 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/LICENSE +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/MANIFEST.in +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/cg_code_graph.egg-info/dependency_links.txt +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/cg_code_graph.egg-info/entry_points.txt +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/cg_code_graph.egg-info/top_level.txt +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/aitools.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/apps.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/blindspots.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/bridges.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/concepts.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/config.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/cache.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/detect.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/extractors.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/fsutil.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/generated.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/model.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/paths.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/plugin.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/store.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/core/syntax_errors.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/doctor.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/external.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/link.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/lint_async.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/parity.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/parity_structure.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/payload.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plans.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/platform_scan.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/cfamily/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/bridges.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/extractor/bin/extract.dart +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/extractor/pubspec.lock +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/extractor/pubspec.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/http.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/models.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/plugin.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/dart/program.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/django/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/django/extras.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/django/models.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/django/plugin.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/django/schemas.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/django/shapes.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/django/urls.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/express/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/express/plugin.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/flutter/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/flutter/plugin.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/kotlin/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/kotlin/reparse.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/laravel/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/laravel/broadcast.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/laravel/plugin.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/laravel/tests.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/laravel/values.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/native/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/native/gates.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/native/runner.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/native/ts.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/nest/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/nest/plugin.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/nextjs/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/nextjs/plugin.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/nuxt/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/nuxt/plugin.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/php/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/php/extractor/composer.json +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/php/extractor/composer.lock +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/php/extractor/extract.php +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/php/gating.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/php/plugin.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/php/strings.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/fields.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/plugin.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/refs.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/roots.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/socketio.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/subproc.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/tests.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/python/values.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/pyweb/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/pyweb/plugin.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/pyweb/values.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/rust/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/rust/cargo.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/scip/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/scip/importer.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/scip/scip.proto +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/scip/scip_pb2.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/stubs/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/stubs/plugins.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/swift/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/swift/baseurl.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/swift/exact.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/swift/indexstore.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/swift/packages.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/swift/plugin.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/ts/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/ts/baseurl.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/ts/extractor/package-lock.json +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/ts/extractor/package.json +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/tsweb/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/plugins/tsweb/common.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/c_cpp.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/common.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/dart.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/django-ninja.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/django.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/djangorestframework.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/express.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/kotlin.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/laravel.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/nest.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/nextjs.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/nuxt.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/php.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/python.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/rust.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/swift.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/presets/typescript.yaml +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/process_runs.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/protocols/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/protocols/matchers.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/realtime.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/roundtrip.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/routes.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/starters.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/tests_index.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/__init__.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/graph.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/server.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/app.css +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/app.js +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/index.html +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/layered.js +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/vendor/VERSIONS.txt +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/vendor/cose-base.js +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/vendor/cytoscape-fcose.js +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/vendor/cytoscape.min.js +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/static/vendor/layout-base.js +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/tools/package-lock.json +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/tools/package.json +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/viz/tools/shoot.mjs +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/codegraph/xcode.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/setup.cfg +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_bridges.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_bridges_pigeon_monorepo.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_cache_clean.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_cache_invalidation.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_channels_tests.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_cli_output.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_completeness.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_config_extras.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_coverage.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_dispatch_interfaces.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_django_flutter.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_enum_constants.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_gating.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_generated.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_impact_overrides.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_index_isolation.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_inherited_overrides.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_kotlin_binding.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_kotlin_exact.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_kotlin_fields.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_kotlin_nav_consts.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_kotlin_props.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_laravel_determinism.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_lint_async.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_mcp.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_mcp_index.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_native_concurrency.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_nuxt_rootsrc.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_packaging.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_parity.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_parity_structure.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_php_props.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_plans.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_platform_gaps.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_platform_type_variants.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_platforms.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_platforms_apple.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_presets_config.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_protocols.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_app_tests_module.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_collection_chains.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_compat.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_entry_refs.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_fields.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_infer_cycles.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_roots.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_subprocess_tests.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_tests.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_web_hosts.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_web_routes.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_python_web_routes_more.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_roundtrip.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_routes_search_explain.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_scip_health.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_starters_budget.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_binding.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_exact.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_facts.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_fields.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_modules.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_more.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_nav_values.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_parse_errors.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_props.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_sdk.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_testing.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_swift_values.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_tests_scope.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_ts_fields.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_ts_fields_js_vue.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_ts_file_specs.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_ts_frameworks.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_ts_nuxt.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_values.py +0 -0
- {cg_code_graph-0.10.1 → cg_code_graph-0.11.0}/tests/test_viz.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cg-code-graph
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0
|
|
4
4
|
Summary: cg: a code graph of routes, calls, data access and platform boundaries for agents and humans (CLI + MCP server)
|
|
5
5
|
Author: cyberchronos00
|
|
6
6
|
License-Expression: MIT
|
|
@@ -17,7 +17,7 @@ Requires-Dist: tree-sitter-rust>=0.23
|
|
|
17
17
|
Requires-Dist: tree-sitter-c>=0.23
|
|
18
18
|
Requires-Dist: tree-sitter-cpp>=0.23
|
|
19
19
|
Requires-Dist: tree-sitter-kotlin>=1.0
|
|
20
|
-
Requires-Dist: tree-sitter-swift
|
|
20
|
+
Requires-Dist: tree-sitter-swift<0.7.4,>=0.6
|
|
21
21
|
Provides-Extra: dev
|
|
22
22
|
Requires-Dist: pytest>=8; extra == "dev"
|
|
23
23
|
Dynamic: license-file
|
|
@@ -93,10 +93,11 @@ other tools; see [Prerequisites per language](#prerequisites-per-language).
|
|
|
93
93
|
options and updates):
|
|
94
94
|
|
|
95
95
|
```bash
|
|
96
|
-
|
|
97
|
-
# or
|
|
98
|
-
#
|
|
99
|
-
# or
|
|
96
|
+
pipx install cg-code-graph # or: uv tool install cg-code-graph (PyPI; the commands are cg and cg-mcp)
|
|
97
|
+
# or the script (also installs exact-mode tools with --with c,rust,...):
|
|
98
|
+
# curl -fsSL https://raw.githubusercontent.com/cyberchronos00/code-graph/main/install.sh | sh
|
|
99
|
+
# or the latest commit: uv tool install git+https://github.com/cyberchronos00/code-graph
|
|
100
|
+
# or: pipx install git+https://github.com/cyberchronos00/code-graph
|
|
100
101
|
cg doctor # what indexes exact / heuristic on this machine, and what to install for the rest
|
|
101
102
|
git clone https://github.com/cyberchronos00/code-graph.git && cd code-graph # the sample apps used below
|
|
102
103
|
```
|
|
@@ -69,10 +69,11 @@ other tools; see [Prerequisites per language](#prerequisites-per-language).
|
|
|
69
69
|
options and updates):
|
|
70
70
|
|
|
71
71
|
```bash
|
|
72
|
-
|
|
73
|
-
# or
|
|
74
|
-
#
|
|
75
|
-
# or
|
|
72
|
+
pipx install cg-code-graph # or: uv tool install cg-code-graph (PyPI; the commands are cg and cg-mcp)
|
|
73
|
+
# or the script (also installs exact-mode tools with --with c,rust,...):
|
|
74
|
+
# curl -fsSL https://raw.githubusercontent.com/cyberchronos00/code-graph/main/install.sh | sh
|
|
75
|
+
# or the latest commit: uv tool install git+https://github.com/cyberchronos00/code-graph
|
|
76
|
+
# or: pipx install git+https://github.com/cyberchronos00/code-graph
|
|
76
77
|
cg doctor # what indexes exact / heuristic on this machine, and what to install for the rest
|
|
77
78
|
git clone https://github.com/cyberchronos00/code-graph.git && cd code-graph # the sample apps used below
|
|
78
79
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cg-code-graph
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0
|
|
4
4
|
Summary: cg: a code graph of routes, calls, data access and platform boundaries for agents and humans (CLI + MCP server)
|
|
5
5
|
Author: cyberchronos00
|
|
6
6
|
License-Expression: MIT
|
|
@@ -17,7 +17,7 @@ Requires-Dist: tree-sitter-rust>=0.23
|
|
|
17
17
|
Requires-Dist: tree-sitter-c>=0.23
|
|
18
18
|
Requires-Dist: tree-sitter-cpp>=0.23
|
|
19
19
|
Requires-Dist: tree-sitter-kotlin>=1.0
|
|
20
|
-
Requires-Dist: tree-sitter-swift
|
|
20
|
+
Requires-Dist: tree-sitter-swift<0.7.4,>=0.6
|
|
21
21
|
Provides-Extra: dev
|
|
22
22
|
Requires-Dist: pytest>=8; extra == "dev"
|
|
23
23
|
Dynamic: license-file
|
|
@@ -93,10 +93,11 @@ other tools; see [Prerequisites per language](#prerequisites-per-language).
|
|
|
93
93
|
options and updates):
|
|
94
94
|
|
|
95
95
|
```bash
|
|
96
|
-
|
|
97
|
-
# or
|
|
98
|
-
#
|
|
99
|
-
# or
|
|
96
|
+
pipx install cg-code-graph # or: uv tool install cg-code-graph (PyPI; the commands are cg and cg-mcp)
|
|
97
|
+
# or the script (also installs exact-mode tools with --with c,rust,...):
|
|
98
|
+
# curl -fsSL https://raw.githubusercontent.com/cyberchronos00/code-graph/main/install.sh | sh
|
|
99
|
+
# or the latest commit: uv tool install git+https://github.com/cyberchronos00/code-graph
|
|
100
|
+
# or: pipx install git+https://github.com/cyberchronos00/code-graph
|
|
100
101
|
cg doctor # what indexes exact / heuristic on this machine, and what to install for the rest
|
|
101
102
|
git clone https://github.com/cyberchronos00/code-graph.git && cd code-graph # the sample apps used below
|
|
102
103
|
```
|
|
@@ -34,8 +34,11 @@ codegraph/query.py
|
|
|
34
34
|
codegraph/realtime.py
|
|
35
35
|
codegraph/roundtrip.py
|
|
36
36
|
codegraph/routes.py
|
|
37
|
+
codegraph/rpc.py
|
|
38
|
+
codegraph/sockets.py
|
|
37
39
|
codegraph/starters.py
|
|
38
40
|
codegraph/tests_index.py
|
|
41
|
+
codegraph/udp_apps.py
|
|
39
42
|
codegraph/xcode.py
|
|
40
43
|
codegraph/core/__init__.py
|
|
41
44
|
codegraph/core/cache.py
|
|
@@ -237,7 +240,9 @@ tests/test_python_web_routes.py
|
|
|
237
240
|
tests/test_python_web_routes_more.py
|
|
238
241
|
tests/test_roundtrip.py
|
|
239
242
|
tests/test_routes_search_explain.py
|
|
243
|
+
tests/test_rpc.py
|
|
240
244
|
tests/test_scip_health.py
|
|
245
|
+
tests/test_sockets.py
|
|
241
246
|
tests/test_starters_budget.py
|
|
242
247
|
tests/test_swift.py
|
|
243
248
|
tests/test_swift_binding.py
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""code-graph: deterministic code knowledge graph (beta)."""
|
|
2
|
-
__version__ = "0.
|
|
2
|
+
__version__ = "0.11.0"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
python -m codegraph.cli bridges [PATTERN] --db ... [--protocol capacitor] [--unmatched] (web / native bridge calls)
|
|
19
19
|
python -m codegraph.cli external [PATTERN] --db ... [--protocol P] [--source S] [--tls-off] (databases, caches, brokers, mail ... and who reaches them)
|
|
20
20
|
python -m codegraph.cli tools [PATTERN] --db ... [--framework F] [--agent A] [--unmatched] (LLM / MCP tools: handler, tables, agents, checks)
|
|
21
|
-
python -m codegraph.cli protocols [PATTERN] --db ... [--protocol P] [--side send|receive] [--unmatched] (every protocol endpoint: senders, receivers, checks)
|
|
21
|
+
python -m codegraph.cli protocols [PATTERN] --db ... [--protocol P] [--side send|receive] [--unmatched] [--listeners] (every protocol endpoint: senders, receivers, checks; listening sockets)
|
|
22
22
|
python -m codegraph.cli platforms [summary|divergence] --db ... [--target ios] (platform-specific code, gaps between variants)
|
|
23
23
|
reaches / impact / downstream / path / routes / search take --platform TARGET: only code built for that target
|
|
24
24
|
spec forms: table.column | connection:<name> (glob *) | env:<KEY*> | config:<a.b> | Class.method or Class::method (either
|
|
@@ -154,6 +154,8 @@ def main(argv=None):
|
|
|
154
154
|
p.add_argument("--side", choices=["send", "receive"]); p.add_argument("--max-items", type=int, default=60)
|
|
155
155
|
p.add_argument("--unmatched", action="store_true", help="only endpoints with a check (no_receiver, no_sender, ambiguous, "
|
|
156
156
|
"schema_mismatch, unguarded) or an external peer")
|
|
157
|
+
p.add_argument("--listeners", action="store_true", help="every listening TCP / UDP socket with its bind address, exposure "
|
|
158
|
+
"(all interfaces / loopback / specific) and handler")
|
|
157
159
|
p = sub.add_parser("external", help="external systems (databases, caches, brokers, mail, directories, file transfer, object "
|
|
158
160
|
"stores, third-party HTTP hosts): users, entry points, address and credential sources")
|
|
159
161
|
p.add_argument("pattern", nargs="?", help="external id, substring or glob (`external:postgres:*`, `redis`)")
|
|
@@ -429,7 +431,8 @@ def main(argv=None):
|
|
|
429
431
|
return
|
|
430
432
|
if a.cmd == "protocols":
|
|
431
433
|
from .protocols.view import protocols, render_protocols
|
|
432
|
-
res = protocols(st, a.pattern, protocol=a.protocol, side=a.side, unmatched=a.unmatched, max_items=max(a.max_items, 200) if a.json else a.max_items
|
|
434
|
+
res = protocols(st, a.pattern, protocol=a.protocol, side=a.side, unmatched=a.unmatched, max_items=max(a.max_items, 200) if a.json else a.max_items,
|
|
435
|
+
listeners=a.listeners)
|
|
433
436
|
print(json.dumps(res, indent=1, default=str) if a.json else render_protocols(res, max_items=a.max_items))
|
|
434
437
|
return
|
|
435
438
|
if a.cmd == "tests":
|
|
@@ -6,6 +6,7 @@ its normal search and file reading."""
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
8
|
import os
|
|
9
|
+
import re
|
|
9
10
|
from collections import Counter
|
|
10
11
|
|
|
11
12
|
from . import presets
|
|
@@ -188,12 +189,27 @@ def scan(root: str | Path) -> Counter:
|
|
|
188
189
|
return scan_tree(root).counts
|
|
189
190
|
|
|
190
191
|
|
|
192
|
+
_TOOL_FILE = re.compile(r"(?:^|/)(?:[^/]*\.config\.[cm]?[jt]sx?|\.[^/]*rc\.[cm]?js|[Gg]runtfile\.js|[Gg]ulpfile\.[cm]?js)$")
|
|
193
|
+
_TEST_NAME = re.compile(r"(?:\.(?:test|spec)\.[cm]?[jt]sx?$|(?:^|/)__tests__/|\.d\.[cm]?ts$)") # + declarations
|
|
194
|
+
|
|
195
|
+
|
|
191
196
|
def file_completeness(discovered: list[str], report: dict) -> dict:
|
|
192
197
|
"""Bucket every discovered file of one language from the plugin's per-file report
|
|
193
198
|
({seen, parse_failed, skipped_oversize, unmapped, excluded}). A discovered file the plugin never looked at
|
|
194
199
|
(its own skip list) is `excluded`."""
|
|
195
200
|
sets = {b: set(report.get(b) or ()) for b in BUCKETS}
|
|
196
201
|
seen = set(report.get("seen") or ())
|
|
202
|
+
roots = report.get("roots")
|
|
203
|
+
if roots is not None:
|
|
204
|
+
# a plugin that reads only some directories (TypeScript: source dirs, bin / script files, test trees): a file
|
|
205
|
+
# outside all of them was never read, so it is unmapped (not indexed), not a deliberate exclusion. Tool
|
|
206
|
+
# configuration (`vite.config.ts`, `.eslintrc.js`) and test files by name stay excluded (#106)
|
|
207
|
+
dirs = tuple(r for r in roots if r.endswith("/"))
|
|
208
|
+
files = {r for r in roots if not r.endswith("/")}
|
|
209
|
+
for f in discovered:
|
|
210
|
+
if f in seen or f in files or f.startswith(dirs) or _TOOL_FILE.search(f) or _TEST_NAME.search(f):
|
|
211
|
+
continue
|
|
212
|
+
sets["unmapped"].add(f)
|
|
197
213
|
out = {b: [] for b in BUCKETS}
|
|
198
214
|
indexed = 0
|
|
199
215
|
for f in sorted(discovered):
|
|
@@ -296,6 +312,9 @@ def compute(root: str | Path, plugins: dict, scip_imported: bool = False, report
|
|
|
296
312
|
e["files_complete"] = missing_files(e) == 0
|
|
297
313
|
if not e["files_complete"] and lang == "python" and e.get("unmapped"):
|
|
298
314
|
e["hint"] = _python_unmapped_hint(st)
|
|
315
|
+
elif not e["files_complete"] and lang == "typescript" and e.get("unmapped"):
|
|
316
|
+
e["hint"] = ("files outside the source dirs and test trees were not read: list the directories that hold "
|
|
317
|
+
"source in .cg.yaml `include` (or a tsconfig.json `include`) and re-index")
|
|
299
318
|
se = (rep or {}).get("syntax_errors")
|
|
300
319
|
if isinstance(se, list) and se and status not in ("skipped", "not_indexed"):
|
|
301
320
|
# files parsed with syntax errors (#73): error spans and the declarations lost there
|
|
@@ -234,6 +234,18 @@ def index_project(root: str | Path, db_path: str | Path, name: str | None = None
|
|
|
234
234
|
from .process_runs import apply as apply_process_runs
|
|
235
235
|
if (pr := apply_process_runs(project, builder)):
|
|
236
236
|
stats["process_runs"] = pr
|
|
237
|
+
# raw TCP / UDP sockets paired by port (#39): endpoint:tcp:<port> / endpoint:udp:<port>
|
|
238
|
+
from .sockets import apply as apply_sockets
|
|
239
|
+
t_so = time.time()
|
|
240
|
+
if (so := apply_sockets(project, builder)):
|
|
241
|
+
so["seconds"] = round(time.time() - t_so, 2)
|
|
242
|
+
stats["sockets"] = so
|
|
243
|
+
# RPC contracts (#33): gRPC services of the .proto files, their implementations and stub calls
|
|
244
|
+
from .rpc import apply as apply_rpc
|
|
245
|
+
t_rpc = time.time()
|
|
246
|
+
if (rp := apply_rpc(project, builder)):
|
|
247
|
+
rp["seconds"] = round(time.time() - t_rpc, 2)
|
|
248
|
+
stats["rpc"] = rp
|
|
237
249
|
# test code (tests/, *.spec.ts ...) never feeds the application graph: its edges become TEST_* kinds
|
|
238
250
|
from .tests_index import isolate_tests
|
|
239
251
|
stats["tests"] = isolate_tests(builder)
|
|
@@ -698,20 +698,21 @@ def bridges(pattern: str | None = None, protocol: str | None = None, unmatched:
|
|
|
698
698
|
|
|
699
699
|
@tool
|
|
700
700
|
def protocol_links(pattern: str | None = None, protocol: str | None = None, side: str | None = None,
|
|
701
|
-
unmatched: bool = False) -> str:
|
|
701
|
+
unmatched: bool = False, listeners: bool = False) -> str:
|
|
702
702
|
"""Every protocol endpoint in one view (#31 model): HTTP client endpoints and routes (http / ws / graphql), Pusher
|
|
703
703
|
broadcast channels and subscriptions, NestJS microservice messages (nest-rpc / nest-event / nest-ws / grpc), job
|
|
704
704
|
queues (bull, laravel-queue, celery), application events (laravel-event, nest-event-emitter, django-signal), web /
|
|
705
705
|
native bridges and desktop IPC (capacitor, react-native, flutter, electron-ipc, tauri ...) and the generic
|
|
706
706
|
endpoint:<protocol>:<name> nodes (code -SENDS_TO-> endpoint -RECEIVED_BY-> handler, MATCHES_ENDPOINT for
|
|
707
|
-
wildcard / template matches; MQTT, NATS, AMQP, Kafka, Redis pub/sub, Socket.IO
|
|
707
|
+
wildcard / template matches; MQTT, NATS, AMQP, Kafka, Redis pub/sub, Socket.IO, raw TCP / UDP sockets by port).
|
|
708
|
+
listeners: every listening TCP / UDP socket with bind address, exposure and handler. Without arguments: one line per
|
|
708
709
|
protocol (endpoints, send / receive sides, linked, check counts). With a pattern (name, id, substring or glob) /
|
|
709
710
|
protocol / side (send | receive) / unmatched: one block per endpoint with senders (and, for a few endpoints, the
|
|
710
711
|
entry points reaching them), receivers, guards, matches and checks: no_receiver, no_sender, test_sender_only,
|
|
711
712
|
ambiguous, schema_mismatch, unguarded, external (.cg.yaml protocols.external, third-party origins, bridge
|
|
712
713
|
packages). impact / reaches / path / downstream follow SENDS_TO / RECEIVED_BY / MATCHES_ENDPOINT as usual."""
|
|
713
714
|
from .protocols.view import protocols as _pr, render_protocols
|
|
714
|
-
return render_protocols(_pr(_st(), pattern, protocol=protocol, side=side, unmatched=unmatched))
|
|
715
|
+
return render_protocols(_pr(_st(), pattern, protocol=protocol, side=side, unmatched=unmatched, listeners=listeners))
|
|
715
716
|
|
|
716
717
|
|
|
717
718
|
@tool
|
|
@@ -944,11 +944,12 @@ def _alt_groups(builder, nvals: dict) -> dict[str, list[str]]:
|
|
|
944
944
|
if g in alts and any(builder.nodes[i].file == file or builder.nodes[i].kind == "macro" for i in alts[g]):
|
|
945
945
|
alts[g] += alts.pop(k)
|
|
946
946
|
# same-named functions of separate programs (libuv docs/code/*/main.c `alloc_buffer`, each file with its own
|
|
947
|
-
# main()) are not one symbol: members in two or more files that define main() leave the group (#63)
|
|
947
|
+
# main()) are not one symbol: members in two or more files that define main() leave the group (#63); the same
|
|
948
|
+
# holds for the classes and structs of those programs (grpc's examples/cpp: a `GreeterServiceImpl` per server, #131)
|
|
948
949
|
mains = {n.file for n in builder.nodes.values() if n.lang in ("c", "cpp") and n.kind == "function" and n.name == "main"}
|
|
949
950
|
if mains:
|
|
950
951
|
for k, ids in list(alts.items()):
|
|
951
|
-
if not k.startswith("c-fn:"):
|
|
952
|
+
if not k.startswith("c-fn:") and not all(builder.nodes[i].lang in ("c", "cpp") for i in ids):
|
|
952
953
|
continue
|
|
953
954
|
prog = [i for i in ids if builder.nodes[i].file in mains]
|
|
954
955
|
if len({builder.nodes[i].file for i in prog}) >= 2:
|
|
@@ -655,6 +655,20 @@ class CFamilyPlugin(LanguagePlugin):
|
|
|
655
655
|
if it.kind in TYPES:
|
|
656
656
|
types[it.name].append(it)
|
|
657
657
|
|
|
658
|
+
cls_files = defaultdict(set)
|
|
659
|
+
for it in self.items:
|
|
660
|
+
if it.kind in TYPES:
|
|
661
|
+
cls_files[it.qual].add(it.file)
|
|
662
|
+
|
|
663
|
+
def _visible(m, rel) -> bool:
|
|
664
|
+
"""A method's class defined only in other source files (not headers) that `rel` does not include is
|
|
665
|
+
out of reach of a member call there (`writer->Write(..)` on a library type is not `HelloReactor::Write`
|
|
666
|
+
of another program's .cc)."""
|
|
667
|
+
files = cls_files.get(m.qual.rsplit("::", 1)[0]) if "::" in m.qual else None
|
|
668
|
+
if not files:
|
|
669
|
+
return True
|
|
670
|
+
return any(f == rel or os.path.splitext(f)[1] in HDR_EXT for f in files) or bool(files & self._included(rel))
|
|
671
|
+
|
|
658
672
|
def pick(cands, rel):
|
|
659
673
|
if not cands:
|
|
660
674
|
return []
|
|
@@ -685,7 +699,8 @@ class CFamilyPlugin(LanguagePlugin):
|
|
|
685
699
|
if name in macros and macros[name].attrs.get("function_like"):
|
|
686
700
|
targets = [macros[name]]
|
|
687
701
|
else:
|
|
688
|
-
targets = pick(funcs.get(name), rel) or (
|
|
702
|
+
targets = pick(funcs.get(name), rel) or (
|
|
703
|
+
[m for m in pick(methods.get(name), rel) if _visible(m, rel)] if owner.kind == "method" else [])
|
|
689
704
|
elif form == "qualified":
|
|
690
705
|
q = quals.get(txt) or next((v for k, v in quals.items() if k.endswith("::" + txt)), None)
|
|
691
706
|
targets = [q] if q else []
|
|
@@ -696,6 +711,12 @@ class CFamilyPlugin(LanguagePlugin):
|
|
|
696
711
|
roots = [m for m in c if self._is_virtual(m) and not self._is_override(m)]
|
|
697
712
|
c = roots if len(roots) == 1 else c
|
|
698
713
|
targets = c if len(c) == 1 else []
|
|
714
|
+
# the only method of that name, but its class is defined only in another source file: not the
|
|
715
|
+
# receiver here. (Dropping such candidates before the uniqueness test would turn `s.data()` on a
|
|
716
|
+
# std::string into leveldb's `Slice::data`, so it only removes.)
|
|
717
|
+
if targets and not _visible(targets[0], rel):
|
|
718
|
+
stats["heuristic_member_call_class_not_visible"] += 1
|
|
719
|
+
targets = []
|
|
699
720
|
if not targets:
|
|
700
721
|
stats["heuristic_unresolved_calls"] += 1
|
|
701
722
|
continue
|
|
@@ -720,6 +741,10 @@ class CFamilyPlugin(LanguagePlugin):
|
|
|
720
741
|
if owner is None:
|
|
721
742
|
continue
|
|
722
743
|
for x in pick(types.get(name), rel):
|
|
744
|
+
# a type is not linked across files: one defined only in another source file is not this one
|
|
745
|
+
if x.file != rel and os.path.splitext(x.file)[1] not in HDR_EXT and x.file not in self._included(rel):
|
|
746
|
+
stats["heuristic_type_ref_not_visible"] += 1
|
|
747
|
+
continue
|
|
723
748
|
self._ref_edge(self.nid(owner), self.nid(x), rel, line, HEURISTIC, "", stats)
|
|
724
749
|
|
|
725
750
|
def _is_virtual(self, it) -> bool:
|
|
@@ -153,7 +153,17 @@ class Extractor:
|
|
|
153
153
|
self.f = CFile(path, lang)
|
|
154
154
|
|
|
155
155
|
def run(self) -> CFile:
|
|
156
|
-
|
|
156
|
+
src = mask_lock_annotations(mask_annotations(self.src, self.blank) if self.blank is not None else self.src)
|
|
157
|
+
tree = parser(self.f.lang).parse(src)
|
|
158
|
+
if tree.root_node.has_error:
|
|
159
|
+
# `ABSL_FLAG(uint16_t, port, 50051, "..");` at file level parses as a broken function definition that
|
|
160
|
+
# runs to the next `}` and swallows the class after it (#131): blank such macro statements and keep
|
|
161
|
+
# the parse that loses fewer lines
|
|
162
|
+
masked = mask_macro_statements(src)
|
|
163
|
+
if masked != src:
|
|
164
|
+
t2 = parser(self.f.lang).parse(masked)
|
|
165
|
+
if _error_lines(t2.root_node) < _error_lines(tree.root_node):
|
|
166
|
+
tree = t2
|
|
157
167
|
self.f.lines = self.src.decode("utf-8", "replace").split("\n")
|
|
158
168
|
if tree.root_node.has_error:
|
|
159
169
|
from ...core.syntax_errors import tree_spans
|
|
@@ -200,7 +210,8 @@ class Extractor:
|
|
|
200
210
|
sub = Extractor(self.path, chunk.encode("utf-8"), self.f.lang, self.module, self.blank)
|
|
201
211
|
sub.f = self.f
|
|
202
212
|
n0 = len(self.f.items)
|
|
203
|
-
t = parser(self.f.lang).parse(
|
|
213
|
+
t = parser(self.f.lang).parse(mask_lock_annotations(
|
|
214
|
+
mask_annotations(sub.src, self.blank) if self.blank is not None else sub.src))
|
|
204
215
|
if not t.root_node.has_error:
|
|
205
216
|
sub.container(t.root_node, {"ns": [], "cls": None, "access": None, "anon": False, "extern_c": False})
|
|
206
217
|
if len(self.f.items) == n0:
|
|
@@ -879,3 +890,94 @@ def mask_annotations(src: bytes, rx: re.Pattern) -> bytes:
|
|
|
879
890
|
cont = directive and line.rstrip().endswith(b"\\")
|
|
880
891
|
out.append(line if directive else rx.sub(lambda m: b" " * (m.end() - m.start()), line))
|
|
881
892
|
return b"\n".join(out)
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
MACRO_STMT = re.compile(rb"^[A-Z][A-Z0-9_]*[ \t]*\(", re.M)
|
|
896
|
+
|
|
897
|
+
|
|
898
|
+
def mask_macro_statements(src: bytes) -> bytes:
|
|
899
|
+
"""File-level `NAME(...);` statements of an upper-case macro starting in column 0 blanked (same length, newlines
|
|
900
|
+
kept). Strings and comments in the arguments are skipped while matching the parentheses."""
|
|
901
|
+
out = bytearray(src)
|
|
902
|
+
for m in MACRO_STMT.finditer(src):
|
|
903
|
+
i, depth, n = m.end() - 1, 0, len(src)
|
|
904
|
+
while i < n:
|
|
905
|
+
ch = src[i:i + 1]
|
|
906
|
+
if ch in (b'"', b"'"):
|
|
907
|
+
j = i + 1
|
|
908
|
+
while j < n and src[j:j + 1] not in (ch, b"\n"):
|
|
909
|
+
j += 2 if src[j:j + 1] == b"\\" else 1
|
|
910
|
+
i = j + 1
|
|
911
|
+
continue
|
|
912
|
+
if src[i:i + 2] == b"/*":
|
|
913
|
+
j = src.find(b"*/", i + 2)
|
|
914
|
+
i = n if j < 0 else j + 2
|
|
915
|
+
continue
|
|
916
|
+
if src[i:i + 2] == b"//":
|
|
917
|
+
j = src.find(b"\n", i)
|
|
918
|
+
i = n if j < 0 else j
|
|
919
|
+
continue
|
|
920
|
+
if ch == b"(":
|
|
921
|
+
depth += 1
|
|
922
|
+
elif ch == b")":
|
|
923
|
+
depth -= 1
|
|
924
|
+
if depth == 0:
|
|
925
|
+
break
|
|
926
|
+
elif ch in (b"{", b"}", b";"):
|
|
927
|
+
i = n
|
|
928
|
+
break
|
|
929
|
+
i += 1
|
|
930
|
+
if i >= n:
|
|
931
|
+
continue
|
|
932
|
+
rest = re.match(rb"[ \t]*;", src[i + 1:i + 40])
|
|
933
|
+
if not rest:
|
|
934
|
+
continue
|
|
935
|
+
end = i + 1 + rest.end()
|
|
936
|
+
for k in range(m.start(), end):
|
|
937
|
+
if out[k] != 10:
|
|
938
|
+
out[k] = 32
|
|
939
|
+
return bytes(out)
|
|
940
|
+
|
|
941
|
+
|
|
942
|
+
def _error_lines(root) -> int:
|
|
943
|
+
from ...core.syntax_errors import tree_spans
|
|
944
|
+
return sum(b - a + 1 for a, b in tree_spans(root))
|
|
945
|
+
|
|
946
|
+
|
|
947
|
+
# Clang thread-safety annotations after a declarator: `void Write() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&mu_) {`,
|
|
948
|
+
# `bool done_ GUARDED_BY(mu_) = false;`, `GTEST_LOCK_EXCLUDED_(mutex_)`. tree-sitter reads them as the declarator
|
|
949
|
+
# (a method `mu_`), so they are blanked (same length) like the name-only annotation macros.
|
|
950
|
+
LOCK_ANNOT = re.compile(
|
|
951
|
+
rb"\b(?:(?:[A-Z][A-Z0-9]*_)*(?:EXCLUSIVE_LOCKS_REQUIRED|SHARED_LOCKS_REQUIRED|LOCKS_EXCLUDED|LOCK_EXCLUDED|"
|
|
952
|
+
rb"LOCK_RETURNED|PT_GUARDED_BY|GUARDED_BY|ACQUIRED_BEFORE|ACQUIRED_AFTER|EXCLUSIVE_LOCK_FUNCTION|SHARED_LOCK_FUNCTION|"
|
|
953
|
+
rb"UNLOCK_FUNCTION|EXCLUSIVE_TRYLOCK_FUNCTION|SHARED_TRYLOCK_FUNCTION|ASSERT_EXCLUSIVE_LOCK|ASSERT_SHARED_LOCK|"
|
|
954
|
+
rb"CAPABILITY)|"
|
|
955
|
+
rb"[A-Z][A-Z0-9]*_(?:REQUIRES_SHARED|REQUIRES|EXCLUDES|ACQUIRE_SHARED|ACQUIRE|RELEASE_SHARED|RELEASE|TRY_ACQUIRE|"
|
|
956
|
+
rb"RETURN_CAPABILITY|ASSERT_CAPABILITY))_?[ \t]*\((?:[^()\n]|\([^()\n]*\))*\)")
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
LOCK_NAME = re.compile(rb"\b(?:[A-Z][A-Z0-9]*_)*(?:SCOPED_LOCKABLE|LOCKABLE|SCOPED_CAPABILITY|NO_THREAD_SAFETY_ANALYSIS)_?\b(?![ \t]*\()")
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
def mask_lock_annotations(src: bytes) -> bytes:
|
|
963
|
+
if b"LOCK" not in src and b"GUARDED_BY" not in src and b"_REQUIRES" not in src and b"_EXCLUDES" not in src \
|
|
964
|
+
and b"_ACQUIRE" not in src and b"_RELEASE" not in src and b"CAPABILITY" not in src:
|
|
965
|
+
return src
|
|
966
|
+
out = bytearray(src)
|
|
967
|
+
for m in LOCK_ANNOT.finditer(src):
|
|
968
|
+
ls = src.rfind(b"\n", 0, m.start()) + 1
|
|
969
|
+
before = src[ls:m.start()].rstrip()
|
|
970
|
+
if not before.strip() and ls > 0:
|
|
971
|
+
# on a line of its own after the declarator: `void Mock::Allow(uintptr_t obj)\n GTEST_LOCK_EXCLUDED_(mu) {`
|
|
972
|
+
pl = src[src.rfind(b"\n", 0, ls - 1) + 1:ls - 1].rstrip()
|
|
973
|
+
before = pl if re.search(rb"(?:\)|\bconst|\boverride|\bnoexcept)$", pl) and not pl.lstrip().startswith(b"#") else b""
|
|
974
|
+
if before.lstrip().startswith(b"#") or not before or not re.search(rb"[\w)&*\]]$", before):
|
|
975
|
+
continue # a directive, or not after a declarator (a statement / call of its own)
|
|
976
|
+
if re.search(rb"\b(?:return|if|while|case)\b[^;{}]*$", before):
|
|
977
|
+
continue
|
|
978
|
+
out[m.start():m.end()] = b" " * (m.end() - m.start())
|
|
979
|
+
for m in LOCK_NAME.finditer(src): # `class SCOPED_LOCKABLE MutexLock {`, `void f() NO_THREAD_SAFETY_ANALYSIS {`
|
|
980
|
+
ls = src.rfind(b"\n", 0, m.start()) + 1
|
|
981
|
+
if not src[ls:m.start()].lstrip().startswith(b"#"):
|
|
982
|
+
out[m.start():m.end()] = b" " * (m.end() - m.start())
|
|
983
|
+
return bytes(out)
|
|
@@ -40,6 +40,7 @@ CALL_KINDS = ("CALLS", "INSTANTIATES")
|
|
|
40
40
|
# `valueOf` / `entries` (`<init>` and `<anonymous object at ...>` start with "<")
|
|
41
41
|
SYNTHETIC = re.compile(r"copy|component\d+|values|valueOf|entries")
|
|
42
42
|
FACADE = re.compile(r"(?<=/)\w+Kt#(?=[^#]+\.$)") # the JVM facade class of a Kotlin file's top-level functions
|
|
43
|
+
ACCESSOR = re.compile(r"[gs]et[A-Z]\w*") # a property accessor's JVM name
|
|
43
44
|
|
|
44
45
|
|
|
45
46
|
def _has_kotlin_docs(path: str) -> bool:
|
|
@@ -301,10 +302,19 @@ class ExactLayer:
|
|
|
301
302
|
if d.name == name and d.line <= o.line + 1 <= d.end and (suf == "#") == (d.kind == "class"):
|
|
302
303
|
nid = d.id
|
|
303
304
|
break
|
|
305
|
+
if nid is None and suf == "(" and ACCESSOR.fullmatch(name):
|
|
306
|
+
# an explicit `get()` / `set(v)` accessor: scip-java defines `getX().` at the keyword (0.13)
|
|
307
|
+
pn = name[3].lower() + name[4:]
|
|
308
|
+
for d in by_file.get(rel, ()):
|
|
309
|
+
if d.name == pn and d.id in self.p.props and d.line <= o.line + 1 <= d.end:
|
|
310
|
+
nid = d.id
|
|
311
|
+
break
|
|
304
312
|
if nid is None:
|
|
305
313
|
if (suf in ("(", "#") and not name.startswith("<") and not SYNTHETIC.fullmatch(name)
|
|
306
314
|
and (rel, o.line, o.col) not in term_pos):
|
|
307
315
|
unmatched += 1
|
|
316
|
+
if len(st.setdefault("scip_defs_unmatched_samples", [])) < 10:
|
|
317
|
+
st["scip_defs_unmatched_samples"].append(f"{rel}:{o.line + 1}:{o.col + 1} {name}{suf}")
|
|
308
318
|
continue
|
|
309
319
|
sym[s] = nid
|
|
310
320
|
matched += 1
|