diff --git a/src/Unitverse.Core.Tests/Resources/PrimaryConstructor.txt b/src/Unitverse.Core.Tests/Resources/PrimaryConstructor.txt new file mode 100644 index 0000000..ac96c74 --- /dev/null +++ b/src/Unitverse.Core.Tests/Resources/PrimaryConstructor.txt @@ -0,0 +1,3 @@ +namespace TestNamespace.SubNameSpace; + +public class RequestHandler(string options) { private readonly string _options = options; } \ No newline at end of file diff --git a/src/Unitverse.Core.Tests/TestClasses.Designer.cs b/src/Unitverse.Core.Tests/TestClasses.Designer.cs index 07907dd..3813f55 100644 --- a/src/Unitverse.Core.Tests/TestClasses.Designer.cs +++ b/src/Unitverse.Core.Tests/TestClasses.Designer.cs @@ -1534,7 +1534,8 @@ public static string NullableReferenceTypes { } /// - /// Looks up a localized string similar to using System; + /// Looks up a localized string similar to // # UseSeparateChecksForNullAndEmpty=true + /// ///using System.Collections.Generic; ///using System.Text; /// @@ -1544,14 +1545,14 @@ public static string NullableReferenceTypes { /// { /// public NullOrWhitespace(string argumentOne, string argumentTwo) /// { - /// ArgumentException.ThrowIfNullOrWhiteSpace(argumentOne); - /// ArgumentException.ThrowIfNullOrWhiteSpace(argumentTwo); /// } /// - /// public int MethodOne(string argumentOne) + /// public void MethodOne(string argumentOne) /// { - /// ArgumentException.ThrowIfNullOrWhiteSpace(argumentOne); - /// [rest of string was truncated]";. + /// } + /// } + ///} + ///. /// public static string NullOrWhiteSpaceSeparation { get { @@ -1741,6 +1742,15 @@ public static string PocoInitialization { } } + /// + /// Looks up a localized string similar to public class RequestHandler(IOptions<CommonOptions> options) { private readonly CommonOptions _options = options.Value!; }. + /// + public static string PrimaryConstructor { + get { + return ResourceManager.GetString("PrimaryConstructor", resourceCulture); + } + } + /// /// Looks up a localized string similar to using System.ComponentModel; ///using System.Windows.Media; diff --git a/src/Unitverse.Core.Tests/TestClasses.resx b/src/Unitverse.Core.Tests/TestClasses.resx index cd4cb84..4b060ab 100644 --- a/src/Unitverse.Core.Tests/TestClasses.resx +++ b/src/Unitverse.Core.Tests/TestClasses.resx @@ -295,6 +295,9 @@ Resources\PocoInitialization.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + Resources\PrimaryConstructor.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + Resources\PropertyChangeTestFile.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 diff --git a/src/Unitverse.Core.Tests/UnitTestGeneratorTests.cs b/src/Unitverse.Core.Tests/UnitTestGeneratorTests.cs index 9b18c65..a4f24a7 100644 --- a/src/Unitverse.Core.Tests/UnitTestGeneratorTests.cs +++ b/src/Unitverse.Core.Tests/UnitTestGeneratorTests.cs @@ -75,7 +75,7 @@ public static IEnumerable TestClassResourceNames var mocks = new object[] { MockingFrameworkType.Moq, MockingFrameworkType.NSubstitute, MockingFrameworkType.FakeItEasy, MockingFrameworkType.MoqAutoMock, MockingFrameworkType.JustMock }; #if VS2019 - entryKeys = entryKeys.Where(x => x.IndexOf("FileScoped", StringComparison.OrdinalIgnoreCase) < 0).ToList(); + entryKeys = entryKeys.Where(x => x.IndexOf("FileScoped", StringComparison.OrdinalIgnoreCase) < 0 && x.IndexOf("PrimaryConstructor", StringComparison.OrdinalIgnoreCase) < 0).ToList(); #endif var baseSet = entryKeys.Select(x => new List { x }); diff --git a/src/Unitverse.Core.Tests/Unitverse.Core.Tests.csproj b/src/Unitverse.Core.Tests/Unitverse.Core.Tests.csproj index 611db3d..b81e867 100644 --- a/src/Unitverse.Core.Tests/Unitverse.Core.Tests.csproj +++ b/src/Unitverse.Core.Tests/Unitverse.Core.Tests.csproj @@ -20,7 +20,7 @@ - + diff --git a/src/Unitverse.Core/Frameworks/Test/BaseTestFramework.cs b/src/Unitverse.Core/Frameworks/Test/BaseTestFramework.cs index 85581d9..6f7f393 100644 --- a/src/Unitverse.Core/Frameworks/Test/BaseTestFramework.cs +++ b/src/Unitverse.Core/Frameworks/Test/BaseTestFramework.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; + using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Unitverse.Core.Helpers; @@ -41,7 +42,7 @@ IEnumerable Elements() yield return XmlCommentHelper.Param(parameterName, parameterDescription); } - if (method.Modifiers.Any(x => x.Kind() == SyntaxKind.AsyncKeyword)) + if (method.Modifiers.Any(x => x.IsKind(SyntaxKind.AsyncKeyword))) { yield return XmlCommentHelper.Returns("A task that represents the running test."); } diff --git a/src/Unitverse.Core/Generation/CategorizedUsings.cs b/src/Unitverse.Core/Generation/CategorizedUsings.cs index cf4a4ce..91bbad6 100644 --- a/src/Unitverse.Core/Generation/CategorizedUsings.cs +++ b/src/Unitverse.Core/Generation/CategorizedUsings.cs @@ -64,18 +64,18 @@ public List GetResolvedUsingDirectives() { var resolvedUsings = new List(); - resolvedUsings.AddRange(_systemUsings.OrderBy(x => x.Name.ToString())); - resolvedUsings.AddRange(_nonSystemUsings.OrderBy(x => x.Name.ToString())); + resolvedUsings.AddRange(_systemUsings.OrderBy(x => x.Name?.ToString())); + resolvedUsings.AddRange(_nonSystemUsings.OrderBy(x => x.Name?.ToString())); resolvedUsings.AddRange(_aliasUsings.OrderBy(x => x.Alias?.ToString())); - resolvedUsings.AddRange(_staticSystemUsings.OrderBy(x => x.Name.ToString())); - resolvedUsings.AddRange(_staticNonSystemUsings.OrderBy(x => x.Name.ToString())); + resolvedUsings.AddRange(_staticSystemUsings.OrderBy(x => x.Name?.ToString())); + resolvedUsings.AddRange(_staticNonSystemUsings.OrderBy(x => x.Name?.ToString())); return resolvedUsings; } private static bool IsSystemUsing(UsingDirectiveSyntax usingDirective) { - var name = usingDirective.Name.ToString(); + var name = usingDirective.Name?.ToString(); return string.Equals(name, nameof(System), StringComparison.OrdinalIgnoreCase) || name.StartsWith(nameof(System) + ".", StringComparison.OrdinalIgnoreCase); } diff --git a/src/Unitverse.Core/Helpers/Generate.cs b/src/Unitverse.Core/Helpers/Generate.cs index b77d6f1..85742ee 100644 --- a/src/Unitverse.Core/Helpers/Generate.cs +++ b/src/Unitverse.Core/Helpers/Generate.cs @@ -241,7 +241,7 @@ public static ExpressionSyntax MethodCall( throw new ArgumentNullException(nameof(name)); } - if (method.ParameterList.Parameters.Count > 0 && method.ParameterList.Parameters[0].Modifiers.Any(x => x.Kind() == SyntaxKind.ThisKeyword) && arguments.Length > 0 && arguments[0] is ExpressionSyntax expression) + if (method.ParameterList.Parameters.Count > 0 && method.ParameterList.Parameters[0].Modifiers.Any(x => x.IsKind(SyntaxKind.ThisKeyword)) && arguments.Length > 0 && arguments[0] is ExpressionSyntax expression) { target = expression; arguments = arguments.Skip(1).ToArray(); diff --git a/src/Unitverse.Core/Helpers/NameExtractor.cs b/src/Unitverse.Core/Helpers/NameExtractor.cs index 6e67ef0..883f28a 100644 --- a/src/Unitverse.Core/Helpers/NameExtractor.cs +++ b/src/Unitverse.Core/Helpers/NameExtractor.cs @@ -17,7 +17,7 @@ public static string GetClassName(this TypeDeclarationSyntax declaration) throw new ArgumentNullException(nameof(declaration)); } - var classIdentifierToken = declaration.ChildTokens().FirstOrDefault(n => n.Kind() == SyntaxKind.IdentifierToken); + var classIdentifierToken = declaration.ChildTokens().FirstOrDefault(n => n.IsKind(SyntaxKind.IdentifierToken)); if (classIdentifierToken == default(SyntaxToken)) { throw new InvalidOperationException(Strings.NameExtractor_GetClassName_Could_not_find_type_identifier_); diff --git a/src/Unitverse.Core/Helpers/TestableItemExtractor.cs b/src/Unitverse.Core/Helpers/TestableItemExtractor.cs index 7352400..21d6a35 100644 --- a/src/Unitverse.Core/Helpers/TestableItemExtractor.cs +++ b/src/Unitverse.Core/Helpers/TestableItemExtractor.cs @@ -144,6 +144,15 @@ private ClassModel ExtractClassModel(TypeDeclarationSyntax syntax, SemanticModel } } } +#if VS2022 + else if (syntax.ParameterList != null) + { + var constructor = SyntaxFactory.ConstructorDeclaration(model.ClassName).WithParameterList(syntax.ParameterList); + var parameters = ExtractParameters(syntax.ParameterList.Parameters, semanticModel); + + model.Constructors.Add(new ConstructorModel(model.ClassName, parameters, constructor)); + } +#endif foreach (var methodModel in syntax.ChildNodes().OfType().Where(x => x.ExplicitInterfaceSpecifier != null).Select(x => ExtractMethodModel(x, semanticModel))) { @@ -163,7 +172,7 @@ private ClassModel ExtractClassModel(TypeDeclarationSyntax syntax, SemanticModel private void CollectRelatedPartialTypeConstructors(TypeDeclarationSyntax syntax, SemanticModel semanticModel, IList> allowedModifiers, ClassModel model) { - if (!syntax.Modifiers.Any(x => x.Kind() == SyntaxKind.PartialKeyword)) + if (!syntax.Modifiers.Any(x => x.IsKind(SyntaxKind.PartialKeyword))) { return; } diff --git a/src/Unitverse.Core/Strategies/ClassLevelGeneration/CanConstructNoConstructorGenerationStrategy.cs b/src/Unitverse.Core/Strategies/ClassLevelGeneration/CanConstructNoConstructorGenerationStrategy.cs index 98f1e2f..1b05c3c 100644 --- a/src/Unitverse.Core/Strategies/ClassLevelGeneration/CanConstructNoConstructorGenerationStrategy.cs +++ b/src/Unitverse.Core/Strategies/ClassLevelGeneration/CanConstructNoConstructorGenerationStrategy.cs @@ -36,8 +36,11 @@ public bool CanHandle(ClassModel method, ClassModel model) { throw new ArgumentNullException(nameof(model)); } - +#if VS2022 + return !model.Declaration.ChildNodes().OfType().Any() && !(model.Declaration is RecordDeclarationSyntax) && model.Declaration.ParameterList is null && !model.IsStatic; +#else return !model.Declaration.ChildNodes().OfType().Any() && !(model.Declaration is RecordDeclarationSyntax) && !model.IsStatic; +#endif } public IEnumerable Create(ClassModel method, ClassModel model, NamingContext namingContext) diff --git a/src/Unitverse.Core/Strategies/ClassLevelGeneration/CanConstructSingleConstructorGenerationStrategy.cs b/src/Unitverse.Core/Strategies/ClassLevelGeneration/CanConstructSingleConstructorGenerationStrategy.cs index 5af4c40..3a55e09 100644 --- a/src/Unitverse.Core/Strategies/ClassLevelGeneration/CanConstructSingleConstructorGenerationStrategy.cs +++ b/src/Unitverse.Core/Strategies/ClassLevelGeneration/CanConstructSingleConstructorGenerationStrategy.cs @@ -43,7 +43,7 @@ public bool CanHandle(ClassModel method, ClassModel model) return false; } - if (model.Declaration.ChildNodes().OfType().Count() == 1 && model.DefaultConstructor.Node.Modifiers.Any(x => x.Kind() == SyntaxKind.PublicKeyword)) + if (model.Declaration.ChildNodes().OfType().Count() == 1 && model.DefaultConstructor.Node.Modifiers.Any(x => x.IsKind(SyntaxKind.PublicKeyword))) { return true; } diff --git a/src/Unitverse.Core/Strategies/MethodGeneration/CanCallMethodGenerationStrategy.cs b/src/Unitverse.Core/Strategies/MethodGeneration/CanCallMethodGenerationStrategy.cs index cf81b61..0f81e57 100644 --- a/src/Unitverse.Core/Strategies/MethodGeneration/CanCallMethodGenerationStrategy.cs +++ b/src/Unitverse.Core/Strategies/MethodGeneration/CanCallMethodGenerationStrategy.cs @@ -68,7 +68,7 @@ public IEnumerable Create(IMethodModel method, ClassMode foreach (var parameter in method.Parameters) { - if (parameter.Node.Modifiers.Any(x => x.Kind() == SyntaxKind.OutKeyword)) + if (parameter.Node.Modifiers.Any(x => x.IsKind(SyntaxKind.OutKeyword))) { paramExpressions.Add(SyntaxFactory.Argument(SyntaxFactory.DeclarationExpression(SyntaxFactory.IdentifierName("var"), SyntaxFactory.SingleVariableDesignation(parameter.Identifier))).WithRefKindKeyword(SyntaxFactory.Token(SyntaxKind.OutKeyword))); } @@ -89,7 +89,7 @@ public IEnumerable Create(IMethodModel method, ClassMode generatedMethod.Arrange(Generate.VariableDeclaration(parameter.TypeInfo.Type, _frameworkSet, paramName, defaultAssignmentValue)); } - if (parameter.Node.Modifiers.Any(x => x.Kind() == SyntaxKind.RefKeyword)) + if (parameter.Node.Modifiers.Any(x => x.IsKind(SyntaxKind.RefKeyword))) { paramExpressions.Add(SyntaxFactory.Argument(paramIdentifier).WithRefKindKeyword(SyntaxFactory.Token(SyntaxKind.RefKeyword))); } diff --git a/src/Unitverse.Core/Strategies/MethodGeneration/MappingMethodGenerationStrategy.cs b/src/Unitverse.Core/Strategies/MethodGeneration/MappingMethodGenerationStrategy.cs index 2ce3bd6..36a32af 100644 --- a/src/Unitverse.Core/Strategies/MethodGeneration/MappingMethodGenerationStrategy.cs +++ b/src/Unitverse.Core/Strategies/MethodGeneration/MappingMethodGenerationStrategy.cs @@ -108,7 +108,7 @@ public IEnumerable Create(IMethodModel method, ClassMode foreach (var parameter in method.Parameters) { - if (parameter.Node.Modifiers.Any(x => x.Kind() == SyntaxKind.OutKeyword)) + if (parameter.Node.Modifiers.Any(x => x.IsKind(SyntaxKind.OutKeyword))) { paramExpressions.Add(SyntaxFactory.Argument(SyntaxFactory.DeclarationExpression(SyntaxFactory.IdentifierName("var"), SyntaxFactory.SingleVariableDesignation(parameter.Identifier))).WithRefKindKeyword(SyntaxFactory.Token(SyntaxKind.OutKeyword))); } @@ -121,7 +121,7 @@ public IEnumerable Create(IMethodModel method, ClassMode generatedMethod.Arrange(Generate.VariableDeclaration(parameter.TypeInfo.Type, _frameworkSet, parameter.Name, defaultAssignmentValue)); } - if (parameter.Node.Modifiers.Any(x => x.Kind() == SyntaxKind.RefKeyword)) + if (parameter.Node.Modifiers.Any(x => x.IsKind(SyntaxKind.RefKeyword))) { paramExpressions.Add(SyntaxFactory.Argument(SyntaxFactory.IdentifierName(parameter.Name)).WithRefKindKeyword(SyntaxFactory.Token(SyntaxKind.RefKeyword))); } diff --git a/src/Unitverse.Core/Strategies/MethodGeneration/NullParameterCheckMethodGenerationStrategy.cs b/src/Unitverse.Core/Strategies/MethodGeneration/NullParameterCheckMethodGenerationStrategy.cs index 3998f78..7a7a6b3 100644 --- a/src/Unitverse.Core/Strategies/MethodGeneration/NullParameterCheckMethodGenerationStrategy.cs +++ b/src/Unitverse.Core/Strategies/MethodGeneration/NullParameterCheckMethodGenerationStrategy.cs @@ -65,7 +65,7 @@ public IEnumerable Create(IMethodModel method, ClassMode continue; } - if (currentParam.Node.Modifiers.Any(x => x.Kind() == SyntaxKind.OutKeyword)) + if (currentParam.Node.Modifiers.Any(x => x.IsKind(SyntaxKind.OutKeyword))) { continue; } @@ -83,7 +83,7 @@ public IEnumerable Create(IMethodModel method, ClassMode for (var index = 0; index < method.Parameters.Count; index++) { var parameter = method.Parameters[index]; - if (parameter.Node.Modifiers.Any(x => x.Kind() == SyntaxKind.RefKeyword)) + if (parameter.Node.Modifiers.Any(x => x.IsKind(SyntaxKind.RefKeyword))) { var defaultAssignmentValue = AssignmentValueHelper.GetDefaultAssignmentValue(parameter.TypeInfo, model.SemanticModel, _frameworkSet); @@ -99,7 +99,7 @@ public IEnumerable Create(IMethodModel method, ClassMode paramList.Add(SyntaxFactory.Argument(SyntaxFactory.IdentifierName(parameter.Name)).WithRefKindKeyword(SyntaxFactory.Token(SyntaxKind.RefKeyword))); } - else if (parameter.Node.Modifiers.Any(x => x.Kind() == SyntaxKind.OutKeyword)) + else if (parameter.Node.Modifiers.Any(x => x.IsKind(SyntaxKind.OutKeyword))) { paramList.Add(SyntaxFactory.Argument(SyntaxFactory.IdentifierName("_")).WithRefKindKeyword(SyntaxFactory.Token(SyntaxKind.OutKeyword))); } diff --git a/src/Unitverse.Core/Strategies/MethodGeneration/StringParameterCheckMethodGenerationStrategy.cs b/src/Unitverse.Core/Strategies/MethodGeneration/StringParameterCheckMethodGenerationStrategy.cs index bdcf804..23a0fc2 100644 --- a/src/Unitverse.Core/Strategies/MethodGeneration/StringParameterCheckMethodGenerationStrategy.cs +++ b/src/Unitverse.Core/Strategies/MethodGeneration/StringParameterCheckMethodGenerationStrategy.cs @@ -65,7 +65,7 @@ public IEnumerable Create(IMethodModel method, ClassMode continue; } - if (currentParam.Node.Modifiers.Any(x => x.Kind() == SyntaxKind.OutKeyword)) + if (currentParam.Node.Modifiers.Any(x => x.IsKind(SyntaxKind.OutKeyword))) { continue; } @@ -115,7 +115,7 @@ private void AddMethodBody(IMethodModel method, ClassModel model, int parameterI for (var index = 0; index < method.Parameters.Count; index++) { var parameter = method.Parameters[index]; - if (parameter.Node.Modifiers.Any(x => x.Kind() == SyntaxKind.RefKeyword)) + if (parameter.Node.Modifiers.Any(x => x.IsKind(SyntaxKind.RefKeyword))) { var defaultAssignmentValue = AssignmentValueHelper.GetDefaultAssignmentValue(parameter.TypeInfo, model.SemanticModel, _frameworkSet); @@ -131,7 +131,7 @@ private void AddMethodBody(IMethodModel method, ClassModel model, int parameterI paramList.Add(SyntaxFactory.Argument(SyntaxFactory.IdentifierName(parameter.Name)).WithRefKindKeyword(SyntaxFactory.Token(SyntaxKind.RefKeyword))); } - else if (parameter.Node.Modifiers.Any(x => x.Kind() == SyntaxKind.OutKeyword)) + else if (parameter.Node.Modifiers.Any(x => x.IsKind(SyntaxKind.OutKeyword))) { paramList.Add(SyntaxFactory.Argument(SyntaxFactory.IdentifierName("_")).WithRefKindKeyword(SyntaxFactory.Token(SyntaxKind.OutKeyword))); } diff --git a/src/Unitverse.Core/Unitverse.Core.csproj b/src/Unitverse.Core/Unitverse.Core.csproj index 206ef73..a8c0db4 100644 --- a/src/Unitverse.Core/Unitverse.Core.csproj +++ b/src/Unitverse.Core/Unitverse.Core.csproj @@ -25,8 +25,8 @@ - - + + @@ -37,7 +37,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Unitverse.ExampleGenerator/Unitverse.ExampleGenerator.csproj b/src/Unitverse.ExampleGenerator/Unitverse.ExampleGenerator.csproj index 97190ca..e0ad3f8 100644 --- a/src/Unitverse.ExampleGenerator/Unitverse.ExampleGenerator.csproj +++ b/src/Unitverse.ExampleGenerator/Unitverse.ExampleGenerator.csproj @@ -33,7 +33,7 @@ - + diff --git a/src/Unitverse.Tests.Common/Unitverse.Tests.Common.csproj b/src/Unitverse.Tests.Common/Unitverse.Tests.Common.csproj index ff7cd7f..9ed9b86 100644 --- a/src/Unitverse.Tests.Common/Unitverse.Tests.Common.csproj +++ b/src/Unitverse.Tests.Common/Unitverse.Tests.Common.csproj @@ -22,8 +22,8 @@ - - + + @@ -33,7 +33,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Unitverse/Unitverse.csproj b/src/Unitverse/Unitverse.csproj index a3244a2..e24e457 100644 --- a/src/Unitverse/Unitverse.csproj +++ b/src/Unitverse/Unitverse.csproj @@ -203,18 +203,19 @@ Designer - + compile; build; native; contentfiles; analyzers; buildtransitive - + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - - + + + + + @@ -235,14 +236,10 @@ + - - - 2.8.54 - - ExportOptionsControl.cs