Skip to main content
Glama
test_csharp_discovery.py4.96 kB
#!/usr/bin/env python3 """Test for C# symbol discovery and call relationships.""" from code_index_mcp.indexing.strategies.csharp_strategy import CSharpParsingStrategy C_SHARP_SAMPLE = """ namespace Demo.App { using System; using DG.Tweening; class Service { public void Run() {} } static class StaticService { public static void Run() {} } class Greeter { private readonly string _name; public Greeter(string name) { _name = name; Helper(); } public void Greet() { Helper(); var svc = new Service(); svc.Run(); StaticService.Run(); } void Helper() {} } } """ C_SHARP_COMPLEX = """ namespace Complex.App; using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Threading.Tasks; using Alias = System.Collections.Generic.Dictionary<string, List<int>>; [AttributeUsage(AttributeTargets.Method)] sealed class MarkerAttribute : Attribute {} partial class Outer<T> where T : class { public partial class Inner<U> where U : struct { private Alias _map = new(); public async IAsyncEnumerable<T> StreamAsync( Func<U, T> factory, [EnumeratorCancellation] System.Threading.CancellationToken ct = default) { yield return await Task.Run(() => factory(default), ct); yield return await Task.Run(() => factory(default), ct); } public T Invoke(Func<T> f) => f(); } public partial class Inner<U> { [Marker] public T Make<U2>(U2 value) where U2 : notnull { return (T)(object)value.ToString(); } } } partial class Outer<T> { public static Outer<T>.Inner<int> Build(Func<int, T> factory) { var inner = new Inner<int>(); var _ = inner.Invoke(() => factory(0)); return inner; } } """ def _symbol_by_name(symbols): result = {} for symbol_id, symbol_info in symbols.items(): if "::" in symbol_id: result[symbol_id.split("::", 1)[1]] = (symbol_id, symbol_info) return result def test_csharp_symbol_and_calls_discovery(): strategy = CSharpParsingStrategy() symbols, file_info = strategy.parse_file("Demo/App/Greeter.cs", C_SHARP_SAMPLE) assert file_info.package == "Demo.App" assert "System" in file_info.imports assert "DG.Tweening" in file_info.imports discovered_functions = set(file_info.symbols.get("functions", [])) assert "Demo.App.Greeter.#ctor" in discovered_functions assert "Demo.App.Greeter.Greet" in discovered_functions assert "Demo.App.Greeter.Helper" in discovered_functions assert "Demo.App.Service.Run" in discovered_functions assert "Demo.App.StaticService.Run" in discovered_functions discovered_classes = set(file_info.symbols.get("classes", [])) assert "Demo.App.Greeter" in discovered_classes assert "Demo.App.Service" in discovered_classes assert "Demo.App.StaticService" in discovered_classes by_name = _symbol_by_name(symbols) helper_id, helper_info = by_name["Demo.App.Greeter.Helper"] greet_id, _ = by_name["Demo.App.Greeter.Greet"] ctor_id, _ = by_name["Demo.App.Greeter.#ctor"] static_run_id, static_run_info = by_name["Demo.App.StaticService.Run"] # Helper is called from both constructor and greet assert greet_id in helper_info.called_by assert ctor_id in helper_info.called_by # StaticService.Run is resolved as a call target assert static_run_info.called_by == [greet_id] def test_csharp_complex_sample(): strategy = CSharpParsingStrategy() symbols, file_info = strategy.parse_file("Complex/App/Outer.cs", C_SHARP_COMPLEX) assert file_info.package == "Complex.App" assert "System" in file_info.imports assert "System.Collections.Generic" in file_info.imports assert "System.Runtime.CompilerServices" in file_info.imports assert "System.Threading.Tasks" in file_info.imports discovered_classes = set(file_info.symbols.get("classes", [])) assert "Complex.App.Outer" in discovered_classes assert "Complex.App.Outer.Inner" in discovered_classes discovered_functions = set(file_info.symbols.get("functions", [])) assert "Complex.App.Outer.Inner.StreamAsync" in discovered_functions assert "Complex.App.Outer.Inner.Invoke" in discovered_functions assert "Complex.App.Outer.Inner.Make" in discovered_functions assert "Complex.App.Outer.Build" in discovered_functions by_name = _symbol_by_name(symbols) invoke_id, _ = by_name["Complex.App.Outer.Inner.Invoke"] build_id, _ = by_name["Complex.App.Outer.Build"] # inner.Invoke should be resolved as a call target of Build invoke_info = symbols.get(by_name["Complex.App.Outer.Inner.Invoke"][0]) assert build_id in invoke_info.called_by

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/johnhuang316/code-index-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server