Skip to content

refactor: Replace string comparison with SymbolEqualityComparer in analyzers#1684

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

refactor: Replace string comparison with SymbolEqualityComparer in analyzers#1684
thomhurst merged 1 commit into
mainfrom
fix/analyzer-refactor

Conversation

@thomhurst

Copy link
Copy Markdown
Owner

Summary

  • Changes SymbolExtensions.InheritsFrom from string-based comparison to proper Roslyn symbol comparison using SymbolEqualityComparer
  • Simplifies complex nested conditionals in LoggerInConstructorAnalyzer with early returns and helper methods
  • Improves maintainability and correctness of analyzer code

Fixes #1606, #1599

Test plan

  • Build passes
  • All analyzer tests pass

🤖 Generated with Claude Code

…alyzers

- Update IsDependsOnAttributeFor to use proper symbol comparison via
  Compilation.GetTypeByMetadataName instead of string.StartsWith
- Add IsDependsOnAttribute helper method using SymbolEqualityComparer
- Fix ConflictingDependsOnAttributeAnalyzer.IsDependsOn to use symbol comparison
- Simplify LoggerInConstructorAnalyzer by:
  - Replacing complex nested conditionals with single TryGetProhibitedLoggerType method
  - Using IsAnyType extension method instead of string.StartsWith
  - Declaring logging types as static ImmutableArray for better maintainability
- Add ReadOnlySpan<string> overload to IsAnyType for efficient iteration

Fixes #1599, #1606

🤖 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

Refactors analyzer code to use proper Roslyn symbol comparison (SymbolEqualityComparer) instead of string-based comparison, improving correctness and maintainability.

Critical Issues

None found ✅

Suggestions

Code Quality Improvements

SymbolExtensions.cs:15 - Consider caching GetTypeByMetadataName results
The InheritsFrom(ITypeSymbol?, Compilation, string) method calls compilation.GetTypeByMetadataName() on every invocation. For performance-critical analyzer scenarios, consider:

  • Passing the resolved INamedTypeSymbol directly where possible (like the overload on line 33)
  • Or adding inline documentation noting this is intentional for simplicity

ConflictingDependsOnAttributeAnalyzer.cs:103 and SymbolExtensions.cs:184 - Code duplication
The IsDependsOnAttributeType method is duplicated in two locations with identical logic. Consider:

  • Moving it to SymbolExtensions and making it internal
  • The one in SymbolExtensions (line 184) is already private in the right location - just make it internal and remove the duplicate

LoggerInConstructorAnalyzer.cs:26 - Consider using ImmutableHashSet
Since LoggingTypeMetadataNames is used for membership checks in IsAnyType, an ImmutableHashSet would be more semantically appropriate than ImmutableArray (though the performance difference is negligible for 4 items).

SymbolExtensions.cs:46 - Minor: Early exit opportunity
In InheritsFrom(ITypeSymbol?, INamedTypeSymbol?), you could check SymbolEqualityComparer.Default.Equals(typeSymbol.OriginalDefinition, targetType.OriginalDefinition) before the loop to handle the case where the type equals the target directly.

Previous Review Status

No previous comments found.

Verdict

APPROVE - No critical issues

This is a solid refactoring that improves code quality by using proper Roslyn symbol comparison semantics. The suggested improvements are minor and optional.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Code smell: SymbolExtensions.InheritsFrom uses string comparison for type matching

1 participant