diff --git a/src/AutoCtor.CodeFixes/AddAutoConstructCodeFixer.cs b/src/AutoCtor.CodeFixes/AddAutoConstructCodeFixer.cs new file mode 100644 index 0000000..4187829 --- /dev/null +++ b/src/AutoCtor.CodeFixes/AddAutoConstructCodeFixer.cs @@ -0,0 +1,52 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.Collections.Immutable; +using System.Composition; + +namespace AutoCtor.CodeFixes; + +[ExportCodeFixProvider(LanguageNames.CSharp), Shared] +public sealed class AddAutoConstructCodeFixer : CodeFixProvider +{ + public override ImmutableArray FixableDiagnosticIds => + ImmutableArray.Create(Diagnostics.ACTR008_AddAutoConstruct.Id); + + public override FixAllProvider? GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; + + public override async Task RegisterCodeFixesAsync(CodeFixContext context) + { + var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken) + .ConfigureAwait(false); + if (root is null) + return; + + var token = root.FindToken(context.Diagnostics[0].Location.SourceSpan.Start); + if (token.Parent is not TypeDeclarationSyntax typeDeclaration) + return; + + context.RegisterCodeFix( + CodeAction.Create( + title: "Add [AutoConstruct]", + createChangedDocument: ct => ApplyFixAsync(context.Document, typeDeclaration, ct), + equivalenceKey: "AddAutoConstruct"), + context.Diagnostics[0]); + } + + private static async Task ApplyFixAsync( + Document document, + TypeDeclarationSyntax typeDeclaration, + CancellationToken cancellationToken) + { + var root = await document.GetSyntaxRootAsync(cancellationToken) + .ConfigureAwait(false); + + if (root is null) + return document; + + root = (CompilationUnitSyntax)new AutoCtorRewriter(typeDeclaration, null) + .Visit(root); + return document.WithSyntaxRoot(root); + } +} diff --git a/src/AutoCtor.CodeFixes/AutoCtor.CodeFixes.csproj b/src/AutoCtor.CodeFixes/AutoCtor.CodeFixes.csproj index a30d66a..d3012d6 100644 --- a/src/AutoCtor.CodeFixes/AutoCtor.CodeFixes.csproj +++ b/src/AutoCtor.CodeFixes/AutoCtor.CodeFixes.csproj @@ -12,14 +12,6 @@ https://github.com/distantcam/AutoCtor - - 1701;1702;RS2008 - - - - 1701;1702;RS2008 - - @@ -30,8 +22,9 @@ - - + + + diff --git a/src/AutoCtor.CodeFixes/AutoCtorRewriter.cs b/src/AutoCtor.CodeFixes/AutoCtorRewriter.cs new file mode 100644 index 0000000..4297821 --- /dev/null +++ b/src/AutoCtor.CodeFixes/AutoCtorRewriter.cs @@ -0,0 +1,160 @@ +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; + +namespace AutoCtor.CodeFixes; + +internal sealed class AutoCtorRewriter( + TypeDeclarationSyntax typeDeclaration, + ConstructorDeclarationSyntax? ctorDeclaration +) : CSharpSyntaxRewriter +{ + // The target type and all containing types – the only types that need 'partial'. + private readonly ImmutableArray _targetAndAncestors = + typeDeclaration + .AncestorsAndSelf() + .OfType() + .ToImmutableArray(); + + public override SyntaxNode? VisitCompilationUnit(CompilationUnitSyntax node) + { + node = (CompilationUnitSyntax)base.VisitCompilationUnit(node)!; + + // Add using AutoCtor; + if (!node.Usings.Any(u => u.Name is IdentifierNameSyntax { Identifier.Text: "AutoCtor" } + || u.Name is AliasQualifiedNameSyntax { Name.Identifier.Text: "AutoCtor" })) + { + var usingName = IdentifierName("AutoCtor"); + var usingDirective = UsingDirective(usingName); + node = node.AddUsings(usingDirective); + } + + return node; + } + + public override SyntaxNode? VisitClassDeclaration(ClassDeclarationSyntax node) + { + var isTargetOrAncestor = _targetAndAncestors.Any(a => a.IsEquivalentTo(node)); + + // Remove matching constructor + // Add [AutoConstruct] attribute + if (node.IsEquivalentTo(typeDeclaration)) + { + node = RemoveCtor(node); + if (!HasAutoConstructAttribute(node)) + { + var attrList = CreateAutoConstructAttributeList(); + node = node.AddAttributeLists(attrList); + } + } + + // Add partial modifier only to the target type and its containing types + if (isTargetOrAncestor && !node.Modifiers.Any(SyntaxKind.PartialKeyword)) + { + var partialToken = CreatePartialToken(node.Modifiers.Count == 0); + node = node.AddModifiers(partialToken); + } + + return base.VisitClassDeclaration(node); + } + + public override SyntaxNode? VisitStructDeclaration(StructDeclarationSyntax node) + { + var isTargetOrAncestor = _targetAndAncestors.Any(a => a.IsEquivalentTo(node)); + + // Remove matching constructor + // Add [AutoConstruct] attribute + if (node.IsEquivalentTo(typeDeclaration)) + { + node = RemoveCtor(node); + if (!HasAutoConstructAttribute(node)) + { + var attrList = CreateAutoConstructAttributeList(); + node = node.AddAttributeLists(attrList); + } + } + + // Add partial modifier only to the target type and its containing types + if (isTargetOrAncestor && !node.Modifiers.Any(SyntaxKind.PartialKeyword)) + { + var partialToken = CreatePartialToken(node.Modifiers.Count == 0); + node = node.AddModifiers(partialToken); + } + + return base.VisitStructDeclaration(node); + } + + public override SyntaxNode? VisitRecordDeclaration(RecordDeclarationSyntax node) + { + var isTargetOrAncestor = _targetAndAncestors.Any(a => a.IsEquivalentTo(node)); + + // Remove matching constructor + // Add [AutoConstruct] attribute + if (node.IsEquivalentTo(typeDeclaration)) + { + node = RemoveCtor(node); + if (!HasAutoConstructAttribute(node)) + { + var attrList = CreateAutoConstructAttributeList(); + node = node.AddAttributeLists(attrList); + } + } + + // Add partial modifier only to the target type and its containing types + if (isTargetOrAncestor && !node.Modifiers.Any(SyntaxKind.PartialKeyword)) + { + var partialToken = CreatePartialToken(node.Modifiers.Count == 0); + node = node.AddModifiers(partialToken); + } + + return base.VisitRecordDeclaration(node); + } + + private TRoot RemoveCtor(TRoot node) where TRoot : SyntaxNode + { + if (ctorDeclaration is null) + return node; + var ctor = node.ChildNodes().First(ctor => ctor.IsEquivalentTo(ctorDeclaration)); + return node.RemoveNode(ctor, SyntaxRemoveOptions.KeepUnbalancedDirectives)!; + } + + private static SyntaxToken CreatePartialToken(bool noSpace) + { + return Token( + SyntaxTriviaList.Empty, + SyntaxKind.PartialKeyword, + noSpace ? SyntaxTriviaList.Empty : SyntaxTriviaList.Create(Space)); + } + + private static AttributeListSyntax CreateAutoConstructAttributeList() + { + var attrName = IdentifierName("AutoConstruct"); + var attr = Attribute(attrName); + return AttributeList(SingletonSeparatedList(attr)) + .WithTrailingTrivia(ElasticEndOfLine("\n")); + } + + private static bool HasAutoConstructAttribute(TypeDeclarationSyntax typeDeclaration) + { + foreach (var attributeList in typeDeclaration.AttributeLists) + { + foreach (var attribute in attributeList.Attributes) + { + var simplifiedName = attribute.Name switch + { + IdentifierNameSyntax i => i, + QualifiedNameSyntax q => q.Right, + AliasQualifiedNameSyntax a => a.Name, + _ => null + }; + + if (simplifiedName?.Identifier.Text == "AutoConstruct") + return true; + } + } + + return false; + } +} diff --git a/src/AutoCtor.CodeFixes/UseAutoConstructCodeFixer.cs b/src/AutoCtor.CodeFixes/UseAutoConstructCodeFixer.cs index 77f79c2..19897c6 100644 --- a/src/AutoCtor.CodeFixes/UseAutoConstructCodeFixer.cs +++ b/src/AutoCtor.CodeFixes/UseAutoConstructCodeFixer.cs @@ -3,9 +3,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace AutoCtor.CodeFixes; @@ -50,157 +48,9 @@ private static async Task ApplyFixAsync( if (root is null) return document; - root = (CompilationUnitSyntax)new AutoCtorRewriter(ctorDeclaration).Visit(root); + root = (CompilationUnitSyntax)new AutoCtorRewriter( + (TypeDeclarationSyntax)ctorDeclaration.Parent!, ctorDeclaration) + .Visit(root); return document.WithSyntaxRoot(root); } - - private sealed class AutoCtorRewriter( - ConstructorDeclarationSyntax ctorDeclaration - ) : CSharpSyntaxRewriter - { - // The target type and all containing types – the only types that need 'partial'. - private readonly ImmutableArray _targetAndAncestors = - ctorDeclaration - .Ancestors() - .OfType() - .ToImmutableArray(); - - public override SyntaxNode? VisitCompilationUnit(CompilationUnitSyntax node) - { - node = (CompilationUnitSyntax)base.VisitCompilationUnit(node)!; - - // Add using AutoCtor; - if (!node.Usings.Any(u => u.Name is IdentifierNameSyntax { Identifier.Text: "AutoCtor" } - || u.Name is AliasQualifiedNameSyntax { Name.Identifier.Text: "AutoCtor" })) - { - var usingName = IdentifierName("AutoCtor"); - var usingDirective = UsingDirective(usingName); - node = node.AddUsings(usingDirective); - } - - return node; - } - - public override SyntaxNode? VisitClassDeclaration(ClassDeclarationSyntax node) - { - var isTargetOrAncestor = _targetAndAncestors.Any(a => a.IsEquivalentTo(node)); - - // Remove matching constructor - // Add [AutoConstruct] attribute - if (node.IsEquivalentTo(ctorDeclaration.Parent)) - { - node = RemoveCtor(node); - if (!HasAutoConstructAttribute(node.AttributeLists)) - { - var attrList = CreateAutoConstructAttributeList(); - node = node.AddAttributeLists(attrList); - } - } - - // Add partial modifier only to the target type and its containing types - if (isTargetOrAncestor && !node.Modifiers.Any(SyntaxKind.PartialKeyword)) - { - var partialToken = CreatePartialToken(node.Modifiers.Count == 0); - node = node.AddModifiers(partialToken); - } - - return base.VisitClassDeclaration(node); - } - - public override SyntaxNode? VisitStructDeclaration(StructDeclarationSyntax node) - { - var isTargetOrAncestor = _targetAndAncestors.Any(a => a.IsEquivalentTo(node)); - - // Remove matching constructor - // Add [AutoConstruct] attribute - if (node.IsEquivalentTo(ctorDeclaration.Parent)) - { - node = RemoveCtor(node); - if (!HasAutoConstructAttribute(node.AttributeLists)) - { - var attrList = CreateAutoConstructAttributeList(); - node = node.AddAttributeLists(attrList); - } - } - - // Add partial modifier only to the target type and its containing types - if (isTargetOrAncestor && !node.Modifiers.Any(SyntaxKind.PartialKeyword)) - { - var partialToken = CreatePartialToken(node.Modifiers.Count == 0); - node = node.AddModifiers(partialToken); - } - - return base.VisitStructDeclaration(node); - } - - public override SyntaxNode? VisitRecordDeclaration(RecordDeclarationSyntax node) - { - var isTargetOrAncestor = _targetAndAncestors.Any(a => a.IsEquivalentTo(node)); - - // Remove matching constructor - // Add [AutoConstruct] attribute - if (node.IsEquivalentTo(ctorDeclaration.Parent)) - { - node = RemoveCtor(node); - if (!HasAutoConstructAttribute(node.AttributeLists)) - { - var attrList = CreateAutoConstructAttributeList(); - node = node.AddAttributeLists(attrList); - } - } - - // Add partial modifier only to the target type and its containing types - if (isTargetOrAncestor && !node.Modifiers.Any(SyntaxKind.PartialKeyword)) - { - var partialToken = CreatePartialToken(node.Modifiers.Count == 0); - node = node.AddModifiers(partialToken); - } - - return base.VisitRecordDeclaration(node); - } - - private TRoot RemoveCtor(TRoot node) where TRoot : SyntaxNode - { - var ctor = node.ChildNodes().First(ctor => ctor.IsEquivalentTo(ctorDeclaration)); - return node.RemoveNode(ctor, SyntaxRemoveOptions.KeepUnbalancedDirectives)!; - } - - private static SyntaxToken CreatePartialToken(bool noSpace) - { - return Token( - SyntaxTriviaList.Empty, - SyntaxKind.PartialKeyword, - noSpace ? SyntaxTriviaList.Empty : SyntaxTriviaList.Create(Space)); - } - - private static AttributeListSyntax CreateAutoConstructAttributeList() - { - var attrName = IdentifierName("AutoConstruct"); - var attr = Attribute(attrName); - return AttributeList(SingletonSeparatedList(attr)) - .WithTrailingTrivia(ElasticEndOfLine("\n")); - } - - private static bool HasAutoConstructAttribute(SyntaxList attributeLists) - { - foreach (var attributeList in attributeLists) - { - foreach (var attribute in attributeList.Attributes) - { - var simplifiedName = attribute.Name switch - { - IdentifierNameSyntax i => i, - QualifiedNameSyntax q => q.Right, - AliasQualifiedNameSyntax a => a.Name, - _ => null - }; - - if (simplifiedName?.Identifier.Text == "AutoConstruct") - return true; - } - } - - return false; - } - } } diff --git a/src/AutoCtor.Roslyn3.11/AutoConstructSourceGenerator.cs b/src/AutoCtor.Roslyn3.11/AutoConstructSourceGenerator.cs index fab7e01..e1917de 100644 --- a/src/AutoCtor.Roslyn3.11/AutoConstructSourceGenerator.cs +++ b/src/AutoCtor.Roslyn3.11/AutoConstructSourceGenerator.cs @@ -18,7 +18,7 @@ public void OnVisitSyntaxNode(GeneratorSyntaxContext context) && (type = GeneratorUtilities.GetSymbol(context, cancellationToken)) != null - && GeneratorUtilities.HasAttribute(type, AttributeNames.AutoConstruct)) + && Utilities.HasAttribute(type, AttributeNames.AutoConstruct)) { (TypeModels ??= []).Add(TypeModel.Create(type)); } @@ -27,7 +27,7 @@ public void OnVisitSyntaxNode(GeneratorSyntaxContext context) && (method = GeneratorUtilities.GetSymbol(context, cancellationToken)) != null - && GeneratorUtilities.HasAttribute(method, AttributeNames.AutoPostConstruct)) + && Utilities.HasAttribute(method, AttributeNames.AutoPostConstruct)) { (MarkedMethods ??= []).Add(PostCtorModel.Create(method)); } diff --git a/src/AutoCtor.Roslyn4.0/AutoConstructSourceGenerator.cs b/src/AutoCtor.Roslyn4.0/AutoConstructSourceGenerator.cs index ec48808..15d2f47 100644 --- a/src/AutoCtor.Roslyn4.0/AutoConstructSourceGenerator.cs +++ b/src/AutoCtor.Roslyn4.0/AutoConstructSourceGenerator.cs @@ -17,14 +17,14 @@ public void Initialize(IncrementalGeneratorInitializationContext context) var types = context.SyntaxProvider.CreateSyntaxProvider( GeneratorUtilities.IsTypeDeclarationWithAttributes, GeneratorUtilities.GetSymbol) - .Where(static x => GeneratorUtilities.HasAttribute(x, AttributeNames.AutoConstruct)) + .Where(static x => Utilities.HasAttribute(x, AttributeNames.AutoConstruct)) .Select(static (x, _) => TypeModel.Create(x!)) .Collect(); var postCtorMethods = context.SyntaxProvider.CreateSyntaxProvider( GeneratorUtilities.IsMethodDeclarationWithAttributes, GeneratorUtilities.GetSymbol) - .Where(static x => GeneratorUtilities.HasAttribute(x, AttributeNames.AutoPostConstruct)) + .Where(static x => Utilities.HasAttribute(x, AttributeNames.AutoPostConstruct)) .Select(static (x, _) => PostCtorModel.Create(x!)) .Collect(); diff --git a/src/Shared/AnalyzerReleases.Unshipped.md b/src/Shared/AnalyzerReleases.Unshipped.md index 9e9925f..8b0bfa0 100644 --- a/src/Shared/AnalyzerReleases.Unshipped.md +++ b/src/Shared/AnalyzerReleases.Unshipped.md @@ -1,3 +1,8 @@ ; Unshipped analyzer release ; https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md +### New Rules + +Rule ID | Category | Severity | Notes +--------|----------|----------|------- +ACTR008 | AutoCtor | Info | AddAutoConstruct diff --git a/src/Shared/AutoConstructSourceGenerator/AddAutoConstructAnalyzer.cs b/src/Shared/AutoConstructSourceGenerator/AddAutoConstructAnalyzer.cs new file mode 100644 index 0000000..dcaebef --- /dev/null +++ b/src/Shared/AutoConstructSourceGenerator/AddAutoConstructAnalyzer.cs @@ -0,0 +1,59 @@ +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; + +namespace AutoCtor; + +[DiagnosticAnalyzer(LanguageNames.CSharp)] +public sealed class AddAutoConstructAnalyzer : DiagnosticAnalyzer +{ + public override ImmutableArray SupportedDiagnostics => + ImmutableArray.Create(Diagnostics.ACTR008_AddAutoConstruct); + + public override void Initialize(AnalysisContext context) + { + if (context is null) + throw new ArgumentNullException(nameof(context)); + + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + context.EnableConcurrentExecution(); + + context.RegisterCompilationStartAction(static compilationContext => + { + if (!Utilities.IsAutoConstructInCompilation(compilationContext.Compilation)) + return; + + compilationContext.RegisterSyntaxNodeAction(AnalyzeType, SyntaxKind.ClassDeclaration); + compilationContext.RegisterSyntaxNodeAction(AnalyzeType, SyntaxKind.StructDeclaration); + compilationContext.RegisterSyntaxNodeAction(AnalyzeType, SyntaxKind.RecordDeclaration); + compilationContext.RegisterSyntaxNodeAction(AnalyzeType, SyntaxKind.RecordStructDeclaration); + }); + } + + private static void AnalyzeType(SyntaxNodeAnalysisContext context) + { + var typeSyntax = (TypeDeclarationSyntax)context.Node; + + if (context.SemanticModel.GetDeclaredSymbol(typeSyntax, context.CancellationToken) is not INamedTypeSymbol type) + return; + + if (Utilities.HasAttribute(type, AttributeNames.AutoConstruct)) + return; + + // no constructors + if (type.InstanceConstructors.Any(c => !c.IsImplicitlyDeclared)) + return; + + if (!Utilities.HasEligibleMember(type)) + return; + + var location = typeSyntax.Identifier.GetLocation(); + + context.ReportDiagnostic(Diagnostic.Create( + Diagnostics.ACTR008_AddAutoConstruct, + location, + type.Name)); + } +} diff --git a/src/Shared/AutoConstructSourceGenerator/UseAutoConstructAnalyzer.cs b/src/Shared/AutoConstructSourceGenerator/UseAutoConstructAnalyzer.cs index 2ff142b..91e4231 100644 --- a/src/Shared/AutoConstructSourceGenerator/UseAutoConstructAnalyzer.cs +++ b/src/Shared/AutoConstructSourceGenerator/UseAutoConstructAnalyzer.cs @@ -22,18 +22,16 @@ public override void Initialize(AnalysisContext context) context.RegisterCompilationStartAction(static compilationContext => { - var autoConstructType = compilationContext.Compilation - .GetTypeByMetadataName(AttributeNames.AutoConstruct); - if (autoConstructType is null) + if (!Utilities.IsAutoConstructInCompilation(compilationContext.Compilation)) return; compilationContext.RegisterSyntaxNodeAction( - ctx => AnalyzeConstructor(ctx, autoConstructType), + AnalyzeConstructor, SyntaxKind.ConstructorDeclaration); }); } - private static void AnalyzeConstructor(SyntaxNodeAnalysisContext context, INamedTypeSymbol autoConstructType) + private static void AnalyzeConstructor(SyntaxNodeAnalysisContext context) { var ctorSyntax = (ConstructorDeclarationSyntax)context.Node; @@ -46,24 +44,23 @@ private static void AnalyzeConstructor(SyntaxNodeAnalysisContext context, INamed if (ctor.IsImplicitlyDeclared) return; - if (IsEligibleConstructor(ctor, ctorSyntax, type, context.SemanticModel, out var location)) - { - context.ReportDiagnostic(Diagnostic.Create( - Diagnostics.ACTR007_UseAutoConstruct, - location, - type.Name)); - } + if (!IsEligibleConstructor(ctor, ctorSyntax, type, context.SemanticModel)) + return; + + var location = ctorSyntax.Identifier.GetLocation(); + + context.ReportDiagnostic(Diagnostic.Create( + Diagnostics.ACTR007_UseAutoConstruct, + location, + type.Name)); } private static bool IsEligibleConstructor( IMethodSymbol ctor, ConstructorDeclarationSyntax ctorSyntax, INamedTypeSymbol type, - SemanticModel semanticModel, - out Location location) + SemanticModel semanticModel) { - location = Location.None; - // Not public if (ctor.DeclaredAccessibility != Accessibility.Public) return false; @@ -72,8 +69,6 @@ private static bool IsEligibleConstructor( if (ctor.GetAttributes().Any()) return false; - location = ctorSyntax.Identifier.GetLocation(); - // No initializer (: base() or : this()) if (ctorSyntax.Initializer is not null) return false; @@ -92,7 +87,7 @@ private static bool IsEligibleConstructor( var assignedMembers = new Dictionary(SymbolEqualityComparer.Default); // Every eligible member in the type must be covered - var eligibleMembers = GetEligibleMembers(type); + var eligibleMembers = Utilities.GetEligibleMembers(type).ToList(); // Every statement must be a qualifying assignment foreach (var statement in ctorSyntax.Body.Statements) @@ -138,18 +133,4 @@ private static bool IsEligibleConstructor( return true; } - - private static List GetEligibleMembers(INamedTypeSymbol type) - { - var result = new List(); - foreach (var member in type.GetMembers()) - { - if (member is IFieldSymbol field && ModelUtilities.IsValidField(field)) - result.Add(member); - - if (member is IPropertySymbol property && ModelUtilities.IsValidProperty(property)) - result.Add(member); - } - return result; - } } diff --git a/src/Shared/Constants/Diagnostics.cs b/src/Shared/Constants/Diagnostics.cs index 4e786d3..8cfe8f4 100644 --- a/src/Shared/Constants/Diagnostics.cs +++ b/src/Shared/Constants/Diagnostics.cs @@ -88,4 +88,16 @@ internal static class Diagnostics category: "AutoCtor", DiagnosticSeverity.Info, isEnabledByDefault: true); + + /// + /// Id: ACTR008
+ /// Title: Add [AutoConstruct] to type + ///
+ public static readonly DiagnosticDescriptor ACTR008_AddAutoConstruct = new DiagnosticDescriptor( + id: "ACTR008", + title: "Add [AutoConstruct] to type", + messageFormat: "[AutoConstruct] can be added to type '{0}'", + category: "AutoCtor", + DiagnosticSeverity.Info, + isEnabledByDefault: true); } diff --git a/src/Shared/Helpers/GeneratorUtilities.cs b/src/Shared/Helpers/GeneratorUtilities.cs index 69e660f..0d49e2c 100644 --- a/src/Shared/Helpers/GeneratorUtilities.cs +++ b/src/Shared/Helpers/GeneratorUtilities.cs @@ -76,9 +76,4 @@ public static bool IsMethodDeclarationWithAttributes(SyntaxNode node, Cancellati public static TSymbol? GetSymbol(GeneratorSyntaxContext context, CancellationToken cancellationToken) where TSymbol : class, ISymbol => context.SemanticModel.GetDeclaredSymbol(context.Node, cancellationToken) as TSymbol; - - public static bool HasAttribute(ISymbol? symbol, string attributeName) - { - return symbol != null && symbol.GetAttributes().Any(a => a.AttributeClass?.ToDisplayString() == attributeName); - } } diff --git a/src/Shared/Models/ModelUtilities.cs b/src/Shared/Helpers/Utilities.cs similarity index 73% rename from src/Shared/Models/ModelUtilities.cs rename to src/Shared/Helpers/Utilities.cs index 5567317..9724dce 100644 --- a/src/Shared/Models/ModelUtilities.cs +++ b/src/Shared/Helpers/Utilities.cs @@ -2,7 +2,7 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -internal static class ModelUtilities +internal static class Utilities { public static string? GetServiceKey(ISymbol symbol) { @@ -89,4 +89,39 @@ public static bool IsValidProperty(IPropertySymbol property) return true; } + + public static bool HasEligibleMember(INamedTypeSymbol type) + { + foreach (var member in type.GetMembers()) + { + if (member is IFieldSymbol field && IsValidField(field)) + return true; + + if (member is IPropertySymbol property && IsValidProperty(property)) + return true; + } + return false; + } + + public static IEnumerable GetEligibleMembers(INamedTypeSymbol type) + { + foreach (var member in type.GetMembers()) + { + if (member is IFieldSymbol field && IsValidField(field)) + yield return member; + + if (member is IPropertySymbol property && IsValidProperty(property)) + yield return member; + } + } + + public static bool HasAttribute(ISymbol? symbol, string attributeName) + { + return symbol != null && symbol.GetAttributes().Any(a => a.AttributeClass?.ToDisplayString() == attributeName); + } + + public static bool IsAutoConstructInCompilation(Compilation compilation) + { + return compilation.GetTypeByMetadataName(AttributeNames.AutoConstruct) is not null; + } } diff --git a/src/Shared/Models/MemberModel.cs b/src/Shared/Models/MemberModel.cs index c02bf71..38af259 100644 --- a/src/Shared/Models/MemberModel.cs +++ b/src/Shared/Models/MemberModel.cs @@ -1,5 +1,5 @@ using Microsoft.CodeAnalysis; -using static ModelUtilities; +using static Utilities; internal readonly record struct MemberModel( EquatableTypeSymbol Type, diff --git a/src/Shared/Models/ParameterModel.cs b/src/Shared/Models/ParameterModel.cs index 241b351..c5a062e 100644 --- a/src/Shared/Models/ParameterModel.cs +++ b/src/Shared/Models/ParameterModel.cs @@ -36,7 +36,7 @@ public static ParameterModel Create(IParameterSymbol parameter) RefKind: parameter.RefKind, Name: parameter.Name.EscapeKeywordIdentifier(), ErrorName: parameter.Name, - KeyedService: ModelUtilities.GetServiceKey(parameter), + KeyedService: Utilities.GetServiceKey(parameter), HasExplicitDefaultValue: parameter.HasExplicitDefaultValue, ExplicitDefaultValue: defaultValue, IsOutOrRef: parameter.RefKind == RefKind.Ref diff --git a/src/Shared/Models/TypeModel.cs b/src/Shared/Models/TypeModel.cs index 4d1225f..095c822 100644 --- a/src/Shared/Models/TypeModel.cs +++ b/src/Shared/Models/TypeModel.cs @@ -124,7 +124,7 @@ private static EquatableList GetFields(IEnumerable members { return new(members .OfType() - .Where(ModelUtilities.IsValidField) + .Where(Utilities.IsValidField) .Select(MemberModel.Create)); } @@ -132,7 +132,7 @@ private static EquatableList GetProperties(IEnumerable mem { return new(members .OfType() - .Where(ModelUtilities.IsValidProperty) + .Where(Utilities.IsValidProperty) .Select(MemberModel.Create)); } } diff --git a/src/Tests/CodeAnalyzerExamples/AlreadyHasAutoConstruct.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/AlreadyHasAutoConstruct.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/AlreadyHasAutoConstruct.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/AlreadyHasAutoConstruct.cs diff --git a/src/Tests/CodeAnalyzerExamples/AlreadyHasAutoConstruct.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/AlreadyHasAutoConstruct.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/AlreadyHasAutoConstruct.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/AlreadyHasAutoConstruct.cs.verified.txt diff --git a/src/Tests/CodeAnalyzerExamples/AlreadyPartial.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/AlreadyPartial.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/AlreadyPartial.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/AlreadyPartial.cs diff --git a/src/Tests/CodeAnalyzerExamples/AlreadyPartial.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/AlreadyPartial.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/AlreadyPartial.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/AlreadyPartial.cs.verified.txt diff --git a/src/Tests/CodeAnalyzerExamples/BlankConstructor.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/BlankConstructor.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/BlankConstructor.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/BlankConstructor.cs diff --git a/src/Tests/CodeAnalyzerExamples/BlankConstructor.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/BlankConstructor.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/BlankConstructor.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/BlankConstructor.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsExpression.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsExpression.cs new file mode 100644 index 0000000..7121f59 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsExpression.cs @@ -0,0 +1,9 @@ +public class ConstructorAssignsExpression +{ + private readonly string _value; + + public ConstructorAssignsExpression(string value) + { + _value = value + "!"; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsExpression.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsExpression.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsExpression.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/CodeAnalyzerExamples/ConstructorAssignsIgnoredField.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsIgnoredField.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/ConstructorAssignsIgnoredField.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsIgnoredField.cs diff --git a/src/Tests/CodeAnalyzerExamples/ConstructorAssignsIgnoredField.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsIgnoredField.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/ConstructorAssignsIgnoredField.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsIgnoredField.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsLiteral.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsLiteral.cs new file mode 100644 index 0000000..7f97294 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsLiteral.cs @@ -0,0 +1,9 @@ +public class ConstructorAssignsLiteral +{ + private readonly string _value; + + public ConstructorAssignsLiteral(string value) + { + _value = "literal"; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsLiteral.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsLiteral.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsLiteral.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsMethodCall.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsMethodCall.cs new file mode 100644 index 0000000..1f21c5b --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsMethodCall.cs @@ -0,0 +1,9 @@ +public class ConstructorAssignsMethodCall +{ + private readonly string _value; + + public ConstructorAssignsMethodCall(string value) + { + _value = value.ToUpper(); + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsMethodCall.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsMethodCall.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsMethodCall.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsNonParameter.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsNonParameter.cs new file mode 100644 index 0000000..f284bf2 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsNonParameter.cs @@ -0,0 +1,10 @@ +public class ConstructorAssignsNonParameter +{ + private static readonly string s_default = "default"; + private readonly string _value; + + public ConstructorAssignsNonParameter(string value) + { + _value = s_default; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsNonParameter.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsNonParameter.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsNonParameter.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToBaseField.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToBaseField.cs new file mode 100644 index 0000000..5e721d2 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToBaseField.cs @@ -0,0 +1,15 @@ +public class BaseWithField +{ + protected string _baseValue = ""; +} + +public class ConstructorAssignsToBaseField : BaseWithField +{ + private readonly string _value; + + public ConstructorAssignsToBaseField(string value, string baseValue) + { + _value = value; + _baseValue = baseValue; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToBaseField.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToBaseField.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToBaseField.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToMutableAutoProperty.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToMutableAutoProperty.cs new file mode 100644 index 0000000..84a0c4b --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToMutableAutoProperty.cs @@ -0,0 +1,9 @@ +public class ConstructorAssignsToMutableAutoProperty +{ + public string Value { get; set; } + + public ConstructorAssignsToMutableAutoProperty(string value) + { + Value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToMutableAutoProperty.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToMutableAutoProperty.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToMutableAutoProperty.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToMutableField.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToMutableField.cs new file mode 100644 index 0000000..425daa5 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToMutableField.cs @@ -0,0 +1,9 @@ +public class ConstructorAssignsToMutableField +{ + private string _value; + + public ConstructorAssignsToMutableField(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToMutableField.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToMutableField.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToMutableField.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToReadWriteProperty.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToReadWriteProperty.cs new file mode 100644 index 0000000..c68826f --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToReadWriteProperty.cs @@ -0,0 +1,9 @@ +public class ConstructorAssignsToReadWriteProperty +{ + public string Value { get; private set; } + + public ConstructorAssignsToReadWriteProperty(string value) + { + Value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToReadWriteProperty.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToReadWriteProperty.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorAssignsToReadWriteProperty.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/CodeAnalyzerExamples/ConstructorWithAttribute.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithAttribute.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/ConstructorWithAttribute.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithAttribute.cs diff --git a/src/Tests/CodeAnalyzerExamples/ConstructorWithAttribute.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithAttribute.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/ConstructorWithAttribute.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithAttribute.cs.verified.txt diff --git a/src/Tests/CodeAnalyzerExamples/ConstructorWithExplicitDefault.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithExplicitDefault.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/ConstructorWithExplicitDefault.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithExplicitDefault.cs diff --git a/src/Tests/CodeAnalyzerExamples/ConstructorWithExplicitDefault.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithExplicitDefault.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/ConstructorWithExplicitDefault.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithExplicitDefault.cs.verified.txt diff --git a/src/Tests/CodeAnalyzerExamples/ConstructorWithExtraParameter.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithExtraParameter.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/ConstructorWithExtraParameter.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithExtraParameter.cs diff --git a/src/Tests/CodeAnalyzerExamples/ConstructorWithExtraParameter.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithExtraParameter.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/ConstructorWithExtraParameter.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithExtraParameter.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithInParameter.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithInParameter.cs new file mode 100644 index 0000000..ee8ab32 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithInParameter.cs @@ -0,0 +1,9 @@ +public class ConstructorWithInParameter +{ + private readonly int _value; + + public ConstructorWithInParameter(in int value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithInParameter.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithInParameter.cs.verified.txt new file mode 100644 index 0000000..3955508 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithInParameter.cs.verified.txt @@ -0,0 +1,22 @@ +[ + { + Location: /* + + public ConstructorWithInParameter(in int value) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + { +*/ + : (4,11)-(4,37), + Message: Constructor for 'ConstructorWithInParameter' can be replaced with [AutoConstruct], + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR007, + Title: Use [AutoConstruct] instead of manual constructor, + MessageFormat: Constructor for '{0}' can be replaced with [AutoConstruct], + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithLocalVariable.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithLocalVariable.cs new file mode 100644 index 0000000..70752bf --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithLocalVariable.cs @@ -0,0 +1,10 @@ +public class ConstructorWithLocalVariable +{ + private readonly string _value; + + public ConstructorWithLocalVariable(string value) + { + var temp = value.Trim(); + _value = temp; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithLocalVariable.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithLocalVariable.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithLocalVariable.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/CodeAnalyzerExamples/ConstructorWithNonAssignment.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithNonAssignment.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/ConstructorWithNonAssignment.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithNonAssignment.cs diff --git a/src/Tests/CodeAnalyzerExamples/ConstructorWithNonAssignment.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithNonAssignment.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/ConstructorWithNonAssignment.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithNonAssignment.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithOutParameter.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithOutParameter.cs new file mode 100644 index 0000000..37fae81 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithOutParameter.cs @@ -0,0 +1,10 @@ +public class ConstructorWithOutParameter +{ + private readonly string _value; + + public ConstructorWithOutParameter(string value, out string result) + { + _value = value; + result = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithOutParameter.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithOutParameter.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithOutParameter.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithParamsArray.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithParamsArray.cs new file mode 100644 index 0000000..52fb0a4 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithParamsArray.cs @@ -0,0 +1,9 @@ +public class ConstructorWithParamsArray +{ + private readonly int[] _values; + + public ConstructorWithParamsArray(params int[] values) + { + _values = values; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithParamsArray.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithParamsArray.cs.verified.txt new file mode 100644 index 0000000..b04a7ac --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithParamsArray.cs.verified.txt @@ -0,0 +1,22 @@ +[ + { + Location: /* + + public ConstructorWithParamsArray(params int[] values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + { +*/ + : (4,11)-(4,37), + Message: Constructor for 'ConstructorWithParamsArray' can be replaced with [AutoConstruct], + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR007, + Title: Use [AutoConstruct] instead of manual constructor, + MessageFormat: Constructor for '{0}' can be replaced with [AutoConstruct], + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithRefParameter.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithRefParameter.cs new file mode 100644 index 0000000..d2952ee --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithRefParameter.cs @@ -0,0 +1,9 @@ +public class ConstructorWithRefParameter +{ + private readonly string _value; + + public ConstructorWithRefParameter(ref string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithRefParameter.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithRefParameter.cs.verified.txt new file mode 100644 index 0000000..f8c47ab --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ConstructorWithRefParameter.cs.verified.txt @@ -0,0 +1,22 @@ +[ + { + Location: /* + + public ConstructorWithRefParameter(ref string value) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + { +*/ + : (4,11)-(4,38), + Message: Constructor for 'ConstructorWithRefParameter' can be replaced with [AutoConstruct], + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR007, + Title: Use [AutoConstruct] instead of manual constructor, + MessageFormat: Constructor for '{0}' can be replaced with [AutoConstruct], + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/CodeAnalyzerExamples/FieldHasInitializer.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/FieldHasInitializer.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/FieldHasInitializer.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/FieldHasInitializer.cs diff --git a/src/Tests/CodeAnalyzerExamples/FieldHasInitializer.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/FieldHasInitializer.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/FieldHasInitializer.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/FieldHasInitializer.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/GenericClass.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/GenericClass.cs new file mode 100644 index 0000000..020b1df --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/GenericClass.cs @@ -0,0 +1,9 @@ +public class GenericClass +{ + private readonly T _value; + + public GenericClass(T value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/GenericClass.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/GenericClass.cs.verified.txt new file mode 100644 index 0000000..dfe022e --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/GenericClass.cs.verified.txt @@ -0,0 +1,22 @@ +[ + { + Location: /* + + public GenericClass(T value) + ^^^^^^^^^^^^ + { +*/ + : (4,11)-(4,23), + Message: Constructor for 'GenericClass' can be replaced with [AutoConstruct], + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR007, + Title: Use [AutoConstruct] instead of manual constructor, + MessageFormat: Constructor for '{0}' can be replaced with [AutoConstruct], + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/GenericClassWithConstraints.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/GenericClassWithConstraints.cs new file mode 100644 index 0000000..2433ac6 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/GenericClassWithConstraints.cs @@ -0,0 +1,9 @@ +public class GenericClassWithConstraints where T : class +{ + private readonly T _value; + + public GenericClassWithConstraints(T value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/GenericClassWithConstraints.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/GenericClassWithConstraints.cs.verified.txt new file mode 100644 index 0000000..2824fc2 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/GenericClassWithConstraints.cs.verified.txt @@ -0,0 +1,22 @@ +[ + { + Location: /* + + public GenericClassWithConstraints(T value) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + { +*/ + : (4,11)-(4,38), + Message: Constructor for 'GenericClassWithConstraints' can be replaced with [AutoConstruct], + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR007, + Title: Use [AutoConstruct] instead of manual constructor, + MessageFormat: Constructor for '{0}' can be replaced with [AutoConstruct], + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/CodeAnalyzerExamples/HasBaseInitializer.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/HasBaseInitializer.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/HasBaseInitializer.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/HasBaseInitializer.cs diff --git a/src/Tests/CodeAnalyzerExamples/HasBaseInitializer.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/HasBaseInitializer.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/HasBaseInitializer.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/HasBaseInitializer.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/HasThisInitializer.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/HasThisInitializer.cs new file mode 100644 index 0000000..c22ed89 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/HasThisInitializer.cs @@ -0,0 +1,11 @@ +public class HasThisInitializer +{ + private readonly string _value; + + public HasThisInitializer() { } + + public HasThisInitializer(string value) : this() + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/HasThisInitializer.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/HasThisInitializer.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/HasThisInitializer.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/CodeAnalyzerExamples/IgnoredFieldIsNotAssigned.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/IgnoredFieldIsNotAssigned.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/IgnoredFieldIsNotAssigned.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/IgnoredFieldIsNotAssigned.cs diff --git a/src/Tests/CodeAnalyzerExamples/IgnoredFieldIsNotAssigned.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/IgnoredFieldIsNotAssigned.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/IgnoredFieldIsNotAssigned.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/IgnoredFieldIsNotAssigned.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/InitOnlyProperty.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/InitOnlyProperty.cs new file mode 100644 index 0000000..690203e --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/InitOnlyProperty.cs @@ -0,0 +1,9 @@ +public class InitOnlyProperty +{ + public string Value { get; init; } + + public InitOnlyProperty(string value) + { + Value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/InitOnlyProperty.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/InitOnlyProperty.cs.verified.txt new file mode 100644 index 0000000..8a2ed44 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/InitOnlyProperty.cs.verified.txt @@ -0,0 +1,22 @@ +[ + { + Location: /* + + public InitOnlyProperty(string value) + ^^^^^^^^^^^^^^^^ + { +*/ + : (4,11)-(4,27), + Message: Constructor for 'InitOnlyProperty' can be replaced with [AutoConstruct], + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR007, + Title: Use [AutoConstruct] instead of manual constructor, + MessageFormat: Constructor for '{0}' can be replaced with [AutoConstruct], + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/CodeAnalyzerExamples/InternalConstructor.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/InternalConstructor.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/InternalConstructor.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/InternalConstructor.cs diff --git a/src/Tests/CodeAnalyzerExamples/InternalConstructor.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/InternalConstructor.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/InternalConstructor.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/InternalConstructor.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/MemberAccessWithoutThis.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/MemberAccessWithoutThis.cs new file mode 100644 index 0000000..e926fb6 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/MemberAccessWithoutThis.cs @@ -0,0 +1,11 @@ +public class MemberAccessWithoutThis +{ + private static int s_count; + private readonly int _value; + + public MemberAccessWithoutThis(int value) + { + MemberAccessWithoutThis.s_count = 1; + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/MemberAccessWithoutThis.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/MemberAccessWithoutThis.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/MemberAccessWithoutThis.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/MixedFieldsAndProperties.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/MixedFieldsAndProperties.cs new file mode 100644 index 0000000..e681a9e --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/MixedFieldsAndProperties.cs @@ -0,0 +1,11 @@ +public class MixedFieldsAndProperties +{ + private readonly string _value; + public int Count { get; } + + public MixedFieldsAndProperties(string value, int count) + { + _value = value; + Count = count; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/MixedFieldsAndProperties.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/MixedFieldsAndProperties.cs.verified.txt new file mode 100644 index 0000000..ad0ddcd --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/MixedFieldsAndProperties.cs.verified.txt @@ -0,0 +1,22 @@ +[ + { + Location: /* + + public MixedFieldsAndProperties(string value, int count) + ^^^^^^^^^^^^^^^^^^^^^^^^ + { +*/ + : (5,11)-(5,35), + Message: Constructor for 'MixedFieldsAndProperties' can be replaced with [AutoConstruct], + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR007, + Title: Use [AutoConstruct] instead of manual constructor, + MessageFormat: Constructor for '{0}' can be replaced with [AutoConstruct], + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/CodeAnalyzerExamples/MultipleConstructors.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/MultipleConstructors.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/MultipleConstructors.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/MultipleConstructors.cs diff --git a/src/Tests/CodeAnalyzerExamples/MultipleConstructors.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/MultipleConstructors.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/MultipleConstructors.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/MultipleConstructors.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/NestedTypeWithConstructor.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/NestedTypeWithConstructor.cs new file mode 100644 index 0000000..c31a99a --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/NestedTypeWithConstructor.cs @@ -0,0 +1,12 @@ +public class NestedTypeWithConstructor +{ + public class Inner + { + private readonly string _value; + + public Inner(string value) + { + _value = value; + } + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/NestedTypeWithConstructor.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/NestedTypeWithConstructor.cs.verified.txt new file mode 100644 index 0000000..1d4dd54 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/NestedTypeWithConstructor.cs.verified.txt @@ -0,0 +1,22 @@ +[ + { + Location: /* + + public Inner(string value) + ^^^^^ + { +*/ + : (6,15)-(6,20), + Message: Constructor for 'Inner' can be replaced with [AutoConstruct], + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR007, + Title: Use [AutoConstruct] instead of manual constructor, + MessageFormat: Constructor for '{0}' can be replaced with [AutoConstruct], + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/CodeAnalyzerExamples/NoDeclaredVisibility.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/NoDeclaredVisibility.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/NoDeclaredVisibility.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/NoDeclaredVisibility.cs diff --git a/src/Tests/CodeAnalyzerExamples/NoDeclaredVisibility.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/NoDeclaredVisibility.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/NoDeclaredVisibility.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/NoDeclaredVisibility.cs.verified.txt diff --git a/src/Tests/CodeAnalyzerExamples/NotAllFieldsAssigned.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/NotAllFieldsAssigned.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/NotAllFieldsAssigned.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/NotAllFieldsAssigned.cs diff --git a/src/Tests/CodeAnalyzerExamples/NotAllFieldsAssigned.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/NotAllFieldsAssigned.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/NotAllFieldsAssigned.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/NotAllFieldsAssigned.cs.verified.txt diff --git a/src/Tests/CodeAnalyzerExamples/OnlyFieldAssignments.CheckDiagnostics.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/OnlyFieldAssignments.CheckDiagnostics.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/OnlyFieldAssignments.CheckDiagnostics.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/OnlyFieldAssignments.CheckDiagnostics.verified.txt diff --git a/src/Tests/CodeAnalyzerExamples/OnlyFieldAssignments.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/OnlyFieldAssignments.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/OnlyFieldAssignments.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/OnlyFieldAssignments.cs diff --git a/src/Tests/CodeAnalyzerExamples/OnlyFieldAssignments.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/OnlyFieldAssignments.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/OnlyFieldAssignments.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/OnlyFieldAssignments.cs.verified.txt diff --git a/src/Tests/CodeAnalyzerExamples/OnlyPropertyAssignments.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/OnlyPropertyAssignments.cs similarity index 100% rename from src/Tests/CodeAnalyzerExamples/OnlyPropertyAssignments.cs rename to src/Tests/ACTR007_CodeAnalyzerExamples/OnlyPropertyAssignments.cs diff --git a/src/Tests/CodeAnalyzerExamples/OnlyPropertyAssignments.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/OnlyPropertyAssignments.cs.verified.txt similarity index 100% rename from src/Tests/CodeAnalyzerExamples/OnlyPropertyAssignments.cs.verified.txt rename to src/Tests/ACTR007_CodeAnalyzerExamples/OnlyPropertyAssignments.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ParameterNameDifferentFromMember.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ParameterNameDifferentFromMember.cs new file mode 100644 index 0000000..d00a7ce --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ParameterNameDifferentFromMember.cs @@ -0,0 +1,9 @@ +public class ParameterNameDifferentFromMember +{ + private readonly string _value; + + public ParameterNameDifferentFromMember(string name) + { + _value = name; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ParameterNameDifferentFromMember.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ParameterNameDifferentFromMember.cs.verified.txt new file mode 100644 index 0000000..ec6544e --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ParameterNameDifferentFromMember.cs.verified.txt @@ -0,0 +1,22 @@ +[ + { + Location: /* + + public ParameterNameDifferentFromMember(string name) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + { +*/ + : (4,11)-(4,43), + Message: Constructor for 'ParameterNameDifferentFromMember' can be replaced with [AutoConstruct], + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR007, + Title: Use [AutoConstruct] instead of manual constructor, + MessageFormat: Constructor for '{0}' can be replaced with [AutoConstruct], + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/PrimaryConstructorPresent.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/PrimaryConstructorPresent.cs new file mode 100644 index 0000000..0929275 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/PrimaryConstructorPresent.cs @@ -0,0 +1,10 @@ +public class PrimaryConstructorPresent(int initial) +{ + private readonly string _other; + private readonly int _value = initial; + + public PrimaryConstructorPresent(int initial, string other) : this(initial) + { + _other = other; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/PrimaryConstructorPresent.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/PrimaryConstructorPresent.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/PrimaryConstructorPresent.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/PrivateConstructor.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/PrivateConstructor.cs new file mode 100644 index 0000000..ec2ac0c --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/PrivateConstructor.cs @@ -0,0 +1,9 @@ +public class PrivateConstructor +{ + private readonly string _value; + + private PrivateConstructor(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/PrivateConstructor.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/PrivateConstructor.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/PrivateConstructor.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ProtectedConstructor.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ProtectedConstructor.cs new file mode 100644 index 0000000..9d26fbe --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ProtectedConstructor.cs @@ -0,0 +1,9 @@ +public class ProtectedConstructor +{ + private readonly string _value; + + protected ProtectedConstructor(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ProtectedConstructor.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ProtectedConstructor.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ProtectedConstructor.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/RecordClassConstructor.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/RecordClassConstructor.cs new file mode 100644 index 0000000..fdf0d30 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/RecordClassConstructor.cs @@ -0,0 +1,9 @@ +public record class RecordClassConstructor +{ + private readonly string _value; + + public RecordClassConstructor(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/RecordClassConstructor.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/RecordClassConstructor.cs.verified.txt new file mode 100644 index 0000000..949179d --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/RecordClassConstructor.cs.verified.txt @@ -0,0 +1,22 @@ +[ + { + Location: /* + + public RecordClassConstructor(string value) + ^^^^^^^^^^^^^^^^^^^^^^ + { +*/ + : (4,11)-(4,33), + Message: Constructor for 'RecordClassConstructor' can be replaced with [AutoConstruct], + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR007, + Title: Use [AutoConstruct] instead of manual constructor, + MessageFormat: Constructor for '{0}' can be replaced with [AutoConstruct], + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/RecordStructConstructor.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/RecordStructConstructor.cs new file mode 100644 index 0000000..67a0a19 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/RecordStructConstructor.cs @@ -0,0 +1,9 @@ +public record struct RecordStructConstructor +{ + private readonly string _value; + + public RecordStructConstructor(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/RecordStructConstructor.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/RecordStructConstructor.cs.verified.txt new file mode 100644 index 0000000..e201e8f --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/RecordStructConstructor.cs.verified.txt @@ -0,0 +1,22 @@ +[ + { + Location: /* + + public RecordStructConstructor(string value) + ^^^^^^^^^^^^^^^^^^^^^^^ + { +*/ + : (4,11)-(4,34), + Message: Constructor for 'RecordStructConstructor' can be replaced with [AutoConstruct], + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR007, + Title: Use [AutoConstruct] instead of manual constructor, + MessageFormat: Constructor for '{0}' can be replaced with [AutoConstruct], + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/SameFieldAssignedTwice.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/SameFieldAssignedTwice.cs new file mode 100644 index 0000000..accd644 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/SameFieldAssignedTwice.cs @@ -0,0 +1,10 @@ +public class SameFieldAssignedTwice +{ + private readonly string _value; + + public SameFieldAssignedTwice(string a) + { + _value = a; + _value = a; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/SameFieldAssignedTwice.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/SameFieldAssignedTwice.cs.verified.txt new file mode 100644 index 0000000..b24ea98 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/SameFieldAssignedTwice.cs.verified.txt @@ -0,0 +1,22 @@ +[ + { + Location: /* + + public SameFieldAssignedTwice(string a) + ^^^^^^^^^^^^^^^^^^^^^^ + { +*/ + : (4,11)-(4,33), + Message: Constructor for 'SameFieldAssignedTwice' can be replaced with [AutoConstruct], + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR007, + Title: Use [AutoConstruct] instead of manual constructor, + MessageFormat: Constructor for '{0}' can be replaced with [AutoConstruct], + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/SameParamUsedTwice.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/SameParamUsedTwice.cs new file mode 100644 index 0000000..903fd8e --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/SameParamUsedTwice.cs @@ -0,0 +1,11 @@ +public class SameParamUsedTwice +{ + private readonly string _a; + private readonly string _b; + + public SameParamUsedTwice(string value) + { + _a = value; + _b = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/SameParamUsedTwice.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/SameParamUsedTwice.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/SameParamUsedTwice.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/StructConstructor.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/StructConstructor.cs new file mode 100644 index 0000000..db29111 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/StructConstructor.cs @@ -0,0 +1,9 @@ +public struct StructConstructor +{ + private readonly string _value; + + public StructConstructor(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/StructConstructor.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/StructConstructor.cs.verified.txt new file mode 100644 index 0000000..d284b14 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/StructConstructor.cs.verified.txt @@ -0,0 +1,22 @@ +[ + { + Location: /* + + public StructConstructor(string value) + ^^^^^^^^^^^^^^^^^ + { +*/ + : (4,11)-(4,28), + Message: Constructor for 'StructConstructor' can be replaced with [AutoConstruct], + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR007, + Title: Use [AutoConstruct] instead of manual constructor, + MessageFormat: Constructor for '{0}' can be replaced with [AutoConstruct], + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ThisQualifiedAssignments.cs b/src/Tests/ACTR007_CodeAnalyzerExamples/ThisQualifiedAssignments.cs new file mode 100644 index 0000000..56d55ae --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ThisQualifiedAssignments.cs @@ -0,0 +1,9 @@ +public class ThisQualifiedAssignments +{ + private readonly string _value; + + public ThisQualifiedAssignments(string value) + { + this._value = value; + } +} diff --git a/src/Tests/ACTR007_CodeAnalyzerExamples/ThisQualifiedAssignments.cs.verified.txt b/src/Tests/ACTR007_CodeAnalyzerExamples/ThisQualifiedAssignments.cs.verified.txt new file mode 100644 index 0000000..e0e0ec2 --- /dev/null +++ b/src/Tests/ACTR007_CodeAnalyzerExamples/ThisQualifiedAssignments.cs.verified.txt @@ -0,0 +1,22 @@ +[ + { + Location: /* + + public ThisQualifiedAssignments(string value) + ^^^^^^^^^^^^^^^^^^^^^^^^ + { +*/ + : (4,11)-(4,35), + Message: Constructor for 'ThisQualifiedAssignments' can be replaced with [AutoConstruct], + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR007, + Title: Use [AutoConstruct] instead of manual constructor, + MessageFormat: Constructor for '{0}' can be replaced with [AutoConstruct], + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/CodeAnalyzerTests.cs b/src/Tests/ACTR007_CodeAnalyzerTests.cs similarity index 87% rename from src/Tests/CodeAnalyzerTests.cs rename to src/Tests/ACTR007_CodeAnalyzerTests.cs index 4eb76f9..035e035 100644 --- a/src/Tests/CodeAnalyzerTests.cs +++ b/src/Tests/ACTR007_CodeAnalyzerTests.cs @@ -3,7 +3,7 @@ using Microsoft.CodeAnalysis.Diagnostics; using static ExampleTestsHelper; -internal sealed class CodeAnalyzerTests +internal sealed class ACTR007_CodeAnalyzerTests { [Test] [CombinedDataSources] @@ -13,7 +13,7 @@ public async Task CheckDiagnostics( CompilationBuilderFactory builderFactory) { var builder = builderFactory.Create(theoryData); - var compilation = builder.Build(nameof(CodeAnalyzerTests)); + var compilation = builder.Build(nameof(ACTR007_CodeAnalyzerTests)); var compilationWithAnalyzers = compilation.WithAnalyzers([new UseAutoConstructAnalyzer()]); @@ -31,7 +31,7 @@ await Verify(diagnostics public static IEnumerable> GetExamples() { - foreach (var codeAnalyzerExample in GetExamplesFiles("CodeAnalyzerExamples")) + foreach (var codeAnalyzerExample in GetExamplesFiles("ACTR007_CodeAnalyzerExamples")) { yield return () => new CodeFileTheoryData(codeAnalyzerExample) with { diff --git a/src/Tests/ACTR007_CodeFixExamples/AbstractClass.cs b/src/Tests/ACTR007_CodeFixExamples/AbstractClass.cs new file mode 100644 index 0000000..287488f --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/AbstractClass.cs @@ -0,0 +1,9 @@ +public abstract class AbstractClass +{ + private readonly string _value; + + public AbstractClass(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/AbstractClass.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/AbstractClass.cs.verified.txt new file mode 100644 index 0000000..49eb8f7 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/AbstractClass.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public abstract partial class AbstractClass +{ + private readonly string _value; +} diff --git a/src/Tests/CodeFixExamples/AlreadyPartial.cs b/src/Tests/ACTR007_CodeFixExamples/AlreadyPartial.cs similarity index 100% rename from src/Tests/CodeFixExamples/AlreadyPartial.cs rename to src/Tests/ACTR007_CodeFixExamples/AlreadyPartial.cs diff --git a/src/Tests/CodeFixExamples/AlreadyPartial.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/AlreadyPartial.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/AlreadyPartial.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/AlreadyPartial.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeFixExamples/AutoCtorAlias.cs b/src/Tests/ACTR007_CodeFixExamples/AutoCtorAlias.cs new file mode 100644 index 0000000..30dd5b8 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/AutoCtorAlias.cs @@ -0,0 +1,11 @@ +using AC = AutoCtor; + +public class AutoCtorAlias +{ + private readonly string _value; + + public AutoCtorAlias(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/AutoCtorAlias.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/AutoCtorAlias.cs.verified.txt new file mode 100644 index 0000000..4193c2b --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/AutoCtorAlias.cs.verified.txt @@ -0,0 +1,7 @@ +using AC = AutoCtor; + +[AutoConstruct] +public partial class AutoCtorAlias +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR007_CodeFixExamples/ConstructorWithXmlDoc.cs b/src/Tests/ACTR007_CodeFixExamples/ConstructorWithXmlDoc.cs new file mode 100644 index 0000000..1ceaaa1 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/ConstructorWithXmlDoc.cs @@ -0,0 +1,10 @@ +public class ConstructorWithXmlDoc +{ + private readonly string _value; + + /// Constructs an instance. + public ConstructorWithXmlDoc(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/ConstructorWithXmlDoc.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/ConstructorWithXmlDoc.cs.verified.txt new file mode 100644 index 0000000..f11dff3 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/ConstructorWithXmlDoc.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public partial class ConstructorWithXmlDoc +{ + private readonly string _value; +} diff --git a/src/Tests/CodeFixExamples/ExistingAttribute.cs b/src/Tests/ACTR007_CodeFixExamples/ExistingAttribute.cs similarity index 100% rename from src/Tests/CodeFixExamples/ExistingAttribute.cs rename to src/Tests/ACTR007_CodeFixExamples/ExistingAttribute.cs diff --git a/src/Tests/CodeFixExamples/ExistingAttribute.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/ExistingAttribute.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/ExistingAttribute.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/ExistingAttribute.cs.verified.txt diff --git a/src/Tests/CodeFixExamples/ExistingAutoConstructAttribute.cs b/src/Tests/ACTR007_CodeFixExamples/ExistingAutoConstructAttribute.cs similarity index 100% rename from src/Tests/CodeFixExamples/ExistingAutoConstructAttribute.cs rename to src/Tests/ACTR007_CodeFixExamples/ExistingAutoConstructAttribute.cs diff --git a/src/Tests/CodeFixExamples/ExistingAutoConstructAttribute.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/ExistingAutoConstructAttribute.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/ExistingAutoConstructAttribute.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/ExistingAutoConstructAttribute.cs.verified.txt diff --git a/src/Tests/CodeFixExamples/ExistingUsingAutoCtor.cs b/src/Tests/ACTR007_CodeFixExamples/ExistingUsingAutoCtor.cs similarity index 100% rename from src/Tests/CodeFixExamples/ExistingUsingAutoCtor.cs rename to src/Tests/ACTR007_CodeFixExamples/ExistingUsingAutoCtor.cs diff --git a/src/Tests/CodeFixExamples/ExistingUsingAutoCtor.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/ExistingUsingAutoCtor.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/ExistingUsingAutoCtor.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/ExistingUsingAutoCtor.cs.verified.txt diff --git a/src/Tests/CodeFixExamples/ExistingUsingGlobalAutoCtor.cs b/src/Tests/ACTR007_CodeFixExamples/ExistingUsingGlobalAutoCtor.cs similarity index 100% rename from src/Tests/CodeFixExamples/ExistingUsingGlobalAutoCtor.cs rename to src/Tests/ACTR007_CodeFixExamples/ExistingUsingGlobalAutoCtor.cs diff --git a/src/Tests/CodeFixExamples/ExistingUsingGlobalAutoCtor.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/ExistingUsingGlobalAutoCtor.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/ExistingUsingGlobalAutoCtor.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/ExistingUsingGlobalAutoCtor.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeFixExamples/FileScopedNamespace.cs b/src/Tests/ACTR007_CodeFixExamples/FileScopedNamespace.cs new file mode 100644 index 0000000..c2a2838 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/FileScopedNamespace.cs @@ -0,0 +1,11 @@ +namespace MyNs; + +public class FileScopedNamespace +{ + private readonly string _value; + + public FileScopedNamespace(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/FileScopedNamespace.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/FileScopedNamespace.cs.verified.txt new file mode 100644 index 0000000..38403b3 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/FileScopedNamespace.cs.verified.txt @@ -0,0 +1,9 @@ +using AutoCtor; + +namespace MyNs; + +[AutoConstruct] +public partial class FileScopedNamespace +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR007_CodeFixExamples/GenericClass.cs b/src/Tests/ACTR007_CodeFixExamples/GenericClass.cs new file mode 100644 index 0000000..020b1df --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/GenericClass.cs @@ -0,0 +1,9 @@ +public class GenericClass +{ + private readonly T _value; + + public GenericClass(T value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/GenericClass.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/GenericClass.cs.verified.txt new file mode 100644 index 0000000..05686bf --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/GenericClass.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public partial class GenericClass +{ + private readonly T _value; +} diff --git a/src/Tests/ACTR007_CodeFixExamples/GenericClassWithConstraints.cs b/src/Tests/ACTR007_CodeFixExamples/GenericClassWithConstraints.cs new file mode 100644 index 0000000..f5ea51b --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/GenericClassWithConstraints.cs @@ -0,0 +1,9 @@ +public class GenericClassWithConstraints where T : class, new() +{ + private readonly T _value; + + public GenericClassWithConstraints(T value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/GenericClassWithConstraints.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/GenericClassWithConstraints.cs.verified.txt new file mode 100644 index 0000000..66b8e2d --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/GenericClassWithConstraints.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public partial class GenericClassWithConstraints where T : class, new() +{ + private readonly T _value; +} diff --git a/src/Tests/ACTR007_CodeFixExamples/InitOnlyProperty.cs b/src/Tests/ACTR007_CodeFixExamples/InitOnlyProperty.cs new file mode 100644 index 0000000..690203e --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/InitOnlyProperty.cs @@ -0,0 +1,9 @@ +public class InitOnlyProperty +{ + public string Value { get; init; } + + public InitOnlyProperty(string value) + { + Value = value; + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/InitOnlyProperty.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/InitOnlyProperty.cs.verified.txt new file mode 100644 index 0000000..5e3fe2e --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/InitOnlyProperty.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public partial class InitOnlyProperty +{ + public string Value { get; init; } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/InternalClass.cs b/src/Tests/ACTR007_CodeFixExamples/InternalClass.cs new file mode 100644 index 0000000..7448740 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/InternalClass.cs @@ -0,0 +1,9 @@ +internal class InternalClass +{ + private readonly string _value; + + public InternalClass(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/InternalClass.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/InternalClass.cs.verified.txt new file mode 100644 index 0000000..3fa01bc --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/InternalClass.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +internal partial class InternalClass +{ + private readonly string _value; +} diff --git a/src/Tests/CodeFixExamples/MixedFieldsAndProperties.cs b/src/Tests/ACTR007_CodeFixExamples/MixedFieldsAndProperties.cs similarity index 100% rename from src/Tests/CodeFixExamples/MixedFieldsAndProperties.cs rename to src/Tests/ACTR007_CodeFixExamples/MixedFieldsAndProperties.cs diff --git a/src/Tests/CodeFixExamples/MixedFieldsAndProperties.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/MixedFieldsAndProperties.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/MixedFieldsAndProperties.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/MixedFieldsAndProperties.cs.verified.txt diff --git a/src/Tests/CodeFixExamples/MultipleConstructors.cs b/src/Tests/ACTR007_CodeFixExamples/MultipleConstructors.cs similarity index 100% rename from src/Tests/CodeFixExamples/MultipleConstructors.cs rename to src/Tests/ACTR007_CodeFixExamples/MultipleConstructors.cs diff --git a/src/Tests/CodeFixExamples/MultipleConstructors.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/MultipleConstructors.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/MultipleConstructors.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/MultipleConstructors.cs.verified.txt diff --git a/src/Tests/CodeFixExamples/MultipleMatchingCtors.cs b/src/Tests/ACTR007_CodeFixExamples/MultipleMatchingCtors.cs similarity index 100% rename from src/Tests/CodeFixExamples/MultipleMatchingCtors.cs rename to src/Tests/ACTR007_CodeFixExamples/MultipleMatchingCtors.cs diff --git a/src/Tests/CodeFixExamples/MultipleMatchingCtors.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/MultipleMatchingCtors.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/MultipleMatchingCtors.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/MultipleMatchingCtors.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeFixExamples/MultipleNamespaces.cs b/src/Tests/ACTR007_CodeFixExamples/MultipleNamespaces.cs new file mode 100644 index 0000000..13fbe9d --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/MultipleNamespaces.cs @@ -0,0 +1,17 @@ +namespace First +{ + public class MultipleNamespaces + { + private readonly string _value; + + public MultipleNamespaces(string value) + { + _value = value; + } + } +} + +namespace Second +{ + public class Other { } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/MultipleNamespaces.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/MultipleNamespaces.cs.verified.txt new file mode 100644 index 0000000..563e792 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/MultipleNamespaces.cs.verified.txt @@ -0,0 +1,15 @@ +using AutoCtor; + +namespace First +{ + [AutoConstruct] + public partial class MultipleNamespaces + { + private readonly string _value; + } +} + +namespace Second +{ + public class Other { } +} diff --git a/src/Tests/CodeFixExamples/MultipleNested.cs b/src/Tests/ACTR007_CodeFixExamples/MultipleNested.cs similarity index 100% rename from src/Tests/CodeFixExamples/MultipleNested.cs rename to src/Tests/ACTR007_CodeFixExamples/MultipleNested.cs diff --git a/src/Tests/CodeFixExamples/MultipleNested.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/MultipleNested.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/MultipleNested.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/MultipleNested.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeFixExamples/MultiplePartialFiles.cs b/src/Tests/ACTR007_CodeFixExamples/MultiplePartialFiles.cs new file mode 100644 index 0000000..3677520 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/MultiplePartialFiles.cs @@ -0,0 +1,14 @@ +public partial class MultiplePartialFiles +{ + private readonly string _value; + + public MultiplePartialFiles(string value) + { + _value = value; + } +} + +public partial class MultiplePartialFiles +{ + public void DoSomething() { } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/MultiplePartialFiles.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/MultiplePartialFiles.cs.verified.txt new file mode 100644 index 0000000..550deb2 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/MultiplePartialFiles.cs.verified.txt @@ -0,0 +1,12 @@ +using AutoCtor; + +[AutoConstruct] +public partial class MultiplePartialFiles +{ + private readonly string _value; +} + +public partial class MultiplePartialFiles +{ + public void DoSomething() { } +} diff --git a/src/Tests/CodeFixExamples/MultipleTypes.cs b/src/Tests/ACTR007_CodeFixExamples/MultipleTypes.cs similarity index 100% rename from src/Tests/CodeFixExamples/MultipleTypes.cs rename to src/Tests/ACTR007_CodeFixExamples/MultipleTypes.cs diff --git a/src/Tests/CodeFixExamples/MultipleTypes.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/MultipleTypes.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/MultipleTypes.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/MultipleTypes.cs.verified.txt diff --git a/src/Tests/CodeFixExamples/Nested.cs b/src/Tests/ACTR007_CodeFixExamples/Nested.cs similarity index 100% rename from src/Tests/CodeFixExamples/Nested.cs rename to src/Tests/ACTR007_CodeFixExamples/Nested.cs diff --git a/src/Tests/CodeFixExamples/Nested.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/Nested.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/Nested.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/Nested.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeFixExamples/NestedInPartialParent.cs b/src/Tests/ACTR007_CodeFixExamples/NestedInPartialParent.cs new file mode 100644 index 0000000..17a6480 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/NestedInPartialParent.cs @@ -0,0 +1,12 @@ +public partial class NestedInPartialParent +{ + public class Child + { + private readonly string _value; + + public Child(string value) + { + _value = value; + } + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/NestedInPartialParent.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/NestedInPartialParent.cs.verified.txt new file mode 100644 index 0000000..49492b0 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/NestedInPartialParent.cs.verified.txt @@ -0,0 +1,10 @@ +using AutoCtor; + +public partial class NestedInPartialParent +{ + [AutoConstruct] + public partial class Child + { + private readonly string _value; + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/NestedNamespace.cs b/src/Tests/ACTR007_CodeFixExamples/NestedNamespace.cs new file mode 100644 index 0000000..fa5a737 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/NestedNamespace.cs @@ -0,0 +1,11 @@ +namespace A.B.C; + +public class NestedNamespace +{ + private readonly string _value; + + public NestedNamespace(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/NestedNamespace.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/NestedNamespace.cs.verified.txt new file mode 100644 index 0000000..68eae26 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/NestedNamespace.cs.verified.txt @@ -0,0 +1,9 @@ +using AutoCtor; + +namespace A.B.C; + +[AutoConstruct] +public partial class NestedNamespace +{ + private readonly string _value; +} diff --git a/src/Tests/CodeFixExamples/NestedNoDeclaredVisibility.cs b/src/Tests/ACTR007_CodeFixExamples/NestedNoDeclaredVisibility.cs similarity index 100% rename from src/Tests/CodeFixExamples/NestedNoDeclaredVisibility.cs rename to src/Tests/ACTR007_CodeFixExamples/NestedNoDeclaredVisibility.cs diff --git a/src/Tests/CodeFixExamples/NestedNoDeclaredVisibility.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/NestedNoDeclaredVisibility.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/NestedNoDeclaredVisibility.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/NestedNoDeclaredVisibility.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeFixExamples/PreprocessorDirectives.cs b/src/Tests/ACTR007_CodeFixExamples/PreprocessorDirectives.cs new file mode 100644 index 0000000..bbb4b5e --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/PreprocessorDirectives.cs @@ -0,0 +1,11 @@ +public class PreprocessorDirectives +{ + private readonly string _value; + +#if !DEBUG + public PreprocessorDirectives(string value) + { + _value = value; + } +#endif +} diff --git a/src/Tests/ACTR007_CodeFixExamples/PreprocessorDirectives.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/PreprocessorDirectives.cs.verified.txt new file mode 100644 index 0000000..915b83f --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/PreprocessorDirectives.cs.verified.txt @@ -0,0 +1,10 @@ +using AutoCtor; + +[AutoConstruct] +public partial class PreprocessorDirectives +{ + private readonly string _value; + +#if !DEBUG +#endif +} diff --git a/src/Tests/CodeFixExamples/RecordExample.cs b/src/Tests/ACTR007_CodeFixExamples/RecordExample.cs similarity index 100% rename from src/Tests/CodeFixExamples/RecordExample.cs rename to src/Tests/ACTR007_CodeFixExamples/RecordExample.cs diff --git a/src/Tests/CodeFixExamples/RecordExample.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/RecordExample.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/RecordExample.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/RecordExample.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeFixExamples/RecordStruct.cs b/src/Tests/ACTR007_CodeFixExamples/RecordStruct.cs new file mode 100644 index 0000000..2e3f32f --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/RecordStruct.cs @@ -0,0 +1,9 @@ +public record struct RecordStruct +{ + private readonly string _value; + + public RecordStruct(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/RecordStruct.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/RecordStruct.cs.verified.txt new file mode 100644 index 0000000..b999ec9 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/RecordStruct.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public partial record struct RecordStruct +{ + private readonly string _value; +} diff --git a/src/Tests/CodeFixExamples/Region.cs b/src/Tests/ACTR007_CodeFixExamples/Region.cs similarity index 100% rename from src/Tests/CodeFixExamples/Region.cs rename to src/Tests/ACTR007_CodeFixExamples/Region.cs diff --git a/src/Tests/CodeFixExamples/Region.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/Region.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/Region.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/Region.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeFixExamples/SealedClass.cs b/src/Tests/ACTR007_CodeFixExamples/SealedClass.cs new file mode 100644 index 0000000..693ab25 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/SealedClass.cs @@ -0,0 +1,9 @@ +public sealed class SealedClass +{ + private readonly string _value; + + public SealedClass(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/SealedClass.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/SealedClass.cs.verified.txt new file mode 100644 index 0000000..a6a65ab --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/SealedClass.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public sealed partial class SealedClass +{ + private readonly string _value; +} diff --git a/src/Tests/CodeFixExamples/StandardExample.cs b/src/Tests/ACTR007_CodeFixExamples/StandardExample.cs similarity index 100% rename from src/Tests/CodeFixExamples/StandardExample.cs rename to src/Tests/ACTR007_CodeFixExamples/StandardExample.cs diff --git a/src/Tests/CodeFixExamples/StandardExample.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/StandardExample.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/StandardExample.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/StandardExample.cs.verified.txt diff --git a/src/Tests/CodeFixExamples/StructExample.cs b/src/Tests/ACTR007_CodeFixExamples/StructExample.cs similarity index 100% rename from src/Tests/CodeFixExamples/StructExample.cs rename to src/Tests/ACTR007_CodeFixExamples/StructExample.cs diff --git a/src/Tests/CodeFixExamples/StructExample.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/StructExample.cs.verified.txt similarity index 100% rename from src/Tests/CodeFixExamples/StructExample.cs.verified.txt rename to src/Tests/ACTR007_CodeFixExamples/StructExample.cs.verified.txt diff --git a/src/Tests/ACTR007_CodeFixExamples/TraditionalNamespace.cs b/src/Tests/ACTR007_CodeFixExamples/TraditionalNamespace.cs new file mode 100644 index 0000000..47a0de2 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/TraditionalNamespace.cs @@ -0,0 +1,12 @@ +namespace MyNs +{ + public class TraditionalNamespace + { + private readonly string _value; + + public TraditionalNamespace(string value) + { + _value = value; + } + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/TraditionalNamespace.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/TraditionalNamespace.cs.verified.txt new file mode 100644 index 0000000..2a621f0 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/TraditionalNamespace.cs.verified.txt @@ -0,0 +1,10 @@ +using AutoCtor; + +namespace MyNs +{ + [AutoConstruct] + public partial class TraditionalNamespace + { + private readonly string _value; + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/WithLeadingTrivia.cs b/src/Tests/ACTR007_CodeFixExamples/WithLeadingTrivia.cs new file mode 100644 index 0000000..15fedeb --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/WithLeadingTrivia.cs @@ -0,0 +1,11 @@ +// Leading line comment. + +public class WithLeadingTrivia +{ + private readonly string _value; + + public WithLeadingTrivia(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/WithLeadingTrivia.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/WithLeadingTrivia.cs.verified.txt new file mode 100644 index 0000000..6012bcd --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/WithLeadingTrivia.cs.verified.txt @@ -0,0 +1,9 @@ +using AutoCtor; + +[AutoConstruct] +// Leading line comment. + +public partial class WithLeadingTrivia +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR007_CodeFixExamples/WithXmlDocComment.cs b/src/Tests/ACTR007_CodeFixExamples/WithXmlDocComment.cs new file mode 100644 index 0000000..3e7c436 --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/WithXmlDocComment.cs @@ -0,0 +1,10 @@ +/// A class with documentation. +public class WithXmlDocComment +{ + private readonly string _value; + + public WithXmlDocComment(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR007_CodeFixExamples/WithXmlDocComment.cs.verified.txt b/src/Tests/ACTR007_CodeFixExamples/WithXmlDocComment.cs.verified.txt new file mode 100644 index 0000000..e6d550f --- /dev/null +++ b/src/Tests/ACTR007_CodeFixExamples/WithXmlDocComment.cs.verified.txt @@ -0,0 +1,8 @@ +using AutoCtor; + +[AutoConstruct] +/// A class with documentation. +public partial class WithXmlDocComment +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR007_CodeFixTests.cs b/src/Tests/ACTR007_CodeFixTests.cs new file mode 100644 index 0000000..852939e --- /dev/null +++ b/src/Tests/ACTR007_CodeFixTests.cs @@ -0,0 +1,54 @@ +using AutoCtor; +using AutoCtor.CodeFixes; +using Tests.Utilities; +using static ExampleTestsHelper; + +internal sealed class ACTR007_CodeFixTests +{ + [Test] + [CombinedDataSources] + public async Task ApplyCodeFix( + [MethodDataSource(nameof(GetExamples))] CodeFileTheoryData theoryData, + [ClassDataSource>(Shared = SharedType.PerTestSession)] + CompilationBuilderFactory builderFactory) + { + var builder = builderFactory.Create(theoryData); + var compilation = builder.Build(nameof(ACTR007_CodeFixTests)); + + var workspaceBuilder = new WorkspaceBuilder() + .WithName(nameof(ACTR007_CodeFixTests)) + .WithReferences(compilation.References); + var documentId = workspaceBuilder.AddDocument(theoryData.ToString(), string.Join(Environment.NewLine, theoryData.Codes)); + + using var workspace = workspaceBuilder.Build(); + + await TestHelper.ApplyCodeFix( + workspace, + documentId, + new UseAutoConstructAnalyzer(), + new UseAutoConstructCodeFixer(), + TestHelper.CancellationToken) + .ConfigureAwait(false); + + var newDocument = workspace.CurrentSolution.GetDocument(documentId)!; + var newText = await newDocument.GetTextAsync(TestHelper.CancellationToken) + .ConfigureAwait(false); + + var verifyText = newText.ToString(); + + await Verify(verifyText) + .UseDirectory(theoryData.VerifiedDirectory) + .UseTypeName(theoryData.Name) + .UseMethodName("cs") + .IgnoreParameters() + .ConfigureAwait(false); + } + + public static IEnumerable> GetExamples() + { + foreach (var codeFixExample in GetExamplesFiles("ACTR007_CodeFixExamples")) + { + yield return () => new CodeFileTheoryData(codeFixExample); + } + } +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/AbstractClass.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/AbstractClass.cs new file mode 100644 index 0000000..0e49ce9 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/AbstractClass.cs @@ -0,0 +1,4 @@ +public abstract class AbstractClass +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/AbstractClass.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/AbstractClass.cs.verified.txt new file mode 100644 index 0000000..f6a29e4 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/AbstractClass.cs.verified.txt @@ -0,0 +1,21 @@ +[ + { + Location: /* +public abstract class AbstractClass + ^^^^^^^^^^^^^ +{ +*/ + : (0,22)-(0,35), + Message: [AutoConstruct] can be added to type 'AbstractClass', + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR008, + Title: Add [AutoConstruct] to type, + MessageFormat: [AutoConstruct] can be added to type '{0}', + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/AllFieldsHaveInitializers.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/AllFieldsHaveInitializers.cs new file mode 100644 index 0000000..4eeccdc --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/AllFieldsHaveInitializers.cs @@ -0,0 +1,5 @@ +public class AllFieldsHaveInitializers +{ + private readonly string _value = "default"; + private readonly int _count = 0; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/AllFieldsHaveInitializers.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/AllFieldsHaveInitializers.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/AllFieldsHaveInitializers.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/AllPropertiesHaveInitializers.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/AllPropertiesHaveInitializers.cs new file mode 100644 index 0000000..5d33cf2 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/AllPropertiesHaveInitializers.cs @@ -0,0 +1,5 @@ +public class AllPropertiesHaveInitializers +{ + public string Value { get; init; } = "default"; + public int Count { get; init; } = 0; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/AllPropertiesHaveInitializers.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/AllPropertiesHaveInitializers.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/AllPropertiesHaveInitializers.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/AlreadyAutoCtor.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/AlreadyAutoCtor.cs new file mode 100644 index 0000000..a621134 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/AlreadyAutoCtor.cs @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public partial class AlreadyAutoCtor +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/AlreadyAutoCtor.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/AlreadyAutoCtor.cs.verified.txt new file mode 100644 index 0000000..ad47dbb --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/AlreadyAutoCtor.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/EmptyClass.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/EmptyClass.cs new file mode 100644 index 0000000..59f543e --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/EmptyClass.cs @@ -0,0 +1,3 @@ +public class EmptyClass +{ +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/EmptyClass.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/EmptyClass.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/EmptyClass.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/EnumType.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/EnumType.cs new file mode 100644 index 0000000..f83e648 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/EnumType.cs @@ -0,0 +1,6 @@ +public enum EnumType +{ + None, + First, + Second, +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/EnumType.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/EnumType.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/EnumType.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/GenericClass.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/GenericClass.cs new file mode 100644 index 0000000..598ad88 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/GenericClass.cs @@ -0,0 +1,4 @@ +public class GenericClass +{ + private readonly T _value; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/GenericClass.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/GenericClass.cs.verified.txt new file mode 100644 index 0000000..aa584b0 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/GenericClass.cs.verified.txt @@ -0,0 +1,21 @@ +[ + { + Location: /* +public class GenericClass + ^^^^^^^^^^^^ +{ +*/ + : (0,13)-(0,25), + Message: [AutoConstruct] can be added to type 'GenericClass', + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR008, + Title: Add [AutoConstruct] to type, + MessageFormat: [AutoConstruct] can be added to type '{0}', + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/HasExplicitConstructor.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/HasExplicitConstructor.cs new file mode 100644 index 0000000..968c1f1 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/HasExplicitConstructor.cs @@ -0,0 +1,9 @@ +public class HasExplicitConstructor +{ + private readonly string _value; + + public HasExplicitConstructor(string value) + { + _value = value; + } +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/HasExplicitConstructor.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/HasExplicitConstructor.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/HasExplicitConstructor.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/HasParameterlessConstructor.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/HasParameterlessConstructor.cs new file mode 100644 index 0000000..0b8d51f --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/HasParameterlessConstructor.cs @@ -0,0 +1,8 @@ +public class HasParameterlessConstructor +{ + private readonly string _value; + + public HasParameterlessConstructor() + { + } +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/HasParameterlessConstructor.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/HasParameterlessConstructor.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/HasParameterlessConstructor.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/InitOnlyProperty.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/InitOnlyProperty.cs new file mode 100644 index 0000000..b40e02b --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/InitOnlyProperty.cs @@ -0,0 +1,4 @@ +public class InitOnlyProperty +{ + public string Value { get; init; } +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/InitOnlyProperty.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/InitOnlyProperty.cs.verified.txt new file mode 100644 index 0000000..72d35fa --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/InitOnlyProperty.cs.verified.txt @@ -0,0 +1,21 @@ +[ + { + Location: /* +public class InitOnlyProperty + ^^^^^^^^^^^^^^^^ +{ +*/ + : (0,13)-(0,29), + Message: [AutoConstruct] can be added to type 'InitOnlyProperty', + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR008, + Title: Add [AutoConstruct] to type, + MessageFormat: [AutoConstruct] can be added to type '{0}', + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/Interface.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/Interface.cs new file mode 100644 index 0000000..5619d6a --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/Interface.cs @@ -0,0 +1,4 @@ +public interface IInterfaceExample +{ + string Value { get; } +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/Interface.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/Interface.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/Interface.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/InternalClass.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/InternalClass.cs new file mode 100644 index 0000000..c72208e --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/InternalClass.cs @@ -0,0 +1,4 @@ +internal class InternalClass +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/InternalClass.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/InternalClass.cs.verified.txt new file mode 100644 index 0000000..74bd2c1 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/InternalClass.cs.verified.txt @@ -0,0 +1,21 @@ +[ + { + Location: /* +internal class InternalClass + ^^^^^^^^^^^^^ +{ +*/ + : (0,15)-(0,28), + Message: [AutoConstruct] can be added to type 'InternalClass', + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR008, + Title: Add [AutoConstruct] to type, + MessageFormat: [AutoConstruct] can be added to type '{0}', + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/MixedFieldsAndProperties.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/MixedFieldsAndProperties.cs new file mode 100644 index 0000000..9ee2e36 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/MixedFieldsAndProperties.cs @@ -0,0 +1,5 @@ +public class MixedFieldsAndProperties +{ + private readonly string _value; + public int Count { get; } +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/MixedFieldsAndProperties.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/MixedFieldsAndProperties.cs.verified.txt new file mode 100644 index 0000000..e946754 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/MixedFieldsAndProperties.cs.verified.txt @@ -0,0 +1,21 @@ +[ + { + Location: /* +public class MixedFieldsAndProperties + ^^^^^^^^^^^^^^^^^^^^^^^^ +{ +*/ + : (0,13)-(0,37), + Message: [AutoConstruct] can be added to type 'MixedFieldsAndProperties', + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR008, + Title: Add [AutoConstruct] to type, + MessageFormat: [AutoConstruct] can be added to type '{0}', + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/NestedClass.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/NestedClass.cs new file mode 100644 index 0000000..e08c0e0 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/NestedClass.cs @@ -0,0 +1,7 @@ +public class NestedClass +{ + public class Inner + { + private readonly string _value; + } +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/NestedClass.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/NestedClass.cs.verified.txt new file mode 100644 index 0000000..b4969b3 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/NestedClass.cs.verified.txt @@ -0,0 +1,22 @@ +[ + { + Location: /* +{ + public class Inner + ^^^^^ + { +*/ + : (2,17)-(2,22), + Message: [AutoConstruct] can be added to type 'Inner', + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR008, + Title: Add [AutoConstruct] to type, + MessageFormat: [AutoConstruct] can be added to type '{0}', + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/NoEligibleMembers.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/NoEligibleMembers.cs new file mode 100644 index 0000000..1b4276e --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/NoEligibleMembers.cs @@ -0,0 +1,4 @@ +public class NoEligibleMembers +{ + public string Value; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/NoEligibleMembers.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/NoEligibleMembers.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/NoEligibleMembers.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyIgnoredMembers.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyIgnoredMembers.cs new file mode 100644 index 0000000..a5b8afc --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyIgnoredMembers.cs @@ -0,0 +1,10 @@ +using AutoCtor; + +public class OnlyIgnoredMembers +{ + [AutoConstructIgnore] + private readonly string _value; + + [AutoConstructIgnore] + private readonly int _count; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyIgnoredMembers.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyIgnoredMembers.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyIgnoredMembers.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyMutableFields.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyMutableFields.cs new file mode 100644 index 0000000..e3f9ac2 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyMutableFields.cs @@ -0,0 +1,5 @@ +public class OnlyMutableFields +{ + private string _value; + private int _count; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyMutableFields.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyMutableFields.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyMutableFields.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyMutableProperties.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyMutableProperties.cs new file mode 100644 index 0000000..9fc1033 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyMutableProperties.cs @@ -0,0 +1,5 @@ +public class OnlyMutableProperties +{ + public string Value { get; set; } + public int Count { get; set; } +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyMutableProperties.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyMutableProperties.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyMutableProperties.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyStaticReadonlyFields.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyStaticReadonlyFields.cs new file mode 100644 index 0000000..9da2bd6 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyStaticReadonlyFields.cs @@ -0,0 +1,5 @@ +public class OnlyStaticReadonlyFields +{ + private static readonly string s_value = "default"; + private static readonly int s_count = 0; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyStaticReadonlyFields.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyStaticReadonlyFields.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/OnlyStaticReadonlyFields.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/PartialClassNoAttribute.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/PartialClassNoAttribute.cs new file mode 100644 index 0000000..53e7043 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/PartialClassNoAttribute.cs @@ -0,0 +1,9 @@ +public partial class PartialClassNoAttribute +{ + private readonly string _value; +} + +public partial class PartialClassNoAttribute +{ + public void DoSomething() { } +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/PartialClassNoAttribute.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/PartialClassNoAttribute.cs.verified.txt new file mode 100644 index 0000000..e8f44a5 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/PartialClassNoAttribute.cs.verified.txt @@ -0,0 +1,41 @@ +[ + { + Location: /* +public partial class PartialClassNoAttribute + ^^^^^^^^^^^^^^^^^^^^^^^ +{ +*/ + : (0,21)-(0,44), + Message: [AutoConstruct] can be added to type 'PartialClassNoAttribute', + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR008, + Title: Add [AutoConstruct] to type, + MessageFormat: [AutoConstruct] can be added to type '{0}', + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + }, + { + Location: /* + +public partial class PartialClassNoAttribute + ^^^^^^^^^^^^^^^^^^^^^^^ +{ +*/ + : (5,21)-(5,44), + Message: [AutoConstruct] can be added to type 'PartialClassNoAttribute', + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR008, + Title: Add [AutoConstruct] to type, + MessageFormat: [AutoConstruct] can be added to type '{0}', + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/PartialsAlreadyAutoCtor.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/PartialsAlreadyAutoCtor.cs new file mode 100644 index 0000000..d948acb --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/PartialsAlreadyAutoCtor.cs @@ -0,0 +1,11 @@ +using AutoCtor; + +[AutoConstruct] +public partial class PartialAlreadyAutoCtor +{ +} + +public partial class PartialAlreadyAutoCtor +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/PartialsAlreadyAutoCtor.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/PartialsAlreadyAutoCtor.cs.verified.txt new file mode 100644 index 0000000..ad47dbb --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/PartialsAlreadyAutoCtor.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/PrimaryConstructor.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/PrimaryConstructor.cs new file mode 100644 index 0000000..ad53aa3 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/PrimaryConstructor.cs @@ -0,0 +1,4 @@ +public class PrimaryConstructor(int value) +{ + private readonly int _value = value; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/PrimaryConstructor.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/PrimaryConstructor.cs.verified.txt new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/PrimaryConstructor.cs.verified.txt @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/RecordClass.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/RecordClass.cs new file mode 100644 index 0000000..3e4fab4 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/RecordClass.cs @@ -0,0 +1,4 @@ +public record class RecordClass +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/RecordClass.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/RecordClass.cs.verified.txt new file mode 100644 index 0000000..89e91e1 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/RecordClass.cs.verified.txt @@ -0,0 +1,21 @@ +[ + { + Location: /* +public record class RecordClass + ^^^^^^^^^^^ +{ +*/ + : (0,20)-(0,31), + Message: [AutoConstruct] can be added to type 'RecordClass', + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR008, + Title: Add [AutoConstruct] to type, + MessageFormat: [AutoConstruct] can be added to type '{0}', + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/RecordStruct.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/RecordStruct.cs new file mode 100644 index 0000000..0b11167 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/RecordStruct.cs @@ -0,0 +1,4 @@ +public record struct RecordStruct +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/RecordStruct.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/RecordStruct.cs.verified.txt new file mode 100644 index 0000000..eec8a40 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/RecordStruct.cs.verified.txt @@ -0,0 +1,21 @@ +[ + { + Location: /* +public record struct RecordStruct + ^^^^^^^^^^^^ +{ +*/ + : (0,21)-(0,33), + Message: [AutoConstruct] can be added to type 'RecordStruct', + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR008, + Title: Add [AutoConstruct] to type, + MessageFormat: [AutoConstruct] can be added to type '{0}', + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/SealedClass.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/SealedClass.cs new file mode 100644 index 0000000..d871dd0 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/SealedClass.cs @@ -0,0 +1,4 @@ +public sealed class SealedClass +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/SealedClass.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/SealedClass.cs.verified.txt new file mode 100644 index 0000000..1788677 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/SealedClass.cs.verified.txt @@ -0,0 +1,21 @@ +[ + { + Location: /* +public sealed class SealedClass + ^^^^^^^^^^^ +{ +*/ + : (0,20)-(0,31), + Message: [AutoConstruct] can be added to type 'SealedClass', + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR008, + Title: Add [AutoConstruct] to type, + MessageFormat: [AutoConstruct] can be added to type '{0}', + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/Standard.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/Standard.cs new file mode 100644 index 0000000..9b4b43e --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/Standard.cs @@ -0,0 +1,4 @@ +public class Standard +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/Standard.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/Standard.cs.verified.txt new file mode 100644 index 0000000..2b875bd --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/Standard.cs.verified.txt @@ -0,0 +1,21 @@ +[ + { + Location: /* +public class Standard + ^^^^^^^^ +{ +*/ + : (0,13)-(0,21), + Message: [AutoConstruct] can be added to type 'Standard', + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR008, + Title: Add [AutoConstruct] to type, + MessageFormat: [AutoConstruct] can be added to type '{0}', + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/Struct.cs b/src/Tests/ACTR008_CodeAnalyzerExamples/Struct.cs new file mode 100644 index 0000000..7ff0573 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/Struct.cs @@ -0,0 +1,4 @@ +public struct Struct +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeAnalyzerExamples/Struct.cs.verified.txt b/src/Tests/ACTR008_CodeAnalyzerExamples/Struct.cs.verified.txt new file mode 100644 index 0000000..17cb941 --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerExamples/Struct.cs.verified.txt @@ -0,0 +1,21 @@ +[ + { + Location: /* +public struct Struct + ^^^^^^ +{ +*/ + : (0,14)-(0,20), + Message: [AutoConstruct] can be added to type 'Struct', + Severity: Info, + WarningLevel: 1, + Descriptor: { + Id: ACTR008, + Title: Add [AutoConstruct] to type, + MessageFormat: [AutoConstruct] can be added to type '{0}', + Category: AutoCtor, + DefaultSeverity: Info, + IsEnabledByDefault: true + } + } +] \ No newline at end of file diff --git a/src/Tests/ACTR008_CodeAnalyzerTests.cs b/src/Tests/ACTR008_CodeAnalyzerTests.cs new file mode 100644 index 0000000..03f60af --- /dev/null +++ b/src/Tests/ACTR008_CodeAnalyzerTests.cs @@ -0,0 +1,46 @@ +using System.Collections.Immutable; +using AutoCtor; +using Microsoft.CodeAnalysis.Diagnostics; +using static ExampleTestsHelper; + +internal sealed class ACTR008_CodeAnalyzerTests +{ + [Test] + [CombinedDataSources] + public async Task CheckDiagnostics( + [MethodDataSource(nameof(GetExamples))] CodeFileTheoryData theoryData, + [ClassDataSource>(Shared = SharedType.PerTestSession)] + CompilationBuilderFactory builderFactory) + { + var builder = builderFactory.Create(theoryData); + var compilation = builder.Build(nameof(ACTR008_CodeAnalyzerTests)); + + var compilationWithAnalyzers = compilation.WithAnalyzers([new AddAutoConstructAnalyzer()]); + + var diagnostics = await compilationWithAnalyzers.GetAllDiagnosticsAsync(TestHelper.CancellationToken) + .ConfigureAwait(false); + + await Verify(diagnostics + .Where(d => !theoryData.IgnoredCompileDiagnostics.Contains(d.Id))) + .UseDirectory(theoryData.VerifiedDirectory) + .UseTypeName(theoryData.Name) + .UseMethodName("cs") + .IgnoreParameters() + .ConfigureAwait(false); + } + + public static IEnumerable> GetExamples() + { + foreach (var codeAnalyzerExample in GetExamplesFiles("ACTR008_CodeAnalyzerExamples")) + { + yield return () => new CodeFileTheoryData(codeAnalyzerExample) with + { + IgnoredCompileDiagnostics = [ + "CS0414", "CS0169", // Ignore unused fields + "CS8618", // Non-null field must be set after exiting constructor + "CS8019" // Unnecessary using directive + ] + }; + } + } +} diff --git a/src/Tests/ACTR008_CodeFixExamples/AbstractClass.cs b/src/Tests/ACTR008_CodeFixExamples/AbstractClass.cs new file mode 100644 index 0000000..0e49ce9 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/AbstractClass.cs @@ -0,0 +1,4 @@ +public abstract class AbstractClass +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/AbstractClass.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/AbstractClass.cs.verified.txt new file mode 100644 index 0000000..49eb8f7 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/AbstractClass.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public abstract partial class AbstractClass +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/AlreadyPartial.cs b/src/Tests/ACTR008_CodeFixExamples/AlreadyPartial.cs new file mode 100644 index 0000000..f33cc0a --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/AlreadyPartial.cs @@ -0,0 +1,4 @@ +public partial class AlreadyPartial +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/AlreadyPartial.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/AlreadyPartial.cs.verified.txt new file mode 100644 index 0000000..63e0765 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/AlreadyPartial.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public partial class AlreadyPartial +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/FileScopedNamespace.cs b/src/Tests/ACTR008_CodeFixExamples/FileScopedNamespace.cs new file mode 100644 index 0000000..ba77e56 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/FileScopedNamespace.cs @@ -0,0 +1,6 @@ +namespace MyNs; + +public class FileScopedNamespace +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/FileScopedNamespace.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/FileScopedNamespace.cs.verified.txt new file mode 100644 index 0000000..38403b3 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/FileScopedNamespace.cs.verified.txt @@ -0,0 +1,9 @@ +using AutoCtor; + +namespace MyNs; + +[AutoConstruct] +public partial class FileScopedNamespace +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/GenericClass.cs b/src/Tests/ACTR008_CodeFixExamples/GenericClass.cs new file mode 100644 index 0000000..598ad88 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/GenericClass.cs @@ -0,0 +1,4 @@ +public class GenericClass +{ + private readonly T _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/GenericClass.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/GenericClass.cs.verified.txt new file mode 100644 index 0000000..05686bf --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/GenericClass.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public partial class GenericClass +{ + private readonly T _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/GenericClassWithConstraints.cs b/src/Tests/ACTR008_CodeFixExamples/GenericClassWithConstraints.cs new file mode 100644 index 0000000..7ced4b5 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/GenericClassWithConstraints.cs @@ -0,0 +1,4 @@ +public class GenericClassWithConstraints where T : class, new() +{ + private readonly T _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/GenericClassWithConstraints.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/GenericClassWithConstraints.cs.verified.txt new file mode 100644 index 0000000..66b8e2d --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/GenericClassWithConstraints.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public partial class GenericClassWithConstraints where T : class, new() +{ + private readonly T _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/InitOnlyProperty.cs b/src/Tests/ACTR008_CodeFixExamples/InitOnlyProperty.cs new file mode 100644 index 0000000..b40e02b --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/InitOnlyProperty.cs @@ -0,0 +1,4 @@ +public class InitOnlyProperty +{ + public string Value { get; init; } +} diff --git a/src/Tests/ACTR008_CodeFixExamples/InitOnlyProperty.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/InitOnlyProperty.cs.verified.txt new file mode 100644 index 0000000..5e3fe2e --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/InitOnlyProperty.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public partial class InitOnlyProperty +{ + public string Value { get; init; } +} diff --git a/src/Tests/ACTR008_CodeFixExamples/InternalClass.cs b/src/Tests/ACTR008_CodeFixExamples/InternalClass.cs new file mode 100644 index 0000000..c72208e --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/InternalClass.cs @@ -0,0 +1,4 @@ +internal class InternalClass +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/InternalClass.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/InternalClass.cs.verified.txt new file mode 100644 index 0000000..3fa01bc --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/InternalClass.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +internal partial class InternalClass +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/MultipleNested.cs b/src/Tests/ACTR008_CodeFixExamples/MultipleNested.cs new file mode 100644 index 0000000..6831014 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/MultipleNested.cs @@ -0,0 +1,10 @@ +public class MultipleNested +{ + public class Parent + { + public class Child + { + private readonly string _value; + } + } +} diff --git a/src/Tests/ACTR008_CodeFixExamples/MultipleNested.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/MultipleNested.cs.verified.txt new file mode 100644 index 0000000..00eb048 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/MultipleNested.cs.verified.txt @@ -0,0 +1,13 @@ +using AutoCtor; + +public partial class MultipleNested +{ + public partial class Parent + { + [AutoConstruct] + public partial class Child + { + private readonly string _value; + } + } +} diff --git a/src/Tests/ACTR008_CodeFixExamples/MultipleTypes.cs b/src/Tests/ACTR008_CodeFixExamples/MultipleTypes.cs new file mode 100644 index 0000000..ee5a658 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/MultipleTypes.cs @@ -0,0 +1,10 @@ +public class TargetType +{ + private readonly string _value; +} + +public class OtherClass { } + +public record OtherRecord { } + +public struct OtherStruct { } diff --git a/src/Tests/ACTR008_CodeFixExamples/MultipleTypes.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/MultipleTypes.cs.verified.txt new file mode 100644 index 0000000..a4fce5c --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/MultipleTypes.cs.verified.txt @@ -0,0 +1,13 @@ +using AutoCtor; + +[AutoConstruct] +public partial class TargetType +{ + private readonly string _value; +} + +public class OtherClass { } + +public record OtherRecord { } + +public struct OtherStruct { } diff --git a/src/Tests/ACTR008_CodeFixExamples/NestedClass.cs b/src/Tests/ACTR008_CodeFixExamples/NestedClass.cs new file mode 100644 index 0000000..3d334ab --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/NestedClass.cs @@ -0,0 +1,7 @@ +public class NestedClass +{ + public class Child + { + private readonly string _value; + } +} diff --git a/src/Tests/ACTR008_CodeFixExamples/NestedClass.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/NestedClass.cs.verified.txt new file mode 100644 index 0000000..bd2ccf6 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/NestedClass.cs.verified.txt @@ -0,0 +1,10 @@ +using AutoCtor; + +public partial class NestedClass +{ + [AutoConstruct] + public partial class Child + { + private readonly string _value; + } +} diff --git a/src/Tests/ACTR008_CodeFixExamples/NestedInPartialParent.cs b/src/Tests/ACTR008_CodeFixExamples/NestedInPartialParent.cs new file mode 100644 index 0000000..e44308d --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/NestedInPartialParent.cs @@ -0,0 +1,7 @@ +public partial class NestedInPartialParent +{ + public class Child + { + private readonly string _value; + } +} diff --git a/src/Tests/ACTR008_CodeFixExamples/NestedInPartialParent.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/NestedInPartialParent.cs.verified.txt new file mode 100644 index 0000000..49492b0 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/NestedInPartialParent.cs.verified.txt @@ -0,0 +1,10 @@ +using AutoCtor; + +public partial class NestedInPartialParent +{ + [AutoConstruct] + public partial class Child + { + private readonly string _value; + } +} diff --git a/src/Tests/ACTR008_CodeFixExamples/RecordClass.cs b/src/Tests/ACTR008_CodeFixExamples/RecordClass.cs new file mode 100644 index 0000000..3e4fab4 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/RecordClass.cs @@ -0,0 +1,4 @@ +public record class RecordClass +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/RecordClass.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/RecordClass.cs.verified.txt new file mode 100644 index 0000000..a86af7e --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/RecordClass.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public partial record class RecordClass +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/RecordStruct.cs b/src/Tests/ACTR008_CodeFixExamples/RecordStruct.cs new file mode 100644 index 0000000..0b11167 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/RecordStruct.cs @@ -0,0 +1,4 @@ +public record struct RecordStruct +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/RecordStruct.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/RecordStruct.cs.verified.txt new file mode 100644 index 0000000..b999ec9 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/RecordStruct.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public partial record struct RecordStruct +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/SealedClass.cs b/src/Tests/ACTR008_CodeFixExamples/SealedClass.cs new file mode 100644 index 0000000..d871dd0 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/SealedClass.cs @@ -0,0 +1,4 @@ +public sealed class SealedClass +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/SealedClass.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/SealedClass.cs.verified.txt new file mode 100644 index 0000000..a6a65ab --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/SealedClass.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public sealed partial class SealedClass +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/Standard.cs b/src/Tests/ACTR008_CodeFixExamples/Standard.cs new file mode 100644 index 0000000..9b4b43e --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/Standard.cs @@ -0,0 +1,4 @@ +public class Standard +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/Standard.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/Standard.cs.verified.txt new file mode 100644 index 0000000..25f633f --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/Standard.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public partial class Standard +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/Struct.cs b/src/Tests/ACTR008_CodeFixExamples/Struct.cs new file mode 100644 index 0000000..7ff0573 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/Struct.cs @@ -0,0 +1,4 @@ +public struct Struct +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/Struct.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/Struct.cs.verified.txt new file mode 100644 index 0000000..3591133 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/Struct.cs.verified.txt @@ -0,0 +1,7 @@ +using AutoCtor; + +[AutoConstruct] +public partial struct Struct +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/TraditionalNamespace.cs b/src/Tests/ACTR008_CodeFixExamples/TraditionalNamespace.cs new file mode 100644 index 0000000..d4c513f --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/TraditionalNamespace.cs @@ -0,0 +1,7 @@ +namespace MyNs +{ + public class TraditionalNamespace + { + private readonly string _value; + } +} diff --git a/src/Tests/ACTR008_CodeFixExamples/TraditionalNamespace.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/TraditionalNamespace.cs.verified.txt new file mode 100644 index 0000000..2a621f0 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/TraditionalNamespace.cs.verified.txt @@ -0,0 +1,10 @@ +using AutoCtor; + +namespace MyNs +{ + [AutoConstruct] + public partial class TraditionalNamespace + { + private readonly string _value; + } +} diff --git a/src/Tests/ACTR008_CodeFixExamples/WithExistingAttribute.cs b/src/Tests/ACTR008_CodeFixExamples/WithExistingAttribute.cs new file mode 100644 index 0000000..0f3b41c --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/WithExistingAttribute.cs @@ -0,0 +1,7 @@ +using System; + +[Serializable] +public class WithExistingAttribute +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/WithExistingAttribute.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/WithExistingAttribute.cs.verified.txt new file mode 100644 index 0000000..d7991a9 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/WithExistingAttribute.cs.verified.txt @@ -0,0 +1,9 @@ +using System; +using AutoCtor; + +[Serializable] +[AutoConstruct] +public partial class WithExistingAttribute +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/WithExistingUsingAutoCtor.cs b/src/Tests/ACTR008_CodeFixExamples/WithExistingUsingAutoCtor.cs new file mode 100644 index 0000000..4582f8c --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/WithExistingUsingAutoCtor.cs @@ -0,0 +1,8 @@ +#pragma warning disable CS8019 // Unnecessary using directive. + +using AutoCtor; + +public class WithExistingUsingAutoCtor +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/WithExistingUsingAutoCtor.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/WithExistingUsingAutoCtor.cs.verified.txt new file mode 100644 index 0000000..64e6621 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/WithExistingUsingAutoCtor.cs.verified.txt @@ -0,0 +1,9 @@ +#pragma warning disable CS8019 // Unnecessary using directive. + +using AutoCtor; + +[AutoConstruct] +public partial class WithExistingUsingAutoCtor +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/WithExistingUsingGlobalAutoCtor.cs b/src/Tests/ACTR008_CodeFixExamples/WithExistingUsingGlobalAutoCtor.cs new file mode 100644 index 0000000..2b4de4c --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/WithExistingUsingGlobalAutoCtor.cs @@ -0,0 +1,8 @@ +#pragma warning disable CS8019 // Unnecessary using directive. + +using global::AutoCtor; + +public class WithExistingUsingGlobalAutoCtor +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/WithExistingUsingGlobalAutoCtor.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/WithExistingUsingGlobalAutoCtor.cs.verified.txt new file mode 100644 index 0000000..1274fed --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/WithExistingUsingGlobalAutoCtor.cs.verified.txt @@ -0,0 +1,9 @@ +#pragma warning disable CS8019 // Unnecessary using directive. + +using global::AutoCtor; + +[AutoConstruct] +public partial class WithExistingUsingGlobalAutoCtor +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/WithLeadingTrivia.cs b/src/Tests/ACTR008_CodeFixExamples/WithLeadingTrivia.cs new file mode 100644 index 0000000..c5d2e7c --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/WithLeadingTrivia.cs @@ -0,0 +1,6 @@ +// Leading line comment. + +public class WithLeadingTrivia +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/WithLeadingTrivia.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/WithLeadingTrivia.cs.verified.txt new file mode 100644 index 0000000..6012bcd --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/WithLeadingTrivia.cs.verified.txt @@ -0,0 +1,9 @@ +using AutoCtor; + +[AutoConstruct] +// Leading line comment. + +public partial class WithLeadingTrivia +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/WithXmlDocComment.cs b/src/Tests/ACTR008_CodeFixExamples/WithXmlDocComment.cs new file mode 100644 index 0000000..05f1300 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/WithXmlDocComment.cs @@ -0,0 +1,5 @@ +/// A class with documentation. +public class WithXmlDocComment +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixExamples/WithXmlDocComment.cs.verified.txt b/src/Tests/ACTR008_CodeFixExamples/WithXmlDocComment.cs.verified.txt new file mode 100644 index 0000000..e6d550f --- /dev/null +++ b/src/Tests/ACTR008_CodeFixExamples/WithXmlDocComment.cs.verified.txt @@ -0,0 +1,8 @@ +using AutoCtor; + +[AutoConstruct] +/// A class with documentation. +public partial class WithXmlDocComment +{ + private readonly string _value; +} diff --git a/src/Tests/ACTR008_CodeFixTests.cs b/src/Tests/ACTR008_CodeFixTests.cs new file mode 100644 index 0000000..1e4e1c1 --- /dev/null +++ b/src/Tests/ACTR008_CodeFixTests.cs @@ -0,0 +1,54 @@ +using AutoCtor; +using AutoCtor.CodeFixes; +using Tests.Utilities; +using static ExampleTestsHelper; + +internal sealed class ACTR008_CodeFixTests +{ + [Test] + [CombinedDataSources] + public async Task ApplyCodeFix( + [MethodDataSource(nameof(GetExamples))] CodeFileTheoryData theoryData, + [ClassDataSource>(Shared = SharedType.PerTestSession)] + CompilationBuilderFactory builderFactory) + { + var builder = builderFactory.Create(theoryData); + var compilation = builder.Build(nameof(ACTR008_CodeFixTests)); + + var workspaceBuilder = new WorkspaceBuilder() + .WithName(nameof(ACTR008_CodeFixTests)) + .WithReferences(compilation.References); + var documentId = workspaceBuilder.AddDocument(theoryData.ToString(), string.Join(Environment.NewLine, theoryData.Codes)); + + using var workspace = workspaceBuilder.Build(); + + await TestHelper.ApplyCodeFix( + workspace, + documentId, + new AddAutoConstructAnalyzer(), + new AddAutoConstructCodeFixer(), + TestHelper.CancellationToken) + .ConfigureAwait(false); + + var newDocument = workspace.CurrentSolution.GetDocument(documentId)!; + var newText = await newDocument.GetTextAsync(TestHelper.CancellationToken) + .ConfigureAwait(false); + + var verifyText = newText.ToString(); + + await Verify(verifyText) + .UseDirectory(theoryData.VerifiedDirectory) + .UseTypeName(theoryData.Name) + .UseMethodName("cs") + .IgnoreParameters() + .ConfigureAwait(false); + } + + public static IEnumerable> GetExamples() + { + foreach (var codeFixExample in GetExamplesFiles("ACTR008_CodeFixExamples")) + { + yield return () => new CodeFileTheoryData(codeFixExample); + } + } +} diff --git a/src/Tests/CodeFixTests.cs b/src/Tests/CodeFixTests.cs deleted file mode 100644 index dd30460..0000000 --- a/src/Tests/CodeFixTests.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System.Collections.Immutable; -using AutoCtor; -using AutoCtor.CodeFixes; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CodeActions; -using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.Diagnostics; -using static ExampleTestsHelper; - -internal sealed class CodeFixTests -{ - [Test] - [CombinedDataSources] - public async Task ApplyCodeFix( - [MethodDataSource(nameof(GetExamples))] CodeFileTheoryData theoryData, - [ClassDataSource>(Shared = SharedType.PerTestSession)] - CompilationBuilderFactory builderFactory) - { - var builder = builderFactory.Create(theoryData); - var compilation = builder.Build(nameof(CodeFixTests)); - var fixer = new UseAutoConstructCodeFixer(); - - using var workspace = new AdhocWorkspace(); - - var projectId = ProjectId.CreateNewId(); - var documentId = DocumentId.CreateNewId(projectId); - var solution = workspace.CurrentSolution - .AddProject(projectId, nameof(CodeFixTests), nameof(CodeFixTests), LanguageNames.CSharp); - foreach (var reference in compilation.References) - solution = solution.AddMetadataReference(projectId, reference); - solution = solution.AddDocument(documentId, theoryData.ToString(), - string.Join(Environment.NewLine, theoryData.Codes)); - workspace.TryApplyChanges(solution); - - while (true) - { - var currentDocument = workspace.CurrentSolution.GetDocument(documentId)!; - var currentCompilation = await currentDocument.Project - .GetCompilationAsync(TestHelper.CancellationToken) - .ConfigureAwait(false); - var withAnalyzers = currentCompilation!.WithAnalyzers([new UseAutoConstructAnalyzer()]); - var allDiagnostics = await withAnalyzers - .GetAllDiagnosticsAsync(TestHelper.CancellationToken) - .ConfigureAwait(false); - var diagnostics = allDiagnostics.Where(d => d.Id == "ACTR007").ToImmutableArray(); - - if (diagnostics.IsEmpty) - break; - - var diagnostic = diagnostics[0]; - var actions = new List(); - var fixContext = new CodeFixContext( - currentDocument, - diagnostic, - (action, _) => actions.Add(action), - TestHelper.CancellationToken); - - await fixer.RegisterCodeFixesAsync(fixContext) - .ConfigureAwait(false); - - var changed = false; - foreach (var action in actions) - { - var operations = await action.GetOperationsAsync(TestHelper.CancellationToken) - .ConfigureAwait(false); - foreach (var applyOp in operations.OfType()) - { - applyOp.Apply(workspace, TestHelper.CancellationToken); - changed = true; - } - } - - if (!changed) - break; - } - - var newDocument = workspace.CurrentSolution.GetDocument(documentId)!; - var newText = await newDocument.GetTextAsync(TestHelper.CancellationToken) - .ConfigureAwait(false); - - var verifyText = string.Join(Environment.NewLine, newText); - - await Verify(verifyText) - .UseDirectory(theoryData.VerifiedDirectory) - .UseTypeName(theoryData.Name) - .UseMethodName("cs") - .IgnoreParameters() - .ConfigureAwait(false); - } - - public static IEnumerable> GetExamples() - { - foreach (var codeFixExample in GetExamplesFiles("CodeFixExamples")) - { - yield return () => new CodeFileTheoryData(codeFixExample); - } - } -} diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 174c12f..47b4e67 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -32,15 +32,19 @@ + + + + - - + + + + - - diff --git a/src/Tests/Utilities/TestHelper.cs b/src/Tests/Utilities/TestHelper.cs index 9419a21..7357219 100644 --- a/src/Tests/Utilities/TestHelper.cs +++ b/src/Tests/Utilities/TestHelper.cs @@ -1,5 +1,9 @@ -using System.Runtime.CompilerServices; +using System.Collections.Immutable; +using System.Runtime.CompilerServices; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Diagnostics; using TUnit.Assertions.Core; internal static class TestHelper @@ -13,4 +17,56 @@ internal static class TestHelper { return assertion.AssertAsync().ConfigureAwait(continueOnCapturedContext); } + + public static async Task ApplyCodeFix( + Workspace workspace, + DocumentId documentId, + DiagnosticAnalyzer diagnosticAnalyzer, + CodeFixProvider fixer, + CancellationToken cancellation = default) + { + var diagnosticIds = diagnosticAnalyzer.SupportedDiagnostics.Select(x => x.Id).ToImmutableArray(); + + while (true) + { + var currentDocument = workspace.CurrentSolution.GetDocument(documentId)!; + var currentCompilation = await currentDocument.Project + .GetCompilationAsync(cancellation) + .ConfigureAwait(false); + var withAnalyzers = currentCompilation!.WithAnalyzers([diagnosticAnalyzer]); + var allDiagnostics = await withAnalyzers + .GetAllDiagnosticsAsync(cancellation) + .ConfigureAwait(false); + var diagnostics = allDiagnostics.Where(d => diagnosticIds.Contains(d.Id)).ToImmutableArray(); + + if (diagnostics.IsEmpty) + break; + + var diagnostic = diagnostics[0]; + var actions = new List(); + var fixContext = new CodeFixContext( + currentDocument, + diagnostic, + (action, _) => actions.Add(action), + cancellation); + + await fixer.RegisterCodeFixesAsync(fixContext) + .ConfigureAwait(false); + + var changed = false; + foreach (var action in actions) + { + var operations = await action.GetOperationsAsync(cancellation) + .ConfigureAwait(false); + foreach (var applyOp in operations.OfType()) + { + applyOp.Apply(workspace, cancellation); + changed = true; + } + } + + if (!changed) + break; + } + } } diff --git a/src/Tests/Utilities/WorkspaceBuilder.cs b/src/Tests/Utilities/WorkspaceBuilder.cs new file mode 100644 index 0000000..999a35d --- /dev/null +++ b/src/Tests/Utilities/WorkspaceBuilder.cs @@ -0,0 +1,66 @@ +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; + +namespace Tests.Utilities; + +internal sealed class WorkspaceBuilder +{ + private ImmutableArray _references; + private ImmutableArray<(DocumentId DocumentId, string Name, string Text)> _documents; + + private string _name; + private ProjectId _projectId; + + public WorkspaceBuilder() + { + _references = []; + _documents = []; + _name = string.Empty; + _projectId = ProjectId.CreateNewId(); + } + + public WorkspaceBuilder(WorkspaceBuilder other) + { + _references = other._references; + _documents = other._documents; + _name = other._name; + _projectId = other._projectId; + } + + public Workspace Build() + { + var workspace = new AdhocWorkspace(); + + var solution = workspace.CurrentSolution + .AddProject(_projectId, _name, _name, LanguageNames.CSharp); + solution = solution.AddMetadataReferences(_projectId, _references); + foreach (var doc in _documents) + solution = solution.AddDocument(doc.DocumentId, doc.Name, doc.Text); + workspace.TryApplyChanges(solution); + + return workspace; + } + + public WorkspaceBuilder WithName(string name) + { + return new(this) + { + _name = name + }; + } + + public WorkspaceBuilder WithReferences(IEnumerable references) + { + return new(this) + { + _references = references.ToImmutableArray() + }; + } + + public DocumentId AddDocument(string name, string text) + { + var documentId = DocumentId.CreateNewId(_projectId); + _documents = _documents.Add(new(documentId, name, text)); + return documentId; + } +}