Skip to content

perf: Cache SemanticModel and improve null handling in generators#1678

Merged
thomhurst merged 1 commit into
mainfrom
fix/analyzer-improvements
Dec 30, 2025
Merged

perf: Cache SemanticModel and improve null handling in generators#1678
thomhurst merged 1 commit into
mainfrom
fix/analyzer-improvements

Conversation

@thomhurst

Copy link
Copy Markdown
Owner

Summary

  • Caches SemanticModel in AsyncModuleCodeFixProvider instead of calling GetSemanticModelAsync multiple times
  • Improves null handling consistency in OptionsClassGenerator GeneratorUtils

Issues Fixed

Changes

  • AsyncModuleCodeFixProvider.cs: Caches SemanticModel, makes helper methods static
  • GeneratorUtils.cs: Uses nullable parameters with consistent empty string return

Test plan

  • Build passes for both Analyzers and OptionsGenerator solutions

🤖 Generated with Claude Code

…1572)

- Cache GetSemanticModelAsync result in AsyncModuleCodeFixProvider to avoid
  duplicate async calls in the loop (fixes #1572)
- Convert helper methods to static since they no longer need instance state
- Make EscapeXmlComment and EscapeIdentifier accept nullable strings for
  consistent null handling (fixes #1639)
- Return string.Empty instead of returning null from EscapeIdentifier

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@thomhurst

Copy link
Copy Markdown
Owner Author

Summary

This PR optimizes the AsyncModuleCodeFixProvider by caching the semantic model to avoid redundant async calls, and improves null safety in GeneratorUtils methods.

Critical Issues

None found ✅

Suggestions

AsyncModuleCodeFixProvider.cs - Consider CancellationToken

The cached semantic model at line 64 doesn't pass the cancellationToken parameter:

var semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

This is good - the cancellation token is properly threaded through.

GeneratorUtils.cs - Behavioral Change in EscapeIdentifier

The change at line 163 modifies behavior:

  • Before: EscapeIdentifier(null) or EscapeIdentifier("") → returns the input (null or empty string)
  • After: Returns string.Empty in both cases

This is technically a breaking change for callers expecting null preservation, though current usage appears safe. Consider documenting this behavior change in the method's XML documentation.

Suggested addition:

/// <summary>
/// Escapes a C# identifier if it's a reserved keyword by prefixing with @.
/// Returns an empty string if the input is null or empty.
/// </summary>

Verdict

APPROVE - No critical issues

The performance optimization in AsyncModuleCodeFixProvider is well-implemented and the null safety improvements are beneficial. The behavioral change in EscapeIdentifier appears safe based on current usage patterns.

@thomhurst thomhurst merged commit e38e16b into main Dec 30, 2025
10 of 12 checks passed
@thomhurst thomhurst deleted the fix/analyzer-improvements branch December 30, 2025 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant