| name | add-refactoring |
| description | Use when adding a new RR#### refactoring in roslynator, editing Refactorings.xml, registering in RefactoringContext, or when refactorings-testing.md shows XunitRefactoringVerifier — in-repo uses AbstractCSharpRefactoringVerifier and CHANGELOG.md. |
Add Refactoring
Overview
Refactorings are metadata-driven: Refactorings.xml → codegen → register in RefactoringContext → implement → test → changelog.
When to Use
- New
RR#### refactoring in an approved issue
- Registering a refactoring action on a syntax kind
<OptionKey> required on every refactoring entry
Not for: analyzers (add-analyzer), compiler fixes (add-compiler-diagnostic-fix), deprecation (deprecate-analyzer-or-refactoring).
Gate: approved GitHub issue (CONTRIBUTING.md).
Read references/implementation.md before writing tests — public refactorings-testing.md uses XunitRefactoringVerifier, which does not match in-repo tests.
Confirm metadata parameters (hard gate)
STOP. Do NOT edit Refactorings.xml, run codegen, or implement until the user has confirmed every required parameter below. Do not invent values the user (or issue) did not state.
Use AskQuestion when available; otherwise ask conversationally. Batch related choices.
| Parameter | Required? | Notes |
|---|
Id | propose | Compute next free RR#### from Refactorings.xml; do not ask unless the issue conflicts or multiple ids are plausible |
Identifier | yes | PascalCase; drives generated names |
Title | yes | Short description (light-bulb text) |
OptionKey | yes | EditorConfig key segment → roslynator_refactoring.<key>.enabled |
Syntaxes / Span | yes for docs | Where it can be invoked (documentation only; registration is in code) |
Summary / samples | recommended | Confirm if not in the issue |
When proposing Id, state the chosen value in your plan/summary (e.g. “using next free RR0218”). Skip asking other parameters only when the approved issue or the user's message already states the value explicitly.
Quick Reference
| Step | Location / command |
|---|
| Metadata | src/Refactorings.xml |
| Codegen | cd tools && pwsh ./generate_code.ps1 |
| Register | RefactoringContext.cs or helper under Refactorings/CSharp/Refactorings/ |
| Implement | same folder |
| Tests | src/Tests/Refactorings.Tests/RR####IdentifierTests.cs |
| Changelog | CHANGELOG.md under ## [Unreleased] |
Implementation
- Confirm metadata parameters (hard gate above).
- Details and examples: references/implementation.md.
Changelog:
- Add refactoring "TITLE" ([RR####](https://josefpihrt.github.io/docs/roslynator/refactorings/RR####)) ([#PR](https://github.com/dotnet/roslynator/pull/PR))
Verify:
cd tools && pwsh ./generate_code.ps1
cd src && dotnet build Roslynator.sln
cd src && dotnet test Tests/Refactorings.Tests --no-build --filter "FullyQualifiedName~RR####"
cd src && dotnet format Roslynator.sln --no-restore --verify-no-changes --severity info
Common Mistakes
| Mistake | Fix |
|---|
Guess Title / OptionKey / Identifier | Ask — hard gate above |
Follow refactorings-testing.md verbatim | In-repo: AbstractCSharpRefactoringVerifier + RefactoringId override |
Missing <OptionKey> | Required — EditorConfig id for enable/disable |
| Codegen from repo root | cd tools && pwsh ./generate_code.ps1 |
| `[ | ... |
Only <Syntaxes> / <Span> | Documentation-only; registration is in code |