codegraphcontext-rust 0.9.18__tar.gz → 0.9.19__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.
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/PKG-INFO +1 -1
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/pyproject.toml +1 -1
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/mod.rs +1 -0
- codegraphcontext_rust-0.9.19/rust/cgc-core/src/lang/ts_common.rs +346 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/tsx.rs +38 -11
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/typescript.rs +96 -4
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/resolution/calls.rs +40 -6
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/LICENSE +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/README.md +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/Cargo.lock +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/Cargo.toml +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/Cargo.toml +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/c_lang.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/cpp.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/csharp.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/dart.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/elixir.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/go.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/haskell.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/java.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/javascript.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/kotlin.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/perl.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/php.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/python.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/ruby.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/rust_lang.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/scala.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/swift.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lib.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/parser.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/resolution/inheritance.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/resolution/mod.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/sanitize.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/types.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-python/Cargo.toml +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-python/src/conversions.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-python/src/lib.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/tree-sitter-perl-vendor/Cargo.toml +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/tree-sitter-perl-vendor/build.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/tree-sitter-perl-vendor/src/grammar/alloc.h +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/tree-sitter-perl-vendor/src/grammar/array.h +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/tree-sitter-perl-vendor/src/grammar/parser.c +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/tree-sitter-perl-vendor/src/grammar/parser.h +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/tree-sitter-perl-vendor/src/grammar/scanner.c +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/tree-sitter-perl-vendor/src/grammar/tree_sitter/parser.h +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/tree-sitter-perl-vendor/src/lib.rs +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/__init__.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/__main__.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/cli/__init__.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/cli/cli_helpers.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/cli/config_manager.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/cli/main.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/cli/registry_commands.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/cli/setup_macos.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/cli/setup_wizard.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/cli/visualizer.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/core/__init__.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/core/bundle_registry.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/core/cgc_bundle.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/core/cgcignore.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/core/database.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/core/database_falkordb.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/core/database_falkordb_remote.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/core/database_kuzu.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/core/falkor_worker.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/core/jobs.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/core/watcher.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/prompts.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/server.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tool_definitions.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/__init__.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/advanced_language_query_tool.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/code_finder.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/graph_builder.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/handlers/analysis_handlers.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/handlers/indexing_handlers.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/handlers/management_handlers.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/handlers/query_handlers.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/handlers/watcher_handlers.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/__init__.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/cgc_wiki_cli.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/constants.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/context_generator.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/discovery.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/engine.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/execution_flows.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/module_grouping.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/noise_filter.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/op_param_extraction.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/persistence/__init__.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/persistence/duckdb_writer.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/persistence/parquet_loader.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/persistence/writer.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/pipeline.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/pre_scan.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/rationale_extraction.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/resolution/__init__.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/resolution/calls.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/resolution/inheritance.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/route_extraction.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/sanitize.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/schema.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/schema_contract.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/indexing/scip_pipeline.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/c.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/cpp.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/csharp.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/dart.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/elixir.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/go.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/haskell.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/java.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/javascript.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/kotlin.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/perl.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/php.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/python.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/ruby.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/rust.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/scala.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/swift.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/typescript.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/languages/typescriptjsx.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/package_resolver.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/query_tool_languages/c_toolkit.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/query_tool_languages/dart_toolkit.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/query_tool_languages/go_toolkit.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/query_tool_languages/haskell_toolkit.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/query_tool_languages/perl_toolkit.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/query_tool_languages/python_toolkit.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/query_tool_languages/rust_toolkit.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/query_tool_languages/scala_toolkit.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/query_tool_languages/swift_toolkit.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/scip_indexer.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/scip_pb2.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/system.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/tools/tree_sitter_parser.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/utils/debug_log.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/utils/path_ignore.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/utils/repo_path.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/utils/tree_sitter_manager.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/utils/visualize_graph.py +0 -0
- {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/src/codegraphcontext/viz/server.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "codegraphcontext-rust"
|
|
7
|
-
version = "0.9.
|
|
7
|
+
version = "0.9.19"
|
|
8
8
|
description = "Rust-accelerated code indexing engine for CodeGraphContext. 19 languages, 5-18x faster parsing via tree-sitter + rayon."
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "Shashank Shekhar Singh", email = "shashankshekharsingh1205@gmail.com" },
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
//! Type information shared by the TypeScript and TSX extractors: receiver
|
|
2
|
+
//! types for calls (`this.customerService.get()` → `CustomerService`),
|
|
3
|
+
//! receiver chains, method return types and class fields.
|
|
4
|
+
|
|
5
|
+
use std::collections::HashMap;
|
|
6
|
+
|
|
7
|
+
use streaming_iterator::StreamingIterator;
|
|
8
|
+
use tree_sitter::{Language, Node, Query, QueryCursor};
|
|
9
|
+
|
|
10
|
+
use super::get_node_text;
|
|
11
|
+
use crate::types::VariableData;
|
|
12
|
+
|
|
13
|
+
/// Node kinds that declare a class (own fields / parameter properties).
|
|
14
|
+
pub const TS_CLASS_KINDS: &[&str] = &["class_declaration", "abstract_class_declaration", "class"];
|
|
15
|
+
|
|
16
|
+
/// Node kinds that scope parameters and local variables.
|
|
17
|
+
pub const TS_CALLABLE_KINDS: &[&str] = &[
|
|
18
|
+
"method_definition",
|
|
19
|
+
"function_declaration",
|
|
20
|
+
"generator_function_declaration",
|
|
21
|
+
"function_expression",
|
|
22
|
+
"arrow_function",
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
/// Typed declarations: class fields, parameters and local variables.
|
|
26
|
+
const QUERY_TYPED: &str = r#"
|
|
27
|
+
(public_field_definition name: (property_identifier) @name) @decl
|
|
28
|
+
(required_parameter pattern: (identifier) @name) @decl
|
|
29
|
+
(optional_parameter pattern: (identifier) @name) @decl
|
|
30
|
+
(variable_declarator name: (identifier) @name) @decl
|
|
31
|
+
"#;
|
|
32
|
+
|
|
33
|
+
/// Types that carry no useful receiver information.
|
|
34
|
+
const NON_TYPES: &[&str] = &[
|
|
35
|
+
"string", "number", "boolean", "any", "unknown", "void", "never", "object", "null",
|
|
36
|
+
"undefined", "String", "Number", "Boolean", "Object", "Function", "Array",
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
fn child_of_kind<'t>(node: &Node<'t>, kind: &str) -> Option<Node<'t>> {
|
|
40
|
+
(0..node.child_count()).filter_map(|i| node.child(i)).find(|c| c.kind() == kind)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/// Simple class name of a type node (`Foo`, `Foo<T>`, `ns.Foo`, `Foo | null`).
|
|
44
|
+
pub fn type_name(node: &Node, source: &[u8]) -> Option<String> {
|
|
45
|
+
let node = if node.kind() == "type_annotation" { node.named_child(0)? } else { *node };
|
|
46
|
+
let name = match node.kind() {
|
|
47
|
+
"type_identifier" => get_node_text(&node, source).to_string(),
|
|
48
|
+
"generic_type" => return type_name(&node.child_by_field_name("name").or_else(|| node.named_child(0))?, source),
|
|
49
|
+
"nested_type_identifier" => {
|
|
50
|
+
let t = get_node_text(&node, source);
|
|
51
|
+
t.rsplit('.').next().unwrap_or(t).to_string()
|
|
52
|
+
}
|
|
53
|
+
// `Foo | null | undefined` → Foo
|
|
54
|
+
"union_type" => {
|
|
55
|
+
return (0..node.named_child_count())
|
|
56
|
+
.filter_map(|i| node.named_child(i))
|
|
57
|
+
.find_map(|c| type_name(&c, source));
|
|
58
|
+
}
|
|
59
|
+
"parenthesized_type" => return type_name(&node.named_child(0)?, source),
|
|
60
|
+
_ => return None,
|
|
61
|
+
};
|
|
62
|
+
(!NON_TYPES.contains(&name.as_str()) && name.starts_with(|c: char| c.is_ascii_uppercase())).then_some(name)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/// Raw text of a declared type (kept with generics, for return types).
|
|
66
|
+
pub fn type_text(annotation: &Node, source: &[u8]) -> Option<String> {
|
|
67
|
+
let node = if annotation.kind() == "type_annotation" { annotation.named_child(0)? } else { *annotation };
|
|
68
|
+
Some(get_node_text(&node, source).split_whitespace().collect::<Vec<_>>().join(" "))
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/// Type produced by an initializer: `new Foo()`, `inject(Foo)`,
|
|
72
|
+
/// `inject<Foo>(TOKEN)`, `x as Foo`.
|
|
73
|
+
fn initializer_type(value: &Node, source: &[u8]) -> Option<String> {
|
|
74
|
+
match value.kind() {
|
|
75
|
+
"new_expression" => {
|
|
76
|
+
let ctor = value.child_by_field_name("constructor")?;
|
|
77
|
+
let t = get_node_text(&ctor, source);
|
|
78
|
+
let t = t.rsplit('.').next().unwrap_or(t);
|
|
79
|
+
t.starts_with(|c: char| c.is_ascii_uppercase()).then(|| t.to_string())
|
|
80
|
+
}
|
|
81
|
+
"call_expression" => {
|
|
82
|
+
let f = value.child_by_field_name("function")?;
|
|
83
|
+
if get_node_text(&f, source) != "inject" {
|
|
84
|
+
return None;
|
|
85
|
+
}
|
|
86
|
+
if let Some(targs) = value.child_by_field_name("type_arguments") {
|
|
87
|
+
if let Some(t) = targs.named_child(0).and_then(|t| type_name(&t, source)) {
|
|
88
|
+
return Some(t);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
let arg = value.child_by_field_name("arguments")?.named_child(0)?;
|
|
92
|
+
let t = get_node_text(&arg, source);
|
|
93
|
+
(arg.kind() == "identifier" && t.starts_with(|c: char| c.is_ascii_uppercase())).then(|| t.to_string())
|
|
94
|
+
}
|
|
95
|
+
"as_expression" | "satisfies_expression" => type_name(&value.named_child(1)?, source),
|
|
96
|
+
"await_expression" | "parenthesized_expression" | "non_null_expression" => {
|
|
97
|
+
initializer_type(&value.named_child(0)?, source)
|
|
98
|
+
}
|
|
99
|
+
_ => None,
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
fn enclosing(node: &Node, kinds: &[&str]) -> Option<usize> {
|
|
104
|
+
let mut curr = node.parent();
|
|
105
|
+
while let Some(p) = curr {
|
|
106
|
+
if kinds.contains(&p.kind()) {
|
|
107
|
+
return Some(p.start_byte());
|
|
108
|
+
}
|
|
109
|
+
curr = p.parent();
|
|
110
|
+
}
|
|
111
|
+
None
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/// Is this parameter a constructor parameter property (`private svc: Svc`)?
|
|
115
|
+
fn is_parameter_property(param: &Node) -> bool {
|
|
116
|
+
child_of_kind(param, "accessibility_modifier").is_some()
|
|
117
|
+
|| (0..param.child_count()).filter_map(|i| param.child(i)).any(|c| c.kind() == "readonly")
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
fn in_constructor(param: &Node, source: &[u8]) -> bool {
|
|
121
|
+
let mut curr = param.parent();
|
|
122
|
+
while let Some(p) = curr {
|
|
123
|
+
if p.kind() == "method_definition" {
|
|
124
|
+
return p.child_by_field_name("name").map_or(false, |n| get_node_text(&n, source) == "constructor");
|
|
125
|
+
}
|
|
126
|
+
if TS_CALLABLE_KINDS.contains(&p.kind()) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
curr = p.parent();
|
|
130
|
+
}
|
|
131
|
+
false
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/// `(scope start byte, name) → type`. Class fields and constructor parameter
|
|
135
|
+
/// properties are scoped to the class; parameters and locals to the
|
|
136
|
+
/// enclosing callable.
|
|
137
|
+
pub fn collect_typed_names(lang: &Language, root: &Node, source: &[u8]) -> HashMap<(usize, String), String> {
|
|
138
|
+
let mut map = HashMap::new();
|
|
139
|
+
let Ok(query) = Query::new(lang, QUERY_TYPED) else { return map };
|
|
140
|
+
let names = query.capture_names();
|
|
141
|
+
let mut cursor = QueryCursor::new();
|
|
142
|
+
let mut matches = cursor.matches(&query, *root, source);
|
|
143
|
+
while let Some(m) = matches.next() {
|
|
144
|
+
let (mut decl, mut name) = (None, None);
|
|
145
|
+
for cap in m.captures {
|
|
146
|
+
match names[cap.index as usize] {
|
|
147
|
+
"decl" => decl = Some(cap.node),
|
|
148
|
+
"name" => name = Some(cap.node),
|
|
149
|
+
_ => {}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
let (Some(decl), Some(name)) = (decl, name) else { continue };
|
|
153
|
+
let ty = decl
|
|
154
|
+
.child_by_field_name("type")
|
|
155
|
+
.and_then(|t| type_name(&t, source))
|
|
156
|
+
.or_else(|| decl.child_by_field_name("value").and_then(|v| initializer_type(&v, source)));
|
|
157
|
+
let Some(ty) = ty else { continue };
|
|
158
|
+
let class_scoped = decl.kind() == "public_field_definition"
|
|
159
|
+
|| (matches!(decl.kind(), "required_parameter" | "optional_parameter")
|
|
160
|
+
&& is_parameter_property(&decl)
|
|
161
|
+
&& in_constructor(&decl, source));
|
|
162
|
+
let scope = if class_scoped {
|
|
163
|
+
enclosing(&decl, TS_CLASS_KINDS)
|
|
164
|
+
} else {
|
|
165
|
+
enclosing(&decl, TS_CALLABLE_KINDS).or_else(|| enclosing(&decl, TS_CLASS_KINDS)).or(Some(0))
|
|
166
|
+
};
|
|
167
|
+
if let Some(scope) = scope {
|
|
168
|
+
map.entry((scope, get_node_text(&name, source).to_string())).or_insert(ty);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
map
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/// Type of variable `var` visible at `node`: innermost callable first, then
|
|
175
|
+
/// enclosing classes (fields), then module scope.
|
|
176
|
+
pub fn lookup_var(node: &Node, var: &str, typed: &HashMap<(usize, String), String>) -> Option<String> {
|
|
177
|
+
let mut curr = node.parent();
|
|
178
|
+
while let Some(p) = curr {
|
|
179
|
+
if TS_CALLABLE_KINDS.contains(&p.kind()) || TS_CLASS_KINDS.contains(&p.kind()) {
|
|
180
|
+
if let Some(t) = typed.get(&(p.start_byte(), var.to_string())) {
|
|
181
|
+
return Some(t.clone());
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
curr = p.parent();
|
|
185
|
+
}
|
|
186
|
+
typed.get(&(0, var.to_string())).cloned()
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/// Type of field `field` of the class enclosing `node`.
|
|
190
|
+
pub fn lookup_field(node: &Node, field: &str, typed: &HashMap<(usize, String), String>) -> Option<String> {
|
|
191
|
+
let mut curr = node.parent();
|
|
192
|
+
while let Some(p) = curr {
|
|
193
|
+
if TS_CLASS_KINDS.contains(&p.kind()) {
|
|
194
|
+
if let Some(t) = typed.get(&(p.start_byte(), field.to_string())) {
|
|
195
|
+
return Some(t.clone());
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
curr = p.parent();
|
|
199
|
+
}
|
|
200
|
+
None
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
fn enclosing_class_name(node: &Node, source: &[u8]) -> Option<String> {
|
|
204
|
+
let mut curr = node.parent();
|
|
205
|
+
while let Some(p) = curr {
|
|
206
|
+
if TS_CLASS_KINDS.contains(&p.kind()) {
|
|
207
|
+
return p.child_by_field_name("name").map(|n| get_node_text(&n, source).to_string());
|
|
208
|
+
}
|
|
209
|
+
curr = p.parent();
|
|
210
|
+
}
|
|
211
|
+
None
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/// Peel a receiver into its root and member path:
|
|
215
|
+
/// `this.repo.find(id).items` → (this, ["repo", "find()", "items"]).
|
|
216
|
+
fn split_receiver<'t>(node: Node<'t>, source: &[u8]) -> (Option<Node<'t>>, Vec<String>) {
|
|
217
|
+
match node.kind() {
|
|
218
|
+
"member_expression" => {
|
|
219
|
+
let prop = node.child_by_field_name("property").map(|p| get_node_text(&p, source).to_string());
|
|
220
|
+
let (root, mut chain) = match node.child_by_field_name("object") {
|
|
221
|
+
Some(o) => split_receiver(o, source),
|
|
222
|
+
None => (None, Vec::new()),
|
|
223
|
+
};
|
|
224
|
+
chain.push(prop.unwrap_or_default());
|
|
225
|
+
(root, chain)
|
|
226
|
+
}
|
|
227
|
+
"call_expression" => {
|
|
228
|
+
let Some(f) = node.child_by_field_name("function") else { return (Some(node), Vec::new()) };
|
|
229
|
+
if f.kind() != "member_expression" {
|
|
230
|
+
// plain function call as a root: `getRepo().find()`
|
|
231
|
+
return (Some(node), Vec::new());
|
|
232
|
+
}
|
|
233
|
+
let (root, mut chain) = split_receiver(f, source);
|
|
234
|
+
if let Some(last) = chain.last_mut() {
|
|
235
|
+
last.push_str("()");
|
|
236
|
+
}
|
|
237
|
+
(root, chain)
|
|
238
|
+
}
|
|
239
|
+
"parenthesized_expression" | "non_null_expression" | "await_expression" => match node.named_child(0) {
|
|
240
|
+
Some(inner) => split_receiver(inner, source),
|
|
241
|
+
None => (Some(node), Vec::new()),
|
|
242
|
+
},
|
|
243
|
+
_ => (Some(node), Vec::new()),
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/// Receiver facts for a call: (full_name `recv.method`, inferred receiver
|
|
248
|
+
/// type, receiver chain). `call_node` is a call_expression/new_expression.
|
|
249
|
+
pub fn call_receiver(
|
|
250
|
+
call_node: &Node,
|
|
251
|
+
name: &str,
|
|
252
|
+
source: &[u8],
|
|
253
|
+
typed: &HashMap<(usize, String), String>,
|
|
254
|
+
) -> (String, Option<String>, Vec<String>) {
|
|
255
|
+
let squash = |t: &str| t.split_whitespace().collect::<Vec<_>>().join(" ");
|
|
256
|
+
let Some(func) = call_node.child_by_field_name("function").filter(|f| f.kind() == "member_expression") else {
|
|
257
|
+
// plain `foo()` / `new Foo()`
|
|
258
|
+
let callee = call_node
|
|
259
|
+
.child_by_field_name("function")
|
|
260
|
+
.or_else(|| call_node.child_by_field_name("constructor"))
|
|
261
|
+
.map(|f| squash(get_node_text(&f, source)))
|
|
262
|
+
.unwrap_or_else(|| name.to_string());
|
|
263
|
+
return (callee, None, Vec::new());
|
|
264
|
+
};
|
|
265
|
+
let Some(object) = func.child_by_field_name("object") else {
|
|
266
|
+
return (name.to_string(), None, Vec::new());
|
|
267
|
+
};
|
|
268
|
+
let full_name = format!("{}.{}", squash(get_node_text(&object, source)), name);
|
|
269
|
+
let (root, chain) = split_receiver(object, source);
|
|
270
|
+
let Some(root) = root else { return (full_name, None, Vec::new()) };
|
|
271
|
+
|
|
272
|
+
// this.field.m(): the field's declared type, no chain
|
|
273
|
+
if root.kind() == "this" && chain.len() == 1 && !chain[0].ends_with("()") {
|
|
274
|
+
return (full_name, lookup_field(call_node, &chain[0], typed), Vec::new());
|
|
275
|
+
}
|
|
276
|
+
let root_type = match root.kind() {
|
|
277
|
+
"this" => enclosing_class_name(call_node, source),
|
|
278
|
+
"identifier" => {
|
|
279
|
+
let id = get_node_text(&root, source);
|
|
280
|
+
lookup_var(call_node, id, typed)
|
|
281
|
+
.or_else(|| id.starts_with(|c: char| c.is_ascii_uppercase()).then(|| id.to_string()))
|
|
282
|
+
}
|
|
283
|
+
"new_expression" => initializer_type(&root, source),
|
|
284
|
+
_ => None,
|
|
285
|
+
};
|
|
286
|
+
if chain.is_empty() {
|
|
287
|
+
// x.m(): fall back to the variable name (resolver treats lower-case
|
|
288
|
+
// names as untyped)
|
|
289
|
+
let fallback = (root.kind() == "identifier").then(|| get_node_text(&root, source).to_string());
|
|
290
|
+
return (full_name, root_type.or(fallback), Vec::new());
|
|
291
|
+
}
|
|
292
|
+
match root_type {
|
|
293
|
+
Some(t) => (full_name, Some(t), chain),
|
|
294
|
+
None => (full_name, None, Vec::new()),
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/// Declared return type of a function/method node.
|
|
299
|
+
pub fn return_type(func: &Node, source: &[u8]) -> Option<String> {
|
|
300
|
+
func.child_by_field_name("return_type").and_then(|t| type_text(&t, source))
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/// Class fields and constructor parameter properties as typed variables
|
|
304
|
+
/// (context == class_context == the class), so the resolver can follow
|
|
305
|
+
/// `this.a.b.m()` chains.
|
|
306
|
+
pub fn class_field_variables(lang: &Language, root: &Node, source: &[u8], lang_name: &str) -> Vec<VariableData> {
|
|
307
|
+
let mut out = Vec::new();
|
|
308
|
+
let Ok(query) = Query::new(lang, QUERY_TYPED) else { return out };
|
|
309
|
+
let names = query.capture_names();
|
|
310
|
+
let mut cursor = QueryCursor::new();
|
|
311
|
+
let mut matches = cursor.matches(&query, *root, source);
|
|
312
|
+
while let Some(m) = matches.next() {
|
|
313
|
+
let (mut decl, mut name) = (None, None);
|
|
314
|
+
for cap in m.captures {
|
|
315
|
+
match names[cap.index as usize] {
|
|
316
|
+
"decl" => decl = Some(cap.node),
|
|
317
|
+
"name" => name = Some(cap.node),
|
|
318
|
+
_ => {}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
let (Some(decl), Some(name)) = (decl, name) else { continue };
|
|
322
|
+
let is_field = decl.kind() == "public_field_definition"
|
|
323
|
+
|| (matches!(decl.kind(), "required_parameter" | "optional_parameter")
|
|
324
|
+
&& is_parameter_property(&decl)
|
|
325
|
+
&& in_constructor(&decl, source));
|
|
326
|
+
if !is_field {
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
let Some(class) = enclosing_class_name(&decl, source) else { continue };
|
|
330
|
+
let ty = decl
|
|
331
|
+
.child_by_field_name("type")
|
|
332
|
+
.and_then(|t| type_text(&t, source))
|
|
333
|
+
.or_else(|| decl.child_by_field_name("value").and_then(|v| initializer_type(&v, source)));
|
|
334
|
+
out.push(VariableData {
|
|
335
|
+
name: get_node_text(&name, source).to_string(),
|
|
336
|
+
line_number: name.start_position().row + 1,
|
|
337
|
+
value: None,
|
|
338
|
+
type_annotation: ty,
|
|
339
|
+
context: Some(class.clone()),
|
|
340
|
+
class_context: Some(class),
|
|
341
|
+
lang: lang_name.to_string(),
|
|
342
|
+
is_dependency: false,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
out
|
|
346
|
+
}
|
|
@@ -86,6 +86,12 @@ const QUERY_INTERFACES: &str = r#"
|
|
|
86
86
|
) @interface_node
|
|
87
87
|
"#;
|
|
88
88
|
|
|
89
|
+
const QUERY_ENUMS: &str = r#"
|
|
90
|
+
(enum_declaration
|
|
91
|
+
name: (identifier) @name
|
|
92
|
+
) @enum_node
|
|
93
|
+
"#;
|
|
94
|
+
|
|
89
95
|
const QUERY_TYPE_ALIASES: &str = r#"
|
|
90
96
|
(type_alias_declaration
|
|
91
97
|
name: (type_identifier) @name
|
|
@@ -466,7 +472,7 @@ impl LanguageExtractor for TsxExtractor {
|
|
|
466
472
|
};
|
|
467
473
|
|
|
468
474
|
let mut func = FunctionData {
|
|
469
|
-
return_type:
|
|
475
|
+
return_type: super::ts_common::return_type(func_node, source),
|
|
470
476
|
name,
|
|
471
477
|
line_number: func_node.start_position().row + 1,
|
|
472
478
|
end_line: func_node.end_position().row + 1,
|
|
@@ -654,6 +660,27 @@ impl LanguageExtractor for TsxExtractor {
|
|
|
654
660
|
classes.push(class);
|
|
655
661
|
}
|
|
656
662
|
|
|
663
|
+
|
|
664
|
+
// Enums
|
|
665
|
+
for (node, capture_name) in self.execute_query(QUERY_ENUMS, root, source) {
|
|
666
|
+
if capture_name != "enum_node" {
|
|
667
|
+
continue;
|
|
668
|
+
}
|
|
669
|
+
let Some(name_node) = node.child_by_field_name("name") else { continue };
|
|
670
|
+
classes.push(ClassData {
|
|
671
|
+
kind: class_kind(&node),
|
|
672
|
+
name: get_node_text(&name_node, source).to_string(),
|
|
673
|
+
line_number: node.start_position().row + 1,
|
|
674
|
+
end_line: node.end_position().row + 1,
|
|
675
|
+
bases: Vec::new(),
|
|
676
|
+
context: None,
|
|
677
|
+
decorators: Vec::new(),
|
|
678
|
+
lang: self.lang_name().to_string(),
|
|
679
|
+
is_dependency: false,
|
|
680
|
+
source: index_source.then(|| get_node_text(&node, source).to_string()),
|
|
681
|
+
docstring: None,
|
|
682
|
+
});
|
|
683
|
+
}
|
|
657
684
|
classes
|
|
658
685
|
}
|
|
659
686
|
|
|
@@ -720,6 +747,7 @@ impl LanguageExtractor for TsxExtractor {
|
|
|
720
747
|
|
|
721
748
|
fn find_calls(&self, root: &Node, source: &[u8]) -> Vec<CallData> {
|
|
722
749
|
let mut calls = Vec::new();
|
|
750
|
+
let typed = super::ts_common::collect_typed_names(&self.language(), root, source);
|
|
723
751
|
|
|
724
752
|
for (node, capture_name) in self.execute_query(QUERY_CALLS, root, source) {
|
|
725
753
|
if capture_name != "name" {
|
|
@@ -747,13 +775,9 @@ impl LanguageExtractor for TsxExtractor {
|
|
|
747
775
|
}
|
|
748
776
|
};
|
|
749
777
|
|
|
750
|
-
let
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
let full_name = match full_call_node {
|
|
754
|
-
Some(ref n) => get_node_text(n, source).to_string(),
|
|
755
|
-
None => get_node_text(&node, source).to_string(),
|
|
756
|
-
};
|
|
778
|
+
let name = get_node_text(&node, source).to_string();
|
|
779
|
+
let (full_name, inferred_obj_type, receiver_chain) =
|
|
780
|
+
super::ts_common::call_receiver(&call_node, &name, source, &typed);
|
|
757
781
|
|
|
758
782
|
let context = get_parent_context(&node, source, FC_TYPES);
|
|
759
783
|
let class_ctx = get_parent_context(
|
|
@@ -763,12 +787,12 @@ impl LanguageExtractor for TsxExtractor {
|
|
|
763
787
|
);
|
|
764
788
|
|
|
765
789
|
calls.push(CallData {
|
|
766
|
-
receiver_chain
|
|
767
|
-
name
|
|
790
|
+
receiver_chain,
|
|
791
|
+
name,
|
|
768
792
|
full_name,
|
|
769
793
|
line_number: node.start_position().row + 1,
|
|
770
794
|
args: Vec::new(),
|
|
771
|
-
inferred_obj_type
|
|
795
|
+
inferred_obj_type,
|
|
772
796
|
context,
|
|
773
797
|
class_context: (class_ctx.0, class_ctx.1),
|
|
774
798
|
lang: self.lang_name().to_string(),
|
|
@@ -830,6 +854,9 @@ impl LanguageExtractor for TsxExtractor {
|
|
|
830
854
|
});
|
|
831
855
|
}
|
|
832
856
|
|
|
857
|
+
|
|
858
|
+
// Class fields and constructor parameter properties (typed), for chains
|
|
859
|
+
variables.extend(super::ts_common::class_field_variables(&self.language(), root, source, self.lang_name()));
|
|
833
860
|
variables
|
|
834
861
|
}
|
|
835
862
|
}
|
{codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.19}/rust/cgc-core/src/lang/typescript.rs
RENAMED
|
@@ -82,6 +82,12 @@ const QUERY_INTERFACES: &str = r#"
|
|
|
82
82
|
) @interface_node
|
|
83
83
|
"#;
|
|
84
84
|
|
|
85
|
+
const QUERY_ENUMS: &str = r#"
|
|
86
|
+
(enum_declaration
|
|
87
|
+
name: (identifier) @name
|
|
88
|
+
) @enum_node
|
|
89
|
+
"#;
|
|
90
|
+
|
|
85
91
|
const QUERY_TYPE_ALIASES: &str = r#"
|
|
86
92
|
(type_alias_declaration
|
|
87
93
|
name: (type_identifier) @name
|
|
@@ -114,6 +120,7 @@ const QUERY_PRE_SCAN: &str = r#"
|
|
|
114
120
|
(variable_declarator name: (identifier) @name value: (arrow_function))
|
|
115
121
|
(interface_declaration name: (type_identifier) @name)
|
|
116
122
|
(type_alias_declaration name: (type_identifier) @name)
|
|
123
|
+
(enum_declaration name: (identifier) @name)
|
|
117
124
|
"#;
|
|
118
125
|
|
|
119
126
|
/// Context types used for parent context lookups in TypeScript.
|
|
@@ -475,7 +482,7 @@ impl LanguageExtractor for TypeScriptExtractor {
|
|
|
475
482
|
};
|
|
476
483
|
|
|
477
484
|
let mut func = FunctionData {
|
|
478
|
-
return_type:
|
|
485
|
+
return_type: super::ts_common::return_type(func_node, source),
|
|
479
486
|
name,
|
|
480
487
|
line_number: func_node.start_position().row + 1,
|
|
481
488
|
end_line: func_node.end_position().row + 1,
|
|
@@ -661,6 +668,27 @@ impl LanguageExtractor for TypeScriptExtractor {
|
|
|
661
668
|
classes.push(class);
|
|
662
669
|
}
|
|
663
670
|
|
|
671
|
+
|
|
672
|
+
// Enums
|
|
673
|
+
for (node, capture_name) in self.execute_query(QUERY_ENUMS, root, source) {
|
|
674
|
+
if capture_name != "enum_node" {
|
|
675
|
+
continue;
|
|
676
|
+
}
|
|
677
|
+
let Some(name_node) = node.child_by_field_name("name") else { continue };
|
|
678
|
+
classes.push(ClassData {
|
|
679
|
+
kind: class_kind(&node),
|
|
680
|
+
name: get_node_text(&name_node, source).to_string(),
|
|
681
|
+
line_number: node.start_position().row + 1,
|
|
682
|
+
end_line: node.end_position().row + 1,
|
|
683
|
+
bases: Vec::new(),
|
|
684
|
+
context: None,
|
|
685
|
+
decorators: Vec::new(),
|
|
686
|
+
lang: self.lang_name().to_string(),
|
|
687
|
+
is_dependency: false,
|
|
688
|
+
source: index_source.then(|| get_node_text(&node, source).to_string()),
|
|
689
|
+
docstring: None,
|
|
690
|
+
});
|
|
691
|
+
}
|
|
664
692
|
classes
|
|
665
693
|
}
|
|
666
694
|
|
|
@@ -749,6 +777,7 @@ impl LanguageExtractor for TypeScriptExtractor {
|
|
|
749
777
|
|
|
750
778
|
fn find_calls(&self, root: &Node, source: &[u8]) -> Vec<CallData> {
|
|
751
779
|
let mut calls = Vec::new();
|
|
780
|
+
let typed = super::ts_common::collect_typed_names(&self.language(), root, source);
|
|
752
781
|
|
|
753
782
|
for (node, capture_name) in self.execute_query(QUERY_CALLS, root, source) {
|
|
754
783
|
if capture_name != "name" {
|
|
@@ -778,7 +807,8 @@ impl LanguageExtractor for TypeScriptExtractor {
|
|
|
778
807
|
};
|
|
779
808
|
|
|
780
809
|
let name = get_node_text(&node, source).to_string();
|
|
781
|
-
let full_name
|
|
810
|
+
let (full_name, inferred_obj_type, receiver_chain) =
|
|
811
|
+
super::ts_common::call_receiver(&call_node, &name, source, &typed);
|
|
782
812
|
|
|
783
813
|
let mut args = Vec::new();
|
|
784
814
|
if let Some(arguments_node) = call_node.child_by_field_name("arguments") {
|
|
@@ -804,12 +834,12 @@ impl LanguageExtractor for TypeScriptExtractor {
|
|
|
804
834
|
);
|
|
805
835
|
|
|
806
836
|
calls.push(CallData {
|
|
807
|
-
receiver_chain
|
|
837
|
+
receiver_chain,
|
|
808
838
|
name,
|
|
809
839
|
full_name,
|
|
810
840
|
line_number: node.start_position().row + 1,
|
|
811
841
|
args,
|
|
812
|
-
inferred_obj_type
|
|
842
|
+
inferred_obj_type,
|
|
813
843
|
context,
|
|
814
844
|
class_context: (class_ctx.0, class_ctx.1),
|
|
815
845
|
lang: self.lang_name().to_string(),
|
|
@@ -885,6 +915,9 @@ impl LanguageExtractor for TypeScriptExtractor {
|
|
|
885
915
|
});
|
|
886
916
|
}
|
|
887
917
|
|
|
918
|
+
|
|
919
|
+
// Class fields and constructor parameter properties (typed), for chains
|
|
920
|
+
variables.extend(super::ts_common::class_field_variables(&self.language(), root, source, self.lang_name()));
|
|
888
921
|
variables
|
|
889
922
|
}
|
|
890
923
|
|
|
@@ -1224,4 +1257,63 @@ class Widget {
|
|
|
1224
1257
|
assert_eq!(ctx("helper").as_deref(), Some("bar"));
|
|
1225
1258
|
assert_eq!(ctx("save").as_deref(), Some("onClick"));
|
|
1226
1259
|
}
|
|
1260
|
+
|
|
1261
|
+
#[test]
|
|
1262
|
+
fn test_receiver_types_and_enums() {
|
|
1263
|
+
let code = r#"
|
|
1264
|
+
export enum Status { Active, Blocked }
|
|
1265
|
+
|
|
1266
|
+
@Component({ selector: 'app-x' })
|
|
1267
|
+
export class CustomerComponent {
|
|
1268
|
+
private readonly http = inject(HttpClient);
|
|
1269
|
+
private repo: CustomerRepo;
|
|
1270
|
+
cache = new CacheStore();
|
|
1271
|
+
constructor(private customerService: CustomerService, readonly bus: EventBus, plain: Helper) {}
|
|
1272
|
+
|
|
1273
|
+
load(id: string, opts: LoadOptions): Observable<Customer> {
|
|
1274
|
+
this.customerService.get(id);
|
|
1275
|
+
this.bus.emit('x');
|
|
1276
|
+
this.http.get('/api');
|
|
1277
|
+
this.cache.clear();
|
|
1278
|
+
this.repo.findAll().filter(x => x);
|
|
1279
|
+
opts.validate();
|
|
1280
|
+
const svc: PetService = this.pets;
|
|
1281
|
+
svc.list();
|
|
1282
|
+
const fresh = new Builder();
|
|
1283
|
+
fresh.build();
|
|
1284
|
+
plain.run();
|
|
1285
|
+
return null;
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
"#;
|
|
1289
|
+
let (tree, source) = parse_source(code);
|
|
1290
|
+
let ext = TypeScriptExtractor;
|
|
1291
|
+
let calls = ext.find_calls(&tree.root_node(), &source);
|
|
1292
|
+
let get = |full: &str| calls.iter().find(|c| c.full_name == full).unwrap_or_else(|| panic!("{full}: {:?}", calls.iter().map(|c| &c.full_name).collect::<Vec<_>>()));
|
|
1293
|
+
assert_eq!(get("this.customerService.get").inferred_obj_type.as_deref(), Some("CustomerService"));
|
|
1294
|
+
assert_eq!(get("this.bus.emit").inferred_obj_type.as_deref(), Some("EventBus"));
|
|
1295
|
+
assert_eq!(get("this.http.get").inferred_obj_type.as_deref(), Some("HttpClient"));
|
|
1296
|
+
assert_eq!(get("this.cache.clear").inferred_obj_type.as_deref(), Some("CacheStore"));
|
|
1297
|
+
let chained = get("this.repo.findAll().filter");
|
|
1298
|
+
assert_eq!((chained.inferred_obj_type.as_deref(), chained.receiver_chain.clone()),
|
|
1299
|
+
(Some("CustomerComponent"), vec!["repo".to_string(), "findAll()".to_string()]));
|
|
1300
|
+
assert_eq!(get("opts.validate").inferred_obj_type.as_deref(), Some("LoadOptions"));
|
|
1301
|
+
assert_eq!(get("svc.list").inferred_obj_type.as_deref(), Some("PetService"));
|
|
1302
|
+
assert_eq!(get("fresh.build").inferred_obj_type.as_deref(), Some("Builder"));
|
|
1303
|
+
// constructor param without modifier is not a field, but is typed inside the constructor only
|
|
1304
|
+
assert_eq!(get("plain.run").inferred_obj_type.as_deref(), Some("plain"));
|
|
1305
|
+
|
|
1306
|
+
let funcs = ext.find_functions(&tree.root_node(), &source, false);
|
|
1307
|
+
assert_eq!(funcs.iter().find(|f| f.name == "load").unwrap().return_type.as_deref(), Some("Observable<Customer>"));
|
|
1308
|
+
|
|
1309
|
+
let classes = ext.find_classes(&tree.root_node(), &source, false);
|
|
1310
|
+
assert!(classes.iter().any(|c| c.name == "Status" && c.kind == "enum"));
|
|
1311
|
+
|
|
1312
|
+
let vars = ext.find_variables(&tree.root_node(), &source);
|
|
1313
|
+
let field = |n: &str| vars.iter().find(|v| v.name == n && v.context.as_deref() == Some("CustomerComponent")).map(|v| v.type_annotation.clone());
|
|
1314
|
+
assert_eq!(field("customerService"), Some(Some("CustomerService".to_string())));
|
|
1315
|
+
assert_eq!(field("repo"), Some(Some("CustomerRepo".to_string())));
|
|
1316
|
+
assert_eq!(field("http"), Some(Some("HttpClient".to_string())));
|
|
1317
|
+
assert_eq!(field("plain"), None);
|
|
1318
|
+
}
|
|
1227
1319
|
}
|