This is page 4 of 17. Use http://codebase.md/shashankss1205/codegraphcontext?lines=false&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
--------------------------------------------------------------------------------
/website/src/components/DemoSection.tsx:
--------------------------------------------------------------------------------
```typescript
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog";
import { motion } from "framer-motion";
import graphTotalImage from "../assets/graph-total.png";
import functionCallsImage from "../assets/function-calls.png";
import hierarchyImage from "../assets/hierarchy.png";
import type { Variants } from "framer-motion";
const DemoSection = () => {
const visualizations = [
{
title: "Complete Code Graph",
description: "All components and relationships between code elements.",
image: graphTotalImage,
badge: "Full Overview",
aos: "fade-up",
},
{
title: "Function Call Analysis",
description: "Direct and indirect function calls across directories.",
image: functionCallsImage,
badge: "Call Chains",
aos: "zoom-in",
},
{
title: "Project Hierarchy",
description: "Hierarchical structure of files and dependencies.",
image: hierarchyImage,
badge: "File Structure",
aos: "flip-up",
},
];
const containerVariants: Variants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: { staggerChildren: 0.2, delayChildren: 0.1 },
},
};
const itemVariants: Variants = {
hidden: { y: 20, opacity: 0 },
visible: {
y: 0,
opacity: 1,
transition: { duration: 0.6, ease: "easeOut" },
},
};
return (
<section
className="py-20 px-4 bg-gradient-to-b from-background to-secondary/10"
data-aos="fade-in"
data-aos-duration="800"
>
<div className="container mx-auto max-w-7xl">
{/* Heading Section */}
<motion.div
className="text-center mb-16"
initial={{ opacity: 0, y: -20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, amount: 0.5 }}
transition={{ duration: 0.7 }}
>
<h2
className="text-3xl sm:text-4xl md:text-5xl font-bold mb-6 bg-gradient-to-r from-primary via-primary to-accent bg-clip-text text-transparent py-2"
data-aos="fade-down"
data-aos-duration="1000"
>
See CodeGraphContext in Action
</h2>
<p
className="text-xl text-muted-foreground max-w-3xl mx-auto mb-12"
data-aos="fade-up"
data-aos-delay="200"
>
Watch how CodeGraphContext transforms complex codebases into
interactive knowledge graphs.
</p>
</motion.div>
{/* Embedded Demo Video */}
<motion.div
className="max-w-4xl mx-auto mb-16"
initial={{ opacity: 0, scale: 0.9 }}
whileInView={{ opacity: 1, scale: 1 }}
viewport={{ once: true, amount: 0.3 }}
transition={{ duration: 0.8, ease: "easeInOut" }}
data-aos="zoom-in"
>
<div className="relative aspect-video rounded-lg overflow-hidden shadow-2xl border border-border/50">
<iframe
src="https://www.youtube.com/embed/KYYSdxhg1xU?autoplay=1&mute=1&loop=1&playlist=KYYSdxhg1xU"
title="CodeGraphContext Demo"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
className="w-full h-full"
/>
</div>
</motion.div>
{/* Interactive Visualizations Section */}
<div className="mb-12">
<h3
className="text-3xl font-bold text-center mb-8"
data-aos="fade-up"
data-aos-delay="100"
>
Interactive Visualizations
</h3>
<motion.div
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true, amount: 0.2 }}
>
{visualizations.map((viz, index) => (
<motion.div
key={index}
variants={itemVariants}
data-aos={viz.aos}
data-aos-delay={index * 150}
>
<Card className="group hover:shadow-xl transition-all duration-300 border-border/50 overflow-hidden w-full h-full bg-background/70 backdrop-blur-sm">
<Dialog>
<DialogTrigger asChild>
<div className="relative cursor-pointer flex flex-col h-full">
<div className="relative">
<img
src={viz.image}
alt={viz.title}
className="w-full h-48 object-cover group-hover:scale-105 transition-transform duration-300"
loading="lazy"
/>
<Badge className="absolute top-2 left-2 text-xs">
{viz.badge}
</Badge>
</div>
<CardContent className="p-6 flex-grow flex flex-col">
<h4 className="text-xl font-semibold mb-3 group-hover:text-primary transition-colors">
{viz.title}
</h4>
<p className="text-base text-muted-foreground flex-grow">
{viz.description}
</p>
</CardContent>
</div>
</DialogTrigger>
{/* Dialog Content */}
<DialogContent className="max-w-5xl w-full">
<img
src={viz.image}
alt={`${viz.title} Visualization`}
className="w-full h-auto max-h-[80vh] object-contain rounded-lg"
/>
</DialogContent>
</Dialog>
</Card>
</motion.div>
))}
</motion.div>
</div>
</div>
</section>
);
};
export default DemoSection;
```
--------------------------------------------------------------------------------
/tests/sample_project_rust/src/structs_enums.rs:
--------------------------------------------------------------------------------
```rust
// structs_enums.rs - Demonstrates Rust structs and enums
use std::fmt;
/// Basic struct with public fields
#[derive(Debug, Clone, PartialEq)]
pub struct Person {
pub name: String,
pub age: u32,
}
/// Struct with private fields
#[derive(Debug)]
pub struct BankAccount {
balance: f64,
account_number: String,
}
/// Tuple struct
#[derive(Debug, Clone, Copy)]
pub struct Point(pub i32, pub i32);
/// Unit struct
#[derive(Debug)]
pub struct Unit;
/// Struct with lifetime parameter
#[derive(Debug)]
pub struct BookReference<'a> {
title: &'a str,
author: &'a str,
}
/// Generic struct
#[derive(Debug)]
pub struct Container<T> {
value: T,
}
impl Person {
/// Constructor function (associated function)
pub fn new(name: String, age: u32) -> Self {
Self { name, age }
}
/// Method with immutable self
pub fn greet(&self) -> String {
format!("Hello, my name is {} and I'm {} years old", self.name, self.age)
}
/// Method with mutable self
pub fn have_birthday(&mut self) {
self.age += 1;
}
/// Method consuming self
pub fn into_name(self) -> String {
self.name
}
/// Method returning reference
pub fn get_name(&self) -> &str {
&self.name
}
/// Associated function
pub fn default_person() -> Self {
Self {
name: String::from("Unknown"),
age: 0,
}
}
/// Method with additional parameters
pub fn is_older_than(&self, other: &Person) -> bool {
self.age > other.age
}
}
impl BankAccount {
pub fn new(account_number: String, initial_balance: f64) -> Self {
Self {
balance: initial_balance,
account_number,
}
}
pub fn deposit(&mut self, amount: f64) -> Result<(), String> {
if amount <= 0.0 {
return Err("Deposit amount must be positive".to_string());
}
self.balance += amount;
Ok(())
}
pub fn withdraw(&mut self, amount: f64) -> Result<(), String> {
if amount <= 0.0 {
return Err("Withdrawal amount must be positive".to_string());
}
if amount > self.balance {
return Err("Insufficient funds".to_string());
}
self.balance -= amount;
Ok(())
}
pub fn get_balance(&self) -> f64 {
self.balance
}
}
impl Point {
pub fn new(x: i32, y: i32) -> Self {
Point(x, y)
}
pub fn distance_from_origin(&self) -> f64 {
((self.0.pow(2) + self.1.pow(2)) as f64).sqrt()
}
pub fn translate(&mut self, dx: i32, dy: i32) {
self.0 += dx;
self.1 += dy;
}
}
impl<T> Container<T> {
pub fn new(value: T) -> Self {
Self { value }
}
pub fn get(&self) -> &T {
&self.value
}
pub fn set(&mut self, value: T) {
self.value = value;
}
pub fn into_inner(self) -> T {
self.value
}
}
// Enums
/// Simple enum
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Status {
Active,
Inactive,
Pending,
}
/// Enum with data
#[derive(Debug, Clone, PartialEq)]
pub enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(u8, u8, u8),
}
/// Result-like enum
#[derive(Debug)]
pub enum MyResult<T, E> {
Ok(T),
Err(E),
}
/// Option-like enum
#[derive(Debug)]
pub enum MyOption<T> {
Some(T),
None,
}
/// Enum with methods
#[derive(Debug, Clone)]
pub enum TrafficLight {
Red,
Yellow,
Green,
}
impl TrafficLight {
pub fn duration(&self) -> u32 {
match self {
TrafficLight::Red => 60,
TrafficLight::Yellow => 10,
TrafficLight::Green => 50,
}
}
pub fn next(&self) -> TrafficLight {
match self {
TrafficLight::Red => TrafficLight::Green,
TrafficLight::Yellow => TrafficLight::Red,
TrafficLight::Green => TrafficLight::Yellow,
}
}
}
impl Message {
pub fn call(&self) {
match self {
Message::Quit => println!("Quitting"),
Message::Move { x, y } => println!("Moving to ({}, {})", x, y),
Message::Write(text) => println!("Writing: {}", text),
Message::ChangeColor(r, g, b) => println!("Changing color to RGB({}, {}, {})", r, g, b),
}
}
}
/// Pattern matching with enums
pub fn process_message(msg: Message) -> String {
match msg {
Message::Quit => "Quit command".to_string(),
Message::Move { x, y } if x > 0 && y > 0 => format!("Moving to positive quadrant: ({}, {})", x, y),
Message::Move { x, y } => format!("Moving to: ({}, {})", x, y),
Message::Write(text) => format!("Text: {}", text),
Message::ChangeColor(r, g, b) => format!("Color: RGB({}, {}, {})", r, g, b),
}
}
/// Enum with tuple variants
#[derive(Debug)]
pub enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
impl IpAddr {
pub fn is_loopback(&self) -> bool {
match self {
IpAddr::V4(127, 0, 0, 1) => true,
IpAddr::V6(s) if s == "::1" => true,
_ => false,
}
}
}
impl fmt::Display for Person {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Person {{ name: {}, age: {} }}", self.name, self.age)
}
}
impl fmt::Display for Status {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Status::Active => write!(f, "Active"),
Status::Inactive => write!(f, "Inactive"),
Status::Pending => write!(f, "Pending"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_person_creation() {
let person = Person::new("Alice".to_string(), 30);
assert_eq!(person.name, "Alice");
assert_eq!(person.age, 30);
}
#[test]
fn test_person_birthday() {
let mut person = Person::new("Bob".to_string(), 25);
person.have_birthday();
assert_eq!(person.age, 26);
}
#[test]
fn test_message_matching() {
let msg = Message::Move { x: 10, y: 20 };
let result = process_message(msg);
assert!(result.contains("Moving"));
}
}
```
--------------------------------------------------------------------------------
/website/src/components/ui/carousel.tsx:
--------------------------------------------------------------------------------
```typescript
import * as React from "react";
import useEmblaCarousel, { type UseEmblaCarouselType } from "embla-carousel-react";
import { ArrowLeft, ArrowRight } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
type CarouselApi = UseEmblaCarouselType[1];
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
type CarouselOptions = UseCarouselParameters[0];
type CarouselPlugin = UseCarouselParameters[1];
type CarouselProps = {
opts?: CarouselOptions;
plugins?: CarouselPlugin;
orientation?: "horizontal" | "vertical";
setApi?: (api: CarouselApi) => void;
};
type CarouselContextProps = {
carouselRef: ReturnType<typeof useEmblaCarousel>[0];
api: ReturnType<typeof useEmblaCarousel>[1];
scrollPrev: () => void;
scrollNext: () => void;
canScrollPrev: boolean;
canScrollNext: boolean;
} & CarouselProps;
const CarouselContext = React.createContext<CarouselContextProps | null>(null);
function useCarousel() {
const context = React.useContext(CarouselContext);
if (!context) {
throw new Error("useCarousel must be used within a <Carousel />");
}
return context;
}
const Carousel = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement> & CarouselProps>(
({ orientation = "horizontal", opts, setApi, plugins, className, children, ...props }, ref) => {
const [carouselRef, api] = useEmblaCarousel(
{
...opts,
axis: orientation === "horizontal" ? "x" : "y",
},
plugins,
);
const [canScrollPrev, setCanScrollPrev] = React.useState(false);
const [canScrollNext, setCanScrollNext] = React.useState(false);
const onSelect = React.useCallback((api: CarouselApi) => {
if (!api) {
return;
}
setCanScrollPrev(api.canScrollPrev());
setCanScrollNext(api.canScrollNext());
}, []);
const scrollPrev = React.useCallback(() => {
api?.scrollPrev();
}, [api]);
const scrollNext = React.useCallback(() => {
api?.scrollNext();
}, [api]);
const handleKeyDown = React.useCallback(
(event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.key === "ArrowLeft") {
event.preventDefault();
scrollPrev();
} else if (event.key === "ArrowRight") {
event.preventDefault();
scrollNext();
}
},
[scrollPrev, scrollNext],
);
React.useEffect(() => {
if (!api || !setApi) {
return;
}
setApi(api);
}, [api, setApi]);
React.useEffect(() => {
if (!api) {
return;
}
onSelect(api);
api.on("reInit", onSelect);
api.on("select", onSelect);
return () => {
api?.off("select", onSelect);
};
}, [api, onSelect]);
return (
<CarouselContext.Provider
value={{
carouselRef,
api: api,
opts,
orientation: orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
scrollPrev,
scrollNext,
canScrollPrev,
canScrollNext,
}}
>
<div
ref={ref}
onKeyDownCapture={handleKeyDown}
className={cn("relative", className)}
role="region"
aria-roledescription="carousel"
{...props}
>
{children}
</div>
</CarouselContext.Provider>
);
},
);
Carousel.displayName = "Carousel";
const CarouselContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => {
const { carouselRef, orientation } = useCarousel();
return (
<div ref={carouselRef} className="overflow-hidden">
<div
ref={ref}
className={cn("flex", orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col", className)}
{...props}
/>
</div>
);
},
);
CarouselContent.displayName = "CarouselContent";
const CarouselItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => {
const { orientation } = useCarousel();
return (
<div
ref={ref}
role="group"
aria-roledescription="slide"
className={cn("min-w-0 shrink-0 grow-0 basis-full", orientation === "horizontal" ? "pl-4" : "pt-4", className)}
{...props}
/>
);
},
);
CarouselItem.displayName = "CarouselItem";
const CarouselPrevious = React.forwardRef<HTMLButtonElement, React.ComponentProps<typeof Button>>(
({ className, variant = "outline", size = "icon", ...props }, ref) => {
const { orientation, scrollPrev, canScrollPrev } = useCarousel();
return (
<Button
ref={ref}
variant={variant}
size={size}
className={cn(
"absolute h-8 w-8 rounded-full",
orientation === "horizontal"
? "-left-12 top-1/2 -translate-y-1/2"
: "-top-12 left-1/2 -translate-x-1/2 rotate-90",
className,
)}
disabled={!canScrollPrev}
onClick={scrollPrev}
{...props}
>
<ArrowLeft className="h-4 w-4" />
<span className="sr-only">Previous slide</span>
</Button>
);
},
);
CarouselPrevious.displayName = "CarouselPrevious";
const CarouselNext = React.forwardRef<HTMLButtonElement, React.ComponentProps<typeof Button>>(
({ className, variant = "outline", size = "icon", ...props }, ref) => {
const { orientation, scrollNext, canScrollNext } = useCarousel();
return (
<Button
ref={ref}
variant={variant}
size={size}
className={cn(
"absolute h-8 w-8 rounded-full",
orientation === "horizontal"
? "-right-12 top-1/2 -translate-y-1/2"
: "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
className,
)}
disabled={!canScrollNext}
onClick={scrollNext}
{...props}
>
<ArrowRight className="h-4 w-4" />
<span className="sr-only">Next slide</span>
</Button>
);
},
);
CarouselNext.displayName = "CarouselNext";
export { type CarouselApi, Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext };
```
--------------------------------------------------------------------------------
/docs/docs/installation.md:
--------------------------------------------------------------------------------
```markdown
## 🧩 Installation Guide
Welcome to **CodeGraphContext**! This guide provides a clear and seamless path to installing and configuring the tool.
## 📋 Understanding CodeGraphContext Modes
CodeGraphContext operates in **two modes**, and you can use either or both:
### 🛠️ Mode 1: CLI Toolkit (Standalone)
Use CodeGraphContext as a **powerful command-line toolkit** for code analysis:
- Index and analyze codebases directly from your terminal
- Query code relationships, find dead code, analyze complexity
- Visualize code graphs and dependencies
- Perfect for developers who want direct control via CLI commands
### 🤖 Mode 2: MCP Server (AI-Powered)
Use CodeGraphContext as an **MCP server** for AI assistants:
- Connect to AI IDEs (VS Code, Cursor, Windsurf, Claude, etc.)
- Let AI agents query your codebase using natural language
- Automatic code understanding and relationship analysis
- Perfect for AI-assisted development workflows
**You can use both modes!** Install once, then use CLI commands directly OR connect to your AI assistant.
---
## ⚙️ Prerequisites
Ensure the following are installed before you begin:
- **Python**: Version 3.10 or higher (3.12+ recommended for FalkorDB Lite support)
- **AI Assistant** (optional): An MCP-compatible tool (e.g., VS Code, Cursor, Claude, Gemini CLI) if you plan to use Mode 2
---
## 🚀 Installation
### Step 1: Install from PyPI
Install the `codegraphcontext` package using pip:
```bash
pip install codegraphcontext
```
### Step 2: Database Setup
CodeGraphContext uses a graph database to store code relationships. You have two options:
#### Option A: FalkorDB Lite (Default - Recommended)
- **Automatic** on Unix/Linux/macOS/WSL with Python 3.12+
- **No configuration needed** - works out of the box
- Lightweight, in-memory, perfect for most use cases
If you're on Unix/Linux/macOS/WSL with Python 3.12+, **you're done!** Skip to Step 3.
#### Option B: Neo4j (Alternative)
- Available on **all platforms** (Windows, Linux, macOS)
- Required if you're on Windows without WSL or prefer Neo4j
- Can be installed via Docker, native installation, or cloud (AuraDB)
To set up Neo4j, run:
```bash
cgc neo4j setup
```
The wizard will guide you through:
- **Docker** (recommended): Automatically sets up a local Neo4j container
- **Native Installation**: Installs Neo4j directly on Debian-based systems or macOS
- **Hosted/AuraDB**: Connect to a remote Neo4j instance
- **Existing Instance**: Use your own Neo4j server
---
## 🎯 Mode-Specific Setup
### For CLI Toolkit Mode (Mode 1)
You're ready to go! Start using CLI commands:
```bash
# Index your current directory
cgc index .
# List indexed repositories
cgc list
# Analyze code relationships
cgc analyze callers my_function
# Find complex functions
cgc analyze complexity --threshold 10
# See all available commands
cgc --help
```
**See the [CLI Reference](cli.md) for all available commands.**
---
### For MCP Server Mode (Mode 2)
Configure your AI assistant to connect to CodeGraphContext:
#### Step 1: Run MCP Setup Wizard
```bash
cgc mcp setup
```
The wizard will:
- Detect your installed AI tools (VS Code, Cursor, Claude, etc.)
- Automatically configure the selected tool
- Generate `mcp.json` configuration file
- Store credentials securely in `~/.codegraphcontext/.env`
**Supported AI Tools:**
- VS Code
- Cursor
- Windsurf
- Claude Desktop
- Gemini CLI
- ChatGPT Codex
- Cline
- RooCode
- Amazon Q Developer
#### Step 2: Start the MCP Server
```bash
cgc mcp start
```
Your MCP server is now running and ready to receive requests from your AI assistant!
#### Manual Configuration (Optional)
If you prefer to configure manually or your tool isn't auto-detected, add this to your tool's settings file:
```json
{
"mcpServers": {
"CodeGraphContext": {
"command": "cgc",
"args": ["mcp", "start"],
"env": {
"NEO4J_URI": "bolt://localhost:7687",
"NEO4J_USERNAME": "neo4j",
"NEO4J_PASSWORD": "your-password"
}
}
}
}
```
**Note:** If using FalkorDB Lite (default), you don't need to set NEO4J_* environment variables.
---
## 🧭 Quick Start Examples
### CLI Toolkit Workflow
```bash
# Install
pip install codegraphcontext
# Index a project
cgc index /path/to/my-project
# Find all callers of a function
cgc analyze callers process_payment
# Find dead code
cgc analyze dead-code
# Check database stats
cgc stats
```
### MCP Server Workflow
```bash
# Install
pip install codegraphcontext
# Configure your AI assistant
cgc mcp setup
# Start the server
cgc mcp start
# Now use natural language in your AI assistant:
# "Index the code in /path/to/my-project"
# "Find all functions that call process_payment"
# "Show me the class hierarchy for UserController"
```
---
## 🔧 Database Configuration Details
### FalkorDB Lite (Default)
- **Platform**: Unix/Linux/macOS/WSL
- **Python**: 3.12+ required
- **Setup**: Automatic, no configuration needed
- **Storage**: In-memory
- **Best for**: Most use cases, quick testing, development
### Neo4j
- **Platform**: All (Windows, Linux, macOS)
- **Python**: 3.10+ supported
- **Setup**: Via `cgc neo4j setup` wizard
- **Storage**: Persistent disk storage
- **Best for**: Windows users, production deployments, large codebases
---
## 📚 Next Steps
### For CLI Users
- Explore the [CLI Reference](cli.md) for all available commands
- Check out the [Cookbook](cookbook.md) for common analysis patterns
- Learn about [Code Analysis](core.md) capabilities
### For MCP Users
- See [MCP Tools Documentation](tools.md) for available AI tools
- Review [Natural Language Examples](index.md#natural-language-interaction-examples)
- Explore the [Use Cases](use_cases.md) guide
---
## 🆘 Troubleshooting
If you encounter issues, see our [Troubleshooting Guide](troubleshooting.md) for common problems and solutions.
**Common Issues:**
- **"cgc: command not found"**: Run the PATH fix script (see main README)
- **Database connection errors**: Ensure Neo4j is running (if using Neo4j) or Python 3.12+ (if using FalkorDB)
- **MCP server won't start**: Check that your AI assistant is properly configured
---
With **CodeGraphContext** installed, you're ready to explore powerful code analysis capabilities! Happy coding ✨!
```
--------------------------------------------------------------------------------
/tests/sample_project_go/generics.go:
--------------------------------------------------------------------------------
```go
// generics.go - Demonstrates Go generics (Go 1.18+)
package main
import (
"fmt"
"golang.org/x/exp/constraints"
)
// GenericMax returns the maximum of two values
func GenericMax[T constraints.Ordered](a, b T) T {
if a > b {
return a
}
return b
}
// GenericMin returns the minimum of two values
func GenericMin[T constraints.Ordered](a, b T) T {
if a < b {
return a
}
return b
}
// Stack is a generic stack data structure
type Stack[T any] struct {
items []T
}
// Push adds an item to the stack
func (s *Stack[T]) Push(item T) {
s.items = append(s.items, item)
}
// Pop removes and returns the top item
func (s *Stack[T]) Pop() (T, bool) {
if len(s.items) == 0 {
var zero T
return zero, false
}
item := s.items[len(s.items)-1]
s.items = s.items[:len(s.items)-1]
return item, true
}
// Peek returns the top item without removing it
func (s *Stack[T]) Peek() (T, bool) {
if len(s.items) == 0 {
var zero T
return zero, false
}
return s.items[len(s.items)-1], true
}
// IsEmpty returns true if stack is empty
func (s *Stack[T]) IsEmpty() bool {
return len(s.items) == 0
}
// Size returns the number of items in the stack
func (s *Stack[T]) Size() int {
return len(s.items)
}
// Queue is a generic queue data structure
type Queue[T any] struct {
items []T
}
// Enqueue adds an item to the queue
func (q *Queue[T]) Enqueue(item T) {
q.items = append(q.items, item)
}
// Dequeue removes and returns the first item
func (q *Queue[T]) Dequeue() (T, bool) {
if len(q.items) == 0 {
var zero T
return zero, false
}
item := q.items[0]
q.items = q.items[1:]
return item, true
}
// Map applies a function to each element
func Map[T any, U any](items []T, fn func(T) U) []U {
result := make([]U, len(items))
for i, item := range items {
result[i] = fn(item)
}
return result
}
// Filter filters items based on a predicate
func Filter[T any](items []T, predicate func(T) bool) []T {
var result []T
for _, item := range items {
if predicate(item) {
result = append(result, item)
}
}
return result
}
// Reduce reduces a slice to a single value
func Reduce[T any, U any](items []T, initial U, fn func(U, T) U) U {
result := initial
for _, item := range items {
result = fn(result, item)
}
return result
}
// Contains checks if a slice contains an item
func Contains[T comparable](items []T, target T) bool {
for _, item := range items {
if item == target {
return true
}
}
return false
}
// Pair is a generic pair type
type Pair[T any, U any] struct {
First T
Second U
}
// NewPair creates a new pair
func NewPair[T any, U any](first T, second U) Pair[T, U] {
return Pair[T, U]{First: first, Second: second}
}
// Swap swaps the values in a pair
func (p Pair[T, U]) Swap() Pair[U, T] {
return Pair[U, T]{First: p.Second, Second: p.First}
}
// LinkedListNode is a generic linked list node
type LinkedListNode[T any] struct {
Value T
Next *LinkedListNode[T]
}
// LinkedList is a generic linked list
type LinkedList[T any] struct {
Head *LinkedListNode[T]
Tail *LinkedListNode[T]
size int
}
// Append adds a value to the end of the list
func (ll *LinkedList[T]) Append(value T) {
node := &LinkedListNode[T]{Value: value}
if ll.Head == nil {
ll.Head = node
ll.Tail = node
} else {
ll.Tail.Next = node
ll.Tail = node
}
ll.size++
}
// Prepend adds a value to the beginning of the list
func (ll *LinkedList[T]) Prepend(value T) {
node := &LinkedListNode[T]{Value: value, Next: ll.Head}
ll.Head = node
if ll.Tail == nil {
ll.Tail = node
}
ll.size++
}
// ToSlice converts the linked list to a slice
func (ll *LinkedList[T]) ToSlice() []T {
result := make([]T, 0, ll.size)
current := ll.Head
for current != nil {
result = append(result, current.Value)
current = current.Next
}
return result
}
// Number constraint for numeric types
type Number interface {
constraints.Integer | constraints.Float
}
// Sum calculates the sum of numbers
func Sum[T Number](numbers []T) T {
var sum T
for _, num := range numbers {
sum += num
}
return sum
}
// Average calculates the average of numbers
func Average[T Number](numbers []T) float64 {
if len(numbers) == 0 {
return 0
}
total := Sum(numbers)
return float64(total) / float64(len(numbers))
}
// Cache is a generic cache with type constraints
type Cache[K comparable, V any] struct {
data map[K]V
}
// NewCache creates a new cache
func NewCache[K comparable, V any]() *Cache[K, V] {
return &Cache[K, V]{
data: make(map[K]V),
}
}
// Set adds or updates a value in the cache
func (c *Cache[K, V]) Set(key K, value V) {
c.data[key] = value
}
// Get retrieves a value from the cache
func (c *Cache[K, V]) Get(key K) (V, bool) {
value, ok := c.data[key]
return value, ok
}
// Delete removes a value from the cache
func (c *Cache[K, V]) Delete(key K) {
delete(c.data, key)
}
// Keys returns all keys in the cache
func (c *Cache[K, V]) Keys() []K {
keys := make([]K, 0, len(c.data))
for k := range c.data {
keys = append(keys, k)
}
return keys
}
// FindFirst returns the first item matching the predicate
func FindFirst[T any](items []T, predicate func(T) bool) (T, bool) {
for _, item := range items {
if predicate(item) {
return item, true
}
}
var zero T
return zero, false
}
// GroupBy groups items by a key function
func GroupBy[T any, K comparable](items []T, keyFn func(T) K) map[K][]T {
result := make(map[K][]T)
for _, item := range items {
key := keyFn(item)
result[key] = append(result[key], item)
}
return result
}
func demonstrateGenerics() {
// Generic functions
fmt.Println("Max:", GenericMax(10, 20))
fmt.Println("Max:", GenericMax(3.14, 2.71))
// Generic stack
stack := Stack[int]{}
stack.Push(1)
stack.Push(2)
stack.Push(3)
val, _ := stack.Pop()
fmt.Println("Popped:", val)
// Generic map/filter/reduce
numbers := []int{1, 2, 3, 4, 5}
doubled := Map(numbers, func(n int) int { return n * 2 })
fmt.Println("Doubled:", doubled)
evens := Filter(numbers, func(n int) bool { return n%2 == 0 })
fmt.Println("Evens:", evens)
sum := Reduce(numbers, 0, func(acc, n int) int { return acc + n })
fmt.Println("Sum:", sum)
// Generic cache
cache := NewCache[string, int]()
cache.Set("age", 30)
age, _ := cache.Get("age")
fmt.Println("Age:", age)
}
```
--------------------------------------------------------------------------------
/tests/sample_project_go/embedded_composition.go:
--------------------------------------------------------------------------------
```go
// embedded_composition.go - Demonstrates Go embedding and composition
package main
import "fmt"
// Base is a base struct
type Base struct {
ID int
Name string
}
// GetID returns the ID
func (b Base) GetID() int {
return b.ID
}
// GetName returns the name
func (b Base) GetName() string {
return b.Name
}
// Describe provides a description
func (b Base) Describe() string {
return fmt.Sprintf("Base{ID: %d, Name: %s}", b.ID, b.Name)
}
// Extended embeds Base and adds functionality
type Extended struct {
Base
Extra string
}
// Describe overrides the Base method
func (e Extended) Describe() string {
return fmt.Sprintf("Extended{ID: %d, Name: %s, Extra: %s}", e.ID, e.Name, e.Extra)
}
// GetExtra returns the extra field
func (e Extended) GetExtra() string {
return e.Extra
}
// Address represents a physical address
type Address struct {
Street string
City string
ZipCode string
}
// FullAddress returns formatted address
func (a Address) FullAddress() string {
return fmt.Sprintf("%s, %s %s", a.Street, a.City, a.ZipCode)
}
// ContactInfo has contact details
type ContactInfo struct {
Email string
Phone string
}
// GetContact returns contact string
func (c ContactInfo) GetContact() string {
return fmt.Sprintf("Email: %s, Phone: %s", c.Email, c.Phone)
}
// Customer embeds multiple structs
type Customer struct {
Base
Address
ContactInfo
LoyaltyPoints int
}
// NewCustomer creates a new customer
func NewCustomer(id int, name, email string) *Customer {
return &Customer{
Base: Base{
ID: id,
Name: name,
},
ContactInfo: ContactInfo{
Email: email,
},
}
}
// GetFullInfo returns all customer info
func (c Customer) GetFullInfo() string {
return fmt.Sprintf("%s | %s | Points: %d",
c.Describe(), c.GetContact(), c.LoyaltyPoints)
}
// Logger provides logging functionality
type Logger interface {
Log(message string)
}
// ConsoleLogger logs to console
type ConsoleLogger struct {
Prefix string
}
// Log implements Logger interface
func (cl ConsoleLogger) Log(message string) {
fmt.Printf("[%s] %s\n", cl.Prefix, message)
}
// Service embeds a logger
type Service struct {
Logger
Name string
}
// Execute performs service action
func (s Service) Execute() {
s.Log(fmt.Sprintf("Executing service: %s", s.Name))
}
// Timestamper adds timestamp functionality
type Timestamper struct {
timestamp string
}
// SetTimestamp sets the timestamp
func (t *Timestamper) SetTimestamp(ts string) {
t.timestamp = ts
}
// GetTimestamp gets the timestamp
func (t Timestamper) GetTimestamp() string {
return t.timestamp
}
// Versioned adds version tracking
type Versioned struct {
Version int
}
// IncrementVersion increases version
func (v *Versioned) IncrementVersion() {
v.Version++
}
// GetVersion returns the version
func (v Versioned) GetVersion() int {
return v.Version
}
// Document combines multiple embedded types
type Document struct {
Timestamper
Versioned
Content string
Author string
}
// Update updates the document
func (d *Document) Update(content string) {
d.Content = content
d.IncrementVersion()
}
// GetInfo returns document info
func (d Document) GetInfo() string {
return fmt.Sprintf("Version %d by %s at %s",
d.GetVersion(), d.Author, d.GetTimestamp())
}
// Reader interface
type Reader interface {
Read() string
}
// Writer interface
type Writer interface {
Write(data string) error
}
// ReadWriter combines interfaces
type ReadWriter interface {
Reader
Writer
}
// FileHandler implements ReadWriter
type FileHandler struct {
Filename string
buffer string
}
// Read implements Reader
func (fh FileHandler) Read() string {
return fh.buffer
}
// Write implements Writer
func (fh *FileHandler) Write(data string) error {
fh.buffer = data
return nil
}
// BufferedHandler embeds FileHandler
type BufferedHandler struct {
FileHandler
BufferSize int
}
// Flush clears the buffer
func (bh *BufferedHandler) Flush() {
bh.buffer = ""
}
// Engine represents an engine
type Engine struct {
Horsepower int
Type string
}
// Start starts the engine
func (e Engine) Start() string {
return fmt.Sprintf("Starting %s engine with %d HP", e.Type, e.Horsepower)
}
// Wheels represents wheels
type Wheels struct {
Count int
Size int
}
// Roll makes wheels roll
func (w Wheels) Roll() string {
return fmt.Sprintf("Rolling on %d wheels of size %d", w.Count, w.Size)
}
// Car composes Engine and Wheels
type Car struct {
Engine
Wheels
Make string
Model string
}
// Drive drives the car
func (c Car) Drive() string {
return fmt.Sprintf("%s %s: %s, %s",
c.Make, c.Model, c.Start(), c.Roll())
}
// Metadata provides common metadata
type Metadata struct {
CreatedBy string
Tags []string
}
// AddTag adds a tag
func (m *Metadata) AddTag(tag string) {
m.Tags = append(m.Tags, tag)
}
// GetTags returns all tags
func (m Metadata) GetTags() []string {
return m.Tags
}
// Article combines content and metadata
type Article struct {
Metadata
Title string
Body string
}
// Summary returns article summary
func (a Article) Summary() string {
return fmt.Sprintf("'%s' by %s [%d tags]",
a.Title, a.CreatedBy, len(a.Tags))
}
// ConflictExample shows field name conflicts
type ConflictExample struct {
Base
Extended
}
// AccessConflict demonstrates accessing conflicting fields
func (c ConflictExample) AccessConflict() string {
// Need to specify which embedded type's field to access
return fmt.Sprintf("Base Name: %s, Extended Name: %s",
c.Base.Name, c.Extended.Name)
}
func demonstrateComposition() {
// Basic embedding
extended := Extended{
Base: Base{ID: 1, Name: "Test"},
Extra: "Additional",
}
fmt.Println(extended.Describe())
fmt.Println(extended.GetID()) // Promoted method from Base
// Multiple embedding
customer := NewCustomer(100, "John Doe", "[email protected]")
customer.Street = "123 Main St"
customer.City = "NYC"
customer.Phone = "555-1234"
fmt.Println(customer.GetFullInfo())
// Interface embedding
service := Service{
Logger: ConsoleLogger{Prefix: "SVC"},
Name: "DataProcessor",
}
service.Execute()
// Composition
car := Car{
Engine: Engine{Horsepower: 300, Type: "V8"},
Wheels: Wheels{Count: 4, Size: 18},
Make: "Tesla",
Model: "Model S",
}
fmt.Println(car.Drive())
}
```
--------------------------------------------------------------------------------
/tests/sample_project_go/error_handling.go:
--------------------------------------------------------------------------------
```go
// error_handling.go - Demonstrates Go error handling patterns
package main
import (
"errors"
"fmt"
"io"
"os"
"strconv"
)
// CustomError is a custom error type
type CustomError struct {
Code int
Message string
}
// Error implements error interface for CustomError
func (e *CustomError) Error() string {
return fmt.Sprintf("Error %d: %s", e.Code, e.Message)
}
// ValidationError represents validation failures
type ValidationError struct {
Field string
Value interface{}
Issue string
}
// Error implements error interface for ValidationError
func (e *ValidationError) Error() string {
return fmt.Sprintf("validation failed for field '%s' with value '%v': %s",
e.Field, e.Value, e.Issue)
}
// NewCustomError creates a new custom error
func NewCustomError(code int, message string) error {
return &CustomError{Code: code, Message: message}
}
// BasicErrorReturn demonstrates simple error return
func BasicErrorReturn(x int) (int, error) {
if x < 0 {
return 0, errors.New("negative number not allowed")
}
return x * 2, nil
}
// ErrorWithFormatting uses fmt.Errorf
func ErrorWithFormatting(name string, age int) error {
if age < 0 {
return fmt.Errorf("invalid age %d for person %s", age, name)
}
if name == "" {
return fmt.Errorf("name cannot be empty")
}
return nil
}
// MultipleErrorChecks demonstrates multiple error checks
func MultipleErrorChecks(a, b int) (int, error) {
if a < 0 {
return 0, errors.New("first parameter cannot be negative")
}
if b == 0 {
return 0, errors.New("second parameter cannot be zero")
}
if a > 1000 {
return 0, errors.New("first parameter too large")
}
return a / b, nil
}
// ErrorWrapping demonstrates error wrapping (Go 1.13+)
func ErrorWrapping(filename string) error {
if filename == "" {
return fmt.Errorf("filename is empty")
}
_, err := os.Open(filename)
if err != nil {
return fmt.Errorf("failed to open file %s: %w", filename, err)
}
return nil
}
// ValidateUser validates user data
func ValidateUser(username string, age int) error {
if len(username) < 3 {
return &ValidationError{
Field: "username",
Value: username,
Issue: "must be at least 3 characters",
}
}
if age < 18 {
return &ValidationError{
Field: "age",
Value: age,
Issue: "must be 18 or older",
}
}
return nil
}
// ParseAndValidate demonstrates error handling chain
func ParseAndValidate(input string) (int, error) {
value, err := strconv.Atoi(input)
if err != nil {
return 0, fmt.Errorf("failed to parse input: %w", err)
}
if value < 0 {
return 0, NewCustomError(400, "value must be non-negative")
}
if value > 100 {
return 0, NewCustomError(400, "value must not exceed 100")
}
return value, nil
}
// ErrorTypeAssertion demonstrates error type checking
func ErrorTypeAssertion(err error) string {
if err == nil {
return "no error"
}
// Type assertion for custom error
if customErr, ok := err.(*CustomError); ok {
return fmt.Sprintf("Custom error with code: %d", customErr.Code)
}
// Type assertion for validation error
if valErr, ok := err.(*ValidationError); ok {
return fmt.Sprintf("Validation error on field: %s", valErr.Field)
}
return "unknown error type"
}
// ErrorsIs demonstrates errors.Is (Go 1.13+)
func ErrorsIs(err error) bool {
return errors.Is(err, io.EOF)
}
// ErrorsAs demonstrates errors.As (Go 1.13+)
func ErrorsAs(err error) (*CustomError, bool) {
var customErr *CustomError
if errors.As(err, &customErr) {
return customErr, true
}
return nil, false
}
// DeferredErrorHandling demonstrates defer with error handling
func DeferredErrorHandling(filename string) (err error) {
file, err := os.Open(filename)
if err != nil {
return fmt.Errorf("cannot open file: %w", err)
}
defer func() {
if closeErr := file.Close(); closeErr != nil {
if err != nil {
err = fmt.Errorf("close error: %v (original error: %w)", closeErr, err)
} else {
err = closeErr
}
}
}()
// Do something with file
_, err = file.Read(make([]byte, 100))
if err != nil && err != io.EOF {
return fmt.Errorf("read error: %w", err)
}
return nil
}
// SentinelErrors demonstrates sentinel error pattern
var (
ErrNotFound = errors.New("not found")
ErrUnauthorized = errors.New("unauthorized")
ErrForbidden = errors.New("forbidden")
)
// FindUser demonstrates sentinel error usage
func FindUser(id int) (string, error) {
if id < 0 {
return "", ErrNotFound
}
if id > 1000 {
return "", ErrUnauthorized
}
return fmt.Sprintf("user_%d", id), nil
}
// HandleUserError demonstrates handling sentinel errors
func HandleUserError(id int) string {
user, err := FindUser(id)
if err != nil {
if errors.Is(err, ErrNotFound) {
return "User not found"
}
if errors.Is(err, ErrUnauthorized) {
return "Unauthorized access"
}
return "Unknown error"
}
return user
}
// PanicToError converts panic to error
func PanicToError() (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("recovered from panic: %v", r)
}
}()
panic("something went wrong")
}
// ChainedValidation demonstrates chained error checks
func ChainedValidation(data map[string]interface{}) error {
if err := validateName(data); err != nil {
return fmt.Errorf("name validation: %w", err)
}
if err := validateAge(data); err != nil {
return fmt.Errorf("age validation: %w", err)
}
if err := validateEmail(data); err != nil {
return fmt.Errorf("email validation: %w", err)
}
return nil
}
func validateName(data map[string]interface{}) error {
name, ok := data["name"].(string)
if !ok || name == "" {
return errors.New("name is required")
}
return nil
}
func validateAge(data map[string]interface{}) error {
age, ok := data["age"].(int)
if !ok || age < 0 {
return errors.New("valid age is required")
}
return nil
}
func validateEmail(data map[string]interface{}) error {
email, ok := data["email"].(string)
if !ok || email == "" {
return errors.New("email is required")
}
return nil
}
func demonstrateErrors() {
// Test basic error
_, err := BasicErrorReturn(-1)
if err != nil {
fmt.Println("Error:", err)
}
// Test custom error
err = NewCustomError(404, "Resource not found")
fmt.Println(ErrorTypeAssertion(err))
// Test validation error
err = ValidateUser("ab", 15)
fmt.Println(err)
}
```
--------------------------------------------------------------------------------
/tests/sample_project_rust/src/traits.rs:
--------------------------------------------------------------------------------
```rust
// traits.rs - Demonstrates Rust traits and trait implementations
use std::fmt;
use std::ops::Add;
/// Basic trait definition
pub trait Describable {
fn describe(&self) -> String;
}
/// Trait with default implementation
pub trait Greetable {
fn greet(&self) -> String {
"Hello!".to_string()
}
fn formal_greet(&self) -> String;
}
/// Trait with associated types
pub trait Container {
type Item;
fn add(&mut self, item: Self::Item);
fn get(&self, index: usize) -> Option<&Self::Item>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
}
/// Trait with associated constants
pub trait MathConstants {
const PI: f64;
const E: f64;
}
/// Trait for conversion
pub trait FromString {
fn from_string(s: &str) -> Result<Self, String>
where
Self: Sized;
}
/// Marker trait (empty trait)
pub trait Serializable {}
// Struct definitions
#[derive(Debug, Clone)]
pub struct Rectangle {
pub width: f64,
pub height: f64,
}
#[derive(Debug, Clone)]
pub struct Circle {
pub radius: f64,
}
#[derive(Debug, Clone)]
pub struct Triangle {
pub a: f64,
pub b: f64,
pub c: f64,
}
#[derive(Debug)]
pub struct Student {
pub name: String,
pub grade: u32,
}
#[derive(Debug)]
pub struct Teacher {
pub name: String,
pub subject: String,
}
// Trait implementations
impl Describable for Rectangle {
fn describe(&self) -> String {
format!("Rectangle with width {} and height {}", self.width, self.height)
}
}
impl Describable for Circle {
fn describe(&self) -> String {
format!("Circle with radius {}", self.radius)
}
}
impl Describable for Triangle {
fn describe(&self) -> String {
format!("Triangle with sides {}, {}, {}", self.a, self.b, self.c)
}
}
impl Greetable for Student {
fn formal_greet(&self) -> String {
format!("Good day, student {}", self.name)
}
}
impl Greetable for Teacher {
fn greet(&self) -> String {
format!("Hello, I'm {}", self.name)
}
fn formal_greet(&self) -> String {
format!("Good day, Professor {}", self.name)
}
}
// Trait for area calculation
pub trait Area {
fn area(&self) -> f64;
}
impl Area for Rectangle {
fn area(&self) -> f64 {
self.width * self.height
}
}
impl Area for Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * self.radius * self.radius
}
}
impl Area for Triangle {
fn area(&self) -> f64 {
// Heron's formula
let s = (self.a + self.b + self.c) / 2.0;
(s * (s - self.a) * (s - self.b) * (s - self.c)).sqrt()
}
}
// Trait for perimeter calculation
pub trait Perimeter {
fn perimeter(&self) -> f64;
}
impl Perimeter for Rectangle {
fn perimeter(&self) -> f64 {
2.0 * (self.width + self.height)
}
}
impl Perimeter for Circle {
fn perimeter(&self) -> f64 {
2.0 * std::f64::consts::PI * self.radius
}
}
impl Perimeter for Triangle {
fn perimeter(&self) -> f64 {
self.a + self.b + self.c
}
}
// Generic functions using traits
/// Function accepting any type implementing Describable
pub fn print_description<T: Describable>(item: &T) {
println!("{}", item.describe());
}
/// Function with multiple trait bounds
pub fn print_area_and_perimeter<T: Area + Perimeter>(shape: &T) {
println!("Area: {}, Perimeter: {}", shape.area(), shape.perimeter());
}
/// Function with where clause
pub fn compare_areas<T, U>(shape1: &T, shape2: &U) -> bool
where
T: Area,
U: Area,
{
shape1.area() > shape2.area()
}
/// Function returning impl Trait
pub fn create_circle(radius: f64) -> impl Area + Perimeter {
Circle { radius }
}
/// Generic struct with trait bounds
#[derive(Debug)]
pub struct Pair<T> {
first: T,
second: T,
}
impl<T> Pair<T> {
pub fn new(first: T, second: T) -> Self {
Self { first, second }
}
}
impl<T: PartialOrd> Pair<T> {
pub fn max(&self) -> &T {
if self.first > self.second {
&self.first
} else {
&self.second
}
}
}
impl<T: Clone> Pair<T> {
pub fn clone_first(&self) -> T {
self.first.clone()
}
}
// Trait with supertraits
pub trait Shape: Area + Perimeter + fmt::Display {
fn name(&self) -> &str;
}
impl fmt::Display for Rectangle {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Rectangle({}x{})", self.width, self.height)
}
}
impl Shape for Rectangle {
fn name(&self) -> &str {
"Rectangle"
}
}
// Trait object example
pub fn total_area(shapes: &[&dyn Area]) -> f64 {
shapes.iter().map(|s| s.area()).sum()
}
// Associated type example
pub struct VecContainer<T> {
items: Vec<T>,
}
impl<T> Container for VecContainer<T> {
type Item = T;
fn add(&mut self, item: Self::Item) {
self.items.push(item);
}
fn get(&self, index: usize) -> Option<&Self::Item> {
self.items.get(index)
}
fn len(&self) -> usize {
self.items.len()
}
}
// Operator overloading using traits
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Point {
pub x: i32,
pub y: i32,
}
impl Add for Point {
type Output = Point;
fn add(self, other: Point) -> Point {
Point {
x: self.x + other.x,
y: self.y + other.y,
}
}
}
// Trait for custom equality
pub trait CustomEq {
fn custom_eq(&self, other: &Self) -> bool;
}
impl CustomEq for Rectangle {
fn custom_eq(&self, other: &Self) -> bool {
(self.width * self.height - other.width * other.height).abs() < 0.001
}
}
// Blanket implementations
pub trait Summary {
fn summarize(&self) -> String;
}
impl<T: Describable> Summary for T {
fn summarize(&self) -> String {
format!("Summary: {}", self.describe())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rectangle_area() {
let rect = Rectangle { width: 10.0, height: 5.0 };
assert_eq!(rect.area(), 50.0);
}
#[test]
fn test_circle_area() {
let circle = Circle { radius: 5.0 };
let area = circle.area();
assert!((area - 78.54).abs() < 0.01);
}
#[test]
fn test_point_add() {
let p1 = Point { x: 1, y: 2 };
let p2 = Point { x: 3, y: 4 };
let p3 = p1 + p2;
assert_eq!(p3, Point { x: 4, y: 6 });
}
}
```
--------------------------------------------------------------------------------
/tests/test_graph_indexing_js.py:
--------------------------------------------------------------------------------
```python
import pytest
import os
# Path to the sample JavaScript project used in tests
SAMPLE_JS_PROJECT_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "sample_project_javascript"))
# ==============================================================================
# == EXPECTED RELATIONSHIPS
# ==============================================================================
EXPECTED_STRUCTURE = [
("functions.js", "regularFunction", "Function"),
("functions.js", "greetPerson", "Function"),
("functions.js", "functionExpression", "Function"),
("functions.js", "arrowFunction", "Function"),
("classes.js", "Person", "Class"),
("classes.js", "Employee", "Class"),
("classes.js", "BankAccount", "Class"),
("objects.js", "calculator", "Variable"),
]
EXPECTED_INHERITANCE = [
pytest.param("Employee", "classes.js", "Person", "classes.js", id="Employee inherits from Person"),
]
EXPECTED_CALLS = [
pytest.param("getData", "asyncAwait.js", None, "fetchData", "asyncAwait.js", None, id="asyncAwait.getData->fetchData", marks=pytest.mark.skip(reason="JS parser does not yet detect all call relationships.")),
pytest.param("orchestrator", "functions.js", None, "regularFunction", "functions.js", None, id="functions.orchestrator->regularFunction", marks=pytest.mark.skip(reason="JS parser does not yet detect all call relationships.")),
]
EXPECTED_IMPORTS = [
pytest.param("importer.js", "defaultExport", "exporter.js", "defaultExportedFunction", id="importer.js imports defaultExport", marks=pytest.mark.xfail(reason="Symbol-level import relationships are not yet implemented for JavaScript.")),
pytest.param("importer.js", "exportedFunction", "exporter.js", "exportedFunction", id="importer.js imports exportedFunction", marks=pytest.mark.xfail(reason="Symbol-level import relationships are not yet implemented for JavaScript.")),
pytest.param("importer.js", "ExportedClass", "exporter.js", "ExportedClass", id="importer.js imports ExportedClass", marks=pytest.mark.xfail(reason="Symbol-level import relationships are not yet implemented for JavaScript.")),
]
# ==============================================================================
# == TEST IMPLEMENTATIONS
# ==============================================================================
def check_query(graph, query, description):
"""Helper function to execute a Cypher query and assert that a match is found."""
try:
result = graph.query(query)
except Exception as e:
pytest.fail(f"Query failed for {description} with error: {e}\nQuery was:\n{query}")
assert result is not None, f"Query for {description} returned None.\nQuery was:\n{query}"
assert len(result) > 0, f"Query for {description} returned no records.\nQuery was:\n{query}"
assert result[0].get('count', 0) > 0, f"No match found for {description}.\nQuery was:\n{query}"
@pytest.mark.parametrize("file_name, item_name, item_label", EXPECTED_STRUCTURE)
def test_file_contains_item(graph, file_name, item_name, item_label):
"""Verifies that a File node correctly CONTAINS a Function or Class node."""
description = f"CONTAINS from [{file_name}] to [{item_name}]"
abs_file_path = os.path.join(SAMPLE_JS_PROJECT_PATH, file_name)
query = f"""
MATCH (f:File {{path: '{abs_file_path}'}})-[:CONTAINS]->(item:{item_label} {{name: '{item_name}'}})
RETURN count(*) AS count
"""
check_query(graph, query, description)
@pytest.mark.parametrize("child_name, child_file, parent_name, parent_file", EXPECTED_INHERITANCE)
def test_inheritance_relationship(graph, child_name, child_file, parent_name, parent_file):
"""Verifies that an INHERITS relationship exists between two classes."""
description = f"INHERITS from [{child_name}] to [{parent_name}]"
child_path = os.path.join(SAMPLE_JS_PROJECT_PATH, child_file)
parent_path = os.path.join(SAMPLE_JS_PROJECT_PATH, parent_file)
query = f"""
MATCH (child:Class {{name: '{child_name}', file_path: '{child_path}'}})-[:INHERITS]->(parent:Class {{name: '{parent_name}', file_path: '{parent_path}'}})
RETURN count(*) as count
"""
check_query(graph, query, description)
@pytest.mark.parametrize("caller_name, caller_file, caller_class, callee_name, callee_file, callee_class", EXPECTED_CALLS)
def test_function_call_relationship(graph, caller_name, caller_file, caller_class, callee_name, callee_file, callee_class):
"""Verifies that a CALLS relationship exists by checking for nodes first, then the relationship."""
caller_path = os.path.join(SAMPLE_JS_PROJECT_PATH, caller_file)
callee_path = os.path.join(SAMPLE_JS_PROJECT_PATH, callee_file)
if caller_class:
caller_match = f"(caller_class:Class {{name: '{caller_class}', file_path: '{caller_path}'}})-[:CONTAINS]->(caller:Function {{name: '{caller_name}'}})"
else:
caller_match = f"(caller:Function {{name: '{caller_name}', file_path: '{caller_path}'}})"
if callee_class:
callee_match = f"(callee_class:Class {{name: '{callee_class}', file_path: '{callee_path}'}})-[:CONTAINS]->(callee:Function {{name: '{callee_name}'}})"
else:
callee_match = f"(callee:Function {{name: '{callee_name}', file_path: '{callee_path}'}})"
relationship_description = f"CALLS from [{caller_name}] to [{callee_name}]"
relationship_query = f"""
MATCH {caller_match}
MATCH {callee_match}
MATCH (caller)-[:CALLS]->(callee)
RETURN count(*) as count
"""
check_query(graph, relationship_query, relationship_description)
@pytest.mark.parametrize("importing_file, imported_symbol_alias, exporting_file, original_symbol_name", EXPECTED_IMPORTS)
def test_import_relationship(graph, importing_file, imported_symbol_alias, exporting_file, original_symbol_name):
"""Verifies that a specific IMPORTS relationship exists between a file and a symbol from another file."""
description = f"IMPORTS from [{importing_file}] of symbol [{original_symbol_name}] as [{imported_symbol_alias}] from [{exporting_file}]"
importing_path = os.path.join(SAMPLE_JS_PROJECT_PATH, importing_file)
exporting_path = os.path.join(SAMPLE_JS_PROJECT_PATH, exporting_file)
# This query is designed to fail until the feature is implemented.
# It checks for a direct relationship between the importing file and the specific imported function/class.
query = f"""
MATCH (importer:File {{path: '{importing_path}'}})-[:IMPORTS]->(symbol:Node {{name: '{original_symbol_name}', file_path: '{exporting_path}'}})
RETURN count(*) as count
"""
check_query(graph, query, description)
```
--------------------------------------------------------------------------------
/tests/sample_project_javascript/objects.js:
--------------------------------------------------------------------------------
```javascript
/**
* Sample JavaScript file demonstrating object methods and function assignments
* This file tests methods defined in object literals and prototype assignments
*/
// Object with method definitions
const calculator = {
result: 0,
// Method shorthand syntax
add(value) {
this.result += value;
return this;
},
// Method shorthand syntax with parameters
subtract(value) {
this.result -= value;
return this;
},
// Traditional method definition
multiply: function(value) {
this.result *= value;
return this;
},
// Arrow function as method (note: 'this' behaves differently)
reset: () => {
// Note: Arrow functions don't have their own 'this'
console.log('Calculator reset');
},
// Method with complex logic
calculate(operation, value) {
switch (operation) {
case 'add':
return this.add(value);
case 'subtract':
return this.subtract(value);
case 'multiply':
return this.multiply(value);
default:
throw new Error('Unknown operation');
}
},
// Getter method
get value() {
return this.result;
},
// Setter method
set value(newValue) {
this.result = newValue;
}
};
// Object with nested methods
const api = {
baseUrl: 'https://api.example.com',
users: {
// Nested method
getAll() {
return fetch(`${this.baseUrl}/users`);
},
// Nested method with parameters
getById(id) {
return fetch(`${this.baseUrl}/users/${id}`);
},
// Async nested method
async create(userData) {
const response = await fetch(`${this.baseUrl}/users`, {
method: 'POST',
body: JSON.stringify(userData)
});
return response.json();
}
},
posts: {
getAll() {
return fetch(`${this.baseUrl}/posts`);
},
getByUserId(userId) {
return fetch(`${this.baseUrl}/posts?userId=${userId}`);
}
}
};
// Constructor function with prototype methods
function Vehicle(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
// Prototype method assignment
Vehicle.prototype.getInfo = function() {
return `${this.year} ${this.make} ${this.model}`;
};
// Another prototype method
Vehicle.prototype.start = function() {
console.log(`Starting ${this.getInfo()}`);
};
// Prototype method with parameters
Vehicle.prototype.drive = function(distance) {
console.log(`Driving ${this.getInfo()} for ${distance} miles`);
};
// Static method assignment to constructor function
Vehicle.createElectric = function(make, model, year, batteryCapacity) {
const vehicle = new Vehicle(make, model, year);
vehicle.batteryCapacity = batteryCapacity;
vehicle.charge = function(percentage) {
console.log(`Charging to ${percentage}%`);
};
return vehicle;
};
// Object with methods that call other methods
const gameEngine = {
score: 0,
level: 1,
// Method that calls other methods
startGame() {
this.initializeLevel();
this.resetScore();
this.showWelcomeMessage();
},
initializeLevel() {
console.log(`Initializing level ${this.level}`);
},
resetScore() {
this.score = 0;
console.log('Score reset to 0');
},
showWelcomeMessage() {
console.log('Welcome to the game!');
},
// Method with callback parameter
processInput(input, callback) {
console.log(`Processing input: ${input}`);
if (callback && typeof callback === 'function') {
callback(input);
}
},
// Method that returns a function
createScoreHandler() {
return (points) => {
this.score += points;
console.log(`Score: ${this.score}`);
};
}
};
// Module pattern with private and public methods
const counterModule = (function() {
let count = 0;
// Private function
function validateIncrement(value) {
return typeof value === 'number' && value > 0;
}
// Return public interface
return {
// Public method
increment(value = 1) {
if (validateIncrement(value)) {
count += value;
}
},
// Public method
decrement(value = 1) {
if (validateIncrement(value)) {
count -= value;
}
},
// Public getter
getCount() {
return count;
},
// Public method that uses private function
reset() {
count = 0;
console.log('Counter reset');
}
};
})();
// Factory function that creates objects with methods
function createTimer(name) {
let startTime = null;
let endTime = null;
return {
name: name,
start() {
startTime = Date.now();
console.log(`Timer ${this.name} started`);
},
stop() {
endTime = Date.now();
console.log(`Timer ${this.name} stopped`);
},
getElapsed() {
if (startTime && endTime) {
return endTime - startTime;
}
return 0;
},
reset() {
startTime = null;
endTime = null;
console.log(`Timer ${this.name} reset`);
}
};
}
// Function that demonstrates object method usage
function demonstrateObjects() {
// Use calculator
calculator.add(10).multiply(2).subtract(5);
console.log('Calculator result:', calculator.value);
// Use vehicle
const car = new Vehicle('Toyota', 'Camry', 2022);
car.start();
car.drive(100);
// Use game engine
gameEngine.startGame();
const scoreHandler = gameEngine.createScoreHandler();
scoreHandler(100);
// Use counter module
counterModule.increment(5);
counterModule.decrement(2);
console.log('Counter value:', counterModule.getCount());
// Use timer factory
const timer = createTimer('TestTimer');
timer.start();
setTimeout(() => {
timer.stop();
console.log('Elapsed time:', timer.getElapsed());
}, 1000);
return {
calculator,
car,
gameEngine,
counterModule,
timer
};
}
// Export objects and functions
export { calculator, api, Vehicle, gameEngine, counterModule, createTimer };
export default demonstrateObjects;
```
--------------------------------------------------------------------------------
/website/src/components/HeroSection.tsx:
--------------------------------------------------------------------------------
```typescript
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Github, Download, ExternalLink } from "lucide-react";
import heroGraph from "@/assets/hero-graph.jpg";
import { useState, useEffect } from "react";
import ShowDownloads from "@/components/ShowDownloads";
import ShowStarGraph from "@/components/ShowStarGraph";
import { ThemeToggle } from "@/components/ThemeToggle";
const HeroSection = () => {
const [stars, setStars] = useState(null);
const [forks, setForks] = useState(null);
const [version, setVersion] = useState("");
useEffect(() => {
async function fetchVersion() {
try {
const res = await fetch(
"https://raw.githubusercontent.com/Shashankss1205/CodeGraphContext/main/README.md"
);
if (!res.ok) throw new Error("Failed to fetch README");
const text = await res.text();
const match = text.match(
/\*\*Version:\*\*\s*([0-9]+\.[0-9]+\.[0-9]+)/i
);
setVersion(match ? match[1] : "N/A");
} catch (err) {
console.error(err);
setVersion("N/A");
}
}
fetchVersion();
}, []);
useEffect(() => {
fetch("https://api.github.com/repos/Shashankss1205/CodeGraphContext")
.then((response) => response.json())
.then((data) => {
setStars(data.stargazers_count);
setForks(data.forks_count);
})
.catch((error) => console.error("Error fetching GitHub stats:", error));
}, []);
return (
<section className="relative min-h-screen flex items-center justify-center overflow-hidden">
{/* Header with Theme Toggle */}
<div className="absolute top-0 left-0 right-0 z-20 p-4" data-aos="fade-down">
<div className="container mx-auto flex justify-end">
<div className="rounded-full bg-white/60 backdrop-blur-md border border-gray-200 shadow-sm p-2 dark:bg-transparent dark:border-transparent dark:shadow-none">
<ThemeToggle />
</div>
</div>
</div>
{/* Background Image */}
<div
className="absolute inset-0 bg-cover bg-center bg-no-repeat opacity-20 brightness-110 saturate-110 dark:opacity-30 dark:brightness-100 dark:saturate-100"
style={{ backgroundImage: `url(${heroGraph})` }}
/>
{/* Gradient Overlay */}
<div className="absolute inset-0 bg-gradient-to-b from-white/60 via-white/40 to-white/80 dark:from-background/90 dark:via-background/80 dark:to-background/90" />
{/* Content */}
<div className="relative z-10 container mx-auto px-4 text-center max-w-5xl">
<div className="animate-float-up" data-aos="fade-up">
<Badge variant="secondary" className="mb-6 text-sm font-medium">
<div className="w-2 h-2 bg-accent rounded-full mr-2 animate-graph-pulse" />
Version {version} • MIT License
</Badge>
<h1 className="text-3xl sm:text-4xl md:text-5xl lg:text-6xl xl:text-7xl font-bold mb-6 bg-gradient-to-r from-purple-700 via-indigo-700 to-purple-900 dark:bg-gradient-primary bg-clip-text py-2 text-transparent leading-tight tracking-tight drop-shadow-[0_2px_8px_rgba(0,0,0,0.15)]">
CodeGraphContext
</h1>
<p className="text-xl md:text-2xl text-muted-foreground mb-4 leading-relaxed">
A powerful CLI toolkit & MCP server that indexes local code into a
</p>
<p className="text-xl md:text-2xl text-accent font-semibold mb-8">
knowledge graph for AI assistants
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center mb-12" data-aos="fade-up" data-aos-delay="200">
<Button size="lg" className="bg-gradient-to-r from-purple-600 via-indigo-600 to-purple-800 text-primary-foreground hover:opacity-90 transition-all duration-300 shadow-glow ring-1 ring-primary/20 dark:bg-gradient-primary" asChild>
<a href="https://pypi.org/project/codegraphcontext/" target="_blank" rel="noopener noreferrer">
<Download className="mr-2 h-5 w-5" />
pip install codegraphcontext
</a>
</Button>
<Button variant="outline" size="lg" asChild className="border-gray-300 hover:border-primary/60 bg-white/80 backdrop-blur-sm shadow-sm transition-smooth text-gray-900 dark:bg-transparent dark:text-foreground dark:border-primary/30">
<a href="https://github.com/Shashankss1205/CodeGraphContext" target="_blank" rel="noopener noreferrer">
<Github className="mr-2 h-5 w-5" />
View on GitHub
<ExternalLink className="ml-2 h-4 w-4" />
</a>
</Button>
<Button variant="ghost" size="lg" asChild>
<a href="https://shashankss1205.github.io/CodeGraphContext/" target="_blank" rel="noopener noreferrer" className="flex items-center gap-2">
<ExternalLink className="h-5 w-5" />
Documentation
</a>
</Button>
</div>
{/* Stats */}
<div className="flex flex-wrap justify-center gap-8 text-sm text-muted-foreground" data-aos="fade-up" data-aos-delay="400">
<div className="flex items-center gap-2">
<div className="w-3 h-3 bg-graph-node-1 rounded-full animate-graph-pulse" />
{stars !== null ? <span>{stars} GitHub Stars</span> : <span>Loading...</span>}
</div>
<div className="flex items-center gap-2">
<div className="w-3 h-3 bg-graph-node-2 rounded-full animate-graph-pulse" style={{ animationDelay: '0.5s' }} />
{forks !== null ? <span>{forks} Forks</span> : <span>Loading...</span>}
</div>
<div className="flex items-center gap-2">
<div className="w-3 h-3 bg-graph-node-3 rounded-full animate-graph-pulse" style={{ animationDelay: '1s' }} />
<span><ShowDownloads /></span>
</div>
</div>
</div>
</div>
{/* Floating Graph Nodes */}
<div className="absolute top-20 left-10 w-8 h-8 graph-node animate-graph-pulse" style={{ animationDelay: '0.2s' }} />
<div className="absolute top-40 right-20 w-6 h-6 graph-node animate-graph-pulse" style={{ animationDelay: '0.8s' }} />
<div className="absolute bottom-32 left-20 w-10 h-10 graph-node animate-graph-pulse" style={{ animationDelay: '1.2s' }} />
<div className="absolute bottom-20 right-10 w-7 h-7 graph-node animate-graph-pulse" style={{ animationDelay: '0.6s' }} />
</section>
);
};
export default HeroSection;
```
--------------------------------------------------------------------------------
/src/codegraphcontext/tools/languages/typescriptjsx.py:
--------------------------------------------------------------------------------
```python
from pathlib import Path
def pre_scan_typescript(files: list[Path], parser_wrapper) -> dict:
"""
Scans TypeScript JSX (.tsx) files to create a map of class/function names to their file paths.
Reuses the logic from TypeScript parser, but can be extended for JSX-specific extraction.
"""
imports_map = {}
# Use the same queries as TypeScript
query_strings = [
"(class_declaration) @class",
"(function_declaration) @function",
"(variable_declarator) @var_decl",
"(method_definition) @method",
"(interface_declaration) @interface",
"(type_alias_declaration) @type_alias",
]
for file_path in files:
try:
with open(file_path, "r", encoding="utf-8") as f:
source_code = f.read()
tree = parser_wrapper.parser.parse(bytes(source_code, "utf8"))
for query_str in query_strings:
try:
for node, capture_name in execute_query(parser_wrapper.language, query_str, tree.root_node):
name = None
if capture_name == 'class':
name_node = node.child_by_field_name('name')
if name_node:
name = name_node.text.decode('utf-8')
elif capture_name == 'function':
name_node = node.child_by_field_name('name')
if name_node:
name = name_node.text.decode('utf-8')
elif capture_name == 'var_decl':
name_node = node.child_by_field_name('name')
value_node = node.child_by_field_name('value')
if name_node and value_node:
if value_node.type in ('function', 'arrow_function'):
name = name_node.text.decode('utf-8')
elif capture_name == 'method':
name_node = node.child_by_field_name('name')
if name_node:
name = name_node.text.decode('utf-8')
elif capture_name == 'interface':
name_node = node.child_by_field_name('name')
if name_node:
name = name_node.text.decode('utf-8')
elif capture_name == 'type_alias':
name_node = node.child_by_field_name('name')
if name_node:
name = name_node.text.decode('utf-8')
if name:
if name not in imports_map:
imports_map[name] = []
file_path_str = str(file_path.resolve())
if file_path_str not in imports_map[name]:
imports_map[name].append(file_path_str)
except Exception as query_error:
warning_logger(f"Query failed for pattern '{query_str}': {query_error}")
except Exception as e:
warning_logger(f"Tree-sitter pre-scan failed for {file_path}: {e}")
return imports_map
from typing import Dict
from codegraphcontext.utils.debug_log import warning_logger
from codegraphcontext.utils.tree_sitter_manager import execute_query
from .typescript import TypescriptTreeSitterParser
class TypescriptJSXTreeSitterParser(TypescriptTreeSitterParser):
"""
A parser for TypeScript JSX (.tsx) files.
"""
def __init__(self, generic_parser_wrapper):
super().__init__(generic_parser_wrapper)
self.language_name = 'typescript'
self.jsx_enabled = True
def parse(self, file_path: Path, is_dependency: bool = False) -> Dict:
"""
Parse a .tsx file, reusing TypeScript logic and ensuring JSX nodes are handled.
Indexes components, functions, imports, and exports.
"""
with open(file_path, "r", encoding="utf-8") as f:
source_code = f.read()
tree = self.parser.parse(bytes(source_code, "utf8"))
root_node = tree.root_node
# Reuse TypeScript logic for functions, classes, interfaces, type aliases, imports, calls, variables
functions = self._find_functions(root_node)
classes = self._find_classes(root_node)
interfaces = self._find_interfaces(root_node)
type_aliases = self._find_type_aliases(root_node)
imports = self._find_imports(root_node)
function_calls = self._find_calls(root_node)
variables = self._find_variables(root_node)
# Index React components (function and class components)
components = self._find_react_components(root_node)
return {
"file_path": str(file_path),
"functions": functions,
"classes": classes,
"interfaces": interfaces,
"type_aliases": type_aliases,
"variables": variables,
"imports": imports,
"function_calls": function_calls,
"components": components,
"is_dependency": is_dependency,
"lang": self.language_name,
}
def _find_react_components(self, root_node):
"""
Find React components in .tsx files (function and class components).
"""
components = []
# Function components: exported arrow/function assigned to const, returning JSX
# Class components: class extending React.Component or React.PureComponent
# This is a simplified query, can be extended for more cases
query_strings = [
'(class_declaration extends_clause: (extends_clause (identifier) @base) name: (identifier) @name)',
'(variable_declarator name: (identifier) @name value: (arrow_function) @fn)',
'(variable_declarator name: (identifier) @name value: (function_expression) @fn)',
'(function_declaration name: (identifier) @name)',
]
for query_str in query_strings:
for node, capture_name in execute_query(self.language, query_str, root_node):
if capture_name == 'name':
name = node.text.decode('utf-8')
line_number = node.start_point[0] + 1
components.append({
"name": name,
"line_number": line_number,
"type": "component",
"lang": self.language_name,
})
return components
```
--------------------------------------------------------------------------------
/CLI_Commands.md:
--------------------------------------------------------------------------------
```markdown
# Comprehensive Guide to CodeGraphContext CLI
Here is the **complete list** of all CLI commands available in `CodeGraphContext`, categorized by workflow scenario.
## 1. Project Management
Use these commands to manage the repositories in your code graph.
| Command | Arguments | Description |
| :--- | :--- | :--- |
| **`cgc index`** | `[path]` <br> `--force` | Adds a repository to the graph. Default path is current directory. Use `--force` to re-index from scratch. <br> *(Alias: `cgc i`)* |
| **`cgc list`** | None | Lists all repositories currently indexed in the database. <br> *(Alias: `cgc ls`)* |
| **`cgc delete`** | `[path]` <br> `--all` | Removes a repository from the graph. Use `--all` to wipe everything. <br> *(Alias: `cgc rm`)* |
| **`cgc stats`** | `[path]` | Shows indexing statistics (node counts) for the DB or a specific repo. |
| **`cgc clean`** | None | Removes orphaned nodes and cleans up the database. |
| **`cgc add-package`** | `<name> <lang>` | Manually adds an external package node (e.g., `cgc add-package requests python`). |
## 2. Watching & Monitoring
Automatically track changes and keep your code graph up-to-date when you code.
| Command | Arguments | Description |
| :--- | :--- | :--- |
| **`cgc watch`** | `[path]` | Watches a directory for file changes and automatically re-indexes. Runs in foreground. Default path is current directory. <br> *(Alias: `cgc w`)* |
| **`cgc unwatch`** | `<path>` | Stops watching a previously watched directory. (Primarily for MCP mode) |
| **`cgc watching`** | None | Lists all directories currently being watched for changes. (Primarily for MCP mode) |
## 3. Code Analysis
Understand the structure, quality, and relationships of your code.
| Command | Arguments | Description |
| :--- | :--- | :--- |
| **`cgc analyze calls`** | `<func_name>` <br> `--file` | Shows **outgoing** calls: what functions does this function call? |
| **`cgc analyze callers`** | `<func_name>` <br> `--file` | Shows **incoming** calls: who calls this function? |
| **`cgc analyze chain`** | `<start> <end>` <br> `--depth` | Finds the call path between two functions. Default depth is 5. |
| **`cgc analyze deps`** | `<module>` <br> `--no-external` | Inspects dependencies (imports and importers) for a module. |
| **`cgc analyze tree`** | `<class_name>` <br> `--file` | Visualizes the Class Inheritance hierarchy for a given class. |
| **`cgc analyze complexity`**| `[path]` <br> `--threshold` <br> `--limit` | Lists functions with high Cyclomatic Complexity. Default threshold: 10. |
| **`cgc analyze dead-code`** | `--exclude` | Finds potentially unused functions (0 callers). Use `--exclude` for decorators. |
## 4. Discovery & Search
Find code elements when you don't know the exact structure.
| Command | Arguments | Description |
| :--- | :--- | :--- |
| **`cgc find name`** | `<name>` <br> `--type` | Finds code elements (Class, Function) by their **exact** name. |
| **`cgc find pattern`** | `<pattern>` <br> `--case-sensitive` | Finds elements using fuzzy substring matching (e.g. "User" finds "UserHelper"). |
| **`cgc find type`** | `<type>` <br> `--limit` | Lists all nodes of a specific type (e.g. `function`, `class`, `module`). |
## 5. Configuration & Setup
Manage your environment and database connections.
| Command | Arguments | Description |
| :--- | :--- | :--- |
| **`cgc mcp setup`** | None | Configures your IDE/MCP Client. Creates `mcp.json`. <br> *(Alias: `cgc m`)* |
| **`cgc neo4j setup`** | None | Wizard to configure a Neo4j connection. <br> *(Alias: `cgc n`)* |
| **`cgc config show`** | None | Displays current configuration values. |
| **`cgc config set`** | `<key> <value>` | Sets a config value (e.g. `DEFAULT_DATABASE`). |
| **`cgc config reset`** | None | Resets configuration to defaults. |
| **`cgc config db`** | `<backend>` | Quick switch between `neo4j` and `falkordb`. |
## 6. Utilities & Runtime
Helper commands for developers and the MCP server.
| Command | Arguments | Description |
| :--- | :--- | :--- |
| **`cgc doctor`** | None | Runs system diagnostics (DB connection, dependencies, permissions). |
| **`cgc visualize`** | `[query]` | Generates a link to open the Neo4j Browser. <br> *(Alias: `cgc v`)* |
| **`cgc query`** | `<query>` | Executes a raw Cypher query directly against the DB. |
| **`cgc mcp start`** | None | Starts the MCP Server (used by IDEs). |
| **`cgc mcp tools`** | None | Lists all available MCP tools supported by the server. |
| **`cgc start`** | None | **Deprecated**. Use `cgc mcp start` instead. |
---
## Common Scenarios & Combinations
### Scenario A: Onboarding a New Repository
1. **Index the code:**
```bash
cgc index .
```
2. **Verify status:**
```bash
cgc doctor
```
3. **Check stats:**
```bash
cgc stats
```
### Scenario B: Refactoring Legacy Code
1. **Find complex functions:**
```bash
cgc analyze complexity --threshold 15
```
2. **Find unused code:**
```bash
cgc analyze dead-code --exclude "route,task"
```
3. **Check dependencies:**
```bash
cgc analyze deps target_module --no-external
```
### Scenario C: Bug Hunting
1. **Search for relevant code:**
```bash
cgc find pattern "AuthValidator"
```
2. **Trace execution:**
```bash
cgc analyze callers validate_auth
```
3. **Find full path:**
```bash
cgc analyze chain "main" "validate_auth" --depth 10
```
### Scenario D: Database Switching
1. **Switch to Neo4j:**
```bash
cgc config db neo4j
```
2. **Configure credentials:**
```bash
cgc neo4j setup
```
3. **Verify connection:**
```bash
cgc doctor
```
### Scenario E: Setting Up on Different Operating Systems
**Unix/Linux/macOS (Python 3.12+):**
```bash
# FalkorDB Lite is already configured as default
pip install codegraphcontext
cgc mcp setup # Configure your IDE
cgc index . # Start indexing
```
**Windows:**
```bash
# Option 1: Use WSL (Recommended)
wsl --install
# Then follow Unix instructions above
# Option 2: Use Neo4j with Docker
pip install codegraphcontext
cgc neo4j setup # Choose Docker option
cgc mcp setup # Configure your IDE
cgc index . # Start indexing
# Option 3: Use Neo4j native installation
pip install codegraphcontext
cgc neo4j setup # Choose native installation
cgc mcp setup # Configure your IDE
cgc index . # Start indexing
```
### Scenario F: Live Development with Auto-Update
1. **Start watching your project:**
```bash
cgc watch .
```
2. **Open a new terminal and continue coding**
- The watcher runs in the foreground
- Changes are automatically indexed as you save files
3. **Stop watching when done:**
- Press `Ctrl+C` in the watch terminal
**💡 Tip:** This is perfect for active development sessions where you want your AI assistant to always have the latest code context!
```
--------------------------------------------------------------------------------
/tests/sample_project_rust/src/smart_pointers.rs:
--------------------------------------------------------------------------------
```rust
// smart_pointers.rs - Demonstrates Rust smart pointers
use std::cell::{Cell, RefCell};
use std::rc::{Rc, Weak};
use std::sync::Arc;
// Box - heap allocation
/// Basic Box usage
pub fn box_example() -> Box<i32> {
Box::new(42)
}
/// Recursive type with Box
#[derive(Debug)]
pub enum List {
Cons(i32, Box<List>),
Nil,
}
impl List {
pub fn new() -> Self {
List::Nil
}
pub fn prepend(self, value: i32) -> Self {
List::Cons(value, Box::new(self))
}
pub fn len(&self) -> usize {
match self {
List::Cons(_, tail) => 1 + tail.len(),
List::Nil => 0,
}
}
}
/// Box with trait object
pub trait Shape {
fn area(&self) -> f64;
}
pub struct Circle {
radius: f64,
}
pub struct Rectangle {
width: f64,
height: f64,
}
impl Shape for Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * self.radius * self.radius
}
}
impl Shape for Rectangle {
fn area(&self) -> f64 {
self.width * self.height
}
}
pub fn create_shapes() -> Vec<Box<dyn Shape>> {
vec![
Box::new(Circle { radius: 5.0 }),
Box::new(Rectangle {
width: 10.0,
height: 5.0,
}),
]
}
// Rc - reference counting
/// Shared ownership with Rc
pub fn rc_example() {
let data = Rc::new(vec![1, 2, 3, 4, 5]);
let data2 = Rc::clone(&data);
let data3 = Rc::clone(&data);
println!("Data: {:?}, count: {}", data, Rc::strong_count(&data));
}
/// Graph structure with Rc
#[derive(Debug)]
pub struct Node {
value: i32,
children: Vec<Rc<Node>>,
}
impl Node {
pub fn new(value: i32) -> Rc<Self> {
Rc::new(Self {
value,
children: Vec::new(),
})
}
pub fn value(&self) -> i32 {
self.value
}
}
/// Tree with Rc and Weak
#[derive(Debug)]
pub struct TreeNode {
value: i32,
parent: RefCell<Weak<TreeNode>>,
children: RefCell<Vec<Rc<TreeNode>>>,
}
impl TreeNode {
pub fn new(value: i32) -> Rc<Self> {
Rc::new(Self {
value,
parent: RefCell::new(Weak::new()),
children: RefCell::new(Vec::new()),
})
}
pub fn add_child(self: &Rc<Self>, child: Rc<TreeNode>) {
*child.parent.borrow_mut() = Rc::downgrade(self);
self.children.borrow_mut().push(child);
}
}
// RefCell - interior mutability
/// RefCell for interior mutability
pub struct MockMessenger {
pub sent_messages: RefCell<Vec<String>>,
}
impl MockMessenger {
pub fn new() -> Self {
Self {
sent_messages: RefCell::new(Vec::new()),
}
}
pub fn send(&self, message: &str) {
self.sent_messages.borrow_mut().push(message.to_string());
}
pub fn message_count(&self) -> usize {
self.sent_messages.borrow().len()
}
}
/// Combining Rc and RefCell
pub struct SharedData {
data: Rc<RefCell<Vec<i32>>>,
}
impl SharedData {
pub fn new() -> Self {
Self {
data: Rc::new(RefCell::new(Vec::new())),
}
}
pub fn add(&self, value: i32) {
self.data.borrow_mut().push(value);
}
pub fn get(&self, index: usize) -> Option<i32> {
self.data.borrow().get(index).copied()
}
pub fn clone_ref(&self) -> SharedData {
SharedData {
data: Rc::clone(&self.data),
}
}
}
// Cell - for Copy types
pub struct CellExample {
value: Cell<i32>,
}
impl CellExample {
pub fn new(value: i32) -> Self {
Self {
value: Cell::new(value),
}
}
pub fn get(&self) -> i32 {
self.value.get()
}
pub fn set(&self, value: i32) {
self.value.set(value);
}
pub fn increment(&self) {
let current = self.value.get();
self.value.set(current + 1);
}
}
// Weak references
pub fn weak_reference_example() {
let strong = Rc::new(42);
let weak = Rc::downgrade(&strong);
println!("Strong count: {}", Rc::strong_count(&strong));
println!("Weak count: {}", Rc::weak_count(&strong));
match weak.upgrade() {
Some(value) => println!("Value: {}", value),
None => println!("Value has been dropped"),
}
}
// Custom smart pointer
pub struct MyBox<T> {
value: T,
}
impl<T> MyBox<T> {
pub fn new(value: T) -> Self {
Self { value }
}
}
impl<T> std::ops::Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl<T> std::ops::DerefMut for MyBox<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.value
}
}
// Drop trait
pub struct CustomDrop {
data: String,
}
impl CustomDrop {
pub fn new(data: String) -> Self {
println!("Creating CustomDrop with: {}", data);
Self { data }
}
}
impl Drop for CustomDrop {
fn drop(&mut self) {
println!("Dropping CustomDrop with: {}", self.data);
}
}
// Arc for thread-safe reference counting
use std::sync::Mutex;
use std::thread;
pub fn arc_example() {
let data = Arc::new(Mutex::new(vec![1, 2, 3]));
let mut handles = vec![];
for i in 0..3 {
let data = Arc::clone(&data);
let handle = thread::spawn(move || {
let mut data = data.lock().unwrap();
data.push(i);
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Result: {:?}", data.lock().unwrap());
}
// Cow - Clone on Write
use std::borrow::Cow;
pub fn cow_example(input: &str) -> Cow<str> {
if input.contains(' ') {
Cow::Owned(input.replace(' ', "_"))
} else {
Cow::Borrowed(input)
}
}
pub fn cow_modify(mut data: Cow<[i32]>) -> Cow<[i32]> {
data.to_mut().push(4);
data
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_list() {
let list = List::new().prepend(3).prepend(2).prepend(1);
assert_eq!(list.len(), 3);
}
#[test]
fn test_shared_data() {
let data = SharedData::new();
let data2 = data.clone_ref();
data.add(1);
data2.add(2);
assert_eq!(data.get(0), Some(1));
assert_eq!(data.get(1), Some(2));
assert_eq!(data2.get(0), Some(1));
}
#[test]
fn test_cell() {
let cell = CellExample::new(5);
assert_eq!(cell.get(), 5);
cell.increment();
assert_eq!(cell.get(), 6);
}
#[test]
fn test_mock_messenger() {
let messenger = MockMessenger::new();
messenger.send("hello");
messenger.send("world");
assert_eq!(messenger.message_count(), 2);
}
#[test]
fn test_cow() {
let borrowed = cow_example("hello");
assert!(matches!(borrowed, Cow::Borrowed(_)));
let owned = cow_example("hello world");
assert!(matches!(owned, Cow::Owned(_)));
}
}
```
--------------------------------------------------------------------------------
/tests/test_end_to_end.py:
--------------------------------------------------------------------------------
```python
import subprocess
import json
import os
import time
import pytest
import random
import string
SAMPLE_PROJECT_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "sample_project"))
request_id_counter = 1
def call_tool(server_process, tool_name, tool_args):
global request_id_counter
request = {
"jsonrpc": "2.0",
"id": request_id_counter,
"method": "tools/call",
"params": {"name": tool_name, "arguments": tool_args}
}
request_id_counter += 1
print(f"--> Sending request: {json.dumps(request)}")
server_process.stdin.write(json.dumps(request) + "\n")
server_process.stdin.flush()
while True:
response_line = server_process.stdout.readline()
print(f"<-- Received line: {response_line.strip()}")
try:
response = json.loads(response_line)
if response.get("id") == request["id"]:
return json.loads(response["result"]["content"][0]["text"])
except (json.JSONDecodeError, KeyError):
continue
def run_command(command, shell=False, check=True):
cmd_str = command if isinstance(command, str) else ' '.join(command)
print(f"[CMD] {cmd_str}")
try:
process = subprocess.run(
command,
shell=shell,
check=check,
capture_output=True,
text=True,
timeout=300,
)
return process
except subprocess.CalledProcessError as e:
print(f"[ERROR] Error executing command: {cmd_str}")
if e.stdout:
print(f"[ERROR] STDOUT: {e.stdout}")
if e.stderr:
print(f"[ERROR] STDERR: {e.stderr}")
return None
except subprocess.TimeoutExpired:
print(f"[ERROR] Command timed out: {cmd_str}")
return None
def test_end_to_end_workflow_local_db():
if not run_command(["docker", "--version"], check=False) or not run_command(["docker", "compose", "version"], check=False):
pytest.skip("Docker or Docker Compose not found. Skipping test.")
print("\n--- Setting up local Neo4j database ---")
password = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(12))
compose_content = f"""
services:
neo4j:
image: neo4j:5.21
container_name: neo4j-cgc-test
restart: unless-stopped
ports:
- "7474:7474"
- "7687:7687"
environment:
- NEO4J_AUTH=neo4j/{password}
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
volumes:
- neo4j_data:/data
- neo4j_logs:/logs
volumes:
neo4j_data:
neo4j_logs:
"""
compose_file = os.path.join(os.path.dirname(__file__), "..", "docker-compose-test.yml")
with open(compose_file, "w") as f:
f.write(compose_content)
env_path = os.path.join(os.path.dirname(__file__), "..", ".env")
server_process = None
try:
print("--- Starting Neo4j container ---")
run_command(["docker", "compose", "-f", compose_file, "up", "-d"])
print("--- Waiting for Neo4j to be ready ---")
max_attempts = 24
for attempt in range(max_attempts):
time.sleep(5)
health_check = run_command([
"docker", "exec", "neo4j-cgc-test", "cypher-shell",
"-u", "neo4j", "-p", password,
"RETURN 'Connection successful' as status"
], check=False)
if health_check and health_check.returncode == 0:
print("--- Neo4j is ready ---")
break
if attempt == max_attempts - 1:
pytest.fail("Neo4j container did not become ready in time.")
print("--- Creating .env file for server ---")
env_content = f"""
NEO4J_URI=neo4j://localhost:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD={password}
DEFAULT_DATABASE=neo4j
"""
with open(env_path, "w") as f:
f.write(env_content)
print("--- Starting server ---")
server_process = subprocess.Popen(
["cgc", "mcp", "start"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
cwd=os.path.join(os.path.dirname(__file__), "..")
)
start_time = time.time()
timeout_seconds = 60
server_ready = False
while time.time() - start_time < timeout_seconds:
line = server_process.stderr.readline()
if not line:
# Process might have exited
if server_process.poll() is not None:
break
time.sleep(0.1)
continue
print(f"STDERR: {line.strip()}")
if "MCP Server is running" in line:
server_ready = True
break
if not server_ready:
# If we timed out or process exited without ready message
if server_process.poll() is not None:
print(f"Server exited with code {server_process.returncode}")
pytest.fail(f"Server did not become ready within {timeout_seconds} seconds")
init_request = {"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {}}
server_process.stdin.write(json.dumps(init_request) + "\n")
server_process.stdin.flush()
while True:
response_line = server_process.stdout.readline()
try:
init_response = json.loads(response_line)
if init_response.get("id") == 0:
break
except json.JSONDecodeError:
continue
print("--- Calling tools ---")
# Try to delete in case it exists from a previous run, but don't fail if it doesn't
call_tool(server_process, "delete_repository", {"repo_path": SAMPLE_PROJECT_PATH})
add_result = call_tool(server_process, "add_code_to_graph", {"path": SAMPLE_PROJECT_PATH})
assert add_result.get("success") is True
job_id = add_result.get("job_id")
assert job_id is not None
while True:
status_result = call_tool(server_process, "check_job_status", {"job_id": job_id})
if status_result.get("job", {}).get("status") == "completed":
break
time.sleep(2)
list_result = call_tool(server_process, "list_indexed_repositories", {})
assert list_result.get("success") is True
assert SAMPLE_PROJECT_PATH in [repo["path"] for repo in list_result.get("repositories", [])]
finally:
print("--- Shutting down server and Neo4j container ---")
if server_process:
server_process.terminate()
server_process.wait()
run_command(["docker", "compose", "-f", compose_file, "down"])
if os.path.exists(env_path):
os.remove(env_path)
if os.path.exists(compose_file):
os.remove(compose_file)
```
--------------------------------------------------------------------------------
/tests/sample_project_go/packages_imports.go:
--------------------------------------------------------------------------------
```go
// packages_imports.go - Demonstrates Go package imports and usage
package main
import (
// Standard library imports
"fmt"
"io"
"math"
"math/rand"
"net/http"
"os"
"strings"
"time"
// Aliased imports
str "strings"
// Dot imports (imports all exported names directly)
// . "fmt" // Uncomment to use - not recommended in production
// Blank imports (for side effects only)
_ "image/png"
// Local package import (would be actual import in real project)
// "github.com/user/project/module"
)
// StandardLibraryUsage demonstrates standard library usage
func StandardLibraryUsage() {
// fmt package
fmt.Println("Hello from fmt")
// strings package
upper := strings.ToUpper("hello")
fmt.Println(upper)
// math package
sqrt := math.Sqrt(16)
fmt.Printf("Square root: %.2f\n", sqrt)
// time package
now := time.Now()
fmt.Println("Current time:", now.Format(time.RFC3339))
// rand package
rand.Seed(time.Now().UnixNano())
randomNum := rand.Intn(100)
fmt.Println("Random number:", randomNum)
}
// AliasedImportUsage demonstrates aliased imports
func AliasedImportUsage() {
// Using str alias for strings package
result := str.Contains("hello world", "world")
fmt.Println("Contains:", result)
trimmed := str.TrimSpace(" spaces ")
fmt.Println("Trimmed:", trimmed)
}
// FileOperations demonstrates os and io packages
func FileOperations() error {
// Create a file
file, err := os.Create("example.txt")
if err != nil {
return fmt.Errorf("failed to create file: %w", err)
}
defer file.Close()
// Write to file
_, err = io.WriteString(file, "Hello, File!\n")
if err != nil {
return fmt.Errorf("failed to write to file: %w", err)
}
// Read file
content, err := os.ReadFile("example.txt")
if err != nil {
return fmt.Errorf("failed to read file: %w", err)
}
fmt.Println("File content:", string(content))
// Clean up
os.Remove("example.txt")
return nil
}
// HTTPClientExample demonstrates net/http package
func HTTPClientExample() error {
// Make HTTP request
resp, err := http.Get("https://api.github.com")
if err != nil {
return fmt.Errorf("failed to make request: %w", err)
}
defer resp.Body.Close()
fmt.Println("Status:", resp.Status)
// Read response body
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response: %w", err)
}
fmt.Println("Response length:", len(body))
return nil
}
// HTTPServerExample demonstrates creating an HTTP server
func HTTPServerExample() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
})
http.HandleFunc("/api/users", handleUsers)
// This would start the server (commented out for sample)
// http.ListenAndServe(":8080", nil)
}
func handleUsers(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
fmt.Fprintf(w, "Getting users")
case http.MethodPost:
fmt.Fprintf(w, "Creating user")
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}
// StringsPackageUsage demonstrates extensive strings package usage
func StringsPackageUsage() {
// Various string operations
text := "Hello, World! Hello, Go!"
contains := strings.Contains(text, "World")
hasPrefix := strings.HasPrefix(text, "Hello")
hasSuffix := strings.HasSuffix(text, "Go!")
count := strings.Count(text, "Hello")
index := strings.Index(text, "World")
split := strings.Split(text, " ")
joined := strings.Join(split, "-")
replaced := strings.Replace(text, "Hello", "Hi", -1)
fmt.Printf("Contains: %v, Prefix: %v, Suffix: %v\n", contains, hasPrefix, hasSuffix)
fmt.Printf("Count: %d, Index: %d\n", count, index)
fmt.Printf("Split: %v\n", split)
fmt.Printf("Joined: %s\n", joined)
fmt.Printf("Replaced: %s\n", replaced)
}
// MathPackageUsage demonstrates math package
func MathPackageUsage() {
// Math constants
fmt.Println("Pi:", math.Pi)
fmt.Println("E:", math.E)
// Math functions
fmt.Println("Sqrt(16):", math.Sqrt(16))
fmt.Println("Pow(2, 10):", math.Pow(2, 10))
fmt.Println("Max(10, 20):", math.Max(10, 20))
fmt.Println("Min(10, 20):", math.Min(10, 20))
fmt.Println("Abs(-42):", math.Abs(-42))
fmt.Println("Ceil(4.2):", math.Ceil(4.2))
fmt.Println("Floor(4.8):", math.Floor(4.8))
fmt.Println("Round(4.5):", math.Round(4.5))
}
// TimePackageUsage demonstrates time package
func TimePackageUsage() {
// Current time
now := time.Now()
fmt.Println("Current time:", now)
// Time formatting
formatted := now.Format("2006-01-02 15:04:05")
fmt.Println("Formatted:", formatted)
// Parsing time
parsed, _ := time.Parse("2006-01-02", "2024-01-15")
fmt.Println("Parsed:", parsed)
// Time arithmetic
tomorrow := now.Add(24 * time.Hour)
yesterday := now.Add(-24 * time.Hour)
fmt.Println("Tomorrow:", tomorrow.Format("2006-01-02"))
fmt.Println("Yesterday:", yesterday.Format("2006-01-02"))
// Duration
duration := 2 * time.Hour
fmt.Println("Duration:", duration)
// Sleep
// time.Sleep(time.Second)
}
// OSPackageUsage demonstrates os package
func OSPackageUsage() {
// Environment variables
os.Setenv("MY_VAR", "my_value")
value := os.Getenv("MY_VAR")
fmt.Println("Environment variable:", value)
// Command line arguments
args := os.Args
fmt.Println("Program name:", args[0])
// Working directory
wd, _ := os.Getwd()
fmt.Println("Working directory:", wd)
// File info
fileInfo, err := os.Stat("packages_imports.go")
if err == nil {
fmt.Println("File size:", fileInfo.Size())
fmt.Println("Is directory:", fileInfo.IsDir())
fmt.Println("Modified:", fileInfo.ModTime())
}
}
// IOPackageUsage demonstrates io package
func IOPackageUsage() {
// String reader
reader := strings.NewReader("Hello from io package")
// Read all
content, _ := io.ReadAll(reader)
fmt.Println("Content:", string(content))
// Copy example (would copy from one reader/writer to another)
// io.Copy(dst, src)
}
// MultiplePackageUsage uses multiple packages together
func MultiplePackageUsage() error {
// Combine time, strings, and fmt
now := time.Now()
formatted := now.Format(time.RFC3339)
upper := strings.ToUpper(formatted)
final := fmt.Sprintf("Current time: %s", upper)
// Combine math and fmt
result := math.Sqrt(math.Pow(3, 2) + math.Pow(4, 2))
output := fmt.Sprintf("Hypotenuse: %.2f", result)
fmt.Println(final)
fmt.Println(output)
return nil
}
// PackageInitPattern demonstrates initialization patterns
var (
initialized bool
config map[string]string
)
func init() {
// This runs automatically when package is imported
initialized = true
config = make(map[string]string)
config["version"] = "1.0.0"
config["env"] = "development"
fmt.Println("Package initialized")
}
// GetConfig returns the config
func GetConfig(key string) string {
return config[key]
}
func demonstrateImports() {
StandardLibraryUsage()
AliasedImportUsage()
StringsPackageUsage()
MathPackageUsage()
TimePackageUsage()
OSPackageUsage()
IOPackageUsage()
MultiplePackageUsage()
}
```
--------------------------------------------------------------------------------
/website/src/components/ui/context-menu.tsx:
--------------------------------------------------------------------------------
```typescript
import * as React from "react";
import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
import { Check, ChevronRight, Circle } from "lucide-react";
import { cn } from "@/lib/utils";
const ContextMenu = ContextMenuPrimitive.Root;
const ContextMenuTrigger = ContextMenuPrimitive.Trigger;
const ContextMenuGroup = ContextMenuPrimitive.Group;
const ContextMenuPortal = ContextMenuPrimitive.Portal;
const ContextMenuSub = ContextMenuPrimitive.Sub;
const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
const ContextMenuSubTrigger = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.SubTrigger>,
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubTrigger> & {
inset?: boolean;
}
>(({ className, inset, children, ...props }, ref) => (
<ContextMenuPrimitive.SubTrigger
ref={ref}
className={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[state=open]:bg-accent data-[state=open]:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
inset && "pl-8",
className,
)}
{...props}
>
{children}
<ChevronRight className="ml-auto h-4 w-4" />
</ContextMenuPrimitive.SubTrigger>
));
ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
const ContextMenuSubContent = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.SubContent>,
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubContent>
>(({ className, ...props }, ref) => (
<ContextMenuPrimitive.SubContent
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
)}
{...props}
/>
));
ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName;
const ContextMenuContent = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Content>
>(({ className, ...props }, ref) => (
<ContextMenuPrimitive.Portal>
<ContextMenuPrimitive.Content
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
)}
{...props}
/>
</ContextMenuPrimitive.Portal>
));
ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
const ContextMenuItem = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
<ContextMenuPrimitive.Item
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
inset && "pl-8",
className,
)}
{...props}
/>
));
ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
const ContextMenuCheckboxItem = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.CheckboxItem>,
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.CheckboxItem>
>(({ className, children, checked, ...props }, ref) => (
<ContextMenuPrimitive.CheckboxItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
className,
)}
checked={checked}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<ContextMenuPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</ContextMenuPrimitive.ItemIndicator>
</span>
{children}
</ContextMenuPrimitive.CheckboxItem>
));
ContextMenuCheckboxItem.displayName = ContextMenuPrimitive.CheckboxItem.displayName;
const ContextMenuRadioItem = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.RadioItem>,
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.RadioItem>
>(({ className, children, ...props }, ref) => (
<ContextMenuPrimitive.RadioItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
className,
)}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<ContextMenuPrimitive.ItemIndicator>
<Circle className="h-2 w-2 fill-current" />
</ContextMenuPrimitive.ItemIndicator>
</span>
{children}
</ContextMenuPrimitive.RadioItem>
));
ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName;
const ContextMenuLabel = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Label> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
<ContextMenuPrimitive.Label
ref={ref}
className={cn("px-2 py-1.5 text-sm font-semibold text-foreground", inset && "pl-8", className)}
{...props}
/>
));
ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;
const ContextMenuSeparator = React.forwardRef<
React.ElementRef<typeof ContextMenuPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Separator>
>(({ className, ...props }, ref) => (
<ContextMenuPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-border", className)} {...props} />
));
ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
const ContextMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
return <span className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)} {...props} />;
};
ContextMenuShortcut.displayName = "ContextMenuShortcut";
export {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
ContextMenuCheckboxItem,
ContextMenuRadioItem,
ContextMenuLabel,
ContextMenuSeparator,
ContextMenuShortcut,
ContextMenuGroup,
ContextMenuPortal,
ContextMenuSub,
ContextMenuSubContent,
ContextMenuSubTrigger,
ContextMenuRadioGroup,
};
```
--------------------------------------------------------------------------------
/website/src/components/ui/dropdown-menu.tsx:
--------------------------------------------------------------------------------
```typescript
import * as React from "react";
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
import { Check, ChevronRight, Circle } from "lucide-react";
import { cn } from "@/lib/utils";
const DropdownMenu = DropdownMenuPrimitive.Root;
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
const DropdownMenuGroup = DropdownMenuPrimitive.Group;
const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
const DropdownMenuSub = DropdownMenuPrimitive.Sub;
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
const DropdownMenuSubTrigger = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
inset?: boolean;
}
>(({ className, inset, children, ...props }, ref) => (
<DropdownMenuPrimitive.SubTrigger
ref={ref}
className={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[state=open]:bg-accent focus:bg-accent",
inset && "pl-8",
className,
)}
{...props}
>
{children}
<ChevronRight className="ml-auto h-4 w-4" />
</DropdownMenuPrimitive.SubTrigger>
));
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
const DropdownMenuSubContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.SubContent
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
)}
{...props}
/>
));
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
const DropdownMenuContent = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<DropdownMenuPrimitive.Portal>
<DropdownMenuPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
)}
{...props}
/>
</DropdownMenuPrimitive.Portal>
));
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
const DropdownMenuItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Item
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
inset && "pl-8",
className,
)}
{...props}
/>
));
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
const DropdownMenuCheckboxItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
>(({ className, children, checked, ...props }, ref) => (
<DropdownMenuPrimitive.CheckboxItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
className,
)}
checked={checked}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<DropdownMenuPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</DropdownMenuPrimitive.ItemIndicator>
</span>
{children}
</DropdownMenuPrimitive.CheckboxItem>
));
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
const DropdownMenuRadioItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
>(({ className, children, ...props }, ref) => (
<DropdownMenuPrimitive.RadioItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
className,
)}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<DropdownMenuPrimitive.ItemIndicator>
<Circle className="h-2 w-2 fill-current" />
</DropdownMenuPrimitive.ItemIndicator>
</span>
{children}
</DropdownMenuPrimitive.RadioItem>
));
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
const DropdownMenuLabel = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Label
ref={ref}
className={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
{...props}
/>
));
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
const DropdownMenuSeparator = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-muted", className)} {...props} />
));
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
return <span className={cn("ml-auto text-xs tracking-widest opacity-60", className)} {...props} />;
};
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
export {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuCheckboxItem,
DropdownMenuRadioItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuGroup,
DropdownMenuPortal,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuRadioGroup,
};
```
--------------------------------------------------------------------------------
/organizer/language_specific_nodes.md:
--------------------------------------------------------------------------------
```markdown
# How to Add Language-Specific Features
This document outlines the standard pattern for extending the CodeGraphContext tool to support new, language-specific code constructs (like Go interfaces, Rust traits, C++ macros, etc.).
## Core Philosophy
The system is designed with a clear separation of concerns:
1. **Language-Specific Parsers:** Located in `src/codegraphcontext/tools/languages/`, these are responsible for understanding the syntax of a single language and extracting its constructs into a standardized Python dictionary.
2. **Generic Graph Builder:** The `GraphBuilder` in `src/codegraphcontext/tools/graph_builder.py` consumes these dictionaries and is responsible for creating nodes and relationships in the Neo4j database. It is language-agnostic.
Adding a new feature always involves these two steps: **(1) Specialize the Parser** and **(2) Generalize the Builder**.
---
## Step-by-Step Guide: Adding a New Node Type
We will walk through two examples:
1. Adding support for Go `interface` nodes.
2. Adding support for C/C++ `macro` nodes.
### Part 1: Modify the Language Parser
Your first goal is to teach the correct language parser to identify the new construct and return it under a unique key.
#### Example: Go Interfaces
**File to Edit:** `src/codegraphcontext/tools/languages/go.py`
**1. Add a Tree-sitter Query:**
Ensure a query exists in the `GO_QUERIES` dictionary to find the construct.
```python
GO_QUERIES = {
# ... existing queries
"interfaces": """
(type_declaration
(type_spec
name: (type_identifier) @name
type: (interface_type) @interface_body
)
) @interface_node
""",
}
```
**2. Create a Dedicated Parsing Method:**
Create a new method in the `GoTreeSitterParser` class to handle the results from your new query.
```python
# In GoTreeSitterParser class
def _find_interfaces(self, root_node):
interfaces = []
interface_query = self.queries['interfaces']
for node, capture_name in interface_query.captures(root_node):
if capture_name == 'name':
interface_node = self._find_type_declaration_for_name(node)
if interface_node:
name = self._get_node_text(node)
interfaces.append({
"name": name,
"line_number": interface_node.start_point[0] + 1,
"end_line": interface_node.end_point[0] + 1,
"source": self._get_node_text(interface_node),
})
return interfaces
```
**3. Update the Main `parse` Method:**
In the parser's main `parse` method, call your new function and add its results to the dictionary that gets returned. **The key you use here (e.g., `"interfaces"`) is what the Graph Builder will use.**
```python
# In GoTreeSitterParser.parse()
def parse(self, file_path: Path, is_dependency: bool = False) -> Dict:
# This comment explains the pattern for future developers.
# This method orchestrates the parsing of a single file.
# It calls specialized `_find_*` methods for each language construct.
# The returned dictionary should map a specific key (e.g., 'functions', 'interfaces')
# to a list of dictionaries, where each dictionary represents a single code construct.
# The GraphBuilder will then use these keys to create nodes with corresponding labels.
with open(file_path, "r", encoding="utf-8") as f:
source_code = f.read()
tree = self.parser.parse(bytes(source_code, "utf8"))
root_node = tree.root_node
functions = self._find_functions(root_node)
structs = self._find_structs(root_node)
interfaces = self._find_interfaces(root_node) # Call the new method
# ... find other constructs
return {
"file_path": str(file_path),
"functions": functions,
"classes": structs, # Structs are mapped to the generic :Class label
"interfaces": interfaces, # The new key-value pair
"variables": variables,
"imports": imports,
"function_calls": function_calls,
"is_dependency": is_dependency,
"lang": self.language_name,
}
```
---
### Part 2: Update the Generic Graph Builder
Now, teach the `GraphBuilder` how to handle the new key (e.g., `"interfaces"`) produced by the parser.
**File to Edit:** `src/codegraphcontext/tools/graph_builder.py`
**1. Add a Schema Constraint:**
In the `create_schema` method, add a uniqueness constraint for the new Neo4j node label you are introducing (e.g., `:Interface`, `:Macro`). This is crucial for data integrity.
```python
# In GraphBuilder.create_schema()
def create_schema(self):
"""Create constraints and indexes in Neo4j."""
# When adding a new node type with a unique key, add its constraint here.
with self.driver.session() as session:
try:
# ... existing constraints
session.run("CREATE CONSTRAINT class_unique IF NOT EXISTS FOR (c:Class) REQUIRE (c.name, c.file_path, c.line_number) IS UNIQUE")
# Add constraints for the new types
session.run("CREATE CONSTRAINT interface_unique IF NOT EXISTS FOR (i:Interface) REQUIRE (i.name, i.file_path, i.line_number) IS UNIQUE")
session.run("CREATE CONSTRAINT macro_unique IF NOT EXISTS FOR (m:Macro) REQUIRE (m.name, m.file_path, m.line_number) IS UNIQUE")
# ... other schema items
```
**2. Update the Node Creation Loop:**
In the `add_file_to_graph` method, there is a list called `item_mappings`. Add your new construct to this list. The builder will handle the rest automatically.
```python
# In GraphBuilder.add_file_to_graph()
# To add a new language-specific node type (e.g., 'Trait' for Rust):
# 1. Ensure your language-specific parser returns a list under a unique key (e.g., 'traits': [...] ).
# 2. Add a new constraint for the new label in the `create_schema` method.
# 3. Add a new entry to the `item_mappings` list below (e.g., (file_data.get('traits', []), 'Trait') ).
item_mappings = [
(file_data.get('functions', []), 'Function'),
(file_data.get('classes', []), 'Class'),
(file_data.get('variables', []), 'Variable'),
(file_data.get('interfaces', []), 'Interface'), # Added for Go
(file_data.get('macros', []), 'Macro') # Added for C/C++
]
for item_data, label in item_mappings:
for item in item_data:
# ... generic node creation logic
```
Using `file_data.get('macros', [])` ensures that the builder doesn't fail if a language parser (like Python's) doesn't produce a `macros` key.
---
## Advanced Topic: Scaling with Multi-Labeling
A valid concern is the proliferation of node labels. A more advanced pattern is to use multiple labels to capture both specific and general concepts.
For example:
- A Go interface node could have the labels: `[:Interface, :Contract, :Go]`
- A Rust trait node could have the labels: `[:Trait, :Contract, :Rust]`
This allows for powerful, cross-language queries (e.g., `MATCH (c:Contract)`) while retaining language-specific details.
This can be implemented in `add_file_to_graph` by dynamically constructing the label string based on the data provided by the parser, which already includes a `lang` key.
```
--------------------------------------------------------------------------------
/tests/sample_project_go/advanced_types.go:
--------------------------------------------------------------------------------
```go
// advanced_types.go - Demonstrates advanced Go types
package main
import (
"fmt"
"sort"
)
// CustomString is a custom type based on string
type CustomString string
// Length returns the length of the custom string
func (cs CustomString) Length() int {
return len(cs)
}
// ToUpper converts to uppercase
func (cs CustomString) ToUpper() CustomString {
return CustomString(fmt.Sprintf("%s", cs))
}
// CustomInt is a custom numeric type
type CustomInt int
// IsEven checks if the number is even
func (ci CustomInt) IsEven() bool {
return ci%2 == 0
}
// Double doubles the value
func (ci CustomInt) Double() CustomInt {
return ci * 2
}
// Status is an enum-like type
type Status int
const (
StatusPending Status = iota
StatusActive
StatusInactive
StatusDeleted
)
// String implements Stringer interface for Status
func (s Status) String() string {
return [...]string{"Pending", "Active", "Inactive", "Deleted"}[s]
}
// IsValid checks if status is valid
func (s Status) IsValid() bool {
return s >= StatusPending && s <= StatusDeleted
}
// Priority represents priority levels
type Priority string
const (
PriorityLow Priority = "low"
PriorityMedium Priority = "medium"
PriorityHigh Priority = "high"
)
// MapOperations demonstrates map operations
func MapOperations() map[string]int {
// Initialize map
scores := make(map[string]int)
// Add elements
scores["Alice"] = 95
scores["Bob"] = 87
scores["Charlie"] = 92
// Check existence
if val, ok := scores["Alice"]; ok {
fmt.Printf("Alice's score: %d\n", val)
}
// Delete element
delete(scores, "Bob")
return scores
}
// NestedMap demonstrates nested maps
func NestedMap() map[string]map[string]int {
users := make(map[string]map[string]int)
users["user1"] = make(map[string]int)
users["user1"]["age"] = 25
users["user1"]["score"] = 100
users["user2"] = map[string]int{
"age": 30,
"score": 95,
}
return users
}
// SliceOperations demonstrates slice operations
func SliceOperations() []int {
// Create slice
nums := []int{1, 2, 3, 4, 5}
// Append
nums = append(nums, 6, 7, 8)
// Slice operations
subset := nums[2:5]
fmt.Println(subset)
// Copy
copied := make([]int, len(nums))
copy(copied, nums)
return copied
}
// SliceOfSlices demonstrates 2D slices
func SliceOfSlices() [][]int {
matrix := [][]int{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
}
return matrix
}
// ArrayOperations demonstrates array operations
func ArrayOperations() [5]int {
var arr [5]int
arr[0] = 10
arr[1] = 20
// Array initialization
arr2 := [5]int{1, 2, 3, 4, 5}
return arr2
}
// StructWithTags demonstrates struct tags
type User struct {
ID int `json:"id" db:"user_id"`
Username string `json:"username" db:"username" validate:"required"`
Email string `json:"email" db:"email" validate:"email"`
Age int `json:"age,omitempty" db:"age"`
IsActive bool `json:"is_active" db:"is_active"`
Role string `json:"role" db:"role" default:"user"`
}
// AnonymousStruct demonstrates anonymous structs
func AnonymousStruct() {
person := struct {
Name string
Age int
}{
Name: "John",
Age: 30,
}
fmt.Printf("%+v\n", person)
}
// FunctionType is a function type
type FunctionType func(int, int) int
// ApplyOperation applies a function operation
func ApplyOperation(a, b int, op FunctionType) int {
return op(a, b)
}
// MathOperations demonstrates function types
func MathOperations() {
add := func(a, b int) int { return a + b }
multiply := func(a, b int) int { return a * b }
fmt.Println(ApplyOperation(5, 3, add))
fmt.Println(ApplyOperation(5, 3, multiply))
}
// ChannelTypes demonstrates different channel types
func ChannelTypes() {
// Unbuffered channel
ch1 := make(chan int)
// Buffered channel
ch2 := make(chan string, 5)
// Send-only channel (in function signature)
go func(ch chan<- int) {
ch <- 42
}(ch1)
// Receive-only channel (in function signature)
go func(ch <-chan string) {
<-ch
}(ch2)
}
// SortableInts demonstrates custom sorting
type SortableInts []int
func (s SortableInts) Len() int { return len(s) }
func (s SortableInts) Less(i, j int) bool { return s[i] < s[j] }
func (s SortableInts) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// SortIntegers sorts integers using custom type
func SortIntegers(nums []int) []int {
sortable := SortableInts(nums)
sort.Sort(sortable)
return nums
}
// ByAge implements sort for Person by age
type ByAge []Person
func (a ByAge) Len() int { return len(a) }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
// SortPeople sorts people by age
func SortPeople(people []Person) []Person {
sort.Sort(ByAge(people))
return people
}
// Result is a generic result type
type Result struct {
Success bool
Data interface{}
Error error
}
// NewSuccessResult creates a success result
func NewSuccessResult(data interface{}) Result {
return Result{
Success: true,
Data: data,
Error: nil,
}
}
// NewErrorResult creates an error result
func NewErrorResult(err error) Result {
return Result{
Success: false,
Data: nil,
Error: err,
}
}
// PointerTypes demonstrates pointer operations
func PointerTypes() {
x := 10
ptr := &x
fmt.Printf("Value: %d, Pointer: %p, Dereferenced: %d\n", x, ptr, *ptr)
*ptr = 20
fmt.Printf("Modified value: %d\n", x)
}
// PointerToStruct demonstrates pointer to struct
func PointerToStruct() *User {
user := &User{
ID: 1,
Username: "john_doe",
Email: "[email protected]",
Age: 30,
IsActive: true,
}
return user
}
// TypeAlias demonstrates type aliasing
type UserID = int
type Username = string
type EmailAddress = string
// CreateUserWithAliases uses type aliases
func CreateUserWithAliases(id UserID, name Username, email EmailAddress) User {
return User{
ID: id,
Username: name,
Email: email,
}
}
// InterfaceType demonstrates interface{} (any)
func InterfaceType(data interface{}) string {
switch v := data.(type) {
case int:
return fmt.Sprintf("Integer: %d", v)
case string:
return fmt.Sprintf("String: %s", v)
case []int:
return fmt.Sprintf("Slice of ints: %v", v)
case User:
return fmt.Sprintf("User: %s", v.Username)
default:
return fmt.Sprintf("Unknown type: %T", v)
}
}
// BitFlags demonstrates bit flags
type Permission uint8
const (
PermissionRead Permission = 1 << iota
PermissionWrite
PermissionExecute
PermissionDelete
)
// HasPermission checks if a permission is set
func HasPermission(perms Permission, perm Permission) bool {
return perms&perm != 0
}
// AddPermission adds a permission
func AddPermission(perms Permission, perm Permission) Permission {
return perms | perm
}
// RemovePermission removes a permission
func RemovePermission(perms Permission, perm Permission) Permission {
return perms &^ perm
}
func demonstrateAdvancedTypes() {
// Custom types
cs := CustomString("hello")
fmt.Println(cs.Length())
ci := CustomInt(10)
fmt.Println(ci.IsEven())
// Enums
status := StatusActive
fmt.Println(status.String())
// Maps
scores := MapOperations()
fmt.Println(scores)
// Slices
nums := SliceOperations()
fmt.Println(nums)
// Sorting
sorted := SortIntegers([]int{5, 2, 8, 1, 9})
fmt.Println(sorted)
}
```
--------------------------------------------------------------------------------
/website/src/components/ShowStarGraph.tsx:
--------------------------------------------------------------------------------
```typescript
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { ExternalLink, Star, TrendingUp, RefreshCw } from "lucide-react";
import { useState, useCallback, useEffect } from "react";
export default function ShowStarGraph() {
const [imageLoaded, setImageLoaded] = useState(false);
const [imageError, setImageError] = useState(false);
const [refreshKey, setRefreshKey] = useState(0);
const [isRefreshing, setIsRefreshing] = useState(false);
const baseStarHistoryImageUrl =
"https://api.star-history.com/svg?repos=Shashankss1205/CodeGraphContext&type=Date";
// Add cache busting parameter to force updates
const starHistoryImageUrl = `${baseStarHistoryImageUrl}&t=${refreshKey}`;
const starHistoryDarkImageUrl = `${baseStarHistoryImageUrl}&theme=dark&t=${refreshKey}`;
const githubRepoUrl = "https://github.com/Shashankss1205/CodeGraphContext";
const starHistoryUrl =
"https://star-history.com/#Shashankss1205/CodeGraphContext&Date";
const handleImageLoad = () => {
setImageLoaded(true);
setImageError(false);
setIsRefreshing(false);
};
const handleImageError = () => {
setImageError(true);
setImageLoaded(false);
setIsRefreshing(false);
};
const handleRefresh = useCallback(() => {
setIsRefreshing(true);
setImageLoaded(false);
setImageError(false);
setRefreshKey((prev) => prev + 1);
}, []);
//Refreshed the graph everyday
useEffect(() => {
const today = new Date().toDateString();
const lastUpdated = localStorage.getItem("starHistoryLastUpdate");
if (lastUpdated !== today) {
handleRefresh();
localStorage.setItem("starHistoryLastUpdate", today);
}
}, [handleRefresh]);
return (
<>
<section className="px-4 bg-gradient-to-b from-secondary/10 to-background" data-aos="fade-up">
<div className="container mx-auto max-w-6xl">
<div className="text-center mb-12" data-aos="fade-down">
<div className="flex items-center justify-center gap-2 mb-4">
<Star className="h-6 w-6 text-yellow-500 fill-yellow-500" />
<h2 className="text-4xl md:text-5xl font-bold bg-gradient-to-r from-primary via-primary to-accent bg-clip-text text-transparent py-2">
Star History
</h2>
<TrendingUp className="h-6 w-6 text-green-500" />
</div>
<p className="text-xl text-muted-foreground max-w-3xl mx-auto">
Track the growth and popularity of CodeGraphContext over time
</p>
</div>
<Card className="w-full shadow-2xl border-border/50 bg-card/50 backdrop-blur-sm" data-aos="zoom-in-up">
<CardHeader className="text-center">
<CardTitle className="flex items-center justify-center gap-2 text-2xl">
<Star className="h-5 w-5 text-yellow-500 fill-yellow-500" />
Repository Growth
<Badge variant="outline" className="ml-2">
Updated Daily
</Badge>
</CardTitle>
</CardHeader>
<CardContent className="p-6">
<div className="relative overflow-x-auto">
<div className="min-w-[700px]">
{(!imageLoaded && !imageError) ||
(isRefreshing && (
<div className="w-full h-64 bg-muted rounded-lg flex items-center justify-center">
<div className="text-center">
<div className="animate-spin h-8 w-8 border-4 border-primary border-t-transparent rounded-full mx-auto mb-2"></div>
<p className="text-muted-foreground">
{isRefreshing
? "Refreshing star history..."
: "Loading star history..."}
</p>
</div>
</div>
))}
{imageError && (
<div className="w-full h-64 bg-muted rounded-lg flex items-center justify-center border-2 border-dashed border-border">
<div className="text-center">
<Star className="h-12 w-12 text-muted-foreground mx-auto mb-2" />
<p className="text-muted-foreground mb-2">
Unable to load star history
</p>
<Button
variant="outline"
onClick={() => window.open(starHistoryUrl, "_blank")}
>
<ExternalLink className="h-4 w-4 mr-2" />
View on Star History
</Button>
</div>
</div>
)}
<div key={refreshKey}>
<img
src={starHistoryImageUrl}
alt="CodeGraphContext Star History"
className={`w-full h-auto rounded-lg transition-opacity duration-300 dark:hidden ${imageLoaded && !isRefreshing
? "opacity-100"
: "opacity-0 absolute inset-0"
} ${imageError ? "hidden" : "block"}`}
onLoad={handleImageLoad}
onError={handleImageError}
/>
<img
src={starHistoryDarkImageUrl}
alt="CodeGraphContext Star History"
className={`w-full h-auto rounded-lg transition-opacity duration-300 hidden dark:block ${imageLoaded && !isRefreshing
? "opacity-100"
: "opacity-0 absolute inset-0"
} ${imageError ? "hidden" : "block"}`}
onLoad={handleImageLoad}
onError={handleImageError}
/>
</div>
</div>
</div>
{imageLoaded && !isRefreshing && (
<div className="mt-6 flex flex-col sm:flex-row gap-4 justify-center items-center" data-aos="fade-up" data-aos-delay="200">
<Button
variant="outline"
onClick={() => window.open(githubRepoUrl, "_blank")}
className="flex items-center gap-2"
>
<Star className="h-4 w-4" />
Star on GitHub
<ExternalLink className="h-4 w-4" />
</Button>
<Button
variant="ghost"
onClick={() => window.open(starHistoryUrl, "_blank")}
className="flex items-center gap-2"
>
<TrendingUp className="h-4 w-4" />
View Full History
<ExternalLink className="h-4 w-4" />
</Button>
</div>
)}
</CardContent>
</Card>
</div>
</section>
<br />
<br />
</>
);
}
```
--------------------------------------------------------------------------------
/tests/sample_project_rust/src/iterators_closures.rs:
--------------------------------------------------------------------------------
```rust
// iterators_closures.rs - Demonstrates Rust iterators and closures
use std::collections::HashMap;
// Closure examples
/// Function taking closure as parameter
pub fn apply<F>(f: F, x: i32) -> i32
where
F: Fn(i32) -> i32,
{
f(x)
}
/// Function returning closure
pub fn make_adder(n: i32) -> impl Fn(i32) -> i32 {
move |x| x + n
}
/// Closure capturing environment
pub fn closure_capture() {
let factor = 5;
let multiply = |x| x * factor;
println!("Result: {}", multiply(10));
}
/// Closure with move
pub fn closure_move() -> Box<dyn Fn(i32) -> i32> {
let factor = 5;
Box::new(move |x| x * factor)
}
/// FnOnce closure (consumes captured values)
pub fn call_once<F>(f: F)
where
F: FnOnce(),
{
f();
}
/// FnMut closure (mutates captured values)
pub fn call_mut<F>(mut f: F)
where
F: FnMut(),
{
f();
f();
}
// Iterator examples
/// Custom iterator
pub struct Counter {
count: u32,
max: u32,
}
impl Counter {
pub fn new(max: u32) -> Self {
Self { count: 0, max }
}
}
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
if self.count < self.max {
self.count += 1;
Some(self.count)
} else {
None
}
}
}
/// Range iterator wrapper
pub struct Range {
start: i32,
end: i32,
current: i32,
}
impl Range {
pub fn new(start: i32, end: i32) -> Self {
Self {
start,
end,
current: start,
}
}
}
impl Iterator for Range {
type Item = i32;
fn next(&mut self) -> Option<Self::Item> {
if self.current < self.end {
let result = self.current;
self.current += 1;
Some(result)
} else {
None
}
}
}
// Iterator adapter patterns
/// Map pattern
pub fn double_numbers(numbers: Vec<i32>) -> Vec<i32> {
numbers.iter().map(|&x| x * 2).collect()
}
/// Filter pattern
pub fn filter_evens(numbers: Vec<i32>) -> Vec<i32> {
numbers.into_iter().filter(|&x| x % 2 == 0).collect()
}
/// Filter and map combined
pub fn process_numbers(numbers: Vec<i32>) -> Vec<i32> {
numbers
.into_iter()
.filter(|&x| x > 0)
.map(|x| x * 2)
.collect()
}
/// Fold/reduce pattern
pub fn sum_numbers(numbers: &[i32]) -> i32 {
numbers.iter().fold(0, |acc, &x| acc + x)
}
/// Find pattern
pub fn find_first_even(numbers: &[i32]) -> Option<i32> {
numbers.iter().find(|&&x| x % 2 == 0).copied()
}
/// Any and all
pub fn has_negative(numbers: &[i32]) -> bool {
numbers.iter().any(|&x| x < 0)
}
pub fn all_positive(numbers: &[i32]) -> bool {
numbers.iter().all(|&x| x > 0)
}
/// Take and skip
pub fn take_first_n(numbers: Vec<i32>, n: usize) -> Vec<i32> {
numbers.into_iter().take(n).collect()
}
pub fn skip_first_n(numbers: Vec<i32>, n: usize) -> Vec<i32> {
numbers.into_iter().skip(n).collect()
}
/// Chain iterators
pub fn chain_vectors(v1: Vec<i32>, v2: Vec<i32>) -> Vec<i32> {
v1.into_iter().chain(v2.into_iter()).collect()
}
/// Zip iterators
pub fn zip_vectors(v1: Vec<i32>, v2: Vec<i32>) -> Vec<(i32, i32)> {
v1.into_iter().zip(v2.into_iter()).collect()
}
/// Enumerate
pub fn enumerate_items(items: Vec<String>) -> Vec<(usize, String)> {
items.into_iter().enumerate().collect()
}
/// Flat map
pub fn flat_map_example(nested: Vec<Vec<i32>>) -> Vec<i32> {
nested.into_iter().flat_map(|v| v.into_iter()).collect()
}
/// Partition
pub fn partition_numbers(numbers: Vec<i32>) -> (Vec<i32>, Vec<i32>) {
numbers.into_iter().partition(|&x| x % 2 == 0)
}
// Complex iterator chains
/// Multiple operations
pub fn complex_pipeline(numbers: Vec<i32>) -> i32 {
numbers
.into_iter()
.filter(|&x| x > 0)
.map(|x| x * 2)
.filter(|&x| x < 100)
.fold(0, |acc, x| acc + x)
}
/// Group by pattern (using HashMap)
pub fn group_by_parity(numbers: Vec<i32>) -> HashMap<bool, Vec<i32>> {
let mut map = HashMap::new();
for num in numbers {
let is_even = num % 2 == 0;
map.entry(is_even).or_insert_with(Vec::new).push(num);
}
map
}
/// Max and min
pub fn find_extremes(numbers: &[i32]) -> (Option<i32>, Option<i32>) {
let max = numbers.iter().max().copied();
let min = numbers.iter().min().copied();
(max, min)
}
/// Collect into different types
pub fn collect_examples(numbers: Vec<i32>) -> (Vec<i32>, String) {
let vec: Vec<i32> = numbers.iter().map(|&x| x * 2).collect();
let string: String = numbers
.iter()
.map(|x| x.to_string())
.collect::<Vec<String>>()
.join(", ");
(vec, string)
}
// Custom iterator adapters
pub struct StepBy {
iter: std::vec::IntoIter<i32>,
step: usize,
}
impl StepBy {
pub fn new(vec: Vec<i32>, step: usize) -> Self {
Self {
iter: vec.into_iter(),
step,
}
}
}
impl Iterator for StepBy {
type Item = i32;
fn next(&mut self) -> Option<Self::Item> {
let result = self.iter.next()?;
for _ in 0..self.step - 1 {
self.iter.next();
}
Some(result)
}
}
// Lazy evaluation demonstration
pub struct LazyMap<I, F> {
iter: I,
f: F,
}
impl<I, F, T, U> Iterator for LazyMap<I, F>
where
I: Iterator<Item = T>,
F: FnMut(T) -> U,
{
type Item = U;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|x| (self.f)(x))
}
}
// Infinite iterators
pub fn fibonacci_iterator() -> impl Iterator<Item = u64> {
let mut a = 0;
let mut b = 1;
std::iter::from_fn(move || {
let result = a;
let next = a + b;
a = b;
b = next;
Some(result)
})
}
/// Take from infinite iterator
pub fn first_n_fibonacci(n: usize) -> Vec<u64> {
fibonacci_iterator().take(n).collect()
}
// Peekable iterator
pub fn peek_example(numbers: Vec<i32>) -> Vec<i32> {
let mut iter = numbers.into_iter().peekable();
let mut result = Vec::new();
while let Some(&next) = iter.peek() {
if next % 2 == 0 {
result.push(iter.next().unwrap());
} else {
iter.next();
}
}
result
}
// Cycle iterator
pub fn cycle_example(items: Vec<i32>, count: usize) -> Vec<i32> {
items.into_iter().cycle().take(count).collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_counter() {
let counter = Counter::new(5);
let result: Vec<u32> = counter.collect();
assert_eq!(result, vec![1, 2, 3, 4, 5]);
}
#[test]
fn test_double_numbers() {
let numbers = vec![1, 2, 3, 4, 5];
let doubled = double_numbers(numbers);
assert_eq!(doubled, vec![2, 4, 6, 8, 10]);
}
#[test]
fn test_filter_evens() {
let numbers = vec![1, 2, 3, 4, 5, 6];
let evens = filter_evens(numbers);
assert_eq!(evens, vec![2, 4, 6]);
}
#[test]
fn test_sum_numbers() {
let numbers = vec![1, 2, 3, 4, 5];
assert_eq!(sum_numbers(&numbers), 15);
}
#[test]
fn test_make_adder() {
let add_five = make_adder(5);
assert_eq!(add_five(10), 15);
}
#[test]
fn test_fibonacci() {
let fibs = first_n_fibonacci(10);
assert_eq!(fibs, vec![0, 1, 1, 2, 3, 5, 8, 13, 21, 34]);
}
}
```
--------------------------------------------------------------------------------
/website/src/components/ui/menubar.tsx:
--------------------------------------------------------------------------------
```typescript
import * as React from "react";
import * as MenubarPrimitive from "@radix-ui/react-menubar";
import { Check, ChevronRight, Circle } from "lucide-react";
import { cn } from "@/lib/utils";
const MenubarMenu = MenubarPrimitive.Menu;
const MenubarGroup = MenubarPrimitive.Group;
const MenubarPortal = MenubarPrimitive.Portal;
const MenubarSub = MenubarPrimitive.Sub;
const MenubarRadioGroup = MenubarPrimitive.RadioGroup;
const Menubar = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Root>
>(({ className, ...props }, ref) => (
<MenubarPrimitive.Root
ref={ref}
className={cn("flex h-10 items-center space-x-1 rounded-md border bg-background p-1", className)}
{...props}
/>
));
Menubar.displayName = MenubarPrimitive.Root.displayName;
const MenubarTrigger = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger>
>(({ className, ...props }, ref) => (
<MenubarPrimitive.Trigger
ref={ref}
className={cn(
"flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none data-[state=open]:bg-accent data-[state=open]:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
className,
)}
{...props}
/>
));
MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName;
const MenubarSubTrigger = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.SubTrigger>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubTrigger> & {
inset?: boolean;
}
>(({ className, inset, children, ...props }, ref) => (
<MenubarPrimitive.SubTrigger
ref={ref}
className={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[state=open]:bg-accent data-[state=open]:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
inset && "pl-8",
className,
)}
{...props}
>
{children}
<ChevronRight className="ml-auto h-4 w-4" />
</MenubarPrimitive.SubTrigger>
));
MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName;
const MenubarSubContent = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.SubContent>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubContent>
>(({ className, ...props }, ref) => (
<MenubarPrimitive.SubContent
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
)}
{...props}
/>
));
MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName;
const MenubarContent = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>
>(({ className, align = "start", alignOffset = -4, sideOffset = 8, ...props }, ref) => (
<MenubarPrimitive.Portal>
<MenubarPrimitive.Content
ref={ref}
align={align}
alignOffset={alignOffset}
sideOffset={sideOffset}
className={cn(
"z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
)}
{...props}
/>
</MenubarPrimitive.Portal>
));
MenubarContent.displayName = MenubarPrimitive.Content.displayName;
const MenubarItem = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
<MenubarPrimitive.Item
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
inset && "pl-8",
className,
)}
{...props}
/>
));
MenubarItem.displayName = MenubarPrimitive.Item.displayName;
const MenubarCheckboxItem = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.CheckboxItem>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.CheckboxItem>
>(({ className, children, checked, ...props }, ref) => (
<MenubarPrimitive.CheckboxItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
className,
)}
checked={checked}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<MenubarPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</MenubarPrimitive.ItemIndicator>
</span>
{children}
</MenubarPrimitive.CheckboxItem>
));
MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName;
const MenubarRadioItem = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.RadioItem>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.RadioItem>
>(({ className, children, ...props }, ref) => (
<MenubarPrimitive.RadioItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
className,
)}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<MenubarPrimitive.ItemIndicator>
<Circle className="h-2 w-2 fill-current" />
</MenubarPrimitive.ItemIndicator>
</span>
{children}
</MenubarPrimitive.RadioItem>
));
MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName;
const MenubarLabel = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Label> & {
inset?: boolean;
}
>(({ className, inset, ...props }, ref) => (
<MenubarPrimitive.Label
ref={ref}
className={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
{...props}
/>
));
MenubarLabel.displayName = MenubarPrimitive.Label.displayName;
const MenubarSeparator = React.forwardRef<
React.ElementRef<typeof MenubarPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Separator>
>(({ className, ...props }, ref) => (
<MenubarPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-muted", className)} {...props} />
));
MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName;
const MenubarShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
return <span className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)} {...props} />;
};
MenubarShortcut.displayname = "MenubarShortcut";
export {
Menubar,
MenubarMenu,
MenubarTrigger,
MenubarContent,
MenubarItem,
MenubarSeparator,
MenubarLabel,
MenubarCheckboxItem,
MenubarRadioGroup,
MenubarRadioItem,
MenubarPortal,
MenubarSubContent,
MenubarSubTrigger,
MenubarGroup,
MenubarSub,
MenubarShortcut,
};
```
--------------------------------------------------------------------------------
/tests/sample_project_rust/src/concurrency.rs:
--------------------------------------------------------------------------------
```rust
// concurrency.rs - Demonstrates Rust concurrency patterns
use std::sync::{Arc, Mutex, RwLock, mpsc};
use std::thread;
use std::time::Duration;
/// Simple thread spawning
pub fn spawn_simple_thread() {
let handle = thread::spawn(|| {
for i in 1..5 {
println!("Thread: {}", i);
thread::sleep(Duration::from_millis(10));
}
});
handle.join().unwrap();
}
/// Thread with move closure
pub fn thread_with_ownership() {
let data = vec![1, 2, 3, 4, 5];
let handle = thread::spawn(move || {
println!("Thread got data: {:?}", data);
data.iter().sum::<i32>()
});
let result = handle.join().unwrap();
println!("Sum: {}", result);
}
/// Multiple threads
pub fn spawn_multiple_threads(count: usize) -> Vec<i32> {
let mut handles = vec![];
for i in 0..count {
let handle = thread::spawn(move || {
thread::sleep(Duration::from_millis(10));
i as i32 * 2
});
handles.push(handle);
}
handles.into_iter().map(|h| h.join().unwrap()).collect()
}
// Mutex for shared state
/// Shared counter with Mutex
pub fn shared_counter(thread_count: usize) -> i32 {
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..thread_count {
let counter = Arc::clone(&counter);
let handle = thread::spawn(move || {
for _ in 0..100 {
let mut num = counter.lock().unwrap();
*num += 1;
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
let final_count = *counter.lock().unwrap();
final_count
}
/// Safe data structure with Mutex
#[derive(Debug)]
pub struct SafeCounter {
count: Arc<Mutex<i32>>,
}
impl SafeCounter {
pub fn new() -> Self {
Self {
count: Arc::new(Mutex::new(0)),
}
}
pub fn increment(&self) {
let mut count = self.count.lock().unwrap();
*count += 1;
}
pub fn get(&self) -> i32 {
*self.count.lock().unwrap()
}
pub fn clone_counter(&self) -> SafeCounter {
SafeCounter {
count: Arc::clone(&self.count),
}
}
}
// RwLock for read-heavy workloads
/// Shared data with RwLock
pub struct SharedData {
data: Arc<RwLock<Vec<i32>>>,
}
impl SharedData {
pub fn new() -> Self {
Self {
data: Arc::new(RwLock::new(Vec::new())),
}
}
pub fn add(&self, value: i32) {
let mut data = self.data.write().unwrap();
data.push(value);
}
pub fn get(&self, index: usize) -> Option<i32> {
let data = self.data.read().unwrap();
data.get(index).copied()
}
pub fn len(&self) -> usize {
let data = self.data.read().unwrap();
data.len()
}
pub fn clone_data(&self) -> SharedData {
SharedData {
data: Arc::clone(&self.data),
}
}
}
// Message passing with channels
/// Simple channel communication
pub fn simple_channel() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let messages = vec!["hello", "from", "thread"];
for msg in messages {
tx.send(msg).unwrap();
thread::sleep(Duration::from_millis(10));
}
});
for received in rx {
println!("Got: {}", received);
}
}
/// Multiple producers
pub fn multiple_producers() -> Vec<String> {
let (tx, rx) = mpsc::channel();
let mut results = Vec::new();
for i in 0..3 {
let tx_clone = tx.clone();
thread::spawn(move || {
let message = format!("Message from thread {}", i);
tx_clone.send(message).unwrap();
});
}
drop(tx); // Drop original sender
for received in rx {
results.push(received);
}
results
}
/// Worker pool pattern
pub struct ThreadPool {
workers: Vec<Worker>,
sender: mpsc::Sender<Job>,
}
type Job = Box<dyn FnOnce() + Send + 'static>;
struct Worker {
id: usize,
thread: Option<thread::JoinHandle<()>>,
}
impl Worker {
fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
let thread = thread::spawn(move || loop {
let job = receiver.lock().unwrap().recv();
match job {
Ok(job) => {
println!("Worker {} executing job", id);
job();
}
Err(_) => {
println!("Worker {} shutting down", id);
break;
}
}
});
Worker {
id,
thread: Some(thread),
}
}
}
impl ThreadPool {
pub fn new(size: usize) -> ThreadPool {
assert!(size > 0);
let (sender, receiver) = mpsc::channel();
let receiver = Arc::new(Mutex::new(receiver));
let mut workers = Vec::with_capacity(size);
for id in 0..size {
workers.push(Worker::new(id, Arc::clone(&receiver)));
}
ThreadPool { workers, sender }
}
pub fn execute<F>(&self, f: F)
where
F: FnOnce() + Send + 'static,
{
let job = Box::new(f);
self.sender.send(job).unwrap();
}
}
impl Drop for ThreadPool {
fn drop(&mut self) {
for worker in &mut self.workers {
if let Some(thread) = worker.thread.take() {
thread.join().unwrap();
}
}
}
}
// Barrier synchronization
use std::sync::Barrier;
pub fn barrier_example() {
let barrier = Arc::new(Barrier::new(3));
let mut handles = vec![];
for i in 0..3 {
let barrier = Arc::clone(&barrier);
let handle = thread::spawn(move || {
println!("Thread {} before barrier", i);
barrier.wait();
println!("Thread {} after barrier", i);
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
}
// Atomic operations
use std::sync::atomic::{AtomicUsize, Ordering};
pub struct AtomicCounter {
count: AtomicUsize,
}
impl AtomicCounter {
pub fn new() -> Self {
Self {
count: AtomicUsize::new(0),
}
}
pub fn increment(&self) {
self.count.fetch_add(1, Ordering::SeqCst);
}
pub fn get(&self) -> usize {
self.count.load(Ordering::SeqCst)
}
}
// Once initialization
use std::sync::Once;
static mut SINGLETON: Option<String> = None;
static INIT: Once = Once::new();
pub fn get_singleton() -> &'static String {
unsafe {
INIT.call_once(|| {
SINGLETON = Some(String::from("Singleton instance"));
});
SINGLETON.as_ref().unwrap()
}
}
// Scoped threads (Rust 1.63+)
pub fn scoped_threads() {
let mut data = vec![1, 2, 3, 4, 5];
thread::scope(|s| {
s.spawn(|| {
println!("Thread 1 can access data: {:?}", data);
});
s.spawn(|| {
println!("Thread 2 can also access data: {:?}", data);
});
});
data.push(6); // Can use data after scope
println!("Final data: {:?}", data);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_shared_counter() {
let result = shared_counter(5);
assert_eq!(result, 500);
}
#[test]
fn test_safe_counter() {
let counter = SafeCounter::new();
counter.increment();
counter.increment();
assert_eq!(counter.get(), 2);
}
#[test]
fn test_shared_data() {
let data = SharedData::new();
data.add(1);
data.add(2);
data.add(3);
assert_eq!(data.len(), 3);
assert_eq!(data.get(1), Some(2));
}
#[test]
fn test_atomic_counter() {
let counter = AtomicCounter::new();
counter.increment();
counter.increment();
assert_eq!(counter.get(), 2);
}
}
```
--------------------------------------------------------------------------------
/tests/sample_project_rust/src/error_handling.rs:
--------------------------------------------------------------------------------
```rust
// error_handling.rs - Demonstrates Rust error handling patterns
use std::error::Error;
use std::fmt;
use std::fs::File;
use std::io::{self, Read};
/// Custom error type
#[derive(Debug, Clone)]
pub struct CustomError {
pub code: u32,
pub message: String,
}
impl fmt::Display for CustomError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Error {}: {}", self.code, self.message)
}
}
impl Error for CustomError {}
impl CustomError {
pub fn new(code: u32, message: String) -> Self {
Self { code, message }
}
}
/// Validation error
#[derive(Debug)]
pub struct ValidationError {
pub field: String,
pub value: String,
pub reason: String,
}
impl fmt::Display for ValidationError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"Validation failed for field '{}' with value '{}': {}",
self.field, self.value, self.reason
)
}
}
impl Error for ValidationError {}
/// Multiple error types enum
#[derive(Debug)]
pub enum AppError {
Io(io::Error),
Parse(std::num::ParseIntError),
Custom(CustomError),
Validation(ValidationError),
}
impl fmt::Display for AppError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AppError::Io(err) => write!(f, "IO error: {}", err),
AppError::Parse(err) => write!(f, "Parse error: {}", err),
AppError::Custom(err) => write!(f, "Custom error: {}", err),
AppError::Validation(err) => write!(f, "Validation error: {}", err),
}
}
}
impl Error for AppError {}
impl From<io::Error> for AppError {
fn from(err: io::Error) -> Self {
AppError::Io(err)
}
}
impl From<std::num::ParseIntError> for AppError {
fn from(err: std::num::ParseIntError) -> Self {
AppError::Parse(err)
}
}
impl From<CustomError> for AppError {
fn from(err: CustomError) -> Self {
AppError::Custom(err)
}
}
// Basic Result usage
/// Simple function returning Result
pub fn divide(a: i32, b: i32) -> Result<i32, String> {
if b == 0 {
Err("Division by zero".to_string())
} else {
Ok(a / b)
}
}
/// Function with multiple error conditions
pub fn validate_age(age: i32) -> Result<i32, String> {
if age < 0 {
return Err("Age cannot be negative".to_string());
}
if age > 150 {
return Err("Age is unrealistic".to_string());
}
Ok(age)
}
/// Using custom error type
pub fn validate_username(username: &str) -> Result<String, CustomError> {
if username.is_empty() {
return Err(CustomError::new(400, "Username cannot be empty".to_string()));
}
if username.len() < 3 {
return Err(CustomError::new(400, "Username too short".to_string()));
}
if username.len() > 20 {
return Err(CustomError::new(400, "Username too long".to_string()));
}
Ok(username.to_string())
}
/// Error propagation with ? operator
pub fn read_file_contents(filename: &str) -> Result<String, io::Error> {
let mut file = File::open(filename)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(contents)
}
/// Chaining operations with ?
pub fn parse_and_double(s: &str) -> Result<i32, std::num::ParseIntError> {
let num: i32 = s.parse()?;
Ok(num * 2)
}
/// Multiple error types with ?
pub fn read_and_parse(filename: &str) -> Result<i32, AppError> {
let mut file = File::open(filename)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
let num: i32 = contents.trim().parse()?;
Ok(num)
}
/// Custom validation with ValidationError
pub fn validate_email(email: &str) -> Result<String, ValidationError> {
if !email.contains('@') {
return Err(ValidationError {
field: "email".to_string(),
value: email.to_string(),
reason: "Must contain @ symbol".to_string(),
});
}
if !email.contains('.') {
return Err(ValidationError {
field: "email".to_string(),
value: email.to_string(),
reason: "Must contain domain extension".to_string(),
});
}
Ok(email.to_string())
}
/// Using match for error handling
pub fn process_result(result: Result<i32, String>) -> i32 {
match result {
Ok(value) => value,
Err(e) => {
println!("Error occurred: {}", e);
0
}
}
}
/// Using unwrap_or
pub fn safe_divide(a: i32, b: i32) -> i32 {
divide(a, b).unwrap_or(0)
}
/// Using unwrap_or_else
pub fn safe_divide_with_default(a: i32, b: i32, default: i32) -> i32 {
divide(a, b).unwrap_or_else(|_| default)
}
/// Using map and and_then
pub fn parse_and_validate(s: &str) -> Result<i32, String> {
s.parse::<i32>()
.map_err(|e| format!("Parse error: {}", e))
.and_then(|num| {
if num >= 0 {
Ok(num)
} else {
Err("Number must be non-negative".to_string())
}
})
}
/// Error recovery pattern
pub fn try_parse_or_default(s: &str, default: i32) -> i32 {
s.parse().unwrap_or(default)
}
/// Multiple validation steps
pub fn validate_user(name: &str, age: i32, email: &str) -> Result<User, Vec<String>> {
let mut errors = Vec::new();
if name.is_empty() {
errors.push("Name cannot be empty".to_string());
}
if age < 18 {
errors.push("Must be 18 or older".to_string());
}
if !email.contains('@') {
errors.push("Invalid email".to_string());
}
if errors.is_empty() {
Ok(User {
name: name.to_string(),
age,
email: email.to_string(),
})
} else {
Err(errors)
}
}
#[derive(Debug)]
pub struct User {
name: String,
age: i32,
email: String,
}
/// Panic for unrecoverable errors
pub fn must_succeed(value: Option<i32>) -> i32 {
value.expect("This should never be None")
}
/// Option to Result conversion
pub fn find_user(id: u32) -> Option<String> {
if id > 0 {
Some(format!("User {}", id))
} else {
None
}
}
pub fn get_user_or_error(id: u32) -> Result<String, String> {
find_user(id).ok_or_else(|| "User not found".to_string())
}
/// Combining Results
pub fn validate_and_parse(s: &str) -> Result<i32, String> {
if s.is_empty() {
return Err("Input is empty".to_string());
}
s.parse::<i32>()
.map_err(|e| format!("Failed to parse: {}", e))
}
/// Early return pattern
pub fn process_input(input: &str) -> Result<i32, String> {
let trimmed = input.trim();
if trimmed.is_empty() {
return Err("Empty input".to_string());
}
let num: i32 = trimmed.parse().map_err(|_| "Invalid number".to_string())?;
if num < 0 {
return Err("Negative number".to_string());
}
Ok(num * 2)
}
/// Collecting Results
pub fn parse_numbers(strings: Vec<&str>) -> Result<Vec<i32>, String> {
strings
.iter()
.map(|s| s.parse::<i32>().map_err(|e| e.to_string()))
.collect()
}
/// Result with Box<dyn Error>
pub fn flexible_error_handling(input: &str) -> Result<i32, Box<dyn Error>> {
let num: i32 = input.parse()?;
if num < 0 {
return Err(Box::new(CustomError::new(400, "Negative number".to_string())));
}
Ok(num)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_divide_success() {
assert_eq!(divide(10, 2), Ok(5));
}
#[test]
fn test_divide_error() {
assert!(divide(10, 0).is_err());
}
#[test]
fn test_validate_age() {
assert!(validate_age(25).is_ok());
assert!(validate_age(-1).is_err());
assert!(validate_age(200).is_err());
}
#[test]
fn test_validate_username() {
assert!(validate_username("john_doe").is_ok());
assert!(validate_username("ab").is_err());
assert!(validate_username("").is_err());
}
}
```