Skip to content

feat(tools): add Roslyn-based deep C# analysis tools #82

@CalvinAllen

Description

@CalvinAllen

Description

Add deep C# analysis tools powered by Roslyn (Microsoft.CodeAnalysis), replacing/supplementing the current EnvDTE FileCodeModel-based approach which only provides shallow, syntax-level understanding with no semantic analysis.

The extension will access VS live VisualStudioWorkspace via MEF, giving us incremental compilation, live document buffers (including unsaved changes), and full semantic model access.

Architecture

  • Roslyn lives in the extension (net48) -- accesses VisualStudioWorkspace directly from VS MEF container
  • New service: IRoslynAnalysisService / RoslynAnalysisService (MEF-exported), separate from VisualStudioService
  • NuGet packages: Microsoft.VisualStudio.LanguageServices + Microsoft.CodeAnalysis.CSharp.Workspaces v4.8.0 with ExcludeAssets="runtime" (use VS own runtime assemblies)
  • RPC methods added to existing IVisualStudioRpc interface (single-proxy pattern)

Tools to Implement (~125)

Type System (4)

Tool Description
type_hierarchy Get base types, derived types, and implemented interfaces for a type
type_info Full type information at any position (resolved type, nullability, generic args, base type, interfaces, members)
overload_info At a call site, show resolved overload and all alternatives with full signatures
generic_resolution Resolve concrete generic type arguments at a specific usage site

Symbol Queries (4)

Tool Description
semantic_references True symbol-level references categorized as read/write/invocation
find_implementations All types implementing an interface or overriding a virtual/abstract member
find_by_attribute Find all symbols decorated with a specific attribute across the solution
find_by_type Find all fields/properties/parameters of a given type across the solution

Code Metrics and Quality (4)

Tool Description
code_metrics Cyclomatic complexity, LOC, coupling, maintainability index for a file/class/method
async_analysis Detect async anti-patterns (fire-and-forget, sync-over-async, missing ConfigureAwait)
using_analysis Find unused usings and suggest missing usings
pattern_exhaustiveness Check if switch expressions/statements are exhaustive

Flow Analysis (4)

Tool Description
nullability_analysis Nullable reference type flow analysis - where nulls can flow, potential NREs
data_flow_analysis Variable lifetime, assignments, reads, captures for a code region
control_flow_analysis Control flow graph for a method - branches, loops, returns, unreachable code
call_graph Who calls this method (callers) and what does it call (callees), optionally transitive

Dependency Analysis (2)

Tool Description
dependency_analysis Type/namespace/assembly dependencies for a file or type
assembly_types Browse types in referenced assemblies/NuGet packages

Structural Inspection (4)

Tool Description
syntax_tree Raw AST for a region of code with node types, spans, and trivia
compilation_diagnostics All Roslyn-level warnings/errors with full diagnostic info (richer than Error List)
interface_completeness What members are missing from a partial interface implementation
operation_tree IOperation intermediate representation for a code region (higher-level than syntax, closer to semantic intent)

Unused Code Detection (1)

Tool Description
unused_code Find unused types, methods, fields, properties, parameters. Skips public API, entry points, interface impls, overrides

Refactoring Analysis (5)

Tool Description
rename_check Check if a symbol can be safely renamed, list affected locations, detect conflicts
extract_method_analysis Analyze a selection for extract method feasibility - inputs, outputs, constraints
inline_method_analysis Can a method call be inlined? Show what the result would look like
move_type_analysis Analyze moving a type to a different file/namespace - impacts and required changes
encapsulate_field_analysis Analyze converting a field to a property - affected references and generated code

Source Generation and Analyzers (4)

Tool Description
source_generator_output View code produced by source generators for a file/type
active_analyzers List all active Roslyn analyzers with their diagnostic IDs and severities
analyzer_suppressions Show suppressed diagnostics and their justifications
available_code_fixes Get Roslyn code fix suggestions at a position (lightbulb menu, programmatically)

Code Formatting and Simplification (2)

Tool Description
format_analysis Detect formatting violations using Roslyn formatter rules
simplification_suggestions Find expressions that can be simplified (qualified names, redundant casts, unnecessary parentheses)

Documentation (4)

Tool Description
xmldoc_analysis Extract, validate, and check completeness of XML doc comments (missing params, returns, exceptions)
xmldoc_generate Generate XML doc comment skeleton for a symbol based on its signature
complexity_documentation Generate natural-language summary of what a method does based on its control flow and operations
changelog_generation Compare two commits/versions and describe semantic changes in natural language

Type Conversion and Operators (4)

Tool Description
implicit_conversions Show all implicit conversions happening in an expression (boxing, user-defined, numeric widening)
available_conversions What conversions (implicit/explicit) exist between two types
operator_resolution Which operator overload is being invoked at a binary/unary expression
extension_methods List all extension methods available for a type at a given position

Memory and Performance (6)

Tool Description
allocation_analysis Detect heap allocations (boxing, closures/lambda captures, params arrays, string concatenation)
disposal_analysis Find IDisposable instances that are not properly disposed
span_opportunities Detect where Span/Memory or stackalloc could replace array allocations
string_optimization String.Concat vs interpolation vs StringBuilder analysis based on context
collection_optimization Suggest better collection types (List vs HashSet vs Array vs ImmutableArray) based on usage
numeric_overflow_detection Potential integer overflow in unchecked arithmetic

Code Clone and Similarity (2)

Tool Description
code_clones Find duplicate or structurally similar code blocks across a file/project
semantic_diff Semantic comparison of two code regions (understands renames, reorders, not just text diff)

API Surface (3)

Tool Description
public_api_surface List the complete public API of a project/assembly (types, members, signatures)
breaking_change_detection Compare current API surface against a baseline to detect breaking changes
api_consistency_check Detect inconsistent naming, parameter ordering, return types across similar API methods

Modern C# and Scope Analysis (3)

Tool Description
global_usings List all global usings in effect and where they come from
preprocessor_regions Map all #if/#region preprocessor directives and conditional compilation paths
accessibility_at_point What types/members are accessible from a specific code location (scope-aware)

Expression and LINQ (3)

Tool Description
expression_tree_analysis For EF/LINQ-to-SQL: is this expression translatable to SQL or will it evaluate client-side
linq_analysis Query vs method syntax equivalence, detect potential N+1 patterns, repeated enumeration
ef_query_analysis EF Core issues: client-side evaluation, N+1 queries, missing includes, non-translatable expressions

Compilation and Emit (4)

Tool Description
evaluate_expression Evaluate a C# expression using Roslyn scripting API without a debug session
compilation_check Check if a code snippet compiles in current context, return errors
emit_analysis Compile to IL in-memory, report assembly size and method IL sizes
il_inspection View IL output for a specific method (what the compiler actually generates)

Code Generation (8)

Tool Description
generate_implementation Generate stub implementation for an interface/abstract class
generate_equality Generate Equals(), GetHashCode(), ==/!= for a type based on its fields
generate_constructor Generate constructor from selected fields/properties
generate_test_skeleton Generate unit test method skeletons from a method signature
generate_deconstruct Generate Deconstruct method for a type
suggest_record_conversion Analyze if a class could be a record and generate the conversion
generate_builder Generate builder pattern for a type with many properties
generate_mapper Generate mapping methods between two types with matching property names

Semantic Intelligence (4)

Tool Description
completion_suggestions Code completions available at a position (IntelliSense, programmatically)
signature_help Method signature help at a position (parameter info)
semantic_tokens Semantic classification/coloring of a code region (keyword, type, string, etc.)
symbol_rename_suggestions Suggest better names for a symbol based on type, usage context, and conventions

Thread Safety and Concurrency (5)

Tool Description
thread_safety_analysis Detect shared mutable state accessed without synchronization
immutability_analysis Check if a type is effectively immutable (all fields readonly, no mutable reference types)
pure_function_detection Does a method have side effects? (no field writes, no I/O, no mutable ref params)
await_parallelization Detect sequential awaits in loops that could be parallelized with Task.WhenAll
task_valuetask_analysis When to use ValueTask vs Task based on hot path / allocation patterns

Code Quality - Granular (7)

Tool Description
dead_branch_detection Conditional branches that are always true/false based on constant propagation
magic_number_detection Numeric/string literals that should be named constants
conditional_complexity Deeply nested conditionals, suggest guard clauses / early returns
boolean_simplification Simplify complex boolean expressions (De Morgan, double negation, redundant terms)
exception_handling_analysis Empty catch blocks, catch-all without rethrow, exception swallowing
method_length_ranking Rank all methods by length/complexity across a project (hotspot detection)
parameter_count_analysis Methods with excessive parameters, suggest parameter objects

Optimization Suggestions (4)

Tool Description
sealed_suggestions Types that could be sealed for devirtualization performance
virtual_dispatch_analysis Unnecessary virtual/override chains, methods never overridden
constant_propagation Expressions/fields that could be const or static readonly
exception_flow What exceptions can a method throw, transitively through call chain

Type Design Analysis (6)

Tool Description
struct_analysis Detect mutable structs, large structs (>16 bytes), structs missing IEquatable
enum_flags_analysis Incorrect [Flags] usage, missing None=0, non-power-of-2 values
interface_segregation Detect bloated interfaces where implementors only use a subset
tuple_naming_suggestions Anonymous tuples that should be named types or records
covariance_contravariance Generic type parameters that could declare in/out variance
inheritance_depth_analysis Deep inheritance hierarchies, suggest composition over inheritance

Modern C# Opportunities (13)

Tool Description
modernization_suggestions Detect old C# patterns replaceable with modern features (comprehensive scan)
init_only_opportunities Properties with private setters only set in constructors that could use init
file_scoped_type_opportunities Internal types used only within their file that could be file scoped
required_member_analysis Properties always set in constructors that could use required
range_index_opportunities Array/string access patterns replaceable with C# 8+ ranges/indices
deconstruction_opportunities Tuple/type access patterns that could use deconstruction
static_abstract_opportunities Interface implementations suitable for static abstract/virtual members
collection_expression_opportunities Array/list initializers replaceable with collection expressions
raw_string_opportunities Escaped strings that would be cleaner as raw string literals
primary_constructor_opportunities Classes/structs with simple constructor-to-field assignment
switch_expression_opportunities If-else chains or switch statements convertible to switch expressions
target_typed_new_opportunities new ClassName() where new() could be used
using_declaration_opportunities using blocks replaceable with using declarations (no braces)
null_coalescing_opportunities Null check patterns replaceable with ??, ??=, ?.

Framework and Pattern Specific (6)

Tool Description
di_analysis Dependency injection anti-patterns (service locator, captive dependencies, transient disposables in singletons)
event_leak_detection Event subscriptions without corresponding unsubscriptions (memory leak potential)
cast_analysis Unnecessary casts, unsafe casts replaceable with pattern matching
parameter_validation Public API parameters missing null/range validation
attribute_usage_validation Attributes applied in ways that violate their [AttributeUsage] constraints
configuration_binding_analysis IOptions/configuration binding issues (type mismatches, missing properties)

Domain Specific (5)

Tool Description
regex_validation Validate regex patterns in string literals, detect common regex mistakes
serialization_analysis JSON/XML serialization issues (circular references, non-serializable types, missing attributes)
reflection_detection Reflection usage replaceable with source generators or compile-time alternatives
asp_route_analysis ASP.NET route template validation, detect duplicate/conflicting routes
grpc_proto_consistency Validate gRPC service implementations match proto definitions

Project and Architecture Level (7)

Tool Description
project_health_score Aggregate quality score for a project (weighted metrics: complexity, coupling, duplication)
namespace_organization Detect misplaced types, types in wrong namespace per folder structure
type_dependency_graph Full type-to-type dependency graph data (for visualization)
circular_dependency_detection Detect circular dependencies between types, namespaces, or projects
project_dependency_graph Project-to-project dependency graph with transitive closure
layer_violation_detection Detect dependency rule violations (e.g., UI referencing data layer directly)
nullable_readiness Project-wide assessment of nullable reference type readiness
suggest_annotations Suggest nullable annotations for parameters, returns, and fields based on actual usage

Advanced Metrics (3)

Tool Description
cohesion_analysis LCOM (Lack of Cohesion of Methods) metric for classes
coupling_metrics Afferent/efferent coupling between types and namespaces (Ca/Ce, instability)
abstractness_analysis Abstractness ratio and distance from main sequence for packages/namespaces

New Files

File Purpose
Shared/Models/RoslynAnalysisModels.cs All DTOs (likely split into multiple files by category)
MCPServer/Services/IRoslynAnalysisService.cs Analysis service interface
MCPServer/Services/RoslynAnalysisService.cs Roslyn implementation using VisualStudioWorkspace (likely split into partial classes)
Server/Tools/Roslyn*.cs MCP tool definitions (split into multiple files by category)

Modified Files

File Changes
MCPServer/CodingWithCalvin.MCPServer.csproj Add Roslyn NuGet packages
Shared/RpcContracts.cs Add ~125 methods to IVisualStudioRpc (or split into additional RPC interfaces)
MCPServer/Services/IVisualStudioService.cs Add ~125 methods
MCPServer/Services/VisualStudioService.cs Delegate to RoslynAnalysisService
MCPServer/Services/RpcServer.cs Add ~125 delegation methods
Server/RpcClient.cs Add ~125 proxy methods + update toolTypes
Server/Program.cs Register Roslyn tool classes

Implementation Phases

  1. Foundation - NuGet packages, models, interfaces, plumbing skeleton, verify build
  2. Type System - type_info, overload_info, generic_resolution, type_hierarchy
  3. Symbol Queries - semantic_references, find_implementations, find_by_attribute, find_by_type
  4. Code Metrics and Quality - code_metrics, async_analysis, using_analysis, pattern_exhaustiveness
  5. Flow Analysis - data_flow_analysis, control_flow_analysis, nullability_analysis, call_graph
  6. Structural - syntax_tree, operation_tree, compilation_diagnostics, interface_completeness, dependency_analysis, assembly_types
  7. Unused Code - unused_code
  8. Refactoring - rename_check, extract_method_analysis, inline_method_analysis, move_type_analysis, encapsulate_field_analysis
  9. Source Generation and Analyzers - source_generator_output, active_analyzers, analyzer_suppressions, available_code_fixes
  10. Formatting and Simplification - format_analysis, simplification_suggestions
  11. Documentation - xmldoc_analysis, xmldoc_generate, complexity_documentation, changelog_generation
  12. Type Conversion and Operators - implicit_conversions, available_conversions, operator_resolution, extension_methods
  13. Memory and Performance - allocation_analysis, disposal_analysis, span_opportunities, string_optimization, collection_optimization, numeric_overflow_detection
  14. Code Clone and Similarity - code_clones, semantic_diff
  15. API Surface - public_api_surface, breaking_change_detection, api_consistency_check
  16. Modern C# and Scope - global_usings, preprocessor_regions, accessibility_at_point, modernization_suggestions + all 13 granular opportunities
  17. Expression and LINQ - expression_tree_analysis, linq_analysis, ef_query_analysis
  18. Compilation and Emit - evaluate_expression, compilation_check, emit_analysis, il_inspection
  19. Code Generation - generate_implementation, generate_equality, generate_constructor, generate_test_skeleton, generate_deconstruct, suggest_record_conversion, generate_builder, generate_mapper
  20. Semantic Intelligence - completion_suggestions, signature_help, semantic_tokens, symbol_rename_suggestions
  21. Thread Safety and Concurrency - thread_safety_analysis, immutability_analysis, pure_function_detection, await_parallelization, task_valuetask_analysis
  22. Code Quality Granular - dead_branch_detection, magic_number_detection, conditional_complexity, boolean_simplification, exception_handling_analysis, method_length_ranking, parameter_count_analysis
  23. Optimization - sealed_suggestions, virtual_dispatch_analysis, constant_propagation, exception_flow
  24. Type Design - struct_analysis, enum_flags_analysis, interface_segregation, tuple_naming_suggestions, covariance_contravariance, inheritance_depth_analysis
  25. Framework and Pattern - di_analysis, event_leak_detection, cast_analysis, parameter_validation, attribute_usage_validation, configuration_binding_analysis
  26. Domain Specific - regex_validation, serialization_analysis, reflection_detection, asp_route_analysis, grpc_proto_consistency
  27. Project and Architecture - project_health_score, namespace_organization, type_dependency_graph, circular_dependency_detection, project_dependency_graph, layer_violation_detection, nullable_readiness, suggest_annotations
  28. Advanced Metrics - cohesion_analysis, coupling_metrics, abstractness_analysis

Performance Strategy

  • CancellationToken on all methods (StreamJsonRpc supports this)
  • 30-second default timeout for expensive operations
  • maxResults with Truncated flag on list results
  • Capture workspace.CurrentSolution snapshot once, work on background thread (immutable, thread-safe)
  • Solution-wide queries project-scoped by default
  • Code metrics computed manually (syntax walker) - no external package dependency
  • Consider splitting RoslynAnalysisTools into multiple tool classes by category to keep files manageable

Key Risk

VS 2022 ships its own Roslyn version. Using ExcludeAssets="runtime" on NuGet references avoids conflicts by compiling against v4.8.0 types but using VS own runtime assemblies. May need binding redirects if issues arise.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions