#
tokens: 45806/50000 2/422 files (page 18/22)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 18 of 22. Use http://codebase.md/shashankss1205/codegraphcontext?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .cgcignore
├── .github
│   ├── FUNDING.yml
│   └── workflows
│       ├── e2e-tests.yml
│       ├── post_discord_invite.yml
│       ├── test.yml
│       └── update-contributors.yml
├── .gitignore
├── CLI_Commands.md
├── CONTRIBUTING.md
├── contributors.md
├── docs
│   ├── docs
│   │   ├── architecture.md
│   │   ├── cli.md
│   │   ├── contributing_languages.md
│   │   ├── contributing.md
│   │   ├── cookbook.md
│   │   ├── core.md
│   │   ├── future_work.md
│   │   ├── images
│   │   │   ├── 1.png
│   │   │   ├── 11.png
│   │   │   ├── 12.png
│   │   │   ├── 13.png
│   │   │   ├── 14.png
│   │   │   ├── 16.png
│   │   │   ├── 19.png
│   │   │   ├── 2.png
│   │   │   ├── 20.png
│   │   │   ├── 21.png
│   │   │   ├── 22.png
│   │   │   ├── 23.png
│   │   │   ├── 24.png
│   │   │   ├── 26.png
│   │   │   ├── 28.png
│   │   │   ├── 29.png
│   │   │   ├── 3.png
│   │   │   ├── 30.png
│   │   │   ├── 31.png
│   │   │   ├── 32.png
│   │   │   ├── 33.png
│   │   │   ├── 34.png
│   │   │   ├── 35.png
│   │   │   ├── 36.png
│   │   │   ├── 38.png
│   │   │   ├── 39.png
│   │   │   ├── 4.png
│   │   │   ├── 40.png
│   │   │   ├── 41.png
│   │   │   ├── 42.png
│   │   │   ├── 43.png
│   │   │   ├── 44.png
│   │   │   ├── 5.png
│   │   │   ├── 6.png
│   │   │   ├── 7.png
│   │   │   ├── 8.png
│   │   │   ├── 9.png
│   │   │   ├── Indexing.gif
│   │   │   ├── tool_images
│   │   │   │   ├── 1.png
│   │   │   │   ├── 2.png
│   │   │   │   └── 3.png
│   │   │   └── Usecase.gif
│   │   ├── index.md
│   │   ├── installation.md
│   │   ├── license.md
│   │   ├── server.md
│   │   ├── tools.md
│   │   ├── troubleshooting.md
│   │   ├── use_cases.md
│   │   └── watching.md
│   ├── mkdocs.yml
│   └── site
│       ├── 404.html
│       ├── architecture
│       │   └── index.html
│       ├── assets
│       │   ├── images
│       │   │   └── favicon.png
│       │   ├── javascripts
│       │   │   ├── bundle.79ae519e.min.js
│       │   │   ├── bundle.79ae519e.min.js.map
│       │   │   ├── lunr
│       │   │   │   ├── min
│       │   │   │   │   ├── lunr.ar.min.js
│       │   │   │   │   ├── lunr.da.min.js
│       │   │   │   │   ├── lunr.de.min.js
│       │   │   │   │   ├── lunr.du.min.js
│       │   │   │   │   ├── lunr.el.min.js
│       │   │   │   │   ├── lunr.es.min.js
│       │   │   │   │   ├── lunr.fi.min.js
│       │   │   │   │   ├── lunr.fr.min.js
│       │   │   │   │   ├── lunr.he.min.js
│       │   │   │   │   ├── lunr.hi.min.js
│       │   │   │   │   ├── lunr.hu.min.js
│       │   │   │   │   ├── lunr.hy.min.js
│       │   │   │   │   ├── lunr.it.min.js
│       │   │   │   │   ├── lunr.ja.min.js
│       │   │   │   │   ├── lunr.jp.min.js
│       │   │   │   │   ├── lunr.kn.min.js
│       │   │   │   │   ├── lunr.ko.min.js
│       │   │   │   │   ├── lunr.multi.min.js
│       │   │   │   │   ├── lunr.nl.min.js
│       │   │   │   │   ├── lunr.no.min.js
│       │   │   │   │   ├── lunr.pt.min.js
│       │   │   │   │   ├── lunr.ro.min.js
│       │   │   │   │   ├── lunr.ru.min.js
│       │   │   │   │   ├── lunr.sa.min.js
│       │   │   │   │   ├── lunr.stemmer.support.min.js
│       │   │   │   │   ├── lunr.sv.min.js
│       │   │   │   │   ├── lunr.ta.min.js
│       │   │   │   │   ├── lunr.te.min.js
│       │   │   │   │   ├── lunr.th.min.js
│       │   │   │   │   ├── lunr.tr.min.js
│       │   │   │   │   ├── lunr.vi.min.js
│       │   │   │   │   └── lunr.zh.min.js
│       │   │   │   ├── tinyseg.js
│       │   │   │   └── wordcut.js
│       │   │   └── workers
│       │   │       ├── search.2c215733.min.js
│       │   │       └── search.2c215733.min.js.map
│       │   └── stylesheets
│       │       ├── main.484c7ddc.min.css
│       │       ├── main.484c7ddc.min.css.map
│       │       ├── palette.ab4e12ef.min.css
│       │       └── palette.ab4e12ef.min.css.map
│       ├── cli
│       │   └── index.html
│       ├── contributing
│       │   └── index.html
│       ├── contributing_languages
│       │   └── index.html
│       ├── cookbook
│       │   └── index.html
│       ├── core
│       │   └── index.html
│       ├── future_work
│       │   └── index.html
│       ├── images
│       │   ├── 1.png
│       │   ├── 11.png
│       │   ├── 12.png
│       │   ├── 13.png
│       │   ├── 14.png
│       │   ├── 16.png
│       │   ├── 19.png
│       │   ├── 2.png
│       │   ├── 20.png
│       │   ├── 21.png
│       │   ├── 22.png
│       │   ├── 23.png
│       │   ├── 24.png
│       │   ├── 26.png
│       │   ├── 28.png
│       │   ├── 29.png
│       │   ├── 3.png
│       │   ├── 30.png
│       │   ├── 31.png
│       │   ├── 32.png
│       │   ├── 33.png
│       │   ├── 34.png
│       │   ├── 35.png
│       │   ├── 36.png
│       │   ├── 38.png
│       │   ├── 39.png
│       │   ├── 4.png
│       │   ├── 40.png
│       │   ├── 41.png
│       │   ├── 42.png
│       │   ├── 43.png
│       │   ├── 44.png
│       │   ├── 5.png
│       │   ├── 6.png
│       │   ├── 7.png
│       │   ├── 8.png
│       │   ├── 9.png
│       │   ├── Indexing.gif
│       │   ├── tool_images
│       │   │   ├── 1.png
│       │   │   ├── 2.png
│       │   │   └── 3.png
│       │   └── Usecase.gif
│       ├── index.html
│       ├── installation
│       │   └── index.html
│       ├── license
│       │   └── index.html
│       ├── search
│       │   └── search_index.json
│       ├── server
│       │   └── index.html
│       ├── sitemap.xml
│       ├── sitemap.xml.gz
│       ├── tools
│       │   └── index.html
│       ├── troubleshooting
│       │   └── index.html
│       ├── use_cases
│       │   └── index.html
│       └── watching
│           └── index.html
├── funding.json
├── images
│   ├── 1.png
│   ├── 11.png
│   ├── 12.png
│   ├── 13.png
│   ├── 14.png
│   ├── 16.png
│   ├── 19.png
│   ├── 2.png
│   ├── 20.png
│   ├── 21.png
│   ├── 22.png
│   ├── 23.png
│   ├── 24.png
│   ├── 26.png
│   ├── 28.png
│   ├── 29.png
│   ├── 3.png
│   ├── 30.png
│   ├── 31.png
│   ├── 32.png
│   ├── 33.png
│   ├── 34.png
│   ├── 35.png
│   ├── 36.png
│   ├── 38.png
│   ├── 39.png
│   ├── 4.png
│   ├── 40.png
│   ├── 41.png
│   ├── 42.png
│   ├── 43.png
│   ├── 44.png
│   ├── 5.png
│   ├── 6.png
│   ├── 7.png
│   ├── 8.png
│   ├── 9.png
│   ├── Indexing.gif
│   ├── tool_images
│   │   ├── 1.png
│   │   ├── 2.png
│   │   └── 3.png
│   └── Usecase.gif
├── LICENSE
├── MANIFEST.in
├── organizer
│   ├── CONTRIBUTING_LANGUAGES.md
│   ├── cookbook.md
│   ├── docs.md
│   ├── language_specific_nodes.md
│   ├── Tools_Exploration.md
│   └── troubleshoot.md
├── pyproject.toml
├── README.md
├── scripts
│   ├── generate_lang_contributors.py
│   ├── post_install_fix.sh
│   ├── test_all_parsers.py
│   └── update_language_parsers.py
├── SECURITY.md
├── src
│   └── codegraphcontext
│       ├── __init__.py
│       ├── __main__.py
│       ├── cli
│       │   ├── __init__.py
│       │   ├── cli_helpers.py
│       │   ├── config_manager.py
│       │   ├── main.py
│       │   ├── setup_macos.py
│       │   └── setup_wizard.py
│       ├── core
│       │   ├── __init__.py
│       │   ├── database_falkordb.py
│       │   ├── database.py
│       │   ├── falkor_worker.py
│       │   ├── jobs.py
│       │   └── watcher.py
│       ├── prompts.py
│       ├── server.py
│       ├── tools
│       │   ├── __init__.py
│       │   ├── advanced_language_query_tool.py
│       │   ├── code_finder.py
│       │   ├── graph_builder.py
│       │   ├── languages
│       │   │   ├── c.py
│       │   │   ├── cpp.py
│       │   │   ├── csharp.py
│       │   │   ├── go.py
│       │   │   ├── java.py
│       │   │   ├── javascript.py
│       │   │   ├── kotlin.py
│       │   │   ├── php.py
│       │   │   ├── python.py
│       │   │   ├── ruby.py
│       │   │   ├── rust.py
│       │   │   ├── scala.py
│       │   │   ├── swift.py
│       │   │   ├── typescript.py
│       │   │   └── typescriptjsx.py
│       │   ├── package_resolver.py
│       │   ├── query_tool_languages
│       │   │   ├── c_toolkit.py
│       │   │   ├── cpp_toolkit.py
│       │   │   ├── csharp_toolkit.py
│       │   │   ├── go_toolkit.py
│       │   │   ├── java_toolkit.py
│       │   │   ├── javascript_toolkit.py
│       │   │   ├── python_toolkit.py
│       │   │   ├── ruby_toolkit.py
│       │   │   ├── rust_toolkit.py
│       │   │   ├── scala_toolkit.py
│       │   │   ├── swift_toolkit.py
│       │   │   └── typescript_toolkit.py
│       │   └── system.py
│       └── utils
│           ├── debug_log.py
│           └── tree_sitter_manager.py
├── tests
│   ├── __init__.py
│   ├── conftest.py
│   ├── sample_project
│   │   ├── advanced_calls.py
│   │   ├── advanced_classes.py
│   │   ├── advanced_classes2.py
│   │   ├── advanced_functions.py
│   │   ├── advanced_imports.py
│   │   ├── async_features.py
│   │   ├── callbacks_decorators.py
│   │   ├── circular1.py
│   │   ├── circular2.py
│   │   ├── class_instantiation.py
│   │   ├── cli_and_dunder.py
│   │   ├── complex_classes.py
│   │   ├── comprehensions_generators.py
│   │   ├── context_managers.py
│   │   ├── control_flow.py
│   │   ├── datatypes.py
│   │   ├── dynamic_dispatch.py
│   │   ├── dynamic_imports.py
│   │   ├── edge_cases
│   │   │   ├── comments_only.py
│   │   │   ├── docstring_only.py
│   │   │   ├── empty.py
│   │   │   ├── hardcoded_secrets.py
│   │   │   ├── long_functions.py
│   │   │   └── syntax_error.py
│   │   ├── function_chains.py
│   │   ├── generators.py
│   │   ├── import_reexports.py
│   │   ├── mapping_calls.py
│   │   ├── module_a.py
│   │   ├── module_b.py
│   │   ├── module_c
│   │   │   ├── __init__.py
│   │   │   ├── submodule1.py
│   │   │   └── submodule2.py
│   │   ├── namespace_pkg
│   │   │   └── ns_module.py
│   │   ├── pattern_matching.py
│   │   └── typing_examples.py
│   ├── sample_project_c
│   │   ├── cgc_sample
│   │   ├── include
│   │   │   ├── config.h
│   │   │   ├── math
│   │   │   │   └── vec.h
│   │   │   ├── module.h
│   │   │   ├── platform.h
│   │   │   └── util.h
│   │   ├── Makefile
│   │   ├── README.md
│   │   └── src
│   │       ├── main.c
│   │       ├── math
│   │       │   └── vec.c
│   │       ├── module.c
│   │       └── util.c
│   ├── sample_project_cpp
│   │   ├── class_features.cpp
│   │   ├── classes.cpp
│   │   ├── control_flow.cpp
│   │   ├── edge_cases.cpp
│   │   ├── enum_struct_union.cpp
│   │   ├── exceptions.cpp
│   │   ├── file_io.cpp
│   │   ├── function_chain.cpp
│   │   ├── function_chain.h
│   │   ├── function_types.cpp
│   │   ├── main.cpp
│   │   ├── main.exe
│   │   ├── namespaces.cpp
│   │   ├── raii_example.cpp
│   │   ├── README.md
│   │   ├── sample_project.exe
│   │   ├── stl_usage.cpp
│   │   ├── templates.cpp
│   │   └── types_variable_assignments.cpp
│   ├── sample_project_csharp
│   │   ├── README.md
│   │   └── src
│   │       └── Example.App
│   │           ├── Attributes
│   │           │   └── CustomAttributes.cs
│   │           ├── Example.App.csproj
│   │           ├── Models
│   │           │   ├── Person.cs
│   │           │   ├── Point.cs
│   │           │   ├── Role.cs
│   │           │   └── User.cs
│   │           ├── OuterClass.cs
│   │           ├── Program.cs
│   │           ├── Services
│   │           │   ├── GreetingService.cs
│   │           │   ├── IGreetingService.cs
│   │           │   └── LegacyService.cs
│   │           └── Utils
│   │               ├── CollectionHelper.cs
│   │               └── FileHelper.cs
│   ├── sample_project_go
│   │   ├── advanced_types.go
│   │   ├── basic_functions.go
│   │   ├── embedded_composition.go
│   │   ├── error_handling.go
│   │   ├── generics.go
│   │   ├── go.mod
│   │   ├── goroutines_channels.go
│   │   ├── interfaces.go
│   │   ├── packages_imports.go
│   │   ├── README.md
│   │   ├── structs_methods.go
│   │   └── util
│   │       └── helpers.go
│   ├── sample_project_java
│   │   ├── out
│   │   │   └── com
│   │   │       └── example
│   │   │           └── app
│   │   │               ├── annotations
│   │   │               │   └── Logged.class
│   │   │               ├── Main.class
│   │   │               ├── misc
│   │   │               │   ├── Outer.class
│   │   │               │   └── Outer$Inner.class
│   │   │               ├── model
│   │   │               │   ├── Role.class
│   │   │               │   └── User.class
│   │   │               ├── service
│   │   │               │   ├── AbstractGreeter.class
│   │   │               │   ├── GreetingService.class
│   │   │               │   └── impl
│   │   │               │       └── GreetingServiceImpl.class
│   │   │               └── util
│   │   │                   ├── CollectionUtils.class
│   │   │                   └── IOHelper.class
│   │   ├── README.md
│   │   ├── sources.txt
│   │   └── src
│   │       └── com
│   │           └── example
│   │               └── app
│   │                   ├── annotations
│   │                   │   └── Logged.java
│   │                   ├── Main.java
│   │                   ├── misc
│   │                   │   └── Outer.java
│   │                   ├── model
│   │                   │   ├── Role.java
│   │                   │   └── User.java
│   │                   ├── service
│   │                   │   ├── AbstractGreeter.java
│   │                   │   ├── GreetingService.java
│   │                   │   └── impl
│   │                   │       └── GreetingServiceImpl.java
│   │                   └── util
│   │                       ├── CollectionUtils.java
│   │                       └── IOHelper.java
│   ├── sample_project_javascript
│   │   ├── arrays.js
│   │   ├── asyncAwait.js
│   │   ├── classes.js
│   │   ├── dom.js
│   │   ├── errorHandling.js
│   │   ├── events.js
│   │   ├── exporter.js
│   │   ├── fetchAPI.js
│   │   ├── fixtures
│   │   │   └── js
│   │   │       └── accessors.js
│   │   ├── functions.js
│   │   ├── importer.js
│   │   ├── objects.js
│   │   ├── promises.js
│   │   ├── README.md
│   │   └── variables.js
│   ├── sample_project_kotlin
│   │   ├── AdvancedClasses.kt
│   │   ├── Annotations.kt
│   │   ├── Coroutines.kt
│   │   ├── EdgeCases.kt
│   │   ├── Functions.kt
│   │   ├── Main.kt
│   │   ├── Properties.kt
│   │   └── User.kt
│   ├── sample_project_misc
│   │   ├── index.html
│   │   ├── README.md
│   │   ├── styles.css
│   │   ├── tables.css
│   │   └── tables.html
│   ├── sample_project_php
│   │   ├── classes_objects.php
│   │   ├── database.php
│   │   ├── edgecases.php
│   │   ├── error_handling.php
│   │   ├── file_handling.php
│   │   ├── functions.php
│   │   ├── generators_iterators.php
│   │   ├── globals_superglobals.php
│   │   ├── Inheritance.php
│   │   ├── interface_traits.php
│   │   └── README.md
│   ├── sample_project_ruby
│   │   ├── class_example.rb
│   │   ├── enumerables.rb
│   │   ├── error_handling.rb
│   │   ├── file_io.rb
│   │   ├── inheritance_example.rb
│   │   ├── main.rb
│   │   ├── metaprogramming.rb
│   │   ├── mixins_example.rb
│   │   ├── module_example.rb
│   │   └── tests
│   │       ├── test_mixins.py
│   │       └── test_sample.rb
│   ├── sample_project_rust
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   └── src
│   │       ├── basic_functions.rs
│   │       ├── concurrency.rs
│   │       ├── error_handling.rs
│   │       ├── generics.rs
│   │       ├── iterators_closures.rs
│   │       ├── lib.rs
│   │       ├── lifetimes_references.rs
│   │       ├── modules.rs
│   │       ├── smart_pointers.rs
│   │       ├── structs_enums.rs
│   │       └── traits.rs
│   ├── sample_project_scala
│   │   ├── Animals.scala
│   │   ├── Complex.scala
│   │   ├── Functional.scala
│   │   ├── Geometry.scala
│   │   ├── Main.scala
│   │   ├── PackageObject.scala
│   │   ├── Script.sc
│   │   ├── Services.scala
│   │   ├── Shapes.scala
│   │   ├── Utils.scala
│   │   └── Variables.scala
│   ├── sample_project_swift
│   │   ├── Generics.swift
│   │   ├── Main.swift
│   │   ├── README.md
│   │   ├── Shapes.swift
│   │   ├── User.swift
│   │   └── Vehicles.swift
│   ├── sample_project_typescript
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── sample_tsx.tsx
│   │   ├── src
│   │   │   ├── advanced-types.ts
│   │   │   ├── async-promises.ts
│   │   │   ├── classes-inheritance.ts
│   │   │   ├── decorators-metadata.ts
│   │   │   ├── error-validation.ts
│   │   │   ├── functions-generics.ts
│   │   │   ├── index.ts
│   │   │   ├── modules-namespaces.ts
│   │   │   ├── types-interfaces.ts
│   │   │   └── utilities-helpers.ts
│   │   └── tsconfig.json
│   ├── test_cpp_parser.py
│   ├── test_database_validation.py
│   ├── test_end_to_end.py
│   ├── test_graph_indexing_js.py
│   ├── test_graph_indexing.py
│   ├── test_kotlin_parser.py
│   ├── test_swift_parser.py
│   ├── test_tree_sitter
│   │   ├── __init__.py
│   │   ├── class_instantiation.py
│   │   ├── complex_classes.py
│   │   └── test_file.py
│   ├── test_tree_sitter_manager.py
│   └── test_typescript_parser.py
├── visualize_graph.py
├── website
│   ├── .example.env
│   ├── .gitignore
│   ├── api
│   │   └── pypi.ts
│   ├── bun.lockb
│   ├── components.json
│   ├── eslint.config.js
│   ├── index.html
│   ├── package-lock.json
│   ├── package.json
│   ├── postcss.config.js
│   ├── public
│   │   ├── favicon.ico
│   │   ├── placeholder.svg
│   │   └── robots.txt
│   ├── README.md
│   ├── src
│   │   ├── App.css
│   │   ├── App.tsx
│   │   ├── assets
│   │   │   ├── function-calls.png
│   │   │   ├── graph-total.png
│   │   │   ├── hero-graph.jpg
│   │   │   └── hierarchy.png
│   │   ├── components
│   │   │   ├── ComparisonTable.tsx
│   │   │   ├── CookbookSection.tsx
│   │   │   ├── DemoSection.tsx
│   │   │   ├── ExamplesSection.tsx
│   │   │   ├── FeaturesSection.tsx
│   │   │   ├── Footer.tsx
│   │   │   ├── HeroSection.tsx
│   │   │   ├── InstallationSection.tsx
│   │   │   ├── MoveToTop.tsx
│   │   │   ├── ShowDownloads.tsx
│   │   │   ├── ShowStarGraph.tsx
│   │   │   ├── SocialMentionsTimeline.tsx
│   │   │   ├── TestimonialSection.tsx
│   │   │   ├── ThemeProvider.tsx
│   │   │   ├── ThemeToggle.tsx
│   │   │   └── ui
│   │   │       ├── accordion.tsx
│   │   │       ├── alert-dialog.tsx
│   │   │       ├── alert.tsx
│   │   │       ├── aspect-ratio.tsx
│   │   │       ├── avatar.tsx
│   │   │       ├── badge.tsx
│   │   │       ├── breadcrumb.tsx
│   │   │       ├── button.tsx
│   │   │       ├── calendar.tsx
│   │   │       ├── card.tsx
│   │   │       ├── carousel.tsx
│   │   │       ├── chart.tsx
│   │   │       ├── checkbox.tsx
│   │   │       ├── collapsible.tsx
│   │   │       ├── command.tsx
│   │   │       ├── context-menu.tsx
│   │   │       ├── dialog.tsx
│   │   │       ├── drawer.tsx
│   │   │       ├── dropdown-menu.tsx
│   │   │       ├── form.tsx
│   │   │       ├── hover-card.tsx
│   │   │       ├── input-otp.tsx
│   │   │       ├── input.tsx
│   │   │       ├── label.tsx
│   │   │       ├── menubar.tsx
│   │   │       ├── navigation-menu.tsx
│   │   │       ├── orbiting-circles.tsx
│   │   │       ├── pagination.tsx
│   │   │       ├── popover.tsx
│   │   │       ├── progress.tsx
│   │   │       ├── radio-group.tsx
│   │   │       ├── resizable.tsx
│   │   │       ├── scroll-area.tsx
│   │   │       ├── select.tsx
│   │   │       ├── separator.tsx
│   │   │       ├── sheet.tsx
│   │   │       ├── sidebar.tsx
│   │   │       ├── skeleton.tsx
│   │   │       ├── slider.tsx
│   │   │       ├── sonner.tsx
│   │   │       ├── switch.tsx
│   │   │       ├── table.tsx
│   │   │       ├── tabs.tsx
│   │   │       ├── textarea.tsx
│   │   │       ├── toast.tsx
│   │   │       ├── toaster.tsx
│   │   │       ├── toggle-group.tsx
│   │   │       ├── toggle.tsx
│   │   │       ├── tooltip.tsx
│   │   │       └── use-toast.ts
│   │   ├── hooks
│   │   │   ├── use-mobile.tsx
│   │   │   └── use-toast.ts
│   │   ├── index.css
│   │   ├── lib
│   │   │   └── utils.ts
│   │   ├── main.tsx
│   │   ├── pages
│   │   │   ├── Index.tsx
│   │   │   └── NotFound.tsx
│   │   └── vite-env.d.ts
│   ├── tailwind.config.ts
│   ├── tsconfig.app.json
│   ├── tsconfig.json
│   ├── tsconfig.node.json
│   ├── vercel.json
│   └── vite.config.ts
└── windows_setup_guide.md
```

# Files

--------------------------------------------------------------------------------
/src/codegraphcontext/tools/graph_builder.py:
--------------------------------------------------------------------------------

```python
  1 | 
  2 | # src/codegraphcontext/tools/graph_builder.py
  3 | import asyncio
  4 | import pathspec
  5 | from pathlib import Path
  6 | from typing import Any, Coroutine, Dict, Optional, Tuple
  7 | from datetime import datetime
  8 | 
  9 | from ..core.database import DatabaseManager
 10 | from ..core.jobs import JobManager, JobStatus
 11 | from ..utils.debug_log import debug_log, info_logger, error_logger, warning_logger
 12 | 
 13 | # New imports for tree-sitter (using tree-sitter-language-pack)
 14 | from tree_sitter import Language, Parser
 15 | from ..utils.tree_sitter_manager import get_tree_sitter_manager
 16 | from ..cli.config_manager import get_config_value
 17 | 
 18 | class TreeSitterParser:
 19 |     """A generic parser wrapper for a specific language using tree-sitter."""
 20 | 
 21 |     def __init__(self, language_name: str):
 22 |         self.language_name = language_name
 23 |         self.ts_manager = get_tree_sitter_manager()
 24 |         
 25 |         # Get the language (cached) and create a new parser for this instance
 26 |         self.language: Language = self.ts_manager.get_language_safe(language_name)
 27 |         # In tree-sitter 0.25+, Parser takes language in constructor
 28 |         self.parser = Parser(self.language)
 29 | 
 30 |         self.language_specific_parser = None
 31 |         if self.language_name == 'python':
 32 |             from .languages.python import PythonTreeSitterParser
 33 |             self.language_specific_parser = PythonTreeSitterParser(self)
 34 |         elif self.language_name == 'javascript':
 35 |             from .languages.javascript import JavascriptTreeSitterParser
 36 |             self.language_specific_parser = JavascriptTreeSitterParser(self)
 37 |         elif self.language_name == 'go':
 38 |             from .languages.go import GoTreeSitterParser
 39 |             self.language_specific_parser = GoTreeSitterParser(self)
 40 |         elif self.language_name == 'typescript':
 41 |             from .languages.typescript import TypescriptTreeSitterParser
 42 |             self.language_specific_parser = TypescriptTreeSitterParser(self)
 43 |         elif self.language_name == 'cpp':
 44 |             from .languages.cpp import CppTreeSitterParser
 45 |             self.language_specific_parser = CppTreeSitterParser(self)
 46 |         elif self.language_name == 'rust':
 47 |             from .languages.rust import RustTreeSitterParser
 48 |             self.language_specific_parser = RustTreeSitterParser(self)
 49 |         elif self.language_name == 'c':
 50 |             from .languages.c import CTreeSitterParser
 51 |             self.language_specific_parser = CTreeSitterParser(self)
 52 |         elif self.language_name == 'java':
 53 |             from .languages.java import JavaTreeSitterParser
 54 |             self.language_specific_parser = JavaTreeSitterParser(self)
 55 |         elif self.language_name == 'ruby':
 56 |             from .languages.ruby import RubyTreeSitterParser
 57 |             self.language_specific_parser = RubyTreeSitterParser(self)
 58 |         elif self.language_name == 'c_sharp':
 59 |             from .languages.csharp import CSharpTreeSitterParser
 60 |             self.language_specific_parser = CSharpTreeSitterParser(self)
 61 |         elif self.language_name == 'php':
 62 |             from .languages.php import PhpTreeSitterParser
 63 |             self.language_specific_parser = PhpTreeSitterParser(self)
 64 |         elif self.language_name == 'kotlin':
 65 |             from .languages.kotlin import KotlinTreeSitterParser
 66 |             self.language_specific_parser = KotlinTreeSitterParser(self)
 67 |         elif self.language_name == 'scala':
 68 |             from .languages.scala import ScalaTreeSitterParser
 69 |             self.language_specific_parser = ScalaTreeSitterParser(self)
 70 |         elif self.language_name == 'swift':
 71 |             from .languages.swift import SwiftTreeSitterParser
 72 |             self.language_specific_parser = SwiftTreeSitterParser(self)
 73 | 
 74 | 
 75 | 
 76 |     def parse(self, file_path: Path, is_dependency: bool = False, **kwargs) -> Dict:
 77 |         """Dispatches parsing to the language-specific parser."""
 78 |         if self.language_specific_parser:
 79 |             return self.language_specific_parser.parse(file_path, is_dependency, **kwargs)
 80 |         else:
 81 |             raise NotImplementedError(f"No language-specific parser implemented for {self.language_name}")
 82 | 
 83 | class GraphBuilder:
 84 |     """Module for building and managing the Neo4j code graph."""
 85 | 
 86 |     def __init__(self, db_manager: DatabaseManager, job_manager: JobManager, loop: asyncio.AbstractEventLoop):
 87 |         self.db_manager = db_manager
 88 |         self.job_manager = job_manager
 89 |         self.loop = loop
 90 |         self.driver = self.db_manager.get_driver()
 91 |         self.parsers = {
 92 |             '.py': TreeSitterParser('python'),
 93 |             '.ipynb': TreeSitterParser('python'),
 94 |             '.js': TreeSitterParser('javascript'),
 95 |             '.jsx': TreeSitterParser('javascript'),
 96 |             '.mjs': TreeSitterParser('javascript'),
 97 |             '.cjs': TreeSitterParser('javascript'),
 98 |             '.go': TreeSitterParser('go'),
 99 |             '.ts': TreeSitterParser('typescript'),
100 |             '.tsx': TreeSitterParser('typescript'),
101 |             '.cpp': TreeSitterParser('cpp'),
102 |             '.h': TreeSitterParser('cpp'),
103 |             '.hpp': TreeSitterParser('cpp'),
104 |             '.rs': TreeSitterParser('rust'),
105 |             '.c': TreeSitterParser('c'),
106 |             # '.h': TreeSitterParser('c'), # Need to write an algo for distinguishing C vs C++ headers
107 |             '.java': TreeSitterParser('java'),
108 |             '.rb': TreeSitterParser('ruby'),
109 |             '.java': TreeSitterParser('java'),
110 |             '.rb': TreeSitterParser('ruby'),
111 |             '.cs': TreeSitterParser('c_sharp'),
112 |             '.php': TreeSitterParser('php'),
113 |             '.kt': TreeSitterParser('kotlin'),
114 |             '.scala': TreeSitterParser('scala'),
115 |             '.sc': TreeSitterParser('scala'),
116 |             '.swift': TreeSitterParser('swift'),
117 |         }
118 |         self.create_schema()
119 | 
120 |     # A general schema creation based on common features across languages
121 |     def create_schema(self):
122 |         """Create constraints and indexes in Neo4j."""
123 |         # When adding a new node type with a unique key, add its constraint here.
124 |         with self.driver.session() as session:
125 |             try:
126 |                 session.run("CREATE CONSTRAINT repository_path IF NOT EXISTS FOR (r:Repository) REQUIRE r.path IS UNIQUE")
127 |                 session.run("CREATE CONSTRAINT file_path IF NOT EXISTS FOR (f:File) REQUIRE f.path IS UNIQUE")
128 |                 session.run("CREATE CONSTRAINT directory_path IF NOT EXISTS FOR (d:Directory) REQUIRE d.path IS UNIQUE")
129 |                 session.run("CREATE CONSTRAINT function_unique IF NOT EXISTS FOR (f:Function) REQUIRE (f.name, f.file_path, f.line_number) IS UNIQUE")
130 |                 session.run("CREATE CONSTRAINT class_unique IF NOT EXISTS FOR (c:Class) REQUIRE (c.name, c.file_path, c.line_number) IS UNIQUE")
131 |                 session.run("CREATE CONSTRAINT trait_unique IF NOT EXISTS FOR (t:Trait) REQUIRE (t.name, t.file_path, t.line_number) IS UNIQUE") # Added trait constraint
132 |                 session.run("CREATE CONSTRAINT interface_unique IF NOT EXISTS FOR (i:Interface) REQUIRE (i.name, i.file_path, i.line_number) IS UNIQUE")
133 |                 session.run("CREATE CONSTRAINT macro_unique IF NOT EXISTS FOR (m:Macro) REQUIRE (m.name, m.file_path, m.line_number) IS UNIQUE")
134 |                 session.run("CREATE CONSTRAINT variable_unique IF NOT EXISTS FOR (v:Variable) REQUIRE (v.name, v.file_path, v.line_number) IS UNIQUE")
135 |                 session.run("CREATE CONSTRAINT module_name IF NOT EXISTS FOR (m:Module) REQUIRE m.name IS UNIQUE")
136 |                 session.run("CREATE CONSTRAINT struct_cpp IF NOT EXISTS FOR (cstruct: Struct) REQUIRE (cstruct.name, cstruct.file_path, cstruct.line_number) IS UNIQUE")
137 |                 session.run("CREATE CONSTRAINT enum_cpp IF NOT EXISTS FOR (cenum: Enum) REQUIRE (cenum.name, cenum.file_path, cenum.line_number) IS UNIQUE")
138 |                 session.run("CREATE CONSTRAINT union_cpp IF NOT EXISTS FOR (cunion: Union) REQUIRE (cunion.name, cunion.file_path, cunion.line_number) IS UNIQUE")
139 |                 session.run("CREATE CONSTRAINT annotation_unique IF NOT EXISTS FOR (a:Annotation) REQUIRE (a.name, a.file_path, a.line_number) IS UNIQUE")
140 |                 session.run("CREATE CONSTRAINT record_unique IF NOT EXISTS FOR (r:Record) REQUIRE (r.name, r.file_path, r.line_number) IS UNIQUE")
141 |                 session.run("CREATE CONSTRAINT property_unique IF NOT EXISTS FOR (p:Property) REQUIRE (p.name, p.file_path, p.line_number) IS UNIQUE")
142 |                 
143 |                 # Indexes for language attribute
144 |                 session.run("CREATE INDEX function_lang IF NOT EXISTS FOR (f:Function) ON (f.lang)")
145 |                 session.run("CREATE INDEX class_lang IF NOT EXISTS FOR (c:Class) ON (c.lang)")
146 |                 session.run("CREATE INDEX annotation_lang IF NOT EXISTS FOR (a:Annotation) ON (a.lang)")
147 |                 session.run("""
148 |                     CREATE FULLTEXT INDEX code_search_index IF NOT EXISTS 
149 |                     FOR (n:Function|Class|Variable) 
150 |                     ON EACH [n.name, n.source, n.docstring]
151 |                 """ )
152 |                 
153 |                 info_logger("Database schema verified/created successfully")
154 |             except Exception as e:
155 |                 warning_logger(f"Schema creation warning: {e}")
156 | 
157 | 
158 |     def _pre_scan_for_imports(self, files: list[Path]) -> dict:
159 |         """Dispatches pre-scan to the correct language-specific implementation."""
160 |         imports_map = {}
161 |         
162 |         # Group files by language/extension
163 |         files_by_lang = {}
164 |         for file in files:
165 |             if file.suffix in self.parsers:
166 |                 lang_ext = file.suffix
167 |                 if lang_ext not in files_by_lang:
168 |                     files_by_lang[lang_ext] = []
169 |                 files_by_lang[lang_ext].append(file)
170 | 
171 |         if '.py' in files_by_lang:
172 |             from .languages import python as python_lang_module
173 |             imports_map.update(python_lang_module.pre_scan_python(files_by_lang['.py'], self.parsers['.py']))
174 |         if '.ipynb' in files_by_lang:
175 |             from .languages import python as python_lang_module
176 |             imports_map.update(python_lang_module.pre_scan_python(files_by_lang['.ipynb'], self.parsers['.ipynb']))
177 |         if '.js' in files_by_lang:
178 |             from .languages import javascript as js_lang_module
179 |             imports_map.update(js_lang_module.pre_scan_javascript(files_by_lang['.js'], self.parsers['.js']))
180 |         if '.jsx' in files_by_lang:
181 |             from .languages import javascript as js_lang_module
182 |             imports_map.update(js_lang_module.pre_scan_javascript(files_by_lang['.jsx'], self.parsers['.jsx']))
183 |         if '.mjs' in files_by_lang:
184 |             from .languages import javascript as js_lang_module
185 |             imports_map.update(js_lang_module.pre_scan_javascript(files_by_lang['.mjs'], self.parsers['.mjs']))
186 |         if '.cjs' in files_by_lang:
187 |             from .languages import javascript as js_lang_module
188 |             imports_map.update(js_lang_module.pre_scan_javascript(files_by_lang['.cjs'], self.parsers['.cjs']))
189 |         if '.go' in files_by_lang:
190 |              from .languages import go as go_lang_module
191 |              imports_map.update(go_lang_module.pre_scan_go(files_by_lang['.go'], self.parsers['.go']))
192 |         if '.ts' in files_by_lang:
193 |             from .languages import typescript as ts_lang_module
194 |             imports_map.update(ts_lang_module.pre_scan_typescript(files_by_lang['.ts'], self.parsers['.ts']))
195 |         if '.tsx' in files_by_lang:
196 |             from .languages import typescriptjsx as tsx_lang_module
197 |             imports_map.update(tsx_lang_module.pre_scan_typescript(files_by_lang['.tsx'], self.parsers['.tsx']))
198 |         if '.cpp' in files_by_lang:
199 |             from .languages import cpp as cpp_lang_module
200 |             imports_map.update(cpp_lang_module.pre_scan_cpp(files_by_lang['.cpp'], self.parsers['.cpp']))
201 |         if '.h' in files_by_lang:
202 |             from .languages import cpp as cpp_lang_module
203 |             imports_map.update(cpp_lang_module.pre_scan_cpp(files_by_lang['.h'], self.parsers['.h']))
204 |         if '.hpp' in files_by_lang:
205 |             from .languages import cpp as cpp_lang_module
206 |             imports_map.update(cpp_lang_module.pre_scan_cpp(files_by_lang['.hpp'], self.parsers['.hpp']))
207 |         if '.rs' in files_by_lang:
208 |             from .languages import rust as rust_lang_module
209 |             imports_map.update(rust_lang_module.pre_scan_rust(files_by_lang['.rs'], self.parsers['.rs']))
210 |         if '.c' in files_by_lang:
211 |             from .languages import c as c_lang_module
212 |             imports_map.update(c_lang_module.pre_scan_c(files_by_lang['.c'], self.parsers['.c']))
213 |         elif '.java' in files_by_lang:
214 |             from .languages import java as java_lang_module
215 |             imports_map.update(java_lang_module.pre_scan_java(files_by_lang['.java'], self.parsers['.java']))
216 |         elif '.rb' in files_by_lang:
217 |             from .languages import ruby as ruby_lang_module
218 |             imports_map.update(ruby_lang_module.pre_scan_ruby(files_by_lang['.rb'], self.parsers['.rb']))
219 |         elif '.cs' in files_by_lang:
220 |             from .languages import csharp as csharp_lang_module
221 |             imports_map.update(csharp_lang_module.pre_scan_csharp(files_by_lang['.cs'], self.parsers['.cs']))
222 |         if '.kt' in files_by_lang:
223 |             from .languages import kotlin as kotlin_lang_module
224 |             imports_map.update(kotlin_lang_module.pre_scan_kotlin(files_by_lang['.kt'], self.parsers['.kt']))
225 |         if '.scala' in files_by_lang:
226 |             from .languages import scala as scala_lang_module
227 |             imports_map.update(scala_lang_module.pre_scan_scala(files_by_lang['.scala'], self.parsers['.scala']))
228 |         if '.sc' in files_by_lang:
229 |             from .languages import scala as scala_lang_module
230 |             imports_map.update(scala_lang_module.pre_scan_scala(files_by_lang['.sc'], self.parsers['.sc']))
231 |         if '.swift' in files_by_lang:
232 |             from .languages import swift as swift_lang_module
233 |             imports_map.update(swift_lang_module.pre_scan_swift(files_by_lang['.swift'], self.parsers['.swift']))
234 |             
235 |         return imports_map
236 | 
237 |     # Language-agnostic method
238 |     def add_repository_to_graph(self, repo_path: Path, is_dependency: bool = False):
239 |         """Adds a repository node using its absolute path as the unique key."""
240 |         repo_name = repo_path.name
241 |         repo_path_str = str(repo_path.resolve())
242 |         with self.driver.session() as session:
243 |             session.run(
244 |                 """
245 |                 MERGE (r:Repository {path: $path})
246 |                 SET r.name = $name, r.is_dependency = $is_dependency
247 |                 """,
248 |                 path=repo_path_str,
249 |                 name=repo_name,
250 |                 is_dependency=is_dependency,
251 |             )
252 | 
253 |     # First pass to add file and its contents
254 |     def add_file_to_graph(self, file_data: Dict, repo_name: str, imports_map: dict):
255 |         info_logger("Executing add_file_to_graph with my change!")
256 |         """Adds a file and its contents within a single, unified session."""
257 |         file_path_str = str(Path(file_data['file_path']).resolve())
258 |         file_name = Path(file_path_str).name
259 |         is_dependency = file_data.get('is_dependency', False)
260 | 
261 |         with self.driver.session() as session:
262 |             try:
263 |                 # Match repository by path, not name, to avoid conflicts with same-named folders at different locations
264 |                 repo_result = session.run("MATCH (r:Repository {path: $repo_path}) RETURN r.path as path", repo_path=str(Path(file_data['repo_path']).resolve())).single()
265 |                 relative_path = str(Path(file_path_str).relative_to(Path(repo_result['path']))) if repo_result else file_name
266 |             except ValueError:
267 |                 relative_path = file_name
268 | 
269 |             session.run("""
270 |                 MERGE (f:File {path: $path})
271 |                 SET f.name = $name, f.relative_path = $relative_path, f.is_dependency = $is_dependency
272 |             """, path=file_path_str, name=file_name, relative_path=relative_path, is_dependency=is_dependency)
273 | 
274 |             file_path_obj = Path(file_path_str)
275 |             repo_path_obj = Path(repo_result['path'])
276 |             
277 |             relative_path_to_file = file_path_obj.relative_to(repo_path_obj)
278 |             
279 |             parent_path = str(repo_path_obj)
280 |             parent_label = 'Repository'
281 | 
282 |             for part in relative_path_to_file.parts[:-1]:
283 |                 current_path = Path(parent_path) / part
284 |                 current_path_str = str(current_path)
285 |                 
286 |                 session.run(f"""
287 |                     MATCH (p:{parent_label} {{path: $parent_path}})
288 |                     MERGE (d:Directory {{path: $current_path}})
289 |                     SET d.name = $part
290 |                     MERGE (p)-[:CONTAINS]->(d)
291 |                 """, parent_path=parent_path, current_path=current_path_str, part=part)
292 | 
293 |                 parent_path = current_path_str
294 |                 parent_label = 'Directory'
295 | 
296 |             session.run(f"""
297 |                 MATCH (p:{parent_label} {{path: $parent_path}})
298 |                 MATCH (f:File {{path: $file_path}})
299 |                 MERGE (p)-[:CONTAINS]->(f)
300 |             """, parent_path=parent_path, file_path=file_path_str)
301 | 
302 |             # CONTAINS relationships for functions, classes, and variables
303 |             # To add a new language-specific node type (e.g., 'Trait' for Rust):
304 |             # 1. Ensure your language-specific parser returns a list under a unique key (e.g., 'traits': [...] ).
305 |             # 2. Add a new constraint for the new label in the `create_schema` method.
306 |             # 3. Add a new entry to the `item_mappings` list below (e.g., (file_data.get('traits', []), 'Trait') ).
307 |             item_mappings = [
308 |                 (file_data.get('functions', []), 'Function'),
309 |                 (file_data.get('classes', []), 'Class'),
310 |                 (file_data.get('traits', []), 'Trait'), # <-- Added trait mapping
311 |                 (file_data.get('variables', []), 'Variable'),
312 |                 (file_data.get('interfaces', []), 'Interface'),
313 |                 (file_data.get('macros', []), 'Macro'),
314 |                 (file_data.get('structs',[]), 'Struct'),
315 |                 (file_data.get('enums',[]), 'Enum'),
316 |                 (file_data.get('unions',[]), 'Union'),
317 |                 (file_data.get('records',[]), 'Record'),
318 |                 (file_data.get('properties',[]), 'Property'),
319 |             ]
320 |             for item_data, label in item_mappings:
321 |                 for item in item_data:
322 |                     # Ensure cyclomatic_complexity is set for functions
323 |                     if label == 'Function' and 'cyclomatic_complexity' not in item:
324 |                         item['cyclomatic_complexity'] = 1 # Default value
325 | 
326 |                     query = f"""
327 |                         MATCH (f:File {{path: $file_path}})
328 |                         MERGE (n:{label} {{name: $name, file_path: $file_path, line_number: $line_number}})
329 |                         SET n += $props
330 |                         MERGE (f)-[:CONTAINS]->(n)
331 |                     """
332 |                     session.run(query, file_path=file_path_str, name=item['name'], line_number=item['line_number'], props=item)
333 |                     
334 |                     if label == 'Function':
335 |                         for arg_name in item.get('args', []):
336 |                             session.run("""
337 |                                 MATCH (fn:Function {name: $func_name, file_path: $file_path, line_number: $line_number})
338 |                                 MERGE (p:Parameter {name: $arg_name, file_path: $file_path, function_line_number: $line_number})
339 |                                 MERGE (fn)-[:HAS_PARAMETER]->(p)
340 |                             """, func_name=item['name'], file_path=file_path_str, line_number=item['line_number'], arg_name=arg_name)
341 | 
342 |             # --- NEW: persist Ruby Modules ---
343 |             for m in file_data.get('modules', []):
344 |                 session.run("""
345 |                     MERGE (mod:Module {name: $name})
346 |                     ON CREATE SET mod.lang = $lang
347 |                     ON MATCH  SET mod.lang = coalesce(mod.lang, $lang)
348 |                 """, name=m["name"], lang=file_data.get("lang"))
349 | 
350 |             # Create CONTAINS relationships for nested functions
351 |             for item in file_data.get('functions', []):
352 |                 if item.get("context_type") == "function_definition":
353 |                     session.run("""
354 |                         MATCH (outer:Function {name: $context, file_path: $file_path})
355 |                         MATCH (inner:Function {name: $name, file_path: $file_path, line_number: $line_number})
356 |                         MERGE (outer)-[:CONTAINS]->(inner)
357 |                     """, context=item["context"], file_path=file_path_str, name=item["name"], line_number=item["line_number"])
358 | 
359 |             # Handle imports and create IMPORTS relationships
360 |             for imp in file_data.get('imports', []):
361 |                 info_logger(f"Processing import: {imp}")
362 |                 lang = file_data.get('lang')
363 |                 if lang == 'javascript':
364 |                     # New, correct logic for JS
365 |                     module_name = imp.get('source')
366 |                     if not module_name: continue
367 | 
368 |                     # Use a map for relationship properties to handle optional alias and line_number
369 |                     rel_props = {'imported_name': imp.get('name', '*')}
370 |                     if imp.get('alias'):
371 |                         rel_props['alias'] = imp.get('alias')
372 |                     if imp.get('line_number'):
373 |                         rel_props['line_number'] = imp.get('line_number')
374 | 
375 |                     session.run("""
376 |                         MATCH (f:File {path: $file_path})
377 |                         MERGE (m:Module {name: $module_name})
378 |                         MERGE (f)-[r:IMPORTS]->(m)
379 |                         SET r += $props
380 |                     """, file_path=file_path_str, module_name=module_name, props=rel_props)
381 |                 else:
382 |                     # Existing logic for Python (and other languages)
383 |                     set_clauses = ["m.alias = $alias"]
384 |                     if 'full_import_name' in imp:
385 |                         set_clauses.append("m.full_import_name = $full_import_name")
386 |                     set_clause_str = ", ".join(set_clauses)
387 | 
388 |                     # Build relationship properties
389 |                     rel_props = {}
390 |                     if imp.get('line_number'):
391 |                         rel_props['line_number'] = imp.get('line_number')
392 |                     if imp.get('alias'):
393 |                         rel_props['alias'] = imp.get('alias')
394 | 
395 |                     session.run(f"""
396 |                         MATCH (f:File {{path: $file_path}})
397 |                         MERGE (m:Module {{name: $name}})
398 |                         SET {set_clause_str}
399 |                         MERGE (f)-[r:IMPORTS]->(m)
400 |                         SET r += $rel_props
401 |                     """, file_path=file_path_str, rel_props=rel_props, **imp)
402 | 
403 | 
404 |             # Handle CONTAINS relationship between class to their children like variables
405 |             for func in file_data.get('functions', []):
406 |                 if func.get('class_context'):
407 |                     session.run("""
408 |                         MATCH (c:Class {name: $class_name, file_path: $file_path})
409 |                         MATCH (fn:Function {name: $func_name, file_path: $file_path, line_number: $func_line})
410 |                         MERGE (c)-[:CONTAINS]->(fn)
411 |                     """, 
412 |                     class_name=func['class_context'],
413 |                     file_path=file_path_str,
414 |                     func_name=func['name'],
415 |                     func_line=func['line_number'])
416 | 
417 |             # --- NEW: Class INCLUDES Module (Ruby mixins) ---
418 |             for inc in file_data.get('module_inclusions', []):
419 |                 session.run("""
420 |                     MATCH (c:Class {name: $class_name, file_path: $file_path})
421 |                     MERGE (m:Module {name: $module_name})
422 |                     MERGE (c)-[:INCLUDES]->(m)
423 |                 """,
424 |                 class_name=inc["class"],
425 |                 file_path=file_path_str,
426 |                 module_name=inc["module"])
427 | 
428 |             # Class inheritance is handled in a separate pass after all files are processed.
429 |             # Function calls are also handled in a separate pass after all files are processed.
430 | 
431 |     # Second pass to create relationships that depend on all files being present like call functions and class inheritance
432 |     def _create_function_calls(self, session, file_data: Dict, imports_map: dict):
433 |         """Create CALLS relationships with a unified, prioritized logic flow for all call types."""
434 |         caller_file_path = str(Path(file_data['file_path']).resolve())
435 |         local_names = {f['name'] for f in file_data.get('functions', [])} | \
436 |                       {c['name'] for c in file_data.get('classes', [])}
437 |         local_imports = {imp.get('alias') or imp['name'].split('.')[-1]: imp['name'] 
438 |                         for imp in file_data.get('imports', [])}
439 |         
440 |         for call in file_data.get('function_calls', []):
441 |             called_name = call['name']
442 |             if called_name in __builtins__: continue
443 | 
444 |             resolved_path = None
445 |             full_call = call.get('full_name', called_name)
446 |             base_obj = full_call.split('.')[0] if '.' in full_call else None
447 |             
448 |             # For chained calls like self.graph_builder.method(), we need to look up 'method'
449 |             # For direct calls like self.method(), we can use the caller's file
450 |             is_chained_call = full_call.count('.') > 1 if '.' in full_call else False
451 |             
452 |             # Determine the lookup name:
453 |             # - For chained calls (self.attr.method), use the actual method name
454 |             # - For direct calls (self.method or module.function), use the base object
455 |             if is_chained_call and base_obj in ('self', 'this', 'super', 'super()', 'cls', '@'):
456 |                 lookup_name = called_name  # Use the actual method name for lookup
457 |             else:
458 |                 lookup_name = base_obj if base_obj else called_name
459 | 
460 |             # 1. Check for local context keywords/direct local names
461 |             # Only resolve to caller_file_path for DIRECT self/this calls, not chained ones
462 |             if base_obj in ('self', 'this', 'super', 'super()', 'cls', '@') and not is_chained_call:
463 |                 resolved_path = caller_file_path
464 |             elif lookup_name in local_names:
465 |                 resolved_path = caller_file_path
466 |             
467 |             # 2. Check inferred type if available
468 |             elif call.get('inferred_obj_type'):
469 |                 obj_type = call['inferred_obj_type']
470 |                 possible_paths = imports_map.get(obj_type, [])
471 |                 if len(possible_paths) > 0:
472 |                     resolved_path = possible_paths[0]
473 |             
474 |             # 3. Check imports map with validation against local imports
475 |             if not resolved_path:
476 |                 possible_paths = imports_map.get(lookup_name, [])
477 |                 if len(possible_paths) == 1:
478 |                     resolved_path = possible_paths[0]
479 |                 elif len(possible_paths) > 1:
480 |                     if lookup_name in local_imports:
481 |                         full_import_name = local_imports[lookup_name]
482 |                         
483 |                         # Optimization: Check if the FQN is directly in imports_map (from pre-scan)
484 |                         if full_import_name in imports_map:
485 |                              direct_paths = imports_map[full_import_name]
486 |                              if direct_paths and len(direct_paths) == 1:
487 |                                  resolved_path = direct_paths[0]
488 |                         
489 |                         if not resolved_path:
490 |                             for path in possible_paths:
491 |                                 if full_import_name.replace('.', '/') in path:
492 |                                     resolved_path = path
493 |                                     break
494 |             
495 |             if not resolved_path:
496 |                  warning_logger(f"Could not resolve call {called_name} (lookup: {lookup_name}) in {caller_file_path}")
497 |             # else:
498 |             #      info_logger(f"Resolved call {called_name} -> {resolved_path}")
499 |             
500 |             # Legacy fallback block (was mis-indented)
501 |             if not resolved_path:
502 |                 possible_paths = imports_map.get(lookup_name, [])
503 |                 if len(possible_paths) > 0:
504 |                      # Final fallback: global candidate
505 |                      # Check if it was imported explicitly, otherwise risky
506 |                      if lookup_name in local_imports:
507 |                          # We already tried specific matching above, but if we are here
508 |                          # it means we had ambiguity without matching path?
509 |                          pass
510 |                      else:
511 |                         # Fallback to first available if not imported? Or skip?
512 |                         # Original logic: resolved_path = possible_paths[0]
513 |                         # But wait, original code logic was:
514 |                         pass
515 |             if not resolved_path:
516 |                 if called_name in local_names:
517 |                     resolved_path = caller_file_path
518 |                 elif called_name in imports_map and imports_map[called_name]:
519 |                     # Check if any path in imports_map for called_name matches current file's imports
520 |                     candidates = imports_map[called_name]
521 |                     for path in candidates:
522 |                         for imp_name in local_imports.values():
523 |                             if imp_name.replace('.', '/') in path:
524 |                                 resolved_path = path
525 |                                 break
526 |                         if resolved_path: break
527 |                     if not resolved_path:
528 |                         resolved_path = candidates[0]
529 |                 else:
530 |                     resolved_path = caller_file_path
531 | 
532 |             caller_context = call.get('context')
533 |             if caller_context and len(caller_context) == 3 and caller_context[0] is not None:
534 |                 caller_name, _, caller_line_number = caller_context
535 |                 # if called_name == "sumOfSquares":
536 |                     # print(f"DEBUG_CYPHER: caller={caller_name}, caller_line={caller_line_number}, called={called_name}, path={resolved_path}")
537 | 
538 |                 session.run("""
539 |                     MATCH (caller) WHERE (caller:Function OR caller:Class) 
540 |                       AND caller.name = $caller_name 
541 |                       AND caller.file_path = $caller_file_path 
542 |                       AND caller.line_number = $caller_line_number
543 |                     MATCH (called) WHERE (called:Function OR called:Class)
544 |                       AND called.name = $called_name 
545 |                       AND called.file_path = $called_file_path
546 |                     
547 |                     WITH caller, called
548 |                     OPTIONAL MATCH (called)-[:CONTAINS]->(init:Function)
549 |                     WHERE called:Class AND init.name IN ["__init__", "constructor"]
550 |                     WITH caller, COALESCE(init, called) as final_target
551 |                     
552 |                     MERGE (caller)-[:CALLS {line_number: $line_number, args: $args, full_call_name: $full_call_name}]->(final_target)
553 |                 """,
554 |                 caller_name=caller_name,
555 |                 caller_file_path=caller_file_path,
556 |                 caller_line_number=caller_line_number,
557 |                 called_name=called_name,
558 |                 called_file_path=resolved_path,
559 |                 line_number=call['line_number'],
560 |                 args=call.get('args', []),
561 |                 full_call_name=call.get('full_name', called_name))
562 |             else:
563 |                 session.run("""
564 |                     MATCH (caller:File {path: $caller_file_path})
565 |                     MATCH (called) WHERE (called:Function OR called:Class)
566 |                       AND called.name = $called_name 
567 |                       AND called.file_path = $called_file_path
568 |                     
569 |                     WITH caller, called
570 |                     OPTIONAL MATCH (called)-[:CONTAINS]->(init:Function)
571 |                     WHERE called:Class AND init.name IN ["__init__", "constructor"]
572 |                     WITH caller, COALESCE(init, called) as final_target
573 | 
574 |                     MERGE (caller)-[:CALLS {line_number: $line_number, args: $args, full_call_name: $full_call_name}]->(final_target)
575 |                 """,
576 |                 caller_file_path=caller_file_path,
577 |                 called_name=called_name,
578 |                 called_file_path=resolved_path,
579 |                 line_number=call['line_number'],
580 |                 args=call.get('args', []),
581 |                 full_call_name=call.get('full_name', called_name))
582 | 
583 |     def _create_all_function_calls(self, all_file_data: list[Dict], imports_map: dict):
584 |         """Create CALLS relationships for all functions after all files have been processed."""
585 |         with self.driver.session() as session:
586 |             for file_data in all_file_data:
587 |                 self._create_function_calls(session, file_data, imports_map)
588 | 
589 |     def _create_inheritance_links(self, session, file_data: Dict, imports_map: dict):
590 |         """Create INHERITS relationships with a more robust resolution logic."""
591 |         caller_file_path = str(Path(file_data['file_path']).resolve())
592 |         local_class_names = {c['name'] for c in file_data.get('classes', [])}
593 |         # Create a map of local import aliases/names to full import names
594 |         local_imports = {imp.get('alias') or imp['name'].split('.')[-1]: imp['name']
595 |                          for imp in file_data.get('imports', [])}
596 | 
597 |         for class_item in file_data.get('classes', []):
598 |             if not class_item.get('bases'):
599 |                 continue
600 | 
601 |             for base_class_str in class_item['bases']:
602 |                 if base_class_str == 'object':
603 |                     continue
604 | 
605 |                 resolved_path = None
606 |                 target_class_name = base_class_str.split('.')[-1]
607 | 
608 |                 # Handle qualified names like module.Class or alias.Class
609 |                 if '.' in base_class_str:
610 |                     lookup_name = base_class_str.split('.')[0]
611 |                     
612 |                     # Case 1: The prefix is a known import
613 |                     if lookup_name in local_imports:
614 |                         full_import_name = local_imports[lookup_name]
615 |                         possible_paths = imports_map.get(target_class_name, [])
616 |                         # Find the path that corresponds to the imported module
617 |                         for path in possible_paths:
618 |                             if full_import_name.replace('.', '/') in path:
619 |                                 resolved_path = path
620 |                                 break
621 |                 # Handle simple names
622 |                 else:
623 |                     lookup_name = base_class_str
624 |                     # Case 2: The base class is in the same file
625 |                     if lookup_name in local_class_names:
626 |                         resolved_path = caller_file_path
627 |                     # Case 3: The base class was imported directly (e.g., from module import Parent)
628 |                     elif lookup_name in local_imports:
629 |                         full_import_name = local_imports[lookup_name]
630 |                         possible_paths = imports_map.get(target_class_name, [])
631 |                         for path in possible_paths:
632 |                             if full_import_name.replace('.', '/') in path:
633 |                                 resolved_path = path
634 |                                 break
635 |                     # Case 4: Fallback to global map (less reliable)
636 |                     elif lookup_name in imports_map:
637 |                         possible_paths = imports_map[lookup_name]
638 |                         if len(possible_paths) == 1:
639 |                             resolved_path = possible_paths[0]
640 |                 
641 |                 # If a path was found, create the relationship
642 |                 if resolved_path:
643 |                     session.run("""
644 |                         MATCH (child:Class {name: $child_name, file_path: $file_path})
645 |                         MATCH (parent:Class {name: $parent_name, file_path: $resolved_parent_file_path})
646 |                         MERGE (child)-[:INHERITS]->(parent)
647 |                     """,
648 |                     child_name=class_item['name'],
649 |                     file_path=caller_file_path,
650 |                     parent_name=target_class_name,
651 |                     resolved_parent_file_path=resolved_path)
652 | 
653 | 
654 |     def _create_csharp_inheritance_and_interfaces(self, session, file_data: Dict, imports_map: dict):
655 |         """Create INHERITS and IMPLEMENTS relationships for C# types."""
656 |         if file_data.get('lang') != 'c_sharp':
657 |             return
658 |             
659 |         caller_file_path = str(Path(file_data['file_path']).resolve())
660 |         
661 |         # Collect all local type names
662 |         local_type_names = set()
663 |         for type_list in ['classes', 'interfaces', 'structs', 'records']:
664 |             local_type_names.update(t['name'] for t in file_data.get(type_list, []))
665 |         
666 |         # Process all type declarations that can have bases
667 |         for type_list_name, type_label in [('classes', 'Class'), ('structs', 'Struct'), ('records', 'Record'), ('interfaces', 'Interface')]:
668 |             for type_item in file_data.get(type_list_name, []):
669 |                 if not type_item.get('bases'):
670 |                     continue
671 |                 
672 |                 for base_str in type_item['bases']:
673 |                     # Clean up the base name (remove generic parameters, etc.)
674 |                     base_name = base_str.split('<')[0].strip()
675 |                     
676 |                     # Determine if this is an interface
677 |                     is_interface = False
678 |                     resolved_path = caller_file_path
679 |                     
680 |                     # Check if base is a local interface
681 |                     for iface in file_data.get('interfaces', []):
682 |                         if iface['name'] == base_name:
683 |                             is_interface = True
684 |                             break
685 |                     
686 |                     # Check if base is in imports_map
687 |                     if base_name in imports_map:
688 |                         possible_paths = imports_map[base_name]
689 |                         if len(possible_paths) > 0:
690 |                             resolved_path = possible_paths[0]
691 |                     
692 |                     # For C#, first base is usually the class (if any), rest are interfaces
693 |                     base_index = type_item['bases'].index(base_str)
694 |                     
695 |                     # Try to determine if it's an interface
696 |                     if is_interface or (base_index > 0 and type_label == 'Class'):
697 |                         # This is an IMPLEMENTS relationship
698 |                         session.run("""
699 |                             MATCH (child {name: $child_name, file_path: $file_path})
700 |                             WHERE child:Class OR child:Struct OR child:Record
701 |                             MATCH (iface:Interface {name: $interface_name})
702 |                             MERGE (child)-[:IMPLEMENTS]->(iface)
703 |                         """,
704 |                         child_name=type_item['name'],
705 |                         file_path=caller_file_path,
706 |                         interface_name=base_name)
707 |                     else:
708 |                         # This is an INHERITS relationship
709 |                         session.run("""
710 |                             MATCH (child {name: $child_name, file_path: $file_path})
711 |                             WHERE child:Class OR child:Record OR child:Interface
712 |                             MATCH (parent {name: $parent_name})
713 |                             WHERE parent:Class OR parent:Record OR parent:Interface
714 |                             MERGE (child)-[:INHERITS]->(parent)
715 |                         """,
716 |                         child_name=type_item['name'],
717 |                         file_path=caller_file_path,
718 |                         parent_name=base_name)
719 | 
720 |     def _create_all_inheritance_links(self, all_file_data: list[Dict], imports_map: dict):
721 |         """Create INHERITS relationships for all classes after all files have been processed."""
722 |         with self.driver.session() as session:
723 |             for file_data in all_file_data:
724 |                 # Handle C# separately
725 |                 if file_data.get('lang') == 'c_sharp':
726 |                     self._create_csharp_inheritance_and_interfaces(session, file_data, imports_map)
727 |                 else:
728 |                     self._create_inheritance_links(session, file_data, imports_map)
729 |                 
730 |     def delete_file_from_graph(self, file_path: str):
731 |         """Deletes a file and all its contained elements and relationships."""
732 |         file_path_str = str(Path(file_path).resolve())
733 |         with self.driver.session() as session:
734 |             parents_res = session.run("""
735 |                 MATCH (f:File {path: $path})<-[:CONTAINS*]-(d:Directory)
736 |                 RETURN d.path as path ORDER BY d.path DESC
737 |             """, path=file_path_str)
738 |             parent_paths = [record["path"] for record in parents_res]
739 | 
740 |             session.run(
741 |                 """
742 |                 MATCH (f:File {path: $path})
743 |                 OPTIONAL MATCH (f)-[:CONTAINS]->(element)
744 |                 DETACH DELETE f, element
745 |                 """,
746 |                 path=file_path_str,
747 |             )
748 |             info_logger(f"Deleted file and its elements from graph: {file_path_str}")
749 | 
750 |             for path in parent_paths:
751 |                 session.run("""
752 |                     MATCH (d:Directory {path: $path})
753 |                     WHERE NOT (d)-[:CONTAINS]->()
754 |                     DETACH DELETE d
755 |                 """, path=path)
756 | 
757 |     def delete_repository_from_graph(self, repo_path: str) -> bool:
758 |         """Deletes a repository and all its contents from the graph. Returns True if deleted, False if not found."""
759 |         repo_path_str = str(Path(repo_path).resolve())
760 |         with self.driver.session() as session:
761 |             # Check if it exists
762 |             result = session.run("MATCH (r:Repository {path: $path}) RETURN count(r) as cnt", path=repo_path_str).single()
763 |             if not result or result["cnt"] == 0:
764 |                 warning_logger(f"Attempted to delete non-existent repository: {repo_path_str}")
765 |                 return False
766 | 
767 |             session.run("""MATCH (r:Repository {path: $path})
768 |                           OPTIONAL MATCH (r)-[:CONTAINS*]->(e)
769 |                           DETACH DELETE r, e""", path=repo_path_str)
770 |             info_logger(f"Deleted repository and its contents from graph: {repo_path_str}")
771 |             return True
772 | 
773 |     def update_file_in_graph(self, file_path: Path, repo_path: Path, imports_map: dict):
774 |         """Updates a single file's nodes in the graph."""
775 |         file_path_str = str(file_path.resolve())
776 |         repo_name = repo_path.name
777 |         
778 |         self.delete_file_from_graph(file_path_str)
779 | 
780 |         if file_path.exists():
781 |             file_data = self.parse_file(repo_path, file_path)
782 |             
783 |             if "error" not in file_data:
784 |                 self.add_file_to_graph(file_data, repo_name, imports_map)
785 |                 return file_data
786 |             else:
787 |                 error_logger(f"Skipping graph add for {file_path_str} due to parsing error: {file_data['error']}")
788 |                 return None
789 |         else:
790 |             return {"deleted": True, "path": file_path_str}
791 | 
792 |     def parse_file(self, repo_path: Path, file_path: Path, is_dependency: bool = False) -> Dict:
793 |         """Parses a file with the appropriate language parser and extracts code elements."""
794 |         parser = self.parsers.get(file_path.suffix)
795 |         if not parser:
796 |             warning_logger(f"No parser found for file extension {file_path.suffix}. Skipping {file_path}")
797 |             return {"file_path": str(file_path), "error": f"No parser for {file_path.suffix}"}
798 | 
799 |         debug_log(f"[parse_file] Starting parsing for: {file_path} with {parser.language_name} parser")
800 |         try:
801 |             if parser.language_name == 'python':
802 |                 is_notebook = file_path.suffix == '.ipynb'
803 |                 file_data = parser.parse(file_path, is_dependency, is_notebook=is_notebook)
804 |             else:
805 |                 file_data = parser.parse(file_path, is_dependency)
806 |             file_data['repo_path'] = str(repo_path)
807 |             debug_log(f"[parse_file] Successfully parsed: {file_path}")
808 |             return file_data
809 |             
810 |         except Exception as e:
811 |             error_logger(f"Error parsing {file_path} with {parser.language_name} parser: {e}")
812 |             debug_log(f"[parse_file] Error parsing {file_path}: {e}")
813 |             return {"file_path": str(file_path), "error": str(e)}
814 | 
815 |     def estimate_processing_time(self, path: Path) -> Optional[Tuple[int, float]]:
816 |         """Estimate processing time and file count"""
817 |         try:
818 |             supported_extensions = self.parsers.keys()
819 |             if path.is_file():
820 |                 if path.suffix in supported_extensions:
821 |                     files = [path]
822 |                 else:
823 |                     return 0, 0.0 # Not a supported file type
824 |             else:
825 |                 all_files = path.rglob("*")
826 |                 files = [f for f in all_files if f.is_file() and f.suffix in supported_extensions]
827 | 
828 |                 # Filter default ignored directories
829 |                 ignore_dirs_str = get_config_value("IGNORE_DIRS") or ""
830 |                 if ignore_dirs_str:
831 |                     ignore_dirs = {d.strip().lower() for d in ignore_dirs_str.split(',') if d.strip()}
832 |                     if ignore_dirs:
833 |                         kept_files = []
834 |                         for f in files:
835 |                             try:
836 |                                 parts = set(p.lower() for p in f.relative_to(path).parent.parts)
837 |                                 if not parts.intersection(ignore_dirs):
838 |                                     kept_files.append(f)
839 |                             except ValueError:
840 |                                 kept_files.append(f)
841 |                         files = kept_files
842 |             
843 |             total_files = len(files)
844 |             estimated_time = total_files * 0.05 # tree-sitter is faster
845 |             return total_files, estimated_time
846 |         except Exception as e:
847 |             error_logger(f"Could not estimate processing time for {path}: {e}")
848 |             return None
849 | 
850 |     async def build_graph_from_path_async(
851 |         self, path: Path, is_dependency: bool = False, job_id: str = None
852 |     ):
853 |         """Builds graph from a directory or file path."""
854 |         try:
855 |             if job_id:
856 |                 self.job_manager.update_job(job_id, status=JobStatus.RUNNING)
857 |             
858 |             self.add_repository_to_graph(path, is_dependency)
859 |             repo_name = path.name
860 | 
861 |             # Search for .cgcignore upwards
862 |             cgcignore_path = None
863 |             ignore_root = path.resolve()
864 |             
865 |             # Start search from path (or parent if path is file)
866 |             curr = path.resolve()
867 |             if not curr.is_dir():
868 |                 curr = curr.parent
869 | 
870 |             # Walk up looking for .cgcignore
871 |             while True:
872 |                 candidate = curr / ".cgcignore"
873 |                 if candidate.exists():
874 |                     cgcignore_path = candidate
875 |                     ignore_root = curr
876 |                     debug_log(f"Found .cgcignore at {ignore_root}")
877 |                     break
878 |                 if curr.parent == curr: # Root hit
879 |                     break
880 |                 curr = curr.parent
881 | 
882 |             if cgcignore_path:
883 |                 with open(cgcignore_path) as f:
884 |                     ignore_patterns = f.read().splitlines()
885 |                 spec = pathspec.PathSpec.from_lines('gitwildmatch', ignore_patterns)
886 |             else:
887 |                 spec = None
888 | 
889 |             supported_extensions = self.parsers.keys()
890 |             all_files = path.rglob("*") if path.is_dir() else [path]
891 |             files = [f for f in all_files if f.is_file() and f.suffix in supported_extensions]
892 | 
893 |             # Filter default ignored directories
894 |             ignore_dirs_str = get_config_value("IGNORE_DIRS") or ""
895 |             if ignore_dirs_str and path.is_dir():
896 |                 ignore_dirs = {d.strip().lower() for d in ignore_dirs_str.split(',') if d.strip()}
897 |                 if ignore_dirs:
898 |                     kept_files = []
899 |                     for f in files:
900 |                         try:
901 |                             # Check if any parent directory in the relative path is in ignore list
902 |                             parts = set(p.lower() for p in f.relative_to(path).parent.parts)
903 |                             if not parts.intersection(ignore_dirs):
904 |                                 kept_files.append(f)
905 |                             else:
906 |                                 # debug_log(f"Skipping default ignored file: {f}")
907 |                                 pass
908 |                         except ValueError:
909 |                              kept_files.append(f)
910 |                     files = kept_files
911 |             
912 |             if spec:
913 |                 filtered_files = []
914 |                 for f in files:
915 |                     try:
916 |                         # Match relative to the directory containing .cgcignore
917 |                         rel_path = f.relative_to(ignore_root)
918 |                         if not spec.match_file(str(rel_path)):
919 |                             filtered_files.append(f)
920 |                         else:
921 |                             debug_log(f"Ignored file based on .cgcignore: {rel_path}")
922 |                     except ValueError:
923 |                         # Should not happen if ignore_root is a parent, but safety fallback
924 |                         filtered_files.append(f)
925 |                 files = filtered_files
926 |             if job_id:
927 |                 self.job_manager.update_job(job_id, total_files=len(files))
928 |             
929 |             debug_log("Starting pre-scan to build imports map...")
930 |             imports_map = self._pre_scan_for_imports(files)
931 |             debug_log(f"Pre-scan complete. Found {len(imports_map)} definitions.")
932 | 
933 |             all_file_data = []
934 | 
935 |             processed_count = 0
936 |             for file in files:
937 |                 if file.is_file():
938 |                     if job_id:
939 |                         self.job_manager.update_job(job_id, current_file=str(file))
940 |                     repo_path = path.resolve() if path.is_dir() else file.parent.resolve()
941 |                     file_data = self.parse_file(repo_path, file, is_dependency)
942 |                     if "error" not in file_data:
943 |                         self.add_file_to_graph(file_data, repo_name, imports_map)
944 |                         all_file_data.append(file_data)
945 |                     processed_count += 1
946 |                     if job_id:
947 |                         self.job_manager.update_job(job_id, processed_files=processed_count)
948 |                     await asyncio.sleep(0.01)
949 | 
950 |             self._create_all_inheritance_links(all_file_data, imports_map)
951 |             self._create_all_function_calls(all_file_data, imports_map)
952 |             
953 |             if job_id:
954 |                 self.job_manager.update_job(job_id, status=JobStatus.COMPLETED, end_time=datetime.now())
955 |         except Exception as e:
956 |             error_message=str(e)
957 |             error_logger(f"Failed to build graph for path {path}: {error_message}")
958 |             if job_id:
959 |                 '''checking if the repo got deleted '''
960 |                 if "no such file found" in error_message or "deleted" in error_message or "not found" in error_message:
961 |                     status=JobStatus.CANCELLED
962 |                     
963 |                 else:
964 |                     status=JobStatus.FAILED
965 | 
966 |                 self.job_manager.update_job(
967 |                     job_id, status=status, end_time=datetime.now(), errors=[str(e)]
968 |                 )
969 | 
```

--------------------------------------------------------------------------------
/docs/site/cookbook/index.html:
--------------------------------------------------------------------------------

```html
   1 | 
   2 | <!doctype html>
   3 | <html lang="en" class="no-js">
   4 |   <head>
   5 |     
   6 |       <meta charset="utf-8">
   7 |       <meta name="viewport" content="width=device-width,initial-scale=1">
   8 |       
   9 |       
  10 |       
  11 |       
  12 |         <link rel="prev" href="../tools/">
  13 |       
  14 |       
  15 |         <link rel="next" href="../contributing/">
  16 |       
  17 |       
  18 |         
  19 |       
  20 |       
  21 |       <link rel="icon" href="../assets/images/favicon.png">
  22 |       <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.1">
  23 |     
  24 |     
  25 |       
  26 |         <title>Cookbook - CodeGraphContext</title>
  27 |       
  28 |     
  29 |     
  30 |       <link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
  31 |       
  32 |       
  33 | 
  34 | 
  35 |     
  36 |     
  37 |       
  38 |     
  39 |     
  40 |       
  41 |         
  42 |         
  43 |         <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  44 |         <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
  45 |         <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
  46 |       
  47 |     
  48 |     
  49 |     <script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
  50 |     
  51 |       
  52 | 
  53 |     
  54 |     
  55 |   </head>
  56 |   
  57 |   
  58 |     <body dir="ltr">
  59 |   
  60 |     
  61 |     <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
  62 |     <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
  63 |     <label class="md-overlay" for="__drawer"></label>
  64 |     <div data-md-component="skip">
  65 |       
  66 |         
  67 |         <a href="#mcp-tool-cookbook" class="md-skip">
  68 |           Skip to content
  69 |         </a>
  70 |       
  71 |     </div>
  72 |     <div data-md-component="announce">
  73 |       
  74 |     </div>
  75 |     
  76 |     
  77 |       
  78 | 
  79 |   
  80 | 
  81 | <header class="md-header md-header--shadow" data-md-component="header">
  82 |   <nav class="md-header__inner md-grid" aria-label="Header">
  83 |     <a href=".." title="CodeGraphContext" class="md-header__button md-logo" aria-label="CodeGraphContext" data-md-component="logo">
  84 |       
  85 |   
  86 |   <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
  87 | 
  88 |     </a>
  89 |     <label class="md-header__button md-icon" for="__drawer">
  90 |       
  91 |       <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
  92 |     </label>
  93 |     <div class="md-header__title" data-md-component="header-title">
  94 |       <div class="md-header__ellipsis">
  95 |         <div class="md-header__topic">
  96 |           <span class="md-ellipsis">
  97 |             CodeGraphContext
  98 |           </span>
  99 |         </div>
 100 |         <div class="md-header__topic" data-md-component="header-topic">
 101 |           <span class="md-ellipsis">
 102 |             
 103 |               Cookbook
 104 |             
 105 |           </span>
 106 |         </div>
 107 |       </div>
 108 |     </div>
 109 |     
 110 |     
 111 |       <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
 112 |     
 113 |     
 114 |     
 115 |       
 116 |       
 117 |         <label class="md-header__button md-icon" for="__search">
 118 |           
 119 |           <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
 120 |         </label>
 121 |         <div class="md-search" data-md-component="search" role="dialog">
 122 |   <label class="md-search__overlay" for="__search"></label>
 123 |   <div class="md-search__inner" role="search">
 124 |     <form class="md-search__form" name="search">
 125 |       <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
 126 |       <label class="md-search__icon md-icon" for="__search">
 127 |         
 128 |         <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
 129 |         
 130 |         <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
 131 |       </label>
 132 |       <nav class="md-search__options" aria-label="Search">
 133 |         
 134 |         <button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
 135 |           
 136 |           <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
 137 |         </button>
 138 |       </nav>
 139 |       
 140 |     </form>
 141 |     <div class="md-search__output">
 142 |       <div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
 143 |         <div class="md-search-result" data-md-component="search-result">
 144 |           <div class="md-search-result__meta">
 145 |             Initializing search
 146 |           </div>
 147 |           <ol class="md-search-result__list" role="presentation"></ol>
 148 |         </div>
 149 |       </div>
 150 |     </div>
 151 |   </div>
 152 | </div>
 153 |       
 154 |     
 155 |     
 156 |   </nav>
 157 |   
 158 | </header>
 159 |     
 160 |     <div class="md-container" data-md-component="container">
 161 |       
 162 |       
 163 |         
 164 |           
 165 |         
 166 |       
 167 |       <main class="md-main" data-md-component="main">
 168 |         <div class="md-main__inner md-grid">
 169 |           
 170 |             
 171 |               
 172 |               <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
 173 |                 <div class="md-sidebar__scrollwrap">
 174 |                   <div class="md-sidebar__inner">
 175 |                     
 176 | 
 177 | 
 178 | 
 179 | <nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
 180 |   <label class="md-nav__title" for="__drawer">
 181 |     <a href=".." title="CodeGraphContext" class="md-nav__button md-logo" aria-label="CodeGraphContext" data-md-component="logo">
 182 |       
 183 |   
 184 |   <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
 185 | 
 186 |     </a>
 187 |     CodeGraphContext
 188 |   </label>
 189 |   
 190 |   <ul class="md-nav__list" data-md-scrollfix>
 191 |     
 192 |       
 193 |       
 194 |   
 195 |   
 196 |   
 197 |   
 198 |     <li class="md-nav__item">
 199 |       <a href=".." class="md-nav__link">
 200 |         
 201 |   
 202 |   
 203 |   <span class="md-ellipsis">
 204 |     
 205 |   
 206 |     Home
 207 |   
 208 | 
 209 |     
 210 |   </span>
 211 |   
 212 |   
 213 | 
 214 |       </a>
 215 |     </li>
 216 |   
 217 | 
 218 |     
 219 |       
 220 |       
 221 |   
 222 |   
 223 |   
 224 |   
 225 |     <li class="md-nav__item">
 226 |       <a href="../installation/" class="md-nav__link">
 227 |         
 228 |   
 229 |   
 230 |   <span class="md-ellipsis">
 231 |     
 232 |   
 233 |     Installation
 234 |   
 235 | 
 236 |     
 237 |   </span>
 238 |   
 239 |   
 240 | 
 241 |       </a>
 242 |     </li>
 243 |   
 244 | 
 245 |     
 246 |       
 247 |       
 248 |   
 249 |   
 250 |   
 251 |   
 252 |     <li class="md-nav__item">
 253 |       <a href="../use_cases/" class="md-nav__link">
 254 |         
 255 |   
 256 |   
 257 |   <span class="md-ellipsis">
 258 |     
 259 |   
 260 |     Use Cases
 261 |   
 262 | 
 263 |     
 264 |   </span>
 265 |   
 266 |   
 267 | 
 268 |       </a>
 269 |     </li>
 270 |   
 271 | 
 272 |     
 273 |       
 274 |       
 275 |   
 276 |   
 277 |   
 278 |   
 279 |     <li class="md-nav__item">
 280 |       <a href="../architecture/" class="md-nav__link">
 281 |         
 282 |   
 283 |   
 284 |   <span class="md-ellipsis">
 285 |     
 286 |   
 287 |     Architecture
 288 |   
 289 | 
 290 |     
 291 |   </span>
 292 |   
 293 |   
 294 | 
 295 |       </a>
 296 |     </li>
 297 |   
 298 | 
 299 |     
 300 |       
 301 |       
 302 |   
 303 |   
 304 |   
 305 |   
 306 |     <li class="md-nav__item">
 307 |       <a href="../cli/" class="md-nav__link">
 308 |         
 309 |   
 310 |   
 311 |   <span class="md-ellipsis">
 312 |     
 313 |   
 314 |     CLI Reference
 315 |   
 316 | 
 317 |     
 318 |   </span>
 319 |   
 320 |   
 321 | 
 322 |       </a>
 323 |     </li>
 324 |   
 325 | 
 326 |     
 327 |       
 328 |       
 329 |   
 330 |   
 331 |   
 332 |   
 333 |     <li class="md-nav__item">
 334 |       <a href="../watching/" class="md-nav__link">
 335 |         
 336 |   
 337 |   
 338 |   <span class="md-ellipsis">
 339 |     
 340 |   
 341 |     Live Watching
 342 |   
 343 | 
 344 |     
 345 |   </span>
 346 |   
 347 |   
 348 | 
 349 |       </a>
 350 |     </li>
 351 |   
 352 | 
 353 |     
 354 |       
 355 |       
 356 |   
 357 |   
 358 |   
 359 |   
 360 |     <li class="md-nav__item">
 361 |       <a href="../server/" class="md-nav__link">
 362 |         
 363 |   
 364 |   
 365 |   <span class="md-ellipsis">
 366 |     
 367 |   
 368 |     Server
 369 |   
 370 | 
 371 |     
 372 |   </span>
 373 |   
 374 |   
 375 | 
 376 |       </a>
 377 |     </li>
 378 |   
 379 | 
 380 |     
 381 |       
 382 |       
 383 |   
 384 |   
 385 |   
 386 |   
 387 |     <li class="md-nav__item">
 388 |       <a href="../core/" class="md-nav__link">
 389 |         
 390 |   
 391 |   
 392 |   <span class="md-ellipsis">
 393 |     
 394 |   
 395 |     Core Concepts
 396 |   
 397 | 
 398 |     
 399 |   </span>
 400 |   
 401 |   
 402 | 
 403 |       </a>
 404 |     </li>
 405 |   
 406 | 
 407 |     
 408 |       
 409 |       
 410 |   
 411 |   
 412 |   
 413 |   
 414 |     <li class="md-nav__item">
 415 |       <a href="../tools/" class="md-nav__link">
 416 |         
 417 |   
 418 |   
 419 |   <span class="md-ellipsis">
 420 |     
 421 |   
 422 |     Tools
 423 |   
 424 | 
 425 |     
 426 |   </span>
 427 |   
 428 |   
 429 | 
 430 |       </a>
 431 |     </li>
 432 |   
 433 | 
 434 |     
 435 |       
 436 |       
 437 |   
 438 |   
 439 |     
 440 |   
 441 |   
 442 |   
 443 |     <li class="md-nav__item md-nav__item--active">
 444 |       
 445 |       <input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
 446 |       
 447 |       
 448 |         
 449 |       
 450 |       
 451 |         <label class="md-nav__link md-nav__link--active" for="__toc">
 452 |           
 453 |   
 454 |   
 455 |   <span class="md-ellipsis">
 456 |     
 457 |   
 458 |     Cookbook
 459 |   
 460 | 
 461 |     
 462 |   </span>
 463 |   
 464 |   
 465 | 
 466 |           <span class="md-nav__icon md-icon"></span>
 467 |         </label>
 468 |       
 469 |       <a href="./" class="md-nav__link md-nav__link--active">
 470 |         
 471 |   
 472 |   
 473 |   <span class="md-ellipsis">
 474 |     
 475 |   
 476 |     Cookbook
 477 |   
 478 | 
 479 |     
 480 |   </span>
 481 |   
 482 |   
 483 | 
 484 |       </a>
 485 |       
 486 |         
 487 | 
 488 | <nav class="md-nav md-nav--secondary" aria-label="Table of contents">
 489 |   
 490 |   
 491 |   
 492 |     
 493 |   
 494 |   
 495 |     <label class="md-nav__title" for="__toc">
 496 |       <span class="md-nav__icon md-icon"></span>
 497 |       Table of contents
 498 |     </label>
 499 |     <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
 500 |       
 501 |         <li class="md-nav__item">
 502 |   <a href="#basic-queries" class="md-nav__link">
 503 |     <span class="md-ellipsis">
 504 |       
 505 |         Basic Queries
 506 |       
 507 |     </span>
 508 |   </a>
 509 |   
 510 |     <nav class="md-nav" aria-label="Basic Queries">
 511 |       <ul class="md-nav__list">
 512 |         
 513 |           <li class="md-nav__item">
 514 |   <a href="#1-find-a-specific-function-by-name" class="md-nav__link">
 515 |     <span class="md-ellipsis">
 516 |       
 517 |         1. Find a specific function by name
 518 |       
 519 |     </span>
 520 |   </a>
 521 |   
 522 | </li>
 523 |         
 524 |           <li class="md-nav__item">
 525 |   <a href="#2-find-all-calls-to-a-specific-function" class="md-nav__link">
 526 |     <span class="md-ellipsis">
 527 |       
 528 |         2. Find all calls to a specific function
 529 |       
 530 |     </span>
 531 |   </a>
 532 |   
 533 | </li>
 534 |         
 535 |           <li class="md-nav__item">
 536 |   <a href="#3-find-what-a-function-calls" class="md-nav__link">
 537 |     <span class="md-ellipsis">
 538 |       
 539 |         3. Find what a function calls
 540 |       
 541 |     </span>
 542 |   </a>
 543 |   
 544 | </li>
 545 |         
 546 |           <li class="md-nav__item">
 547 |   <a href="#4-find-all-imports-of-a-specific-module" class="md-nav__link">
 548 |     <span class="md-ellipsis">
 549 |       
 550 |         4. Find all imports of a specific module
 551 |       
 552 |     </span>
 553 |   </a>
 554 |   
 555 | </li>
 556 |         
 557 |           <li class="md-nav__item">
 558 |   <a href="#5-find-all-methods-of-a-class" class="md-nav__link">
 559 |     <span class="md-ellipsis">
 560 |       
 561 |         5. Find all methods of a class
 562 |       
 563 |     </span>
 564 |   </a>
 565 |   
 566 | </li>
 567 |         
 568 |           <li class="md-nav__item">
 569 |   <a href="#6-find-all-classes-that-inherit-from-a-specific-class" class="md-nav__link">
 570 |     <span class="md-ellipsis">
 571 |       
 572 |         6. Find all classes that inherit from a specific class
 573 |       
 574 |     </span>
 575 |   </a>
 576 |   
 577 | </li>
 578 |         
 579 |           <li class="md-nav__item">
 580 |   <a href="#7-find-all-functions-with-a-specific-decorator" class="md-nav__link">
 581 |     <span class="md-ellipsis">
 582 |       
 583 |         7. Find all functions with a specific decorator
 584 |       
 585 |     </span>
 586 |   </a>
 587 |   
 588 | </li>
 589 |         
 590 |           <li class="md-nav__item">
 591 |   <a href="#8-find-all-dataclasses" class="md-nav__link">
 592 |     <span class="md-ellipsis">
 593 |       
 594 |         8. Find all dataclasses
 595 |       
 596 |     </span>
 597 |   </a>
 598 |   
 599 | </li>
 600 |         
 601 |       </ul>
 602 |     </nav>
 603 |   
 604 | </li>
 605 |       
 606 |         <li class="md-nav__item">
 607 |   <a href="#code-analysis-quality" class="md-nav__link">
 608 |     <span class="md-ellipsis">
 609 |       
 610 |         Code Analysis &amp; Quality
 611 |       
 612 |     </span>
 613 |   </a>
 614 |   
 615 |     <nav class="md-nav" aria-label="Code Analysis &amp; Quality">
 616 |       <ul class="md-nav__list">
 617 |         
 618 |           <li class="md-nav__item">
 619 |   <a href="#9-find-the-5-most-complex-functions" class="md-nav__link">
 620 |     <span class="md-ellipsis">
 621 |       
 622 |         9. Find the 5 most complex functions
 623 |       
 624 |     </span>
 625 |   </a>
 626 |   
 627 | </li>
 628 |         
 629 |           <li class="md-nav__item">
 630 |   <a href="#10-calculate-cyclomatic-complexity-of-a-function" class="md-nav__link">
 631 |     <span class="md-ellipsis">
 632 |       
 633 |         10. Calculate cyclomatic complexity of a function
 634 |       
 635 |     </span>
 636 |   </a>
 637 |   
 638 | </li>
 639 |         
 640 |           <li class="md-nav__item">
 641 |   <a href="#11-find-unused-code" class="md-nav__link">
 642 |     <span class="md-ellipsis">
 643 |       
 644 |         11. Find unused code
 645 |       
 646 |     </span>
 647 |   </a>
 648 |   
 649 | </li>
 650 |         
 651 |           <li class="md-nav__item">
 652 |   <a href="#12-find-the-call-chain-between-two-functions" class="md-nav__link">
 653 |     <span class="md-ellipsis">
 654 |       
 655 |         12. Find the call chain between two functions
 656 |       
 657 |     </span>
 658 |   </a>
 659 |   
 660 | </li>
 661 |         
 662 |           <li class="md-nav__item">
 663 |   <a href="#13-find-all-direct-and-indirect-callers-of-a-function" class="md-nav__link">
 664 |     <span class="md-ellipsis">
 665 |       
 666 |         13. Find all direct and indirect callers of a function
 667 |       
 668 |     </span>
 669 |   </a>
 670 |   
 671 | </li>
 672 |         
 673 |           <li class="md-nav__item">
 674 |   <a href="#14-find-functions-by-argument-name" class="md-nav__link">
 675 |     <span class="md-ellipsis">
 676 |       
 677 |         14. Find functions by argument name
 678 |       
 679 |     </span>
 680 |   </a>
 681 |   
 682 | </li>
 683 |         
 684 |           <li class="md-nav__item">
 685 |   <a href="#15-list-all-python-package-imports-from-a-directory" class="md-nav__link">
 686 |     <span class="md-ellipsis">
 687 |       
 688 |         15. List all python package imports from a directory
 689 |       
 690 |     </span>
 691 |   </a>
 692 |   
 693 | </li>
 694 |         
 695 |       </ul>
 696 |     </nav>
 697 |   
 698 | </li>
 699 |       
 700 |         <li class="md-nav__item">
 701 |   <a href="#repository-information-queries" class="md-nav__link">
 702 |     <span class="md-ellipsis">
 703 |       
 704 |         Repository Information Queries
 705 |       
 706 |     </span>
 707 |   </a>
 708 |   
 709 |     <nav class="md-nav" aria-label="Repository Information Queries">
 710 |       <ul class="md-nav__list">
 711 |         
 712 |           <li class="md-nav__item">
 713 |   <a href="#16-list-all-indexed-projects" class="md-nav__link">
 714 |     <span class="md-ellipsis">
 715 |       
 716 |         16. List all indexed projects
 717 |       
 718 |     </span>
 719 |   </a>
 720 |   
 721 | </li>
 722 |         
 723 |           <li class="md-nav__item">
 724 |   <a href="#17-check-the-status-of-an-indexing-job" class="md-nav__link">
 725 |     <span class="md-ellipsis">
 726 |       
 727 |         17. Check the status of an indexing job
 728 |       
 729 |     </span>
 730 |   </a>
 731 |   
 732 | </li>
 733 |         
 734 |           <li class="md-nav__item">
 735 |   <a href="#18-list-all-background-jobs" class="md-nav__link">
 736 |     <span class="md-ellipsis">
 737 |       
 738 |         18. List all background jobs
 739 |       
 740 |     </span>
 741 |   </a>
 742 |   
 743 | </li>
 744 |         
 745 |       </ul>
 746 |     </nav>
 747 |   
 748 | </li>
 749 |       
 750 |         <li class="md-nav__item">
 751 |   <a href="#advanced-cypher-queries" class="md-nav__link">
 752 |     <span class="md-ellipsis">
 753 |       
 754 |         Advanced Cypher Queries
 755 |       
 756 |     </span>
 757 |   </a>
 758 |   
 759 |     <nav class="md-nav" aria-label="Advanced Cypher Queries">
 760 |       <ul class="md-nav__list">
 761 |         
 762 |           <li class="md-nav__item">
 763 |   <a href="#19-find-all-function-definitions" class="md-nav__link">
 764 |     <span class="md-ellipsis">
 765 |       
 766 |         19. Find all function definitions
 767 |       
 768 |     </span>
 769 |   </a>
 770 |   
 771 | </li>
 772 |         
 773 |           <li class="md-nav__item">
 774 |   <a href="#20-find-all-classes" class="md-nav__link">
 775 |     <span class="md-ellipsis">
 776 |       
 777 |         20. Find all classes
 778 |       
 779 |     </span>
 780 |   </a>
 781 |   
 782 | </li>
 783 |         
 784 |           <li class="md-nav__item">
 785 |   <a href="#21-find-all-functions-in-a-file" class="md-nav__link">
 786 |     <span class="md-ellipsis">
 787 |       
 788 |         21. Find all functions in a file
 789 |       
 790 |     </span>
 791 |   </a>
 792 |   
 793 | </li>
 794 |         
 795 |           <li class="md-nav__item">
 796 |   <a href="#22-find-all-classes-in-a-file" class="md-nav__link">
 797 |     <span class="md-ellipsis">
 798 |       
 799 |         22. Find all classes in a file
 800 |       
 801 |     </span>
 802 |   </a>
 803 |   
 804 | </li>
 805 |         
 806 |           <li class="md-nav__item">
 807 |   <a href="#23-list-all-top-level-functions-and-classes-in-a-file" class="md-nav__link">
 808 |     <span class="md-ellipsis">
 809 |       
 810 |         23. List all top-level functions and classes in a file
 811 |       
 812 |     </span>
 813 |   </a>
 814 |   
 815 | </li>
 816 |         
 817 |           <li class="md-nav__item">
 818 |   <a href="#24-find-functions-in-one-module-that-call-a-function-in-another" class="md-nav__link">
 819 |     <span class="md-ellipsis">
 820 |       
 821 |         24. Find functions in one module that call a function in another
 822 |       
 823 |     </span>
 824 |   </a>
 825 |   
 826 | </li>
 827 |         
 828 |           <li class="md-nav__item">
 829 |   <a href="#25-find-circular-file-imports" class="md-nav__link">
 830 |     <span class="md-ellipsis">
 831 |       
 832 |         25. Find circular file imports
 833 |       
 834 |     </span>
 835 |   </a>
 836 |   
 837 | </li>
 838 |         
 839 |           <li class="md-nav__item">
 840 |   <a href="#26-find-all-functions-with-more-than-5-arguments" class="md-nav__link">
 841 |     <span class="md-ellipsis">
 842 |       
 843 |         26. Find all functions with more than 5 arguments
 844 |       
 845 |     </span>
 846 |   </a>
 847 |   
 848 | </li>
 849 |         
 850 |           <li class="md-nav__item">
 851 |   <a href="#27-find-all-functions-in-a-file-that-have-a-docstring" class="md-nav__link">
 852 |     <span class="md-ellipsis">
 853 |       
 854 |         27. Find all functions in a file that have a docstring
 855 |       
 856 |     </span>
 857 |   </a>
 858 |   
 859 | </li>
 860 |         
 861 |           <li class="md-nav__item">
 862 |   <a href="#28-find-all-classes-that-have-a-specific-method" class="md-nav__link">
 863 |     <span class="md-ellipsis">
 864 |       
 865 |         28. Find all classes that have a specific method
 866 |       
 867 |     </span>
 868 |   </a>
 869 |   
 870 | </li>
 871 |         
 872 |           <li class="md-nav__item">
 873 |   <a href="#29-find-the-depth-of-inheritance-for-all-classes" class="md-nav__link">
 874 |     <span class="md-ellipsis">
 875 |       
 876 |         29. Find the depth of inheritance for all classes
 877 |       
 878 |     </span>
 879 |   </a>
 880 |   
 881 | </li>
 882 |         
 883 |           <li class="md-nav__item">
 884 |   <a href="#30-find-all-functions-that-have-a-docstring" class="md-nav__link">
 885 |     <span class="md-ellipsis">
 886 |       
 887 |         30. Find all functions that have a docstring
 888 |       
 889 |     </span>
 890 |   </a>
 891 |   
 892 | </li>
 893 |         
 894 |           <li class="md-nav__item">
 895 |   <a href="#31-find-all-decorated-methods-in-a-class" class="md-nav__link">
 896 |     <span class="md-ellipsis">
 897 |       
 898 |         31. Find all decorated methods in a class
 899 |       
 900 |     </span>
 901 |   </a>
 902 |   
 903 | </li>
 904 |         
 905 |           <li class="md-nav__item">
 906 |   <a href="#32-find-the-number-of-functions-in-each-file" class="md-nav__link">
 907 |     <span class="md-ellipsis">
 908 |       
 909 |         32. Find the number of functions in each file
 910 |       
 911 |     </span>
 912 |   </a>
 913 |   
 914 | </li>
 915 |         
 916 |           <li class="md-nav__item">
 917 |   <a href="#33-find-all-methods-that-override-a-parent-method" class="md-nav__link">
 918 |     <span class="md-ellipsis">
 919 |       
 920 |         33. Find all methods that override a parent method
 921 |       
 922 |     </span>
 923 |   </a>
 924 |   
 925 | </li>
 926 |         
 927 |           <li class="md-nav__item">
 928 |   <a href="#34-find-all-functions-that-call-super" class="md-nav__link">
 929 |     <span class="md-ellipsis">
 930 |       
 931 |         34. Find all functions that call super()
 932 |       
 933 |     </span>
 934 |   </a>
 935 |   
 936 | </li>
 937 |         
 938 |           <li class="md-nav__item">
 939 |   <a href="#35-find-all-calls-to-a-function-with-a-specific-argument" class="md-nav__link">
 940 |     <span class="md-ellipsis">
 941 |       
 942 |         35. Find all calls to a function with a specific argument
 943 |       
 944 |     </span>
 945 |   </a>
 946 |   
 947 | </li>
 948 |         
 949 |           <li class="md-nav__item">
 950 |   <a href="#36-find-all-functions-that-are-not-called-by-any-other-function" class="md-nav__link">
 951 |     <span class="md-ellipsis">
 952 |       
 953 |         36. Find all functions that are not called by any other function
 954 |       
 955 |     </span>
 956 |   </a>
 957 |   
 958 | </li>
 959 |         
 960 |           <li class="md-nav__item">
 961 |   <a href="#37-find-all-functions-that-are-called-with-a-specific-argument" class="md-nav__link">
 962 |     <span class="md-ellipsis">
 963 |       
 964 |         37. Find all functions that are called with a specific argument
 965 |       
 966 |     </span>
 967 |   </a>
 968 |   
 969 | </li>
 970 |         
 971 |           <li class="md-nav__item">
 972 |   <a href="#38-find-all-direct-and-indirect-callees-of-a-function" class="md-nav__link">
 973 |     <span class="md-ellipsis">
 974 |       
 975 |         38. Find all direct and indirect callees of a function
 976 |       
 977 |     </span>
 978 |   </a>
 979 |   
 980 | </li>
 981 |         
 982 |           <li class="md-nav__item">
 983 |   <a href="#39-find-all-functions-that-are-overridden" class="md-nav__link">
 984 |     <span class="md-ellipsis">
 985 |       
 986 |         39. Find all functions that are overridden
 987 |       
 988 |     </span>
 989 |   </a>
 990 |   
 991 | </li>
 992 |         
 993 |           <li class="md-nav__item">
 994 |   <a href="#40-find-all-modules-imported-by-module_a" class="md-nav__link">
 995 |     <span class="md-ellipsis">
 996 |       
 997 |         40. Find all modules imported by module_a
 998 |       
 999 |     </span>
1000 |   </a>
1001 |   
1002 | </li>
1003 |         
1004 |           <li class="md-nav__item">
1005 |   <a href="#41-find-large-functions-that-should-be-refactored" class="md-nav__link">
1006 |     <span class="md-ellipsis">
1007 |       
1008 |         41. Find large functions that should be refactored
1009 |       
1010 |     </span>
1011 |   </a>
1012 |   
1013 | </li>
1014 |         
1015 |           <li class="md-nav__item">
1016 |   <a href="#42-find-recursive-functions" class="md-nav__link">
1017 |     <span class="md-ellipsis">
1018 |       
1019 |         42. Find recursive functions
1020 |       
1021 |     </span>
1022 |   </a>
1023 |   
1024 | </li>
1025 |         
1026 |           <li class="md-nav__item">
1027 |   <a href="#43-find-most-connected-functions-hub-functions" class="md-nav__link">
1028 |     <span class="md-ellipsis">
1029 |       
1030 |         43. Find most connected functions (hub functions)
1031 |       
1032 |     </span>
1033 |   </a>
1034 |   
1035 | </li>
1036 |         
1037 |       </ul>
1038 |     </nav>
1039 |   
1040 | </li>
1041 |       
1042 |         <li class="md-nav__item">
1043 |   <a href="#security-sensitive-data-analysis" class="md-nav__link">
1044 |     <span class="md-ellipsis">
1045 |       
1046 |         Security &amp; Sensitive Data Analysis
1047 |       
1048 |     </span>
1049 |   </a>
1050 |   
1051 |     <nav class="md-nav" aria-label="Security &amp; Sensitive Data Analysis">
1052 |       <ul class="md-nav__list">
1053 |         
1054 |           <li class="md-nav__item">
1055 |   <a href="#44-find-potential-security-vulnerabilities-hardcoded-secrets" class="md-nav__link">
1056 |     <span class="md-ellipsis">
1057 |       
1058 |         44. Find potential security vulnerabilities (hardcoded secrets)
1059 |       
1060 |     </span>
1061 |   </a>
1062 |   
1063 | </li>
1064 |         
1065 |       </ul>
1066 |     </nav>
1067 |   
1068 | </li>
1069 |       
1070 |     </ul>
1071 |   
1072 | </nav>
1073 |       
1074 |     </li>
1075 |   
1076 | 
1077 |     
1078 |       
1079 |       
1080 |   
1081 |   
1082 |   
1083 |   
1084 |     
1085 |     
1086 |     
1087 |     
1088 |     
1089 |     <li class="md-nav__item md-nav__item--nested">
1090 |       
1091 |         
1092 |         
1093 |         <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_11" >
1094 |         
1095 |           
1096 |           <label class="md-nav__link" for="__nav_11" id="__nav_11_label" tabindex="0">
1097 |             
1098 |   
1099 |   
1100 |   <span class="md-ellipsis">
1101 |     
1102 |   
1103 |     Contributing
1104 |   
1105 | 
1106 |     
1107 |   </span>
1108 |   
1109 |   
1110 | 
1111 |             <span class="md-nav__icon md-icon"></span>
1112 |           </label>
1113 |         
1114 |         <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_11_label" aria-expanded="false">
1115 |           <label class="md-nav__title" for="__nav_11">
1116 |             <span class="md-nav__icon md-icon"></span>
1117 |             
1118 |   
1119 |     Contributing
1120 |   
1121 | 
1122 |           </label>
1123 |           <ul class="md-nav__list" data-md-scrollfix>
1124 |             
1125 |               
1126 |                 
1127 |   
1128 |   
1129 |   
1130 |   
1131 |     <li class="md-nav__item">
1132 |       <a href="../contributing/" class="md-nav__link">
1133 |         
1134 |   
1135 |   
1136 |   <span class="md-ellipsis">
1137 |     
1138 |   
1139 |     Overview
1140 |   
1141 | 
1142 |     
1143 |   </span>
1144 |   
1145 |   
1146 | 
1147 |       </a>
1148 |     </li>
1149 |   
1150 | 
1151 |               
1152 |             
1153 |               
1154 |                 
1155 |   
1156 |   
1157 |   
1158 |   
1159 |     <li class="md-nav__item">
1160 |       <a href="../contributing_languages/" class="md-nav__link">
1161 |         
1162 |   
1163 |   
1164 |   <span class="md-ellipsis">
1165 |     
1166 |   
1167 |     Adding New Languages
1168 |   
1169 | 
1170 |     
1171 |   </span>
1172 |   
1173 |   
1174 | 
1175 |       </a>
1176 |     </li>
1177 |   
1178 | 
1179 |               
1180 |             
1181 |           </ul>
1182 |         </nav>
1183 |       
1184 |     </li>
1185 |   
1186 | 
1187 |     
1188 |       
1189 |       
1190 |   
1191 |   
1192 |   
1193 |   
1194 |     <li class="md-nav__item">
1195 |       <a href="../troubleshooting/" class="md-nav__link">
1196 |         
1197 |   
1198 |   
1199 |   <span class="md-ellipsis">
1200 |     
1201 |   
1202 |     Troubleshooting
1203 |   
1204 | 
1205 |     
1206 |   </span>
1207 |   
1208 |   
1209 | 
1210 |       </a>
1211 |     </li>
1212 |   
1213 | 
1214 |     
1215 |       
1216 |       
1217 |   
1218 |   
1219 |   
1220 |   
1221 |     <li class="md-nav__item">
1222 |       <a href="../future_work/" class="md-nav__link">
1223 |         
1224 |   
1225 |   
1226 |   <span class="md-ellipsis">
1227 |     
1228 |   
1229 |     Future Work
1230 |   
1231 | 
1232 |     
1233 |   </span>
1234 |   
1235 |   
1236 | 
1237 |       </a>
1238 |     </li>
1239 |   
1240 | 
1241 |     
1242 |       
1243 |       
1244 |   
1245 |   
1246 |   
1247 |   
1248 |     <li class="md-nav__item">
1249 |       <a href="../license/" class="md-nav__link">
1250 |         
1251 |   
1252 |   
1253 |   <span class="md-ellipsis">
1254 |     
1255 |   
1256 |     License
1257 |   
1258 | 
1259 |     
1260 |   </span>
1261 |   
1262 |   
1263 | 
1264 |       </a>
1265 |     </li>
1266 |   
1267 | 
1268 |     
1269 |   </ul>
1270 | </nav>
1271 |                   </div>
1272 |                 </div>
1273 |               </div>
1274 |             
1275 |             
1276 |               
1277 |               <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
1278 |                 <div class="md-sidebar__scrollwrap">
1279 |                   <div class="md-sidebar__inner">
1280 |                     
1281 | 
1282 | <nav class="md-nav md-nav--secondary" aria-label="Table of contents">
1283 |   
1284 |   
1285 |   
1286 |     
1287 |   
1288 |   
1289 |     <label class="md-nav__title" for="__toc">
1290 |       <span class="md-nav__icon md-icon"></span>
1291 |       Table of contents
1292 |     </label>
1293 |     <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
1294 |       
1295 |         <li class="md-nav__item">
1296 |   <a href="#basic-queries" class="md-nav__link">
1297 |     <span class="md-ellipsis">
1298 |       
1299 |         Basic Queries
1300 |       
1301 |     </span>
1302 |   </a>
1303 |   
1304 |     <nav class="md-nav" aria-label="Basic Queries">
1305 |       <ul class="md-nav__list">
1306 |         
1307 |           <li class="md-nav__item">
1308 |   <a href="#1-find-a-specific-function-by-name" class="md-nav__link">
1309 |     <span class="md-ellipsis">
1310 |       
1311 |         1. Find a specific function by name
1312 |       
1313 |     </span>
1314 |   </a>
1315 |   
1316 | </li>
1317 |         
1318 |           <li class="md-nav__item">
1319 |   <a href="#2-find-all-calls-to-a-specific-function" class="md-nav__link">
1320 |     <span class="md-ellipsis">
1321 |       
1322 |         2. Find all calls to a specific function
1323 |       
1324 |     </span>
1325 |   </a>
1326 |   
1327 | </li>
1328 |         
1329 |           <li class="md-nav__item">
1330 |   <a href="#3-find-what-a-function-calls" class="md-nav__link">
1331 |     <span class="md-ellipsis">
1332 |       
1333 |         3. Find what a function calls
1334 |       
1335 |     </span>
1336 |   </a>
1337 |   
1338 | </li>
1339 |         
1340 |           <li class="md-nav__item">
1341 |   <a href="#4-find-all-imports-of-a-specific-module" class="md-nav__link">
1342 |     <span class="md-ellipsis">
1343 |       
1344 |         4. Find all imports of a specific module
1345 |       
1346 |     </span>
1347 |   </a>
1348 |   
1349 | </li>
1350 |         
1351 |           <li class="md-nav__item">
1352 |   <a href="#5-find-all-methods-of-a-class" class="md-nav__link">
1353 |     <span class="md-ellipsis">
1354 |       
1355 |         5. Find all methods of a class
1356 |       
1357 |     </span>
1358 |   </a>
1359 |   
1360 | </li>
1361 |         
1362 |           <li class="md-nav__item">
1363 |   <a href="#6-find-all-classes-that-inherit-from-a-specific-class" class="md-nav__link">
1364 |     <span class="md-ellipsis">
1365 |       
1366 |         6. Find all classes that inherit from a specific class
1367 |       
1368 |     </span>
1369 |   </a>
1370 |   
1371 | </li>
1372 |         
1373 |           <li class="md-nav__item">
1374 |   <a href="#7-find-all-functions-with-a-specific-decorator" class="md-nav__link">
1375 |     <span class="md-ellipsis">
1376 |       
1377 |         7. Find all functions with a specific decorator
1378 |       
1379 |     </span>
1380 |   </a>
1381 |   
1382 | </li>
1383 |         
1384 |           <li class="md-nav__item">
1385 |   <a href="#8-find-all-dataclasses" class="md-nav__link">
1386 |     <span class="md-ellipsis">
1387 |       
1388 |         8. Find all dataclasses
1389 |       
1390 |     </span>
1391 |   </a>
1392 |   
1393 | </li>
1394 |         
1395 |       </ul>
1396 |     </nav>
1397 |   
1398 | </li>
1399 |       
1400 |         <li class="md-nav__item">
1401 |   <a href="#code-analysis-quality" class="md-nav__link">
1402 |     <span class="md-ellipsis">
1403 |       
1404 |         Code Analysis &amp; Quality
1405 |       
1406 |     </span>
1407 |   </a>
1408 |   
1409 |     <nav class="md-nav" aria-label="Code Analysis &amp; Quality">
1410 |       <ul class="md-nav__list">
1411 |         
1412 |           <li class="md-nav__item">
1413 |   <a href="#9-find-the-5-most-complex-functions" class="md-nav__link">
1414 |     <span class="md-ellipsis">
1415 |       
1416 |         9. Find the 5 most complex functions
1417 |       
1418 |     </span>
1419 |   </a>
1420 |   
1421 | </li>
1422 |         
1423 |           <li class="md-nav__item">
1424 |   <a href="#10-calculate-cyclomatic-complexity-of-a-function" class="md-nav__link">
1425 |     <span class="md-ellipsis">
1426 |       
1427 |         10. Calculate cyclomatic complexity of a function
1428 |       
1429 |     </span>
1430 |   </a>
1431 |   
1432 | </li>
1433 |         
1434 |           <li class="md-nav__item">
1435 |   <a href="#11-find-unused-code" class="md-nav__link">
1436 |     <span class="md-ellipsis">
1437 |       
1438 |         11. Find unused code
1439 |       
1440 |     </span>
1441 |   </a>
1442 |   
1443 | </li>
1444 |         
1445 |           <li class="md-nav__item">
1446 |   <a href="#12-find-the-call-chain-between-two-functions" class="md-nav__link">
1447 |     <span class="md-ellipsis">
1448 |       
1449 |         12. Find the call chain between two functions
1450 |       
1451 |     </span>
1452 |   </a>
1453 |   
1454 | </li>
1455 |         
1456 |           <li class="md-nav__item">
1457 |   <a href="#13-find-all-direct-and-indirect-callers-of-a-function" class="md-nav__link">
1458 |     <span class="md-ellipsis">
1459 |       
1460 |         13. Find all direct and indirect callers of a function
1461 |       
1462 |     </span>
1463 |   </a>
1464 |   
1465 | </li>
1466 |         
1467 |           <li class="md-nav__item">
1468 |   <a href="#14-find-functions-by-argument-name" class="md-nav__link">
1469 |     <span class="md-ellipsis">
1470 |       
1471 |         14. Find functions by argument name
1472 |       
1473 |     </span>
1474 |   </a>
1475 |   
1476 | </li>
1477 |         
1478 |           <li class="md-nav__item">
1479 |   <a href="#15-list-all-python-package-imports-from-a-directory" class="md-nav__link">
1480 |     <span class="md-ellipsis">
1481 |       
1482 |         15. List all python package imports from a directory
1483 |       
1484 |     </span>
1485 |   </a>
1486 |   
1487 | </li>
1488 |         
1489 |       </ul>
1490 |     </nav>
1491 |   
1492 | </li>
1493 |       
1494 |         <li class="md-nav__item">
1495 |   <a href="#repository-information-queries" class="md-nav__link">
1496 |     <span class="md-ellipsis">
1497 |       
1498 |         Repository Information Queries
1499 |       
1500 |     </span>
1501 |   </a>
1502 |   
1503 |     <nav class="md-nav" aria-label="Repository Information Queries">
1504 |       <ul class="md-nav__list">
1505 |         
1506 |           <li class="md-nav__item">
1507 |   <a href="#16-list-all-indexed-projects" class="md-nav__link">
1508 |     <span class="md-ellipsis">
1509 |       
1510 |         16. List all indexed projects
1511 |       
1512 |     </span>
1513 |   </a>
1514 |   
1515 | </li>
1516 |         
1517 |           <li class="md-nav__item">
1518 |   <a href="#17-check-the-status-of-an-indexing-job" class="md-nav__link">
1519 |     <span class="md-ellipsis">
1520 |       
1521 |         17. Check the status of an indexing job
1522 |       
1523 |     </span>
1524 |   </a>
1525 |   
1526 | </li>
1527 |         
1528 |           <li class="md-nav__item">
1529 |   <a href="#18-list-all-background-jobs" class="md-nav__link">
1530 |     <span class="md-ellipsis">
1531 |       
1532 |         18. List all background jobs
1533 |       
1534 |     </span>
1535 |   </a>
1536 |   
1537 | </li>
1538 |         
1539 |       </ul>
1540 |     </nav>
1541 |   
1542 | </li>
1543 |       
1544 |         <li class="md-nav__item">
1545 |   <a href="#advanced-cypher-queries" class="md-nav__link">
1546 |     <span class="md-ellipsis">
1547 |       
1548 |         Advanced Cypher Queries
1549 |       
1550 |     </span>
1551 |   </a>
1552 |   
1553 |     <nav class="md-nav" aria-label="Advanced Cypher Queries">
1554 |       <ul class="md-nav__list">
1555 |         
1556 |           <li class="md-nav__item">
1557 |   <a href="#19-find-all-function-definitions" class="md-nav__link">
1558 |     <span class="md-ellipsis">
1559 |       
1560 |         19. Find all function definitions
1561 |       
1562 |     </span>
1563 |   </a>
1564 |   
1565 | </li>
1566 |         
1567 |           <li class="md-nav__item">
1568 |   <a href="#20-find-all-classes" class="md-nav__link">
1569 |     <span class="md-ellipsis">
1570 |       
1571 |         20. Find all classes
1572 |       
1573 |     </span>
1574 |   </a>
1575 |   
1576 | </li>
1577 |         
1578 |           <li class="md-nav__item">
1579 |   <a href="#21-find-all-functions-in-a-file" class="md-nav__link">
1580 |     <span class="md-ellipsis">
1581 |       
1582 |         21. Find all functions in a file
1583 |       
1584 |     </span>
1585 |   </a>
1586 |   
1587 | </li>
1588 |         
1589 |           <li class="md-nav__item">
1590 |   <a href="#22-find-all-classes-in-a-file" class="md-nav__link">
1591 |     <span class="md-ellipsis">
1592 |       
1593 |         22. Find all classes in a file
1594 |       
1595 |     </span>
1596 |   </a>
1597 |   
1598 | </li>
1599 |         
1600 |           <li class="md-nav__item">
1601 |   <a href="#23-list-all-top-level-functions-and-classes-in-a-file" class="md-nav__link">
1602 |     <span class="md-ellipsis">
1603 |       
1604 |         23. List all top-level functions and classes in a file
1605 |       
1606 |     </span>
1607 |   </a>
1608 |   
1609 | </li>
1610 |         
1611 |           <li class="md-nav__item">
1612 |   <a href="#24-find-functions-in-one-module-that-call-a-function-in-another" class="md-nav__link">
1613 |     <span class="md-ellipsis">
1614 |       
1615 |         24. Find functions in one module that call a function in another
1616 |       
1617 |     </span>
1618 |   </a>
1619 |   
1620 | </li>
1621 |         
1622 |           <li class="md-nav__item">
1623 |   <a href="#25-find-circular-file-imports" class="md-nav__link">
1624 |     <span class="md-ellipsis">
1625 |       
1626 |         25. Find circular file imports
1627 |       
1628 |     </span>
1629 |   </a>
1630 |   
1631 | </li>
1632 |         
1633 |           <li class="md-nav__item">
1634 |   <a href="#26-find-all-functions-with-more-than-5-arguments" class="md-nav__link">
1635 |     <span class="md-ellipsis">
1636 |       
1637 |         26. Find all functions with more than 5 arguments
1638 |       
1639 |     </span>
1640 |   </a>
1641 |   
1642 | </li>
1643 |         
1644 |           <li class="md-nav__item">
1645 |   <a href="#27-find-all-functions-in-a-file-that-have-a-docstring" class="md-nav__link">
1646 |     <span class="md-ellipsis">
1647 |       
1648 |         27. Find all functions in a file that have a docstring
1649 |       
1650 |     </span>
1651 |   </a>
1652 |   
1653 | </li>
1654 |         
1655 |           <li class="md-nav__item">
1656 |   <a href="#28-find-all-classes-that-have-a-specific-method" class="md-nav__link">
1657 |     <span class="md-ellipsis">
1658 |       
1659 |         28. Find all classes that have a specific method
1660 |       
1661 |     </span>
1662 |   </a>
1663 |   
1664 | </li>
1665 |         
1666 |           <li class="md-nav__item">
1667 |   <a href="#29-find-the-depth-of-inheritance-for-all-classes" class="md-nav__link">
1668 |     <span class="md-ellipsis">
1669 |       
1670 |         29. Find the depth of inheritance for all classes
1671 |       
1672 |     </span>
1673 |   </a>
1674 |   
1675 | </li>
1676 |         
1677 |           <li class="md-nav__item">
1678 |   <a href="#30-find-all-functions-that-have-a-docstring" class="md-nav__link">
1679 |     <span class="md-ellipsis">
1680 |       
1681 |         30. Find all functions that have a docstring
1682 |       
1683 |     </span>
1684 |   </a>
1685 |   
1686 | </li>
1687 |         
1688 |           <li class="md-nav__item">
1689 |   <a href="#31-find-all-decorated-methods-in-a-class" class="md-nav__link">
1690 |     <span class="md-ellipsis">
1691 |       
1692 |         31. Find all decorated methods in a class
1693 |       
1694 |     </span>
1695 |   </a>
1696 |   
1697 | </li>
1698 |         
1699 |           <li class="md-nav__item">
1700 |   <a href="#32-find-the-number-of-functions-in-each-file" class="md-nav__link">
1701 |     <span class="md-ellipsis">
1702 |       
1703 |         32. Find the number of functions in each file
1704 |       
1705 |     </span>
1706 |   </a>
1707 |   
1708 | </li>
1709 |         
1710 |           <li class="md-nav__item">
1711 |   <a href="#33-find-all-methods-that-override-a-parent-method" class="md-nav__link">
1712 |     <span class="md-ellipsis">
1713 |       
1714 |         33. Find all methods that override a parent method
1715 |       
1716 |     </span>
1717 |   </a>
1718 |   
1719 | </li>
1720 |         
1721 |           <li class="md-nav__item">
1722 |   <a href="#34-find-all-functions-that-call-super" class="md-nav__link">
1723 |     <span class="md-ellipsis">
1724 |       
1725 |         34. Find all functions that call super()
1726 |       
1727 |     </span>
1728 |   </a>
1729 |   
1730 | </li>
1731 |         
1732 |           <li class="md-nav__item">
1733 |   <a href="#35-find-all-calls-to-a-function-with-a-specific-argument" class="md-nav__link">
1734 |     <span class="md-ellipsis">
1735 |       
1736 |         35. Find all calls to a function with a specific argument
1737 |       
1738 |     </span>
1739 |   </a>
1740 |   
1741 | </li>
1742 |         
1743 |           <li class="md-nav__item">
1744 |   <a href="#36-find-all-functions-that-are-not-called-by-any-other-function" class="md-nav__link">
1745 |     <span class="md-ellipsis">
1746 |       
1747 |         36. Find all functions that are not called by any other function
1748 |       
1749 |     </span>
1750 |   </a>
1751 |   
1752 | </li>
1753 |         
1754 |           <li class="md-nav__item">
1755 |   <a href="#37-find-all-functions-that-are-called-with-a-specific-argument" class="md-nav__link">
1756 |     <span class="md-ellipsis">
1757 |       
1758 |         37. Find all functions that are called with a specific argument
1759 |       
1760 |     </span>
1761 |   </a>
1762 |   
1763 | </li>
1764 |         
1765 |           <li class="md-nav__item">
1766 |   <a href="#38-find-all-direct-and-indirect-callees-of-a-function" class="md-nav__link">
1767 |     <span class="md-ellipsis">
1768 |       
1769 |         38. Find all direct and indirect callees of a function
1770 |       
1771 |     </span>
1772 |   </a>
1773 |   
1774 | </li>
1775 |         
1776 |           <li class="md-nav__item">
1777 |   <a href="#39-find-all-functions-that-are-overridden" class="md-nav__link">
1778 |     <span class="md-ellipsis">
1779 |       
1780 |         39. Find all functions that are overridden
1781 |       
1782 |     </span>
1783 |   </a>
1784 |   
1785 | </li>
1786 |         
1787 |           <li class="md-nav__item">
1788 |   <a href="#40-find-all-modules-imported-by-module_a" class="md-nav__link">
1789 |     <span class="md-ellipsis">
1790 |       
1791 |         40. Find all modules imported by module_a
1792 |       
1793 |     </span>
1794 |   </a>
1795 |   
1796 | </li>
1797 |         
1798 |           <li class="md-nav__item">
1799 |   <a href="#41-find-large-functions-that-should-be-refactored" class="md-nav__link">
1800 |     <span class="md-ellipsis">
1801 |       
1802 |         41. Find large functions that should be refactored
1803 |       
1804 |     </span>
1805 |   </a>
1806 |   
1807 | </li>
1808 |         
1809 |           <li class="md-nav__item">
1810 |   <a href="#42-find-recursive-functions" class="md-nav__link">
1811 |     <span class="md-ellipsis">
1812 |       
1813 |         42. Find recursive functions
1814 |       
1815 |     </span>
1816 |   </a>
1817 |   
1818 | </li>
1819 |         
1820 |           <li class="md-nav__item">
1821 |   <a href="#43-find-most-connected-functions-hub-functions" class="md-nav__link">
1822 |     <span class="md-ellipsis">
1823 |       
1824 |         43. Find most connected functions (hub functions)
1825 |       
1826 |     </span>
1827 |   </a>
1828 |   
1829 | </li>
1830 |         
1831 |       </ul>
1832 |     </nav>
1833 |   
1834 | </li>
1835 |       
1836 |         <li class="md-nav__item">
1837 |   <a href="#security-sensitive-data-analysis" class="md-nav__link">
1838 |     <span class="md-ellipsis">
1839 |       
1840 |         Security &amp; Sensitive Data Analysis
1841 |       
1842 |     </span>
1843 |   </a>
1844 |   
1845 |     <nav class="md-nav" aria-label="Security &amp; Sensitive Data Analysis">
1846 |       <ul class="md-nav__list">
1847 |         
1848 |           <li class="md-nav__item">
1849 |   <a href="#44-find-potential-security-vulnerabilities-hardcoded-secrets" class="md-nav__link">
1850 |     <span class="md-ellipsis">
1851 |       
1852 |         44. Find potential security vulnerabilities (hardcoded secrets)
1853 |       
1854 |     </span>
1855 |   </a>
1856 |   
1857 | </li>
1858 |         
1859 |       </ul>
1860 |     </nav>
1861 |   
1862 | </li>
1863 |       
1864 |     </ul>
1865 |   
1866 | </nav>
1867 |                   </div>
1868 |                 </div>
1869 |               </div>
1870 |             
1871 |           
1872 |           
1873 |             <div class="md-content" data-md-component="content">
1874 |               
1875 |               <article class="md-content__inner md-typeset">
1876 |                 
1877 |                   
1878 | 
1879 | 
1880 | 
1881 | <h1 id="mcp-tool-cookbook">MCP Tool Cookbook</h1>
1882 | <p>This cookbook provides examples of how to use the <code>mcp</code> tool to query and understand your Python codebase. The "Tool" indicates which <code>mcp</code> tool to use, and the "JSON Arguments" are what the LLM would provide to that tool.</p>
1883 | <hr />
1884 | <h2 id="basic-queries">Basic Queries</h2>
1885 | <h3 id="1-find-a-specific-function-by-name">1. Find a specific function by name</h3>
1886 | <ul>
1887 | <li><strong>Natural Language:</strong> "Where is the function <code>foo</code> defined?"</li>
1888 | <li><strong>Tool:</strong> <code>find_code</code></li>
1889 | <li><strong>JSON Arguments:</strong></li>
1890 | </ul>
1891 | <pre><code class="language-json">{
1892 |   &quot;query&quot;: &quot;foo&quot;
1893 | }
1894 | </code></pre>
1895 | <p><img alt="Query 1" src="../images/1.png" /></p>
1896 | <h3 id="2-find-all-calls-to-a-specific-function">2. Find all calls to a specific function</h3>
1897 | <ul>
1898 | <li><strong>Natural Language:</strong> "Find all calls to the <code>helper</code> function."</li>
1899 | <li><strong>Tool:</strong> <code>analyze_code_relationships</code></li>
1900 | <li><strong>JSON Arguments:</strong></li>
1901 | </ul>
1902 | <pre><code class="language-json">{
1903 |   &quot;query_type&quot;: &quot;find_callers&quot;,
1904 |   &quot;target&quot;: &quot;helper&quot;
1905 | }
1906 | </code></pre>
1907 | <p><img alt="Query 2" src="../images/2.png" /></p>
1908 | <h3 id="3-find-what-a-function-calls">3. Find what a function calls</h3>
1909 | <ul>
1910 | <li><strong>Natural Language:</strong> "What functions are called inside the <code>foo</code> function?"</li>
1911 | <li><strong>Tool:</strong> <code>analyze_code_relationships</code></li>
1912 | <li><strong>JSON Arguments:</strong></li>
1913 | </ul>
1914 | <pre><code class="language-json">{
1915 |   &quot;query_type&quot;: &quot;find_callees&quot;,
1916 |   &quot;target&quot;: &quot;foo&quot;,
1917 |   &quot;context&quot;: &quot;/teamspace/studios/this_studio/demo/CodeGraphContext/tests/sample_project/module_a.py&quot;
1918 | }
1919 | </code></pre>
1920 | <p><img alt="Query 3" src="../images/3.png" /></p>
1921 | <h3 id="4-find-all-imports-of-a-specific-module">4. Find all imports of a specific module</h3>
1922 | <ul>
1923 | <li><strong>Natural Language:</strong> "Where is the <code>math</code> module imported?"</li>
1924 | <li><strong>Tool:</strong> <code>analyze_code_relationships</code></li>
1925 | <li><strong>JSON Arguments:</strong></li>
1926 | </ul>
1927 | <pre><code class="language-json">{
1928 |   &quot;query_type&quot;: &quot;find_importers&quot;,
1929 |   &quot;target&quot;: &quot;math&quot;
1930 | }
1931 | </code></pre>
1932 | <p><img alt="Query 4" src="../images/4.png" /></p>
1933 | <h3 id="5-find-all-methods-of-a-class">5. Find all methods of a class</h3>
1934 | <ul>
1935 | <li><strong>Natural Language:</strong> "What are the methods of the <code>A</code> class?"</li>
1936 | <li><strong>Tool:</strong> <code>analyze_code_relationships</code></li>
1937 | <li><strong>JSON Arguments:</strong></li>
1938 | </ul>
1939 | <pre><code class="language-json">{
1940 |   &quot;query_type&quot;: &quot;class_hierarchy&quot;,
1941 |   &quot;target&quot;: &quot;A&quot;
1942 | }
1943 | </code></pre>
1944 | <ul>
1945 | <li><strong>Note:</strong> The response for <code>class_hierarchy</code> includes a list of methods.</li>
1946 | </ul>
1947 | <p><img alt="Query 5" src="../images/5.png" /></p>
1948 | <h3 id="6-find-all-classes-that-inherit-from-a-specific-class">6. Find all classes that inherit from a specific class</h3>
1949 | <ul>
1950 | <li><strong>Natural Language:</strong> "Show me all classes that inherit from <code>Base</code>."</li>
1951 | <li><strong>Tool:</strong> <code>analyze_code_relationships</code></li>
1952 | <li><strong>JSON Arguments:</strong></li>
1953 | </ul>
1954 | <pre><code class="language-json">{
1955 |   &quot;query_type&quot;: &quot;class_hierarchy&quot;,
1956 |   &quot;target&quot;: &quot;Base&quot;
1957 | }
1958 | </code></pre>
1959 | <ul>
1960 | <li><strong>Note:</strong> The response for <code>class_hierarchy</code> includes a list of child classes.</li>
1961 | </ul>
1962 | <p><img alt="Query 6" src="../images/6.png" /></p>
1963 | <h3 id="7-find-all-functions-with-a-specific-decorator">7. Find all functions with a specific decorator</h3>
1964 | <ul>
1965 | <li><strong>Natural Language:</strong> "Find all functions with the <code>log_decorator</code>."</li>
1966 | <li><strong>Tool:</strong> <code>analyze_code_relationships</code></li>
1967 | <li><strong>JSON Arguments:</strong></li>
1968 | </ul>
1969 | <pre><code class="language-json">{
1970 |   &quot;query_type&quot;: &quot;find_functions_by_decorator&quot;,
1971 |   &quot;target&quot;: &quot;log_decorator&quot;
1972 | }
1973 | </code></pre>
1974 | <p><img alt="Query 7" src="../images/7.png" /></p>
1975 | <h3 id="8-find-all-dataclasses">8. Find all dataclasses</h3>
1976 | <ul>
1977 | <li><strong>Natural Language:</strong> "Find all dataclasses."</li>
1978 | <li><strong>Tool:</strong> <code>execute_cypher_query</code></li>
1979 | <li><strong>JSON Arguments:</strong></li>
1980 | </ul>
1981 | <pre><code class="language-json">{
1982 |   &quot;cypher_query&quot;: &quot;MATCH (c:Class) WHERE 'dataclass' IN c.decorators RETURN c.name, c.file_path&quot;
1983 | }
1984 | </code></pre>
1985 | <p><img alt="Query 8" src="../images/8.png" /></p>
1986 | <hr />
1987 | <h2 id="code-analysis-quality">Code Analysis &amp; Quality</h2>
1988 | <h3 id="9-find-the-5-most-complex-functions">9. Find the 5 most complex functions</h3>
1989 | <ul>
1990 | <li><strong>Natural Language:</strong> "Find the 5 most complex functions."</li>
1991 | <li><strong>Tool:</strong> <code>find_most_complex_functions</code></li>
1992 | <li><strong>JSON Arguments:</strong></li>
1993 | </ul>
1994 | <pre><code class="language-json">{
1995 |   &quot;limit&quot;: 5
1996 | }
1997 | </code></pre>
1998 | <p><img alt="Query 9" src="../images/9.png" /></p>
1999 | <h3 id="10-calculate-cyclomatic-complexity-of-a-function">10. Calculate cyclomatic complexity of a function</h3>
2000 | <ul>
2001 | <li><strong>Natural Language:</strong> "What is the cyclomatic complexity of <code>try_except_finally</code>?"</li>
2002 | <li><strong>Tool:</strong> <code>calculate_cyclomatic_complexity</code></li>
2003 | <li><strong>JSON Arguments:</strong></li>
2004 | </ul>
2005 | <pre><code class="language-json">{
2006 |   &quot;function_name&quot;: &quot;try_except_finally&quot;
2007 | }
2008 | </code></pre>
2009 | <h3 id="11-find-unused-code">11. Find unused code</h3>
2010 | <ul>
2011 | <li><strong>Natural Language:</strong> "Find unused code, but ignore API endpoints decorated with <code>@app.route</code>."</li>
2012 | <li><strong>Tool:</strong> <code>find_dead_code</code></li>
2013 | <li><strong>JSON Arguments:</strong></li>
2014 | </ul>
2015 | <pre><code class="language-json">{
2016 |   &quot;exclude_decorated_with&quot;: [&quot;@app.route&quot;]
2017 | }
2018 | </code></pre>
2019 | <p><img alt="Query 11" src="../images/11.png" /></p>
2020 | <h3 id="12-find-the-call-chain-between-two-functions">12. Find the call chain between two functions</h3>
2021 | <ul>
2022 | <li><strong>Natural Language:</strong> "What is the call chain from <code>wrapper</code> to <code>helper</code>?"</li>
2023 | <li><strong>Tool:</strong> <code>analyze_code_relationships</code></li>
2024 | <li><strong>JSON Arguments:</strong></li>
2025 | </ul>
2026 | <pre><code class="language-json">{
2027 |   &quot;query_type&quot;: &quot;call_chain&quot;,
2028 |   &quot;target&quot;: &quot;wrapper-&gt;helper&quot;
2029 | }
2030 | </code></pre>
2031 | <p><img alt="Query 12" src="../images/12.png" /></p>
2032 | <h3 id="13-find-all-direct-and-indirect-callers-of-a-function">13. Find all direct and indirect callers of a function</h3>
2033 | <ul>
2034 | <li><strong>Natural Language:</strong> "Show me all functions that eventually call the <code>helper</code> function."</li>
2035 | <li><strong>Tool:</strong> <code>analyze_code_relationships</code></li>
2036 | <li><strong>JSON Arguments:</strong></li>
2037 | </ul>
2038 | <pre><code class="language-json">{
2039 |   &quot;query_type&quot;: &quot;find_all_callers&quot;,
2040 |   &quot;target&quot;: &quot;helper&quot;
2041 | }
2042 | </code></pre>
2043 | <p><img alt="Query 13" src="../images/13.png" /></p>
2044 | <h3 id="14-find-functions-by-argument-name">14. Find functions by argument name</h3>
2045 | <ul>
2046 | <li><strong>Natural Language:</strong> "Find all functions that take <code>self</code> as an argument."</li>
2047 | <li><strong>Tool:</strong> <code>analyze_code_relationships</code></li>
2048 | <li><strong>JSON Arguments:</strong></li>
2049 | </ul>
2050 | <pre><code class="language-json">{
2051 |   &quot;query_type&quot;: &quot;find_functions_by_argument&quot;,
2052 |   &quot;target&quot;: &quot;self&quot;
2053 | }
2054 | </code></pre>
2055 | <p><img alt="Query 14" src="../images/14.png" /></p>
2056 | <h3 id="15-list-all-python-package-imports-from-a-directory">15. List all python package imports from a directory</h3>
2057 | <ul>
2058 | <li><strong>Natural Language:</strong> "List all python package imports from my project directory."</li>
2059 | <li><strong>Tool:</strong> <code>execute_cypher_query</code></li>
2060 | <li><strong>JSON Arguments:</strong></li>
2061 | </ul>
2062 | <pre><code class="language-json">{
2063 |   &quot;cypher_query&quot;: &quot;MATCH (f:File)-[:IMPORTS]-&gt;(m:Module) WHERE f.path ENDS WITH '.py' RETURN DISTINCT m.name&quot;
2064 | }
2065 | </code></pre>
2066 | <hr />
2067 | <h2 id="repository-information-queries">Repository Information Queries</h2>
2068 | <h3 id="16-list-all-indexed-projects">16. List all indexed projects</h3>
2069 | <ul>
2070 | <li><strong>Natural Language:</strong> "List all projects I have indexed."</li>
2071 | <li><strong>Tool:</strong> <code>list_indexed_repositories</code></li>
2072 | <li><strong>JSON Arguments:</strong></li>
2073 | </ul>
2074 | <pre><code class="language-json">  {}
2075 | </code></pre>
2076 | <p><img alt="Query 16" src="../images/16.png" /></p>
2077 | <h3 id="17-check-the-status-of-an-indexing-job">17. Check the status of an indexing job</h3>
2078 | <ul>
2079 | <li><strong>Natural Language:</strong> "What is the status of job <code>4cb9a60e-c1b1-43a7-9c94-c840771506bc</code>?"</li>
2080 | <li><strong>Tool:</strong> <code>check_job_status</code></li>
2081 | <li><strong>JSON Arguments:</strong></li>
2082 | </ul>
2083 | <pre><code class="language-json">{
2084 |   &quot;job_id&quot;: &quot;4cb9a60e-c1b1-43a7-9c94-c840771506bc&quot;
2085 | }
2086 | </code></pre>
2087 | <h3 id="18-list-all-background-jobs">18. List all background jobs</h3>
2088 | <ul>
2089 | <li><strong>Natural Language:</strong> "Show me all background jobs."</li>
2090 | <li><strong>Tool:</strong> <code>list_jobs</code></li>
2091 | <li><strong>JSON Arguments:</strong></li>
2092 | </ul>
2093 | <pre><code class="language-json">  {}
2094 | </code></pre>
2095 | <hr />
2096 | <h2 id="advanced-cypher-queries">Advanced Cypher Queries</h2>
2097 | <p>These examples use the <code>execute_cypher_query</code> tool for more specific and complex questions.</p>
2098 | <h3 id="19-find-all-function-definitions">19. Find all function definitions</h3>
2099 | <ul>
2100 | <li><strong>Natural Language:</strong> "Find all function definitions in the codebase."</li>
2101 | <li><strong>JSON Arguments:</strong></li>
2102 | </ul>
2103 | <pre><code class="language-json">{
2104 |   &quot;cypher_query&quot;: &quot;MATCH (n:Function) RETURN n.name, n.file_path, n.line_number LIMIT 50&quot;
2105 | }
2106 | </code></pre>
2107 | <p><img alt="Query 19" src="../images/19.png" /></p>
2108 | <h3 id="20-find-all-classes">20. Find all classes</h3>
2109 | <ul>
2110 | <li><strong>Natural Language:</strong> "Show me all the classes."</li>
2111 | <li><strong>JSON Arguments:</strong></li>
2112 | </ul>
2113 | <pre><code class="language-json">{
2114 |   &quot;cypher_query&quot;: &quot;MATCH (n:Class) RETURN n.name, n.file_path, n.line_number LIMIT 50&quot;
2115 | }
2116 | </code></pre>
2117 | <p><img alt="Query 20" src="../images/20.png" /></p>
2118 | <h3 id="21-find-all-functions-in-a-file">21. Find all functions in a file</h3>
2119 | <ul>
2120 | <li><strong>Natural Language:</strong> "Find all functions in <code>module_a.py</code>."</li>
2121 | <li><strong>JSON Arguments:</strong></li>
2122 | </ul>
2123 | <pre><code class="language-json">{
2124 |   &quot;cypher_query&quot;: &quot;MATCH (f:Function) WHERE f.file_path ENDS WITH 'module_a.py' RETURN f.name&quot;
2125 | }
2126 | </code></pre>
2127 | <p><img alt="Query 21" src="../images/21.png" /></p>
2128 | <h3 id="22-find-all-classes-in-a-file">22. Find all classes in a file</h3>
2129 | <ul>
2130 | <li><strong>Natural Language:</strong> "Find all classes in <code>advanced_classes.py</code>."</li>
2131 | <li><strong>JSON Arguments:</strong></li>
2132 | </ul>
2133 | <pre><code class="language-json">{
2134 |   &quot;cypher_query&quot;: &quot;MATCH (c:Class) WHERE c.file_path ENDS WITH 'advanced_classes.py' RETURN c.name&quot;
2135 | }
2136 | </code></pre>
2137 | <p><img alt="Query 22" src="../images/22.png" /></p>
2138 | <h3 id="23-list-all-top-level-functions-and-classes-in-a-file">23. List all top-level functions and classes in a file</h3>
2139 | <ul>
2140 | <li><strong>Natural Language:</strong> "List all top-level functions and classes in <code>module_a.py</code>."</li>
2141 | <li><strong>JSON Arguments:</strong></li>
2142 | </ul>
2143 | <pre><code class="language-json">{
2144 |   &quot;cypher_query&quot;: &quot;MATCH (f:File)-[:CONTAINS]-&gt;(n) WHERE f.name = 'module_a.py' AND (n:Function OR n:Class) AND n.context IS NULL RETURN n.name&quot;
2145 | }
2146 | </code></pre>
2147 | <p><img alt="Query 23" src="../images/23.png" /></p>
2148 | <h3 id="24-find-functions-in-one-module-that-call-a-function-in-another">24. Find functions in one module that call a function in another</h3>
2149 | <ul>
2150 | <li><strong>Natural Language:</strong> "Find functions in <code>module_a.py</code> that call <code>helper</code> in <code>module_b.py</code>."</li>
2151 | <li><strong>JSON Arguments:</strong></li>
2152 | </ul>
2153 | <pre><code class="language-json">{
2154 |   &quot;cypher_query&quot;: &quot;MATCH (caller:Function)-[:CALLS]-&gt;(callee:Function {name: 'helper'}) WHERE caller.file_path ENDS WITH 'module_a.py' AND callee.file_path ENDS WITH 'module_b.py' RETURN caller.name&quot;
2155 | }
2156 | </code></pre>
2157 | <p><img alt="Query 24" src="../images/24.png" /></p>
2158 | <h3 id="25-find-circular-file-imports">25. Find circular file imports</h3>
2159 | <ul>
2160 | <li><strong>Natural Language:</strong> "Are there any circular dependencies between files?"</li>
2161 | <li><strong>JSON Arguments:</strong></li>
2162 | </ul>
2163 | <pre><code class="language-json">{
2164 |   &quot;cypher_query&quot;: &quot;MATCH (f1:File)-[:IMPORTS]-&gt;(m2:Module), (f2:File)-[:IMPORTS]-&gt;(m1:Module) WHERE f1.name = m1.name + '.py' AND f2.name = m2.name + '.py' RETURN f1.name, f2.name&quot;
2165 | }
2166 | </code></pre>
2167 | <h3 id="26-find-all-functions-with-more-than-5-arguments">26. Find all functions with more than 5 arguments</h3>
2168 | <ul>
2169 | <li><strong>Natural Language:</strong> "Find all functions with a large number of arguments."</li>
2170 | <li><strong>JSON Arguments:</strong></li>
2171 | </ul>
2172 | <pre><code class="language-json">{
2173 |   &quot;cypher_query&quot;: &quot;MATCH (f:Function) WHERE size(f.args) &gt; 5 RETURN f.name, f.file_path, size(f.args) as arg_count&quot;
2174 | }
2175 | </code></pre>
2176 | <p><img alt="Query 26" src="../images/26.png" /></p>
2177 | <h3 id="27-find-all-functions-in-a-file-that-have-a-docstring">27. Find all functions in a file that have a docstring</h3>
2178 | <ul>
2179 | <li><strong>Natural Language:</strong> "Find all functions in <code>module_a.py</code> that have a docstring."</li>
2180 | <li><strong>JSON Arguments:</strong></li>
2181 | </ul>
2182 | <pre><code class="language-json">{
2183 |   &quot;cypher_query&quot;: &quot;MATCH (f:Function) WHERE f.file_path ENDS WITH 'module_a.py' AND f.docstring IS NOT NULL AND f.docstring &lt;&gt; '' RETURN f.name&quot;
2184 | }
2185 | </code></pre>
2186 | <h3 id="28-find-all-classes-that-have-a-specific-method">28. Find all classes that have a specific method</h3>
2187 | <ul>
2188 | <li><strong>Natural Language:</strong> "Find all classes that have a <code>greet</code> method."</li>
2189 | <li><strong>JSON Arguments:</strong></li>
2190 | </ul>
2191 | <pre><code class="language-json">{
2192 |   &quot;cypher_query&quot;: &quot;MATCH (c:Class)-[:CONTAINS]-&gt;(m:Function {name: 'greet'}) RETURN c.name, c.file_path&quot;
2193 | }
2194 | </code></pre>
2195 | <p><img alt="Query 28" src="../images/28.png" /></p>
2196 | <h3 id="29-find-the-depth-of-inheritance-for-all-classes">29. Find the depth of inheritance for all classes</h3>
2197 | <ul>
2198 | <li><strong>Natural Language:</strong> "How deep are the inheritance chains for all classes?"</li>
2199 | <li><strong>JSON Arguments:</strong></li>
2200 | </ul>
2201 | <pre><code class="language-json">{
2202 |   &quot;cypher_query&quot;: &quot;MATCH (c:Class) OPTIONAL MATCH path = (c)-[:INHERITS*]-&gt;(parent:Class) RETURN c.name, c.file_path, length(path) AS depth ORDER BY depth DESC&quot;
2203 | }
2204 | </code></pre>
2205 | <p><img alt="Query 29" src="../images/29.png" /></p>
2206 | <h3 id="30-find-all-functions-that-have-a-docstring">30. Find all functions that have a docstring</h3>
2207 | <ul>
2208 | <li><strong>Natural Language:</strong> "Show me all functions that are documented."</li>
2209 | <li><strong>JSON Arguments:</strong></li>
2210 | </ul>
2211 | <pre><code class="language-json">{
2212 |   &quot;cypher_query&quot;: &quot;MATCH (f:Function) WHERE f.docstring IS NOT NULL AND f.docstring &lt;&gt; '' RETURN f.name, f.file_path LIMIT 50&quot;
2213 | }
2214 | </code></pre>
2215 | <p><img alt="Query 30" src="../images/30.png" /></p>
2216 | <h3 id="31-find-all-decorated-methods-in-a-class">31. Find all decorated methods in a class</h3>
2217 | <ul>
2218 | <li><strong>Natural Language:</strong> "Find all decorated methods in the <code>Child</code> class."</li>
2219 | <li><strong>JSON Arguments:</strong></li>
2220 | </ul>
2221 | <pre><code class="language-json">{
2222 |   &quot;cypher_query&quot;: &quot;MATCH (c:Class {name: 'Child'})-[:CONTAINS]-&gt;(m:Function) WHERE m.decorators IS NOT NULL AND size(m.decorators) &gt; 0 RETURN m.name&quot;
2223 | }
2224 | </code></pre>
2225 | <p><img alt="Query 31" src="../images/31.png" /></p>
2226 | <h3 id="32-find-the-number-of-functions-in-each-file">32. Find the number of functions in each file</h3>
2227 | <ul>
2228 | <li><strong>Natural Language:</strong> "How many functions are in each file?"</li>
2229 | <li><strong>JSON Arguments:</strong></li>
2230 | </ul>
2231 | <pre><code class="language-json">{
2232 |   &quot;cypher_query&quot;: &quot;MATCH (f:Function) RETURN f.file_path, count(f) AS function_count ORDER BY function_count DESC&quot;
2233 | }
2234 | </code></pre>
2235 | <p><img alt="Query 32" src="../images/32.png" /></p>
2236 | <h3 id="33-find-all-methods-that-override-a-parent-method">33. Find all methods that override a parent method</h3>
2237 | <ul>
2238 | <li><strong>Natural Language:</strong> "Find all methods that are overridden from a parent class."</li>
2239 | <li><strong>JSON Arguments:</strong></li>
2240 | </ul>
2241 | <pre><code class="language-json">{
2242 |   &quot;cypher_query&quot;: &quot;MATCH (c:Class)-[:INHERITS]-&gt;(p:Class), (c)-[:CONTAINS]-&gt;(m:Function), (p)-[:CONTAINS]-&gt;(m_parent:Function) WHERE m.name = m_parent.name RETURN m.name as method, c.name as child_class, p.name as parent_class&quot;
2243 | }
2244 | </code></pre>
2245 | <p><img alt="Query 33" src="../images/33.png" /></p>
2246 | <h3 id="34-find-all-functions-that-call-super">34. Find all functions that call <code>super()</code></h3>
2247 | <ul>
2248 | <li><strong>Natural Language:</strong> "Find all methods that call their parent's method via <code>super()</code>."</li>
2249 | <li><strong>JSON Arguments:</strong></li>
2250 | </ul>
2251 | <pre><code class="language-json">{
2252 |   &quot;cypher_query&quot;: &quot;MATCH (f:Function)-[r:CALLS]-&gt;() WHERE r.full_call_name STARTS WITH 'super(' RETURN f.name, f.file_path&quot;
2253 | }
2254 | </code></pre>
2255 | <p><img alt="Query 34" src="../images/34.png" /></p>
2256 | <h3 id="35-find-all-calls-to-a-function-with-a-specific-argument">35. Find all calls to a function with a specific argument</h3>
2257 | <ul>
2258 | <li><strong>Natural Language:</strong> "Find all calls to <code>helper</code> with the argument <code>x</code>."</li>
2259 | <li><strong>JSON Arguments:</strong></li>
2260 | </ul>
2261 | <pre><code class="language-json">{
2262 |   &quot;cypher_query&quot;: &quot;MATCH ()-[r:CALLS]-&gt;(f:Function {name: 'helper'}) WHERE 'x' IN r.args RETURN r.full_call_name, r.line_number, r.file_path&quot;
2263 | }
2264 | </code></pre>
2265 | <p><img alt="Query 35" src="../images/35.png" /></p>
2266 | <h3 id="36-find-all-functions-that-are-not-called-by-any-other-function">36. Find all functions that are not called by any other function</h3>
2267 | <ul>
2268 | <li><strong>Natural Language:</strong> "Find all dead code (functions that are never called)."</li>
2269 | <li><strong>JSON Arguments:</strong></li>
2270 | </ul>
2271 | <pre><code class="language-json">{
2272 |   &quot;cypher_query&quot;: &quot;MATCH (f:Function) WHERE NOT (()-[:CALLS]-&gt;(f)) AND f.is_dependency = false RETURN f.name, f.file_path&quot;
2273 | }
2274 | </code></pre>
2275 | <p><img alt="Query 36" src="../images/36.png" /></p>
2276 | <h3 id="37-find-all-functions-that-are-called-with-a-specific-argument">37. Find all functions that are called with a specific argument</h3>
2277 | <ul>
2278 | <li><strong>Natural Language:</strong> "Find all calls to <code>print</code> with the argument <code>'hello'</code>."</li>
2279 | <li><strong>JSON Arguments:</strong></li>
2280 | </ul>
2281 | <pre><code class="language-json">{
2282 |   &quot;cypher_query&quot;: &quot;MATCH (c:Call) WHERE c.name = 'print' AND 'hello' IN c.args RETURN c.file, c.lineno&quot;
2283 | }
2284 | </code></pre>
2285 | <h3 id="38-find-all-direct-and-indirect-callees-of-a-function">38. Find all direct and indirect callees of a function</h3>
2286 | <ul>
2287 | <li><strong>Natural Language:</strong> "Show me all functions that are eventually called by the <code>foo</code> function."</li>
2288 | <li><strong>Tool:</strong> <code>analyze_code_relationships</code></li>
2289 | <li><strong>JSON Arguments:</strong></li>
2290 | </ul>
2291 | <pre><code class="language-json">{
2292 |   &quot;query_type&quot;: &quot;find_all_callees&quot;,
2293 |   &quot;target&quot;: &quot;foo&quot;,
2294 |   &quot;context&quot;: &quot;/teamspace/studios/this_studio/demo/CodeGraphContext/tests/sample_project/module_a.py&quot;
2295 | }
2296 | </code></pre>
2297 | <p><img alt="Query 38" src="../images/38.png" /></p>
2298 | <h3 id="39-find-all-functions-that-are-overridden">39. Find all functions that are overridden</h3>
2299 | <ul>
2300 | <li><strong>Natural Language:</strong> "Find all functions that are overridden."</li>
2301 | <li><strong>Tool:</strong> <code>analyze_code_relationships</code></li>
2302 | <li><strong>JSON Arguments:</strong></li>
2303 | </ul>
2304 | <pre><code class="language-json">{
2305 |   &quot;query_type&quot;: &quot;overrides&quot;,
2306 |   &quot;target&quot;: &quot;foo&quot;
2307 | }
2308 | </code></pre>
2309 | <p><img alt="Query 39" src="../images/39.png" /></p>
2310 | <h3 id="40-find-all-modules-imported-by-module_a">40. Find all modules imported by <code>module_a</code></h3>
2311 | <ul>
2312 | <li><strong>Natural Language:</strong> "Find all modules imported by <code>module_a</code>."</li>
2313 | <li><strong>Tool:</strong> <code>execute_cypher_query</code></li>
2314 | <li><strong>JSON Arguments:</strong></li>
2315 | </ul>
2316 | <pre><code class="language-json">{
2317 |   &quot;cypher_query&quot;: &quot;MATCH (f:File {name: 'module_a.py'})-[:IMPORTS]-&gt;(m:Module) RETURN m.name AS imported_module_name&quot;
2318 | }
2319 | </code></pre>
2320 | <p><img alt="Query 40" src="../images/40.png" /></p>
2321 | <h3 id="41-find-large-functions-that-should-be-refactored">41. Find large functions that should be refactored</h3>
2322 | <ul>
2323 | <li><strong>Natural Language:</strong> "Find functions with more than 20 lines of code that might need refactoring."</li>
2324 | <li><strong>Tool:</strong> <code>execute_cypher_query</code></li>
2325 | <li><strong>JSON Arguments:</strong></li>
2326 | </ul>
2327 | <pre><code class="language-json">{
2328 |   &quot;cypher_query&quot;: &quot;MATCH (f:Function)\n    WHERE f.end_line - f.line_number &gt; 20\n    RETURN f&quot;
2329 | }
2330 | </code></pre>
2331 | <p><img alt="Query 41" src="../images/41.png" /></p>
2332 | <h3 id="42-find-recursive-functions">42. Find recursive functions</h3>
2333 | <ul>
2334 | <li><strong>Natural Language:</strong> "Find all functions that call themselves (recursive functions)."</li>
2335 | <li><strong>Tool:</strong> <code>execute_cypher_query</code></li>
2336 | <li><strong>JSON Arguments:</strong></li>
2337 | </ul>
2338 | <pre><code class="language-json">{
2339 |   &quot;cypher_query&quot;: &quot;MATCH p=(f:Function)-[:CALLS]-&gt;(f2:Function)\n    WHERE f.name = f2.name AND f.file_path = f2.file_path\n    RETURN p&quot;
2340 | }
2341 | </code></pre>
2342 | <p><img alt="Query 42" src="../images/42.png" /></p>
2343 | <h3 id="43-find-most-connected-functions-hub-functions">43. Find most connected functions (hub functions)</h3>
2344 | <ul>
2345 | <li><strong>Natural Language:</strong> "Find the functions that are most central to the codebase (called by many and call many others)."</li>
2346 | <li><strong>Tool:</strong> <code>execute_cypher_query</code></li>
2347 | <li><strong>JSON Arguments:</strong></li>
2348 | </ul>
2349 | <pre><code class="language-json">{
2350 |   &quot;cypher_query&quot;: &quot;MATCH (f:Function)\n    OPTIONAL MATCH (f)-[:CALLS]-&gt;(callee:Function)\n    OPTIONAL MATCH (caller:Function)-[:CALLS]-&gt;(f)\n    WITH f, count(DISTINCT callee) AS calls_out, count(DISTINCT caller) AS calls_in\n    ORDER BY (calls_out + calls_in) DESC\n    LIMIT 5\n    MATCH p=(f)-[*0..2]-()\n    RETURN p&quot;
2351 | }
2352 | </code></pre>
2353 | <p><img alt="Query 43" src="../images/43.png" /></p>
2354 | <h2 id="security-sensitive-data-analysis">Security &amp; Sensitive Data Analysis</h2>
2355 | <h3 id="44-find-potential-security-vulnerabilities-hardcoded-secrets">44. Find potential security vulnerabilities (hardcoded secrets)</h3>
2356 | <ul>
2357 | <li><strong>Natural Language:</strong> "Find potential hardcoded passwords, API keys, or secrets in the codebase."</li>
2358 | <li><strong>Tool:</strong> <code>execute_cypher_query</code></li>
2359 | <li><strong>JSON Arguments:</strong></li>
2360 | </ul>
2361 | <pre><code class="language-json">{
2362 |   &quot;cypher_query&quot;: &quot;WITH [\&quot;password\&quot;,  \&quot;api_key\&quot;, \&quot;apikey\&quot;,    \&quot;secret_token\&quot;, \&quot;token\&quot;, \&quot;auth\&quot;, \&quot;access_key\&quot;, \&quot;private_key\&quot;, \&quot;client_secret\&quot;, \&quot;sessionid\&quot;, \&quot;jwt\&quot;] AS keywords\n    MATCH (f:Function)\n    WHERE ANY(word IN keywords WHERE toLower(f.source_code) CONTAINS word)\n    RETURN f&quot;
2363 | }
2364 | </code></pre>
2365 | 
2366 | 
2367 | 
2368 | 
2369 | 
2370 | 
2371 | 
2372 | 
2373 | 
2374 | 
2375 | 
2376 | 
2377 |                 
2378 |               </article>
2379 |             </div>
2380 |           
2381 |           
2382 | <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
2383 |         </div>
2384 |         
2385 |       </main>
2386 |       
2387 |         <footer class="md-footer">
2388 |   
2389 |   <div class="md-footer-meta md-typeset">
2390 |     <div class="md-footer-meta__inner md-grid">
2391 |       <div class="md-copyright">
2392 |   
2393 |   
2394 |     Made with
2395 |     <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
2396 |       Material for MkDocs
2397 |     </a>
2398 |   
2399 | </div>
2400 |       
2401 |     </div>
2402 |   </div>
2403 | </footer>
2404 |       
2405 |     </div>
2406 |     <div class="md-dialog" data-md-component="dialog">
2407 |       <div class="md-dialog__inner md-typeset"></div>
2408 |     </div>
2409 |     
2410 |     
2411 |     
2412 |       
2413 |       
2414 |       <script id="__config" type="application/json">{"annotate": null, "base": "..", "features": [], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
2415 |     
2416 |     
2417 |       <script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
2418 |       
2419 |     
2420 |   </body>
2421 | </html>
```
Page 18/22FirstPrevNextLast