Add a code fixer and a code refactorer to transform factory methods into constructors#183
Add a code fixer and a code refactorer to transform factory methods into constructors#183
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new generator diagnostic (EFP0012) to flag [Projectable] factory methods that can be expressed as constructors, and introduces a CodeFix + CodeRefactoring to automate converting those factory methods into [Projectable] constructors (optionally updating callers), with accompanying tests and sample wiring.
Changes:
- Emit EFP0012 (Info) from the source generator when a
[Projectable]factory method matches an object-initializer pattern. - Add CodeFix/Refactoring providers (and shared transformation helper) to convert the factory method into a constructor and optionally update call sites.
- Add generator and codefix/refactoring tests + snapshots; wire CodeFixes analyzer into the Readme sample.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/EntityFrameworkCore.Projectables.Generator.Tests/FactoryMethodDiagnosticTests.cs | New tests validating EFP0012 emission/non-emission scenarios. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/RefactoringTestBase.cs | New test base for code refactoring providers. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToConstructorCodeRefactoringProviderTests.cs | Refactoring provider tests + Verify snapshots. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToConstructorCodeRefactoringProviderTests.ConvertToConstructor_WithExistingMembers_PreservesMemberOrder.verified.txt | Snapshot for member-order preservation case. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToConstructorCodeRefactoringProviderTests.ConvertToConstructor_SimpleFactoryMethod.verified.txt | Snapshot for basic conversion case. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToConstructorCodeRefactoringProviderTests.ConvertToConstructor_PreservesProjectableOptions.verified.txt | Snapshot ensuring attribute args are preserved. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToConstructorCodeRefactoringProviderTests.ConvertToConstructor_MultipleInitializerAssignments.verified.txt | Snapshot for multi-assignment initializer conversion. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToConstructorCodeRefactoringProviderTests.ConvertToConstructor_DoesNotAddParameterlessConstructor_WhenAlreadyPresent.verified.txt | Snapshot ensuring paramless ctor isn’t duplicated. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToConstructorCodeRefactoringProviderTests.ConvertToConstructor_AddsParameterlessConstructor_WhenNoneExists.verified.txt | Snapshot ensuring paramless ctor is added when needed. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToConstructorCodeFixProviderTests.cs | Code fix provider tests + Verify snapshots. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToConstructorCodeFixProviderTests.CodeFix_SimpleStaticFactoryMethod.verified.txt | Snapshot for basic code fix conversion. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToConstructorCodeFixProviderTests.CodeFix_PreservesProjectableOptions.verified.txt | Snapshot ensuring attribute args are preserved by code fix. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToConstructorCodeFixProviderTests.CodeFix_DoesNotAddParameterlessConstructor_WhenAlreadyPresent.verified.txt | Snapshot for existing paramless ctor case. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToConstructorCodeFixProviderTests.CodeFix_AddsParameterlessConstructor_WhenNoneExists.verified.txt | Snapshot for adding paramless ctor case. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/CodeFixTestBase.cs | Makes CreateDocument protected for reuse by refactoring test base. |
| src/EntityFrameworkCore.Projectables.Generator/ProjectionExpressionGenerator.cs | Emits EFP0012 from generator execution pipeline. |
| src/EntityFrameworkCore.Projectables.Generator/Infrastructure/Diagnostics.cs | Adds DiagnosticDescriptor for EFP0012. |
| src/EntityFrameworkCore.Projectables.Generator/AnalyzerReleases.Shipped.md | Ships EFP0012 in analyzer release notes. |
| src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodTransformationHelper.cs | Implements core factory→constructor transformation + caller rewriting. |
| src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodToConstructorCodeRefactoringProvider.cs | Adds refactoring provider with two actions (doc-only / update callers). |
| src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodToConstructorCodeFixProvider.cs | Adds code fix provider for EFP0012 with two actions. |
| samples/ReadmeSample/ReadmeSample.csproj | Adds CodeFixes project as analyzer reference in the sample. |
src/EntityFrameworkCore.Projectables.Generator/ProjectionExpressionGenerator.cs
Outdated
Show resolved
Hide resolved
src/EntityFrameworkCore.Projectables.Generator/ProjectionExpressionGenerator.cs
Outdated
Show resolved
Hide resolved
src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodTransformationHelper.cs
Outdated
Show resolved
Hide resolved
src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodTransformationHelper.cs
Show resolved
Hide resolved
src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodTransformationHelper.cs
Outdated
Show resolved
Hide resolved
src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodTransformationHelper.cs
Outdated
Show resolved
Hide resolved
src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodTransformationHelper.cs
Show resolved
Hide resolved
src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodTransformationHelper.cs
Outdated
Show resolved
Hide resolved
src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodTransformationHelper.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…to feature/factory-method-fixer
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…to feature/factory-method-fixer
There was a problem hiding this comment.
Pull request overview
This PR introduces a new generator diagnostic (EFP0012) for [Projectable] factory methods that look like constructor candidates and adds both a code fix provider and a refactoring provider to convert those factory methods into [Projectable] constructors (optionally updating call sites).
Changes:
- Emit
EFP0012(Info) from the source generator when a projectable factory-method pattern is detected. - Add factory-method → constructor transformation helpers plus a CodeFixProvider and CodeRefactoringProvider (with optional “update callers”).
- Add/extend CodeFixes + Generator test infrastructure and snapshot coverage for the new behaviors.
Reviewed changes
Copilot reviewed 30 out of 30 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/EntityFrameworkCore.Projectables.Generator.Tests/FactoryMethodDiagnosticTests.cs | Adds generator-level tests asserting EFP0012 is (and isn’t) produced for specific patterns. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/RefactoringTestBase.cs | Introduces a reusable base for refactoring-provider tests (collect/apply actions). |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.cs | Adds snapshot-based tests for the refactoring provider (convert + update-callers). |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.UpdateCallers_SameDocument_OnlyReplacesFactoryCallSite.verified.txt | Snapshot for same-document update-callers behavior. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.UpdateCallers_PreservesCallSiteTrivia.verified.txt | Snapshot ensuring call-site trivia is preserved when updating callers. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_WithExistingMembers_PreservesMemberOrder.verified.txt | Snapshot verifying member ordering after conversion. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_SimpleFactoryMethod.verified.txt | Snapshot for basic conversion output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_PreservesProjectableOptions.verified.txt | Snapshot verifying [Projectable(...)] arguments are preserved. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_PreservesLeadingXmlDocComment.verified.txt | Snapshot verifying leading XML doc comments are preserved. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_PreservesInitializerInlineComments.verified.txt | Snapshot focused on initializer inline comments preservation. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_MultipleInitializerAssignments.verified.txt | Snapshot for multiple assignments conversion. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_DoesNotAddParameterlessConstructor_WhenAlreadyPresent.verified.txt | Snapshot confirming no extra parameterless ctor when already present. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_ComplexPropertyExpressions_ArePreserved.verified.txt | Snapshot for more complex initializer expressions. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_AddsParameterlessConstructor_WhenNoneExists.verified.txt | Snapshot confirming a parameterless ctor is introduced when needed. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeFixProviderTests.cs | Adds snapshot-based tests for the code fix provider for EFP0012. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeFixProviderTests.CodeFix_SimpleStaticFactoryMethod.verified.txt | Snapshot for code-fix conversion output (simple case). |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeFixProviderTests.CodeFix_PreservesProjectableOptions.verified.txt | Snapshot verifying options preservation in code fix. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeFixProviderTests.CodeFix_DoesNotAddParameterlessConstructor_WhenAlreadyPresent.verified.txt | Snapshot ensuring no redundant parameterless ctor for code fix. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeFixProviderTests.CodeFix_AddsParameterlessConstructor_WhenNoneExists.verified.txt | Snapshot ensuring parameterless ctor addition for code fix. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/CodeFixTestBase.cs | Extends the test base to create documents with full TPA references for semantic refactorings. |
| src/EntityFrameworkCore.Projectables.Generator/ProjectionExpressionGenerator.cs | Emits EFP0012 during generator execution using the factory-method pattern helper. |
| src/EntityFrameworkCore.Projectables.Generator/Infrastructure/Diagnostics.cs | Adds the EFP0012 DiagnosticDescriptor. |
| src/EntityFrameworkCore.Projectables.Generator/EntityFrameworkCore.Projectables.Generator.csproj | Links SyntaxHelpers.cs from CodeFixes into the generator project. |
| src/EntityFrameworkCore.Projectables.Generator/AnalyzerReleases.Shipped.md | Registers EFP0012 as a shipped rule. |
| src/EntityFrameworkCore.Projectables.CodeFixes/SyntaxHelpers.cs | Adds syntax-level detection for the factory-method pattern. |
| src/EntityFrameworkCore.Projectables.CodeFixes/ProjectableCodeFixHelper.cs | Adds helper to locate fixable factory-method nodes (method + containing type). |
| src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodTransformationHelper.cs | Implements the conversion logic and the “update callers” rewrite across a solution. |
| src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodToCtorCodeFixProvider.cs | Introduces the EFP0012 code fix provider (convert only / convert + update callers). |
| src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodToConstructorCodeRefactoringProvider.cs | Introduces the refactoring provider mirroring the same actions (even if diagnostic is suppressed). |
| samples/ReadmeSample/ReadmeSample.csproj | Adds CodeFixes as an analyzer reference in the sample project. |
src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodTransformationHelper.cs
Outdated
Show resolved
Hide resolved
src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodTransformationHelper.cs
Outdated
Show resolved
Hide resolved
src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodTransformationHelper.cs
Outdated
Show resolved
Hide resolved
src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodTransformationHelper.cs
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
This PR introduces support for identifying [Projectable] factory methods that could be expressed as constructors, and provides both a code fix and a refactoring to convert them (optionally updating call sites across the solution).
Changes:
- Emit a new generator diagnostic
EFP0012(Info) when a[Projectable]method matches the factory-method object-initializer pattern. - Add a code fix provider and a code refactoring provider to transform matched factory methods into
[Projectable]constructors, with an option to update all callers. - Add/extend unit tests and Verify snapshots covering the diagnostic and both transformation actions.
Reviewed changes
Copilot reviewed 41 out of 41 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/EntityFrameworkCore.Projectables.Generator.Tests/FactoryMethodDiagnosticTests.cs | Adds generator tests asserting EFP0012 reporting behavior and non-blocking generation. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/RefactoringTestBase.cs | Introduces a base helper for code refactoring provider tests (collect/apply actions). |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorSources.cs | Adds shared test source snippets and span-locators for factory→ctor scenarios. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.cs | Adds Verify-based tests for the refactoring provider (convert + update-callers). |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_SimpleFactoryMethod.verified.txt | Snapshot for refactoring output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_PreservesProjectableOptions.verified.txt | Snapshot for refactoring output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_MultipleInitializerAssignments.verified.txt | Snapshot for refactoring output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_AddsParamLessCtor_WhenNoneExists.verified.txt | Snapshot for refactoring output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_DoesNotAddParamLessCtor_WhenAlreadyPresent.verified.txt | Snapshot for refactoring output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_DoesNotAddParamLessCtor_WhenOtherExplicitCtorExists.verified.txt | Snapshot for refactoring output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_InsertedParameterlessCtorIsAlwaysPublic.verified.txt | Snapshot for refactoring output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_WithExistingMembers_PreservesMemberOrder.verified.txt | Snapshot for refactoring output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_ComplexPropertyExpressions_ArePreserved.verified.txt | Snapshot for refactoring output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_PreservesLeadingXmlDocComment.verified.txt | Snapshot for refactoring output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_ImplicitObjectCreation.verified.txt | Snapshot for refactoring output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.ConvertToConstructor_PreservesInitializerInlineComments.verified.txt | Snapshot for refactoring output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.UpdateCallers_SameDocument_OnlyReplacesFactoryCallSite.verified.txt | Snapshot verifying caller rewrite selectivity. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.UpdateCallers_PreservesCallSiteTrivia.verified.txt | Snapshot verifying trivia preservation at call sites. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.UpdateCallers_MethodGroup_SingleParameter.verified.txt | Snapshot verifying method-group rewrite (single param). |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.UpdateCallers_MethodGroup_MultipleParameters.verified.txt | Snapshot verifying method-group rewrite (multi param). |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.UpdateCallers_MixedDirectInvocationAndMethodGroup.verified.txt | Snapshot verifying mixed call patterns rewrite. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeRefProviderTests.UpdateCallers_NameOfReference_IsNotRewritten.verified.txt | Snapshot verifying nameof(...) reference is skipped. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeFixProviderTests.cs | Adds Verify-based tests for the code fix provider. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeFixProviderTests.CodeFix_SimpleStaticFactoryMethod.verified.txt | Snapshot for code-fix output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeFixProviderTests.CodeFix_PreservesProjectableOptions.verified.txt | Snapshot for code-fix output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeFixProviderTests.CodeFix_AddsParameterlessConstructor_WhenNoneExists.verified.txt | Snapshot for code-fix output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeFixProviderTests.CodeFix_DoesNotAddParamLessCtor_WhenAlreadyPresent.verified.txt | Snapshot for code-fix output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeFixProviderTests.CodeFix_DoesNotAddParamLessCtor_WhenOtherExplicitCtorExists.verified.txt | Snapshot for code-fix output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeFixProviderTests.CodeFix_InsertedParameterlessCtorIsAlwaysPublic.verified.txt | Snapshot for code-fix output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/FactoryMethodToCtorCodeFixProviderTests.CodeFix_ImplicitObjectCreation.verified.txt | Snapshot for code-fix output. |
| tests/EntityFrameworkCore.Projectables.CodeFixes.Tests/CodeFixTestBase.cs | Extends test infrastructure with CreateDocumentWithReferences for semantic-model-dependent refactorings. |
| src/EntityFrameworkCore.Projectables.Generator/ProjectionExpressionGenerator.cs | Reports EFP0012 during generation using shared syntax pattern matching. |
| src/EntityFrameworkCore.Projectables.Generator/Infrastructure/Diagnostics.cs | Adds EFP0012 DiagnosticDescriptor. |
| src/EntityFrameworkCore.Projectables.Generator/EntityFrameworkCore.Projectables.Generator.csproj | Links SyntaxHelpers.cs into the generator for shared pattern recognition. |
| src/EntityFrameworkCore.Projectables.Generator/AnalyzerReleases.Shipped.md | Ships rule metadata for EFP0012. |
| src/EntityFrameworkCore.Projectables.CodeFixes/SyntaxHelpers.cs | Implements the syntax-only factory-method pattern detection helper. |
| src/EntityFrameworkCore.Projectables.CodeFixes/ProjectableCodeFixHelper.cs | Adds helper to locate a fixable factory-method pattern + [Projectable] attribute. |
| src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodTransformationHelper.cs | Implements the core factory→ctor rewrite and optional update-callers transformation. |
| src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodToCtorCodeFixProvider.cs | Registers code fixes for EFP0012 (document-only and update-callers variants). |
| src/EntityFrameworkCore.Projectables.CodeFixes/FactoryMethodToConstructorCodeRefactoringProvider.cs | Registers equivalent refactoring actions independent of diagnostics. |
| samples/ReadmeSample/ReadmeSample.csproj | References the CodeFixes analyzer so the sample gets refactorings/code fixes. |
No description provided.