diff --git a/.editorconfig b/.editorconfig
index 2eb3de9..10ae800 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -36,7 +36,7 @@ dotnet_style_prefer_inferred_anonymous_type_member_names = true
dotnet_style_prefer_auto_properties = true : suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true : suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true : silent
-dotnet_style_prefer_conditional_expression_over_return = true : silent
+dotnet_style_prefer_conditional_expression_over_return = true
dotnet_style_coalesce_expression = true : warning
dotnet_style_null_propagation = true : warning
@@ -176,5 +176,36 @@ dotnet_naming_rule.everything_else_naming.style = camel_case_
dotnet_naming_symbols.everything_else.applicable_kinds = *
dotnet_naming_symbols.everything_else.applicable_accessibilities = *
+# CA1040: Avoid empty interfaces
+dotnet_diagnostic.CA1040.severity = none
+
+# CA1812: Avoid uninstantiated internal classes
dotnet_diagnostic.CA1812.severity = none
+
+# CA1724: Type names should not match namespaces
dotnet_diagnostic.CA1724.severity = none
+
+# CA1819: Properties should not return arrays
+dotnet_diagnostic.CA1819.severity = none
+
+# CA2225: Provide a method … as an alternate for operator
+dotnet_diagnostic.CA2225.severity = none
+
+# IDE0022: Use expression body for methods
+dotnet_diagnostic.IDE0022.severity = suggestion
+
+# IDE0046: Convert to conditional expression
+dotnet_diagnostic.IDE0046.severity = suggestion
+
+# IDE0055: Fix formatting
+dotnet_diagnostic.IDE0055.severity = none
+
+# IDE0058: Remove unnecessary expression value
+dotnet_diagnostic.IDE0058.severity = none
+
+# IDE0160: Convert to block scoped namespace
+csharp_style_namespace_declarations = file_scoped
+
+# IDE0340: Use unbound generic type
+# To be revised once we are on .NET 10 SDK
+csharp_style_prefer_unbound_generic_type_in_nameof = false
diff --git a/Directory.Build.targets b/Directory.Build.targets
index a442ed5..945c4de 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -24,6 +24,7 @@
+
diff --git a/examples/notifications/generic.cs b/examples/notifications/generic.cs
index 920b58a..4423a66 100644
--- a/examples/notifications/generic.cs
+++ b/examples/notifications/generic.cs
@@ -1,4 +1,6 @@
+#pragma warning disable IDE0005
using System;
+#pragma warning restore IDE0005
using LeanCode.Contracts;
namespace Notifications.Generic;
diff --git a/src/LeanCode.Contracts.Admin/AdminQuery.cs b/src/LeanCode.Contracts.Admin/AdminQuery.cs
index f939b99..4e266ca 100644
--- a/src/LeanCode.Contracts.Admin/AdminQuery.cs
+++ b/src/LeanCode.Contracts.Admin/AdminQuery.cs
@@ -1,47 +1,35 @@
-namespace LeanCode.Contracts.Admin;
-
-public abstract class AdminQuery : IQuery>
-{
- /// 0-based
- public int Page { get; set; }
- public int PageSize { get; set; }
-
- public bool? SortDescending { get; set; }
- public string? SortBy { get; set; }
-}
-
-public class AdminQueryResult
-{
- public long Total { get; set; }
- public List Items { get; set; }
-}
-
-public class AdminFilterRange
-{
- public T? From { get; set; }
- public T? To { get; set; }
-}
-
-[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
-public class AdminFilterFor : Attribute
-{
- public AdminFilterFor(string name) { }
-}
-
-[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
-public class AdminLabel : Attribute
-{
- public AdminLabel(string label) { }
-}
-
-[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
-public class AdminColumn : Attribute
-{
- public AdminColumn(string? name) { }
-}
-
-[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
-public class AdminSortable : Attribute
-{
- public AdminSortable() { }
-}
+namespace LeanCode.Contracts.Admin;
+
+public abstract class AdminQuery : IQuery>
+{
+ /// 0-based
+ public int Page { get; set; }
+ public int PageSize { get; set; }
+
+ public bool? SortDescending { get; set; }
+ public string? SortBy { get; set; }
+}
+
+public class AdminQueryResult
+{
+ public long Total { get; set; }
+ public List Items { get; set; }
+}
+
+public class AdminFilterRange
+{
+ public T? From { get; set; }
+ public T? To { get; set; }
+}
+
+[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
+public class AdminFilterForAttribute(string name) : Attribute;
+
+[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
+public class AdminLabelAttribute(string label) : Attribute;
+
+[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
+public class AdminColumnAttribute(string? name) : Attribute;
+
+[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
+public class AdminSortableAttribute : Attribute;
diff --git a/src/LeanCode.Contracts/Binary.cs b/src/LeanCode.Contracts/Binary.cs
index 3e6cb0d..e2b4f6f 100644
--- a/src/LeanCode.Contracts/Binary.cs
+++ b/src/LeanCode.Contracts/Binary.cs
@@ -1,31 +1,34 @@
+using System.Diagnostics.CodeAnalysis;
+
namespace LeanCode.Contracts;
[System.Text.Json.Serialization.JsonConverter(typeof(Converters.BinaryJsonConverter))]
-public record struct Binary : IEquatable
+public readonly record struct Binary : IEquatable
{
private readonly byte[]? data;
- public byte[] Data => data ?? Array.Empty();
+ public readonly byte[] Data => data ?? [];
- public Binary(byte[] data)
+ public Binary(byte[]? data)
{
- ArgumentNullException.ThrowIfNull(data);
-
this.data = data;
}
- public bool Equals(Binary other)
- {
- var otherData = other.Data;
- return Data.Length == otherData.Length && Data.SequenceEqual(otherData);
- }
+ public bool Equals(Binary other) => MemoryExtensions.SequenceEqual(Data, other.Data);
- public override int GetHashCode() => Data.Length;
+ public override int GetHashCode() =>
+ data switch
+ {
+ { LongLength: > 4 } d => HashCode.Combine(
+ BitConverter.ToInt32(d.AsSpan(0..4)),
+ BitConverter.ToInt32(d.AsSpan(^4..^0))
+ ),
+ { LongLength: 4 } d => BitConverter.ToInt32(d),
+ { LongLength: 2 or 3 } d => BitConverter.ToInt16(d),
+ { LongLength: 1 } d => d[0],
+ _ => 0,
+ };
-#if NET7_0_OR_GREATER
- [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNull(nameof(binary))]
-#else
- [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNull("binary")]
-#endif
+ [return: NotNullIfNotNull(nameof(binary))]
public static implicit operator byte[]?(Binary? binary) => binary?.Data;
}
diff --git a/src/LeanCode.Contracts/CommandResult.cs b/src/LeanCode.Contracts/CommandResult.cs
index ab301fe..282321d 100644
--- a/src/LeanCode.Contracts/CommandResult.cs
+++ b/src/LeanCode.Contracts/CommandResult.cs
@@ -3,17 +3,12 @@
namespace LeanCode.Contracts;
-public sealed class CommandResult
+public sealed class CommandResult(ImmutableList validationErrors)
{
- public ImmutableList ValidationErrors { get; }
+ public ImmutableList ValidationErrors { get; } = validationErrors;
public bool WasSuccessful => ValidationErrors.Count == 0;
- public CommandResult(ImmutableList validationErrors)
- {
- ValidationErrors = validationErrors;
- }
-
- public static CommandResult Success { get; } = new(ImmutableList.Create());
+ public static CommandResult Success { get; } = new([]);
public static CommandResult NotValid(ValidationResult validationResult)
{
diff --git a/src/LeanCode.Contracts/Converters/BinaryJsonConverter.cs b/src/LeanCode.Contracts/Converters/BinaryJsonConverter.cs
index 3d0e14e..a1becf7 100644
--- a/src/LeanCode.Contracts/Converters/BinaryJsonConverter.cs
+++ b/src/LeanCode.Contracts/Converters/BinaryJsonConverter.cs
@@ -3,7 +3,7 @@
namespace LeanCode.Contracts.Converters;
-internal class BinaryJsonConverter : JsonConverter
+internal sealed class BinaryJsonConverter : JsonConverter
{
public override bool HandleNull => false;
diff --git a/src/LeanCode.Contracts/ExcludeFromContractsGenerationAttribute.cs b/src/LeanCode.Contracts/ExcludeFromContractsGenerationAttribute.cs
index 2974dd7..338ce4b 100644
--- a/src/LeanCode.Contracts/ExcludeFromContractsGenerationAttribute.cs
+++ b/src/LeanCode.Contracts/ExcludeFromContractsGenerationAttribute.cs
@@ -7,4 +7,4 @@ namespace LeanCode.Contracts;
AllowMultiple = false,
Inherited = false
)]
-public sealed class ExcludeFromContractsGenerationAttribute : Attribute { }
+public sealed class ExcludeFromContractsGenerationAttribute : Attribute;
diff --git a/src/LeanCode.Contracts/ICommand.cs b/src/LeanCode.Contracts/ICommand.cs
index 6ace3ef..d1e6bc8 100644
--- a/src/LeanCode.Contracts/ICommand.cs
+++ b/src/LeanCode.Contracts/ICommand.cs
@@ -1,4 +1,3 @@
namespace LeanCode.Contracts;
-[System.Diagnostics.CodeAnalysis.SuppressMessage("?", "CA1040", Justification = "Marker interface.")]
-public interface ICommand { }
+public interface ICommand;
diff --git a/src/LeanCode.Contracts/IOperation.cs b/src/LeanCode.Contracts/IOperation.cs
index 87cd347..ed4adc2 100644
--- a/src/LeanCode.Contracts/IOperation.cs
+++ b/src/LeanCode.Contracts/IOperation.cs
@@ -3,8 +3,6 @@ namespace LeanCode.Contracts;
///
/// Marker interface, do not use directly.
///
-[System.Diagnostics.CodeAnalysis.SuppressMessage("?", "CA1040", Justification = "Marker interface.")]
-public interface IOperation { }
+public interface IOperation;
-[System.Diagnostics.CodeAnalysis.SuppressMessage("?", "CA1040", Justification = "Marker interface.")]
-public interface IOperation : IOperation { }
+public interface IOperation : IOperation;
diff --git a/src/LeanCode.Contracts/IProduceNotification.cs b/src/LeanCode.Contracts/IProduceNotification.cs
index 3a85417..992e734 100644
--- a/src/LeanCode.Contracts/IProduceNotification.cs
+++ b/src/LeanCode.Contracts/IProduceNotification.cs
@@ -1,5 +1,4 @@
namespace LeanCode.Contracts;
-[System.Diagnostics.CodeAnalysis.SuppressMessage("?", "CA1040", Justification = "Marker interface.")]
public interface IProduceNotification
- where TNotification : notnull { }
+ where TNotification : notnull;
diff --git a/src/LeanCode.Contracts/IQuery.cs b/src/LeanCode.Contracts/IQuery.cs
index 96816c1..63519fb 100644
--- a/src/LeanCode.Contracts/IQuery.cs
+++ b/src/LeanCode.Contracts/IQuery.cs
@@ -3,8 +3,6 @@ namespace LeanCode.Contracts;
///
/// Marker interface, do not use directly.
///
-[System.Diagnostics.CodeAnalysis.SuppressMessage("?", "CA1040", Justification = "Marker interface.")]
-public interface IQuery { }
+public interface IQuery;
-[System.Diagnostics.CodeAnalysis.SuppressMessage("?", "CA1040", Justification = "Marker interface.")]
-public interface IQuery : IQuery { }
+public interface IQuery : IQuery;
diff --git a/src/LeanCode.Contracts/ITopic.cs b/src/LeanCode.Contracts/ITopic.cs
index c2229db..1c94cab 100644
--- a/src/LeanCode.Contracts/ITopic.cs
+++ b/src/LeanCode.Contracts/ITopic.cs
@@ -1,4 +1,3 @@
namespace LeanCode.Contracts;
-[System.Diagnostics.CodeAnalysis.SuppressMessage("?", "CA1040", Justification = "Marker interface.")]
-public interface ITopic { }
+public interface ITopic;
diff --git a/src/LeanCode.Contracts/NotificationEnvelope.cs b/src/LeanCode.Contracts/NotificationEnvelope.cs
index 1ea3718..b6775e3 100644
--- a/src/LeanCode.Contracts/NotificationEnvelope.cs
+++ b/src/LeanCode.Contracts/NotificationEnvelope.cs
@@ -21,10 +21,7 @@ public NotificationEnvelope(Guid id, ITopic topic, object notification)
public static NotificationEnvelope Create(TTopic topic, TNotification notification)
where TTopic : ITopic, IProduceNotification
- where TNotification : notnull
- {
- return new(Guid.NewGuid(), topic, notification);
- }
+ where TNotification : notnull => new(Guid.NewGuid(), topic, notification);
[JsonConstructor]
public NotificationEnvelope(Guid id, string topicType, string notificationType, object topic, object notification)
diff --git a/src/LeanCode.Contracts/NotificationTagGenerator.cs b/src/LeanCode.Contracts/NotificationTagGenerator.cs
index 126a529..9d3984d 100644
--- a/src/LeanCode.Contracts/NotificationTagGenerator.cs
+++ b/src/LeanCode.Contracts/NotificationTagGenerator.cs
@@ -1,5 +1,3 @@
-using System.Text;
-
namespace LeanCode.Contracts;
public static class NotificationTagGenerator
@@ -12,9 +10,8 @@ public static class NotificationTagGenerator
/// `LeanCode.ContractsGenerator.Generation.NotificationTagGenerator` that generates a tag based on `TypeRef`.
/// Both methods generate the same tags.
///
- public static string Generate(Type type)
- {
- return type switch
+ public static string Generate(Type type) =>
+ type switch
{
_ when TryKnownType(type) is string name => type.GetElementType() is Type t
? $"{KnownTypePrefix}{name}{GetArgumentsString(t)}"
@@ -22,12 +19,11 @@ _ when TryKnownType(type) is string name => type.GetElementType() is Type t
_ when type.IsGenericType => $"{type.GetSimpleName()}{GetArgumentsString(type.GetGenericArguments())}",
_ => type.FullName!,
};
- }
private static string GetSimpleName(this Type type)
{
var typeName = type.FullName!;
- var backtickIndex = typeName.IndexOf('`');
+ var backtickIndex = typeName.IndexOf('`', StringComparison.Ordinal);
if (backtickIndex > 0)
{
@@ -37,34 +33,11 @@ private static string GetSimpleName(this Type type)
return typeName;
}
- private static string GetArgumentsString(params Type[] args)
- {
- var argsBuilder = new StringBuilder();
-
- if (args.Any())
- {
- argsBuilder.Append('[');
-
- foreach (var arg in args)
- {
- if (argsBuilder.Length > 1)
- {
- argsBuilder.Append(',');
- }
+ private static string GetArgumentsString(params Type[] args) =>
+ args.Length > 0 ? $"[{string.Join(',', args.Select(Generate))}]" : string.Empty;
- var argName = Generate(arg);
- argsBuilder.Append(argName);
- }
-
- argsBuilder.Append(']');
- }
-
- return argsBuilder.ToString();
- }
-
- private static string? TryKnownType(Type type)
- {
- return type switch
+ private static string? TryKnownType(Type type) =>
+ type switch
{
_ when type == typeof(object) => "Object",
_ when type == typeof(string) => "String",
@@ -111,5 +84,4 @@ when type.IsGenericType
_ when type.IsArray => "Array",
_ => null,
};
- }
}
diff --git a/src/LeanCode.Contracts/Security/AllowUnauthorizedAttribute.cs b/src/LeanCode.Contracts/Security/AllowUnauthorizedAttribute.cs
index 4bc0a13..8a2736a 100644
--- a/src/LeanCode.Contracts/Security/AllowUnauthorizedAttribute.cs
+++ b/src/LeanCode.Contracts/Security/AllowUnauthorizedAttribute.cs
@@ -1,4 +1,4 @@
namespace LeanCode.Contracts.Security;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false, Inherited = true)]
-public sealed class AllowUnauthorizedAttribute : Attribute { }
+public sealed class AllowUnauthorizedAttribute : Attribute;
diff --git a/src/LeanCode.Contracts/Security/AuthorizeWhenAttribute.cs b/src/LeanCode.Contracts/Security/AuthorizeWhenAttribute.cs
index 8b60fa5..d7a6571 100644
--- a/src/LeanCode.Contracts/Security/AuthorizeWhenAttribute.cs
+++ b/src/LeanCode.Contracts/Security/AuthorizeWhenAttribute.cs
@@ -4,23 +4,15 @@
namespace LeanCode.Contracts.Security;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = true)]
-public abstract class AuthorizeWhenAttribute : Attribute
+public abstract class AuthorizeWhenAttribute(Type authorizerType, object? customData = null) : Attribute
{
- private readonly Type authorizerType;
- private readonly object? customData;
-
- protected AuthorizeWhenAttribute(Type authorizerType, object? customData = null)
- {
- this.authorizerType = authorizerType;
- this.customData = customData;
- }
+ private readonly Type authorizerType = authorizerType;
+ private readonly object? customData = customData;
public static List GetCustomAuthorizers() => GetCustomAuthorizers(typeof(T));
- public static List GetCustomAuthorizers(Type type)
- {
- return type.GetCustomAttributes().Select(AuthorizerDefinition.Create).ToList();
- }
+ public static List GetCustomAuthorizers(Type type) =>
+ [.. type.GetCustomAttributes().Select(AuthorizerDefinition.Create)];
[SuppressMessage("?", "CA1034", Justification = "Deliberate nesting.")]
public sealed class AuthorizerDefinition
@@ -39,11 +31,9 @@ private AuthorizerDefinition(AuthorizeWhenAttribute attr)
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = true)]
-public abstract class AuthorizeWhenAttribute : AuthorizeWhenAttribute
+public abstract class AuthorizeWhenAttribute(object? customData = null)
+ : AuthorizeWhenAttribute(typeof(T), customData)
{
- protected AuthorizeWhenAttribute(object? customData = null)
- : base(typeof(T), customData) { }
-
[SuppressMessage("?", "CA1000", Justification = "Alternative method also exists.")]
- public static List GetCustomAuthorizers() => GetCustomAuthorizers(typeof(T));
+ public static List GetCustomAuthorizers() => GetCustomAuthorizers();
}
diff --git a/src/LeanCode.Contracts/Security/AuthorizeWhenHasAnyOfAttribute.cs b/src/LeanCode.Contracts/Security/AuthorizeWhenHasAnyOfAttribute.cs
index a90ab64..52205af 100644
--- a/src/LeanCode.Contracts/Security/AuthorizeWhenHasAnyOfAttribute.cs
+++ b/src/LeanCode.Contracts/Security/AuthorizeWhenHasAnyOfAttribute.cs
@@ -1,12 +1,6 @@
-using System.Diagnostics.CodeAnalysis;
-
namespace LeanCode.Contracts.Security;
-[SuppressMessage("?", "CA1040", Justification = "Marker interface.")]
-public interface IHasPermissions { }
+public interface IHasPermissions;
-public sealed class AuthorizeWhenHasAnyOfAttribute : AuthorizeWhenAttribute
-{
- public AuthorizeWhenHasAnyOfAttribute(params string[] permissions)
- : base(typeof(IHasPermissions), permissions) { }
-}
+public sealed class AuthorizeWhenHasAnyOfAttribute(params string[] permissions)
+ : AuthorizeWhenAttribute(typeof(IHasPermissions), permissions);
diff --git a/src/LeanCode.Contracts/SubscriptionEnvelope.cs b/src/LeanCode.Contracts/SubscriptionEnvelope.cs
index cbba4bd..77a613f 100644
--- a/src/LeanCode.Contracts/SubscriptionEnvelope.cs
+++ b/src/LeanCode.Contracts/SubscriptionEnvelope.cs
@@ -2,9 +2,11 @@
namespace LeanCode.Contracts;
-public sealed class SubscriptionEnvelope
+public sealed class SubscriptionEnvelope : IDisposable
{
public Guid Id { get; set; }
public string TopicType { get; set; } = default!;
public JsonDocument Topic { get; set; } = default!;
+
+ public void Dispose() => Topic.Dispose();
}
diff --git a/src/LeanCode.Contracts/SubscriptionResult.cs b/src/LeanCode.Contracts/SubscriptionResult.cs
index b57726c..dce1b58 100644
--- a/src/LeanCode.Contracts/SubscriptionResult.cs
+++ b/src/LeanCode.Contracts/SubscriptionResult.cs
@@ -1,17 +1,10 @@
namespace LeanCode.Contracts;
-public sealed class SubscriptionResult
+public sealed class SubscriptionResult(Guid subscriptionId, SubscriptionStatus status, OperationType type)
{
- public Guid SubscriptionId { get; private init; }
- public SubscriptionStatus Status { get; private init; }
- public OperationType Type { get; private init; }
-
- public SubscriptionResult(Guid subscriptionId, SubscriptionStatus status, OperationType type)
- {
- SubscriptionId = subscriptionId;
- Status = status;
- Type = type;
- }
+ public Guid SubscriptionId { get; private init; } = subscriptionId;
+ public SubscriptionStatus Status { get; private init; } = status;
+ public OperationType Type { get; private init; } = type;
}
public enum SubscriptionStatus
diff --git a/src/LeanCode.Contracts/Validation/ValidationError.cs b/src/LeanCode.Contracts/Validation/ValidationError.cs
index 36bfdbf..54fc6d3 100644
--- a/src/LeanCode.Contracts/Validation/ValidationError.cs
+++ b/src/LeanCode.Contracts/Validation/ValidationError.cs
@@ -1,15 +1,8 @@
namespace LeanCode.Contracts.Validation;
-public class ValidationError
+public class ValidationError(string propertyName, string errorMessage, int errorCode)
{
- public string PropertyName { get; }
- public string ErrorMessage { get; }
- public int ErrorCode { get; }
-
- public ValidationError(string propertyName, string errorMessage, int errorCode)
- {
- PropertyName = propertyName;
- ErrorMessage = errorMessage;
- ErrorCode = errorCode;
- }
+ public string PropertyName { get; } = propertyName;
+ public string ErrorMessage { get; } = errorMessage;
+ public int ErrorCode { get; } = errorCode;
}
diff --git a/src/LeanCode.Contracts/Validation/ValidationResult.cs b/src/LeanCode.Contracts/Validation/ValidationResult.cs
index 6de5cd7..4f01279 100644
--- a/src/LeanCode.Contracts/Validation/ValidationResult.cs
+++ b/src/LeanCode.Contracts/Validation/ValidationResult.cs
@@ -2,13 +2,8 @@
namespace LeanCode.Contracts.Validation;
-public class ValidationResult
+public class ValidationResult(IReadOnlyList? errors)
{
- public ImmutableList Errors { get; }
+ public ImmutableList Errors { get; } = errors is null ? [] : [.. errors];
public bool IsValid => Errors.Count == 0;
-
- public ValidationResult(IReadOnlyList? errors)
- {
- Errors = errors is null ? ImmutableList.Create() : errors.ToImmutableList();
- }
}
diff --git a/src/LeanCode.ContractsGenerator.Tests/ExampleBased/Glob.cs b/src/LeanCode.ContractsGenerator.Tests/ExampleBased/Glob.cs
index 3de24b0..1bb6a4c 100644
--- a/src/LeanCode.ContractsGenerator.Tests/ExampleBased/Glob.cs
+++ b/src/LeanCode.ContractsGenerator.Tests/ExampleBased/Glob.cs
@@ -8,7 +8,7 @@ public class Glob
[Fact]
public void Globbing_finds_necessary_files()
{
- GlobCompiles(includes: new[] { "project/globs/**/*.cs" }, excludes: Array.Empty())
+ GlobCompiles(includes: ["project/globs/**/*.cs"], excludes: [])
.WithCommand("A.Command")
.WithQuery("B.Query")
.WithDto("A.Dto");
@@ -17,7 +17,7 @@ public void Globbing_finds_necessary_files()
[Fact]
public void Globbing_includes_correct_files()
{
- GlobCompiles(includes: new[] { "project/globs/A/*" }, excludes: Array.Empty())
+ GlobCompiles(includes: ["project/globs/A/*"], excludes: [])
.WithCommand("A.Command")
.WithDto("A.Dto")
.Without("B.Query");
@@ -26,7 +26,7 @@ public void Globbing_includes_correct_files()
[Fact]
public void Globbing_excludes_correct_files()
{
- GlobCompiles(includes: new[] { "project/globs/**" }, excludes: new[] { "**/Dto.cs" })
+ GlobCompiles(includes: ["project/globs/**"], excludes: ["**/Dto.cs"])
.WithCommand("A.Command")
.Without("A.Dto")
.WithQuery("B.Query");
diff --git a/src/LeanCode.ContractsGenerator.Tests/Generation/ObjectExtensionsTests.cs b/src/LeanCode.ContractsGenerator.Tests/Generation/ObjectExtensionsTests.cs
index 772f284..979709e 100644
--- a/src/LeanCode.ContractsGenerator.Tests/Generation/ObjectExtensionsTests.cs
+++ b/src/LeanCode.ContractsGenerator.Tests/Generation/ObjectExtensionsTests.cs
@@ -12,16 +12,15 @@ public void Null_is_converted()
Assert.NotNull(vr.Null);
}
-#pragma warning disable SA1139
[Theory]
[InlineData((byte)10)]
[InlineData((sbyte)10)]
- [InlineData((int)10)]
- [InlineData((long)10)]
[InlineData((short)10)]
- [InlineData((uint)10)]
- [InlineData((ulong)10)]
[InlineData((ushort)10)]
+ [InlineData(10)]
+ [InlineData(10L)]
+ [InlineData(10U)]
+ [InlineData(10UL)]
public void Number_is_converted(object value)
{
var vr = value.ToValueRef();
@@ -30,15 +29,14 @@ public void Number_is_converted(object value)
}
[Theory]
- [InlineData((float)10.015000343322754)]
- [InlineData((double)10.015000343322754)]
+ [InlineData(10.015000343322754f)]
+ [InlineData(10.015000343322754d)]
public void FloatingPoint_is_converted(object value)
{
var vr = value.ToValueRef();
Assert.NotNull(vr.FloatingPoint);
Assert.Equal(10.015000343322754, vr.FloatingPoint.Value);
}
-#pragma warning restore
[Fact]
public void String_is_converted()
diff --git a/src/LeanCode.ContractsGenerator.Tests/Serialization/BinarySerializationTests.cs b/src/LeanCode.ContractsGenerator.Tests/Serialization/BinarySerializationTests.cs
index 43e4ce6..f117933 100644
--- a/src/LeanCode.ContractsGenerator.Tests/Serialization/BinarySerializationTests.cs
+++ b/src/LeanCode.ContractsGenerator.Tests/Serialization/BinarySerializationTests.cs
@@ -8,7 +8,7 @@ public class BinarySerializationTests
{
private sealed record class BinaryDTO(Binary? Null, Binary? NullableValue, Binary Value);
- private static readonly byte[] Hello = { 0x68, 0x65, 0x6c, 0x6c, 0x6f };
+ private static readonly byte[] Hello = [.. "hello"u8];
private static readonly BinaryDTO DTO = new(null, Hello?.AsBinary(), Hello!.AsBinary());
diff --git a/src/LeanCode.ContractsGenerator.Tests/Serialization/CommandResultSerializationTests.cs b/src/LeanCode.ContractsGenerator.Tests/Serialization/CommandResultSerializationTests.cs
index 30b88e2..47d2b03 100644
--- a/src/LeanCode.ContractsGenerator.Tests/Serialization/CommandResultSerializationTests.cs
+++ b/src/LeanCode.ContractsGenerator.Tests/Serialization/CommandResultSerializationTests.cs
@@ -9,7 +9,7 @@ namespace LeanCode.ContractsGenerator.Tests.Serialization;
public class CommandResultSerializationTests
{
private static readonly CommandResult SampleCommandResult = CommandResult.NotValid(
- new(new[] { new ValidationError("A property", "An error message", 1) })
+ new([new ValidationError("A property", "An error message", 1)])
);
private const string Json = $$"""
diff --git a/src/LeanCode.ContractsGenerator.Tests/Serialization/NotificationEnvelopeSerializationTests.cs b/src/LeanCode.ContractsGenerator.Tests/Serialization/NotificationEnvelopeSerializationTests.cs
index 254b74b..5758764 100644
--- a/src/LeanCode.ContractsGenerator.Tests/Serialization/NotificationEnvelopeSerializationTests.cs
+++ b/src/LeanCode.ContractsGenerator.Tests/Serialization/NotificationEnvelopeSerializationTests.cs
@@ -2,7 +2,6 @@
using FluentAssertions;
using FluentAssertions.Execution;
using LeanCode.Contracts;
-using LeanCode.Contracts.Validation;
using Xunit;
namespace LeanCode.ContractsGenerator.Tests.Serialization;
@@ -11,10 +10,7 @@ public class NotificationEnvelopeSerializationTests
{
private const string NotificationId = "4d3b45e6-a2c1-4d6a-9e23-94e0d9f8ca01";
- private static readonly Topic SampleTopic = new()
- {
- EntityIds = new() { "Entity1", "Entity2" },
- };
+ private static readonly Topic SampleTopic = new() { EntityIds = ["Entity1", "Entity2"] };
private static readonly Notification SampleNotification = new() { EntityId = "Entity1" };
diff --git a/src/LeanCode.ContractsGenerator.Tests/Serialization/SubscriptionEnvelopeSerializationTests.cs b/src/LeanCode.ContractsGenerator.Tests/Serialization/SubscriptionEnvelopeSerializationTests.cs
index 99aec02..e1a9109 100644
--- a/src/LeanCode.ContractsGenerator.Tests/Serialization/SubscriptionEnvelopeSerializationTests.cs
+++ b/src/LeanCode.ContractsGenerator.Tests/Serialization/SubscriptionEnvelopeSerializationTests.cs
@@ -2,7 +2,6 @@
using FluentAssertions;
using FluentAssertions.Execution;
using LeanCode.Contracts;
-using LeanCode.Contracts.Validation;
using Xunit;
namespace LeanCode.ContractsGenerator.Tests.Serialization;
@@ -11,10 +10,7 @@ public class SubscriptionEnvelopeSerializationTests
{
private const string SubscriptionId = "4d3b45e6-a2c1-4d6a-9e23-94e0d9f8ca01";
- private static readonly Topic SampleTopic = new()
- {
- EntityIds = new() { "Entity1", "Entity2" },
- };
+ private static readonly Topic SampleTopic = new() { EntityIds = ["Entity1", "Entity2"] };
private static readonly SubscriptionEnvelope SampleSubscriptionEnvelope = new()
{
diff --git a/src/LeanCode.ContractsGenerator/AnalyzeFailedException.cs b/src/LeanCode.ContractsGenerator/AnalyzeFailedException.cs
index 6e11b55..b42e556 100644
--- a/src/LeanCode.ContractsGenerator/AnalyzeFailedException.cs
+++ b/src/LeanCode.ContractsGenerator/AnalyzeFailedException.cs
@@ -1,12 +1,7 @@
namespace LeanCode.ContractsGenerator;
-public class AnalyzeFailedException : Exception
+public class AnalyzeFailedException(IReadOnlyList errors)
+ : Exception(string.Join('\n', errors.Select(e => e.ToString()).Prepend("Analyze phase failed.")))
{
- public IReadOnlyList Errors { get; }
-
- public AnalyzeFailedException(IReadOnlyList errors)
- : base(string.Join('\n', errors.Select(e => e.ToString()).Prepend("Analyze phase failed.")))
- {
- Errors = errors;
- }
+ public IReadOnlyList Errors { get; } = errors;
}
diff --git a/src/LeanCode.ContractsGenerator/AnalyzerContext.cs b/src/LeanCode.ContractsGenerator/AnalyzerContext.cs
index 53afbb7..60dee10 100644
--- a/src/LeanCode.ContractsGenerator/AnalyzerContext.cs
+++ b/src/LeanCode.ContractsGenerator/AnalyzerContext.cs
@@ -1,9 +1,7 @@
-using System.Diagnostics.CodeAnalysis;
using System.Globalization;
namespace LeanCode.ContractsGenerator;
-[SuppressMessage("?", "SA1313", Justification = "False positive.")]
public readonly record struct AnalyzerContext(string Path)
{
public static readonly AnalyzerContext Empty = new("");
@@ -58,10 +56,7 @@ private AnalyzerContext Descend(string nextName)
}
}
- private AnalyzerContext Append(string nextName)
- {
- return new($"{Path}{nextName}");
- }
+ private AnalyzerContext Append(string nextName) => new($"{Path}{nextName}");
private static string NameOf(TypeRef typeRef)
{
diff --git a/src/LeanCode.ContractsGenerator/Analyzers/AllAnalyzers.cs b/src/LeanCode.ContractsGenerator/Analyzers/AllAnalyzers.cs
index 02c2b07..05e41bd 100644
--- a/src/LeanCode.ContractsGenerator/Analyzers/AllAnalyzers.cs
+++ b/src/LeanCode.ContractsGenerator/Analyzers/AllAnalyzers.cs
@@ -2,8 +2,8 @@ namespace LeanCode.ContractsGenerator.Analyzers;
public class AllAnalyzers : IAnalyzer
{
- private readonly IReadOnlyList analyzers = new IAnalyzer[]
- {
+ private readonly IReadOnlyList analyzers =
+ [
new InternalStructureCheck(),
new KnownTypeCheck(),
new ErrorCodesUniqueness(),
@@ -12,10 +12,7 @@ public class AllAnalyzers : IAnalyzer
new TopicWithoutNotificationCheck(),
new TopicWithNullableNotificationCheck(),
new TopicMustProduceInternalType(),
- };
+ ];
- public IEnumerable Analyze(Export export)
- {
- return analyzers.SelectMany(a => a.Analyze(export));
- }
+ public IEnumerable Analyze(Export export) => analyzers.SelectMany(a => a.Analyze(export));
}
diff --git a/src/LeanCode.ContractsGenerator/AnalyzerCodes.cs b/src/LeanCode.ContractsGenerator/Analyzers/AnalyzerCodes.cs
similarity index 100%
rename from src/LeanCode.ContractsGenerator/AnalyzerCodes.cs
rename to src/LeanCode.ContractsGenerator/Analyzers/AnalyzerCodes.cs
diff --git a/src/LeanCode.ContractsGenerator/Analyzers/BaseAnalyzer.cs b/src/LeanCode.ContractsGenerator/Analyzers/BaseAnalyzer.cs
index 23f4d8e..11045df 100644
--- a/src/LeanCode.ContractsGenerator/Analyzers/BaseAnalyzer.cs
+++ b/src/LeanCode.ContractsGenerator/Analyzers/BaseAnalyzer.cs
@@ -5,47 +5,33 @@ public class BaseAnalyzer : IAnalyzer
public virtual IEnumerable Analyze(Export export)
{
var context = AnalyzerContext.Empty;
- return export.Statements.SelectMany(s => AnalyzeStatement(context.Descend(s), s)).ToList();
+ return [.. export.Statements.SelectMany(s => AnalyzeStatement(context.Descend(s), s))];
}
- public virtual IEnumerable AnalyzeKnownType(AnalyzerContext context, KnownType knownType)
- {
- return Enumerable.Empty();
- }
+ public virtual IEnumerable AnalyzeKnownType(AnalyzerContext context, KnownType knownType) => [];
- public virtual IEnumerable AnalyzeValueRef(AnalyzerContext context, ValueRef valueRef)
- {
- return Enumerable.Empty();
- }
+ public virtual IEnumerable AnalyzeValueRef(AnalyzerContext context, ValueRef valueRef) => [];
public virtual IEnumerable AnalyzeGenericTypeRef(
AnalyzerContext context,
TypeRef typeRef,
TypeRef.Types.Generic g
- )
- {
- return Enumerable.Empty();
- }
+ ) => [];
public virtual IEnumerable AnalyzeInternalTypeRef(
AnalyzerContext context,
TypeRef typeRef,
TypeRef.Types.Internal i
- )
- {
- return i.Arguments.SelectMany((a, i) => AnalyzeTypeRef(context.Argument(i, a), a));
- }
+ ) => i.Arguments.SelectMany((a, i) => AnalyzeTypeRef(context.Argument(i, a), a));
public virtual IEnumerable AnalyzeKnownTypeRef(
AnalyzerContext context,
TypeRef typeRef,
TypeRef.Types.Known k
- )
- {
- return k
+ ) =>
+ k
.Arguments.SelectMany((a, i) => AnalyzeTypeRef(context.Argument(i, a), a))
.Concat(AnalyzeKnownType(context, k.Type));
- }
public virtual IEnumerable AnalyzeTypeRef(AnalyzerContext context, TypeRef typeRef)
{
@@ -63,35 +49,26 @@ public virtual IEnumerable AnalyzeTypeRef(AnalyzerContext context,
}
else
{
- return Enumerable.Empty();
+ return [];
}
}
public virtual IEnumerable AnalyzeGenericParameter(
AnalyzerContext context,
GenericParameter genericParam
- )
- {
- return Enumerable.Empty();
- }
+ ) => [];
public virtual IEnumerable AnalyzePositionalAttributeArgument(
AnalyzerContext context,
AttributeArgument arg,
AttributeArgument.Types.Positional p
- )
- {
- return AnalyzeValueRef(context, p.Value);
- }
+ ) => AnalyzeValueRef(context, p.Value);
public virtual IEnumerable AnalyzeNamedAttributeArgument(
AnalyzerContext context,
AttributeArgument arg,
AttributeArgument.Types.Named n
- )
- {
- return AnalyzeValueRef(context, n.Value);
- }
+ ) => AnalyzeValueRef(context, n.Value);
public virtual IEnumerable AnalyzeAttributeArgument(AnalyzerContext context, AttributeArgument arg)
{
@@ -105,48 +82,33 @@ public virtual IEnumerable AnalyzeAttributeArgument(AnalyzerContex
}
else
{
- return Enumerable.Empty();
+ return [];
}
}
- public virtual IEnumerable AnalyzeAttributeRef(AnalyzerContext context, AttributeRef attrRef)
- {
- return attrRef.Argument.SelectMany(a => AnalyzeAttributeArgument(context.Argument(a), a));
- }
+ public virtual IEnumerable AnalyzeAttributeRef(AnalyzerContext context, AttributeRef attrRef) =>
+ attrRef.Argument.SelectMany(a => AnalyzeAttributeArgument(context.Argument(a), a));
- public virtual IEnumerable AnalyzePropertyRef(AnalyzerContext context, PropertyRef propRef)
- {
- return AnalyzeTypeRef(context, propRef.Type)
+ public virtual IEnumerable AnalyzePropertyRef(AnalyzerContext context, PropertyRef propRef) =>
+ AnalyzeTypeRef(context, propRef.Type)
.Concat(propRef.Attributes.SelectMany(a => AnalyzeAttributeRef(context.Attribute(a), a)));
- }
- public virtual IEnumerable AnalyzeConstantRef(AnalyzerContext context, ConstantRef constant)
- {
- return AnalyzeValueRef(context, constant.Value);
- }
+ public virtual IEnumerable AnalyzeConstantRef(AnalyzerContext context, ConstantRef constant) =>
+ AnalyzeValueRef(context, constant.Value);
- public virtual IEnumerable AnalyzeEnumValue(AnalyzerContext context, EnumValue enumVal)
- {
- return Enumerable.Empty();
- }
+ public virtual IEnumerable AnalyzeEnumValue(AnalyzerContext context, EnumValue enumVal) => [];
public virtual IEnumerable AnalyzeGroupErrorCode(
AnalyzerContext context,
ErrorCode errCode,
ErrorCode.Types.Group g
- )
- {
- return AnalyzeErrorCodes(context, g.InnerCodes);
- }
+ ) => AnalyzeErrorCodes(context, g.InnerCodes);
public virtual IEnumerable AnalyzeSingleErrorCode(
AnalyzerContext context,
ErrorCode errCode,
ErrorCode.Types.Single s
- )
- {
- return Enumerable.Empty();
- }
+ ) => [];
public virtual IEnumerable AnalyzeErrorCode(AnalyzerContext context, ErrorCode errCode)
{
@@ -160,32 +122,29 @@ public virtual IEnumerable AnalyzeErrorCode(AnalyzerContext contex
}
else
{
- return Enumerable.Empty();
+ return [];
}
}
- public virtual IEnumerable AnalyzeErrorCodes(AnalyzerContext context, IEnumerable errCodes)
- {
- return errCodes.SelectMany(e => AnalyzeErrorCode(context.Descend(e), e));
- }
+ public virtual IEnumerable AnalyzeErrorCodes(
+ AnalyzerContext context,
+ IEnumerable errCodes
+ ) => errCodes.SelectMany(e => AnalyzeErrorCode(context.Descend(e), e));
- public virtual IEnumerable AnalyzeTypeDescriptor(AnalyzerContext context, TypeDescriptor descr)
- {
- return descr
+ public virtual IEnumerable AnalyzeTypeDescriptor(AnalyzerContext context, TypeDescriptor descr) =>
+ descr
.Extends.SelectMany(t => AnalyzeTypeRef(context.Extends(t), t))
.Concat(
descr.GenericParameters.SelectMany((g, i) => AnalyzeGenericParameter(context.GenericParameter(i, g), g))
)
.Concat(descr.Properties.SelectMany(p => AnalyzePropertyRef(context.Descend(p), p)))
.Concat(descr.Constants.SelectMany(c => AnalyzeConstantRef(context.Descend(c), c)));
- }
public virtual IEnumerable AnalyzeTypeDescriptorForQuery(
AnalyzerContext context,
TypeDescriptor descr
- )
- {
- return descr
+ ) =>
+ descr
.Extends.Where(e => e.Known is null || e.Known.Type != KnownType.Query) // Exclude `Query` type, as it will be checked by the `Return` check
.SelectMany(t => AnalyzeTypeRef(context.Extends(t), t))
.Concat(
@@ -193,14 +152,12 @@ TypeDescriptor descr
)
.Concat(descr.Properties.SelectMany(p => AnalyzePropertyRef(context.Descend(p), p)))
.Concat(descr.Constants.SelectMany(c => AnalyzeConstantRef(context.Descend(c), c)));
- }
public virtual IEnumerable AnalyzeTypeDescriptorForOperation(
AnalyzerContext context,
TypeDescriptor descr
- )
- {
- return descr
+ ) =>
+ descr
.Extends.Where(e => e.Known is null || e.Known.Type != KnownType.Operation) // Exclude `Operation` type, as it will be checked by the `Return` check
.SelectMany(t => AnalyzeTypeRef(context.Extends(t), t))
.Concat(
@@ -208,77 +165,60 @@ TypeDescriptor descr
)
.Concat(descr.Properties.SelectMany(p => AnalyzePropertyRef(context.Descend(p), p)))
.Concat(descr.Constants.SelectMany(c => AnalyzeConstantRef(context.Descend(c), c)));
- }
public virtual IEnumerable AnalyzeTypeDescriptorForTopic(
AnalyzerContext context,
TypeDescriptor descr
- )
- {
- return descr
+ ) =>
+ descr
.Extends.Where(e => e.Known is null || e.Known.Type != KnownType.Topic)
.SelectMany(t => AnalyzeTypeRef(context.Extends(t), t))
.Concat(descr.Properties.SelectMany(p => AnalyzePropertyRef(context.Descend(p), p)))
.Concat(descr.Constants.SelectMany(c => AnalyzeConstantRef(context.Descend(c), c)));
- }
public virtual IEnumerable AnalyzeDTO(
AnalyzerContext context,
Statement stmt,
Statement.Types.DTO dto
- )
- {
- return AnalyzeTypeDescriptor(context, dto.TypeDescriptor);
- }
+ ) => AnalyzeTypeDescriptor(context, dto.TypeDescriptor);
public virtual IEnumerable AnalyzeEnum(
AnalyzerContext context,
Statement stmt,
Statement.Types.Enum @enum
- )
- {
- return @enum.Members.SelectMany(m => AnalyzeEnumValue(context.Descend(m), m));
- }
+ ) => @enum.Members.SelectMany(m => AnalyzeEnumValue(context.Descend(m), m));
public virtual IEnumerable AnalyzeQuery(
AnalyzerContext context,
Statement stmt,
Statement.Types.Query query
- )
- {
- return AnalyzeTypeDescriptorForQuery(context, query.TypeDescriptor)
+ ) =>
+ AnalyzeTypeDescriptorForQuery(context, query.TypeDescriptor)
.Concat(AnalyzeTypeRef(context.Returns(query.ReturnType), query.ReturnType));
- }
public virtual IEnumerable AnalyzeCommand(
AnalyzerContext context,
Statement stmt,
Statement.Types.Command command
- )
- {
- return AnalyzeTypeDescriptor(context, command.TypeDescriptor)
+ ) =>
+ AnalyzeTypeDescriptor(context, command.TypeDescriptor)
.Concat(AnalyzeErrorCodes(context.ErrorCodes(), command.ErrorCodes));
- }
public virtual IEnumerable AnalyzeOperation(
AnalyzerContext context,
Statement stmt,
Statement.Types.Operation operation
- )
- {
- return AnalyzeTypeDescriptorForOperation(context, operation.TypeDescriptor)
+ ) =>
+ AnalyzeTypeDescriptorForOperation(context, operation.TypeDescriptor)
.Concat(AnalyzeTypeRef(context.Returns(operation.ReturnType), operation.ReturnType));
- }
public virtual IEnumerable AnalyzeTopic(
AnalyzerContext context,
Statement stmt,
Statement.Types.Topic topic
- )
- {
- return AnalyzeTypeDescriptorForTopic(context, topic.TypeDescriptor)
+ ) =>
+ AnalyzeTypeDescriptorForTopic(context, topic.TypeDescriptor)
.Concat(topic.Notifications.SelectMany(n => AnalyzeTypeRef(context.Returns(n.Type), n.Type)));
- }
public virtual IEnumerable AnalyzeStatement(AnalyzerContext context, Statement stmt)
{
@@ -313,7 +253,7 @@ IEnumerable AnalyzeInner(AnalyzerContext context, Statement stmt)
}
else
{
- return Enumerable.Empty();
+ return [];
}
}
}
diff --git a/src/LeanCode.ContractsGenerator/Analyzers/ErrorCodesUniqueness.cs b/src/LeanCode.ContractsGenerator/Analyzers/ErrorCodesUniqueness.cs
index 3980ec2..d69f7e4 100644
--- a/src/LeanCode.ContractsGenerator/Analyzers/ErrorCodesUniqueness.cs
+++ b/src/LeanCode.ContractsGenerator/Analyzers/ErrorCodesUniqueness.cs
@@ -19,14 +19,7 @@ IEnumerable errCodes
static IEnumerable Flatten(ErrorCode errCode)
{
- if (errCode.Single is ErrorCode.Types.Single s)
- {
- return new[] { s };
- }
- else
- {
- return errCode.Group.InnerCodes.SelectMany(Flatten);
- }
+ return errCode.Single is ErrorCode.Types.Single s ? [s] : errCode.Group.InnerCodes.SelectMany(Flatten);
}
}
@@ -34,27 +27,15 @@ public override IEnumerable Analyze(Export export)
{
var context = AnalyzerContext.Empty;
- return export.Statements.SelectMany(s => AnalyzeStatement(context.Descend(s), s)).ToList();
+ return [.. export.Statements.SelectMany(s => AnalyzeStatement(context.Descend(s), s))];
}
public override IEnumerable AnalyzeCommand(
AnalyzerContext context,
Statement stmt,
Statement.Types.Command command
- )
- {
- return AnalyzeErrorCodes(context.ErrorCodes(), command.ErrorCodes);
- }
+ ) => AnalyzeErrorCodes(context.ErrorCodes(), command.ErrorCodes);
- public override IEnumerable AnalyzeStatement(AnalyzerContext context, Statement stmt)
- {
- if (stmt.Command is Statement.Types.Command cmd)
- {
- return AnalyzeCommand(context, stmt, cmd);
- }
- else
- {
- return Enumerable.Empty();
- }
- }
+ public override IEnumerable AnalyzeStatement(AnalyzerContext context, Statement stmt) =>
+ stmt.Command is Statement.Types.Command cmd ? AnalyzeCommand(context, stmt, cmd) : [];
}
diff --git a/src/LeanCode.ContractsGenerator/Analyzers/ExternalTypeCheck.cs b/src/LeanCode.ContractsGenerator/Analyzers/ExternalTypeCheck.cs
index f7b12c8..64ced18 100644
--- a/src/LeanCode.ContractsGenerator/Analyzers/ExternalTypeCheck.cs
+++ b/src/LeanCode.ContractsGenerator/Analyzers/ExternalTypeCheck.cs
@@ -4,7 +4,7 @@ namespace LeanCode.ContractsGenerator.Analyzers;
public class ExternalTypeCheck : BaseAnalyzer
{
- private ImmutableHashSet knownTypes = ImmutableHashSet.Empty;
+ private ImmutableHashSet knownTypes = [];
public override IEnumerable Analyze(Export export)
{
@@ -24,19 +24,16 @@ TypeRef.Types.Internal i
}
else
{
- return new[]
- {
+ return
+ [
new AnalyzeError(
AnalyzerCodes.InternalTypeIsNotKnown,
$"Internal type `{i.Name}` is not known.",
context
),
- };
+ ];
}
}
- private static ImmutableHashSet GatherTypes(Export export)
- {
- return export.Statements.Select(s => s.Name).ToImmutableHashSet();
- }
+ private static ImmutableHashSet GatherTypes(Export export) => [.. export.Statements.Select(s => s.Name)];
}
diff --git a/src/LeanCode.ContractsGenerator/Analyzers/InvalidTypeCheck.cs b/src/LeanCode.ContractsGenerator/Analyzers/InvalidTypeCheck.cs
index 1596d5c..a3088ee 100644
--- a/src/LeanCode.ContractsGenerator/Analyzers/InvalidTypeCheck.cs
+++ b/src/LeanCode.ContractsGenerator/Analyzers/InvalidTypeCheck.cs
@@ -15,10 +15,7 @@ TypeRef.Types.Internal i
{
if (InvalidTypes.TryGetValue(i.Name, out var msg))
{
- return new[]
- {
- new AnalyzeError(AnalyzerCodes.UnsupportedType, $"Type `{i.Name}` is unsupported. {msg}", context),
- };
+ return [new AnalyzeError(AnalyzerCodes.UnsupportedType, $"Type `{i.Name}` is unsupported. {msg}", context)];
}
else
{
diff --git a/src/LeanCode.ContractsGenerator/Analyzers/KnownTypeCheck.cs b/src/LeanCode.ContractsGenerator/Analyzers/KnownTypeCheck.cs
index 2222af3..c2ffc9c 100644
--- a/src/LeanCode.ContractsGenerator/Analyzers/KnownTypeCheck.cs
+++ b/src/LeanCode.ContractsGenerator/Analyzers/KnownTypeCheck.cs
@@ -2,11 +2,9 @@ namespace LeanCode.ContractsGenerator.Analyzers;
public class KnownTypeCheck : BaseAnalyzer
{
- private static readonly IReadOnlySet ValidKnownTypeValues = Enum.GetValues().ToHashSet();
-
public override IEnumerable AnalyzeKnownType(AnalyzerContext context, KnownType knownType)
{
- if (!ValidKnownTypeValues.Contains(knownType))
+ if (!Enum.IsDefined(knownType))
{
yield return new(
AnalyzerCodes.UnsupportedKnownType,
diff --git a/src/LeanCode.ContractsGenerator/Compilation/CompilationFailedException.cs b/src/LeanCode.ContractsGenerator/Compilation/CompilationFailedException.cs
index 4bf7c6e..8bedd17 100644
--- a/src/LeanCode.ContractsGenerator/Compilation/CompilationFailedException.cs
+++ b/src/LeanCode.ContractsGenerator/Compilation/CompilationFailedException.cs
@@ -17,12 +17,13 @@ public CompilationFailedException(ImmutableArray diagnostics)
public CompilationFailedException(string message)
: base(message)
{
- Diagnostics = ImmutableArray.Empty;
+ Diagnostics = [];
}
private static string GetDiagnosticsMessage(ImmutableArray diagnostics)
{
var sb = new StringBuilder();
+
foreach (var d in diagnostics)
{
sb.AppendLine($"[{d.Severity}] {d.GetMessage()} at {FormatLocation(d.Location)}");
diff --git a/src/LeanCode.ContractsGenerator/Compilation/CompiledContracts.cs b/src/LeanCode.ContractsGenerator/Compilation/CompiledContracts.cs
index 7b044e9..2ad407d 100644
--- a/src/LeanCode.ContractsGenerator/Compilation/CompiledContracts.cs
+++ b/src/LeanCode.ContractsGenerator/Compilation/CompiledContracts.cs
@@ -4,24 +4,13 @@
namespace LeanCode.ContractsGenerator.Compilation;
-public sealed class CompiledContracts
+public sealed class CompiledContracts(IReadOnlyCollection compilations, string projectName)
{
- private readonly IReadOnlyCollection compilations;
+ public ContractTypes Types { get; } = new(compilations);
+ public string ProjectName { get; } = projectName;
- public ContractTypes Types { get; }
- public string ProjectName { get; }
-
- public CompiledContracts(IReadOnlyCollection compilations, string projectName)
- {
- this.compilations = compilations;
- ProjectName = projectName;
-
- Types = new(compilations);
- }
-
- public IEnumerable ListAllTypes()
- {
- return compilations.SelectMany(c =>
+ public IEnumerable ListAllTypes() =>
+ compilations.SelectMany(c =>
c.SyntaxTrees.SelectMany(t =>
{
var model = c.GetSemanticModel(t);
@@ -33,5 +22,4 @@ public IEnumerable ListAllTypes()
.OfType();
})
);
- }
}
diff --git a/src/LeanCode.ContractsGenerator/Compilation/ContractTypes.cs b/src/LeanCode.ContractsGenerator/Compilation/ContractTypes.cs
index 8996fcf..da88829 100644
--- a/src/LeanCode.ContractsGenerator/Compilation/ContractTypes.cs
+++ b/src/LeanCode.ContractsGenerator/Compilation/ContractTypes.cs
@@ -30,7 +30,9 @@ public sealed class ContractTypes
private HashSet Equatable { get; }
+#pragma warning disable IDE0290 // Use primary constructor
public ContractTypes(IReadOnlyCollection compilations)
+#pragma warning restore IDE0290 // Use primary constructor
{
QueryType = GetUnboundTypeSymbols(compilations, typeof(IQuery<>));
CommandType = GetTypeSymbols(compilations);
@@ -54,16 +56,14 @@ private static HashSet GetTypeSymbols(IReadOnlyCollection(SymbolEqualityComparer.Default);
+
foreach (var c in compilations)
{
- var type = c.GetTypeByMetadataName(name);
- if (type is null)
- {
- throw new CompilationFailedException(
+ var type =
+ c.GetTypeByMetadataName(name)
+ ?? throw new CompilationFailedException(
$"Cannot locate type {name} in compilation unit `{c.AssemblyName ?? "UNKNOWN"}`."
);
- }
-
result.Add(type);
}
@@ -77,53 +77,43 @@ Type type
{
var name = type.FullName!;
var result = new HashSet(SymbolEqualityComparer.Default);
+
foreach (var c in compilations)
{
- var t = c.GetTypeByMetadataName(name)?.ConstructUnboundGenericType();
- if (t is null)
- {
- throw new CompilationFailedException(
+ var t =
+ (c.GetTypeByMetadataName(name)?.ConstructUnboundGenericType())
+ ?? throw new CompilationFailedException(
$"Cannot locate generic type {name} in compilation unit `{c.AssemblyName ?? "UNKNOWN"}`."
);
- }
-
result.Add(t);
}
return result;
}
- public bool IsQuery(ITypeSymbol symbol)
- {
- return symbol is INamedTypeSymbol ns
- && !ns.IsUnboundGenericType
- && !ns.IsAbstract
- && ns.AllInterfaces.Any(IsQueryType);
- }
-
- public bool IsCommand(ITypeSymbol symbol)
- {
- return symbol is INamedTypeSymbol ns
- && !ns.IsUnboundGenericType
- && !ns.IsAbstract
- && ns.AllInterfaces.Any(IsCommandType);
- }
-
- public bool IsOperation(ITypeSymbol symbol)
- {
- return symbol is INamedTypeSymbol ns
- && !ns.IsUnboundGenericType
- && !ns.IsAbstract
- && ns.AllInterfaces.Any(IsOperationType);
- }
-
- public bool IsTopic(ITypeSymbol symbol)
- {
- return symbol is INamedTypeSymbol ns
- && !ns.IsUnboundGenericType
- && !ns.IsAbstract
- && ns.AllInterfaces.Any(IsTopicType);
- }
+ public bool IsQuery(ITypeSymbol symbol) =>
+ symbol is INamedTypeSymbol ns
+ && !ns.IsUnboundGenericType
+ && !ns.IsAbstract
+ && ns.AllInterfaces.Any(IsQueryType);
+
+ public bool IsCommand(ITypeSymbol symbol) =>
+ symbol is INamedTypeSymbol ns
+ && !ns.IsUnboundGenericType
+ && !ns.IsAbstract
+ && ns.AllInterfaces.Any(IsCommandType);
+
+ public bool IsOperation(ITypeSymbol symbol) =>
+ symbol is INamedTypeSymbol ns
+ && !ns.IsUnboundGenericType
+ && !ns.IsAbstract
+ && ns.AllInterfaces.Any(IsOperationType);
+
+ public bool IsTopic(ITypeSymbol symbol) =>
+ symbol is INamedTypeSymbol ns
+ && !ns.IsUnboundGenericType
+ && !ns.IsAbstract
+ && ns.AllInterfaces.Any(IsTopicType);
public ITypeSymbol ExtractQueryResult(ITypeSymbol symbol)
{
@@ -201,27 +191,21 @@ public bool IsExcludeFromContractsGenerationType(ITypeSymbol? i) =>
public bool IsAttributeUsageType(ITypeSymbol i) => AttributeUsageAttribute.Contains(i);
- public bool IsReadOnlyDictionary(ITypeSymbol i)
- {
- return i is INamedTypeSymbol ns
- && ns.IsGenericType
- && (
- ReadOnlyDictionary.Contains(ns.ConstructUnboundGenericType())
- || Dictionary.Contains(ns.ConstructUnboundGenericType())
- );
- }
+ public bool IsReadOnlyDictionary(ITypeSymbol i) =>
+ i is INamedTypeSymbol ns
+ && ns.IsGenericType
+ && (
+ ReadOnlyDictionary.Contains(ns.ConstructUnboundGenericType())
+ || Dictionary.Contains(ns.ConstructUnboundGenericType())
+ );
- public bool IsRecordEquatable(ITypeSymbol i)
- {
- return i is INamedTypeSymbol ns
- && ns.IsGenericType
- && ns.TypeArguments is [INamedTypeSymbol namedType]
- && namedType.IsRecord
- && Equatable.Contains(ns.ConstructUnboundGenericType());
- }
+ public bool IsRecordEquatable(ITypeSymbol i) =>
+ i is INamedTypeSymbol ns
+ && ns.IsGenericType
+ && ns.TypeArguments is [INamedTypeSymbol namedType]
+ && namedType.IsRecord
+ && Equatable.Contains(ns.ConstructUnboundGenericType());
- public static bool IsRecordEqualityContract(IPropertySymbol i)
- {
- return i.ContainingType is INamedTypeSymbol ns && ns.IsRecord && i.Name == RecordEqualityContractPropertyName;
- }
+ public static bool IsRecordEqualityContract(IPropertySymbol i) =>
+ i.ContainingType is INamedTypeSymbol ns && ns.IsRecord && i.Name == RecordEqualityContractPropertyName;
}
diff --git a/src/LeanCode.ContractsGenerator/Compilation/ContractsCompiler.cs b/src/LeanCode.ContractsGenerator/Compilation/ContractsCompiler.cs
index 80f66e6..b8df78b 100644
--- a/src/LeanCode.ContractsGenerator/Compilation/ContractsCompiler.cs
+++ b/src/LeanCode.ContractsGenerator/Compilation/ContractsCompiler.cs
@@ -1,3 +1,4 @@
+using System.Collections.Frozen;
using System.Collections.Immutable;
using System.Reflection;
using Microsoft.CodeAnalysis;
@@ -11,37 +12,23 @@ namespace LeanCode.ContractsGenerator.Compilation;
public static class ContractsCompiler
{
- public static readonly ImmutableHashSet ReferenceAssemblyNames = ImmutableHashSet.Empty;
- public static readonly ImmutableHashSet DefaultAssemblyNames = ImmutableHashSet.CreateRange(
- new string[]
- {
- "System.Collections",
- "System.Linq",
- "System.Net.Http",
- "System.Runtime",
- "System.Runtime.Extensions",
- }
+ public static readonly FrozenSet DefaultAssemblyNames = FrozenSet.Create(
+ StringComparer.InvariantCultureIgnoreCase,
+ "System.Collections",
+ "System.Linq",
+ "System.Net.Http",
+ "System.Runtime",
+ "System.Runtime.Extensions"
);
- public static readonly ImmutableHashSet LeanCodeAssemblyNames = ImmutableHashSet.CreateRange(
- new[] { "LeanCode.Contracts" }
+ public static readonly FrozenSet LeanCodeAssemblyNames = FrozenSet.Create(
+ StringComparer.InvariantCultureIgnoreCase,
+ "LeanCode.Contracts"
);
- private static bool IsWantedReferenceAssembly(CompilationLibrary cl)
- {
- return cl.Type == "referenceassembly"
- && ReferenceAssemblyNames.Contains(cl.Name, StringComparer.InvariantCultureIgnoreCase);
- }
-
- private static bool IsWantedLeanCodeAssembly(CompilationLibrary cl)
- {
- return LeanCodeAssemblyNames.Contains(cl.Name, StringComparer.InvariantCultureIgnoreCase);
- }
+ private static bool IsWantedDefaultAssembly(CompilationLibrary cl) => DefaultAssemblyNames.Contains(cl.Name);
- private static bool IsWantedDefaultAssembly(CompilationLibrary cl)
- {
- return DefaultAssemblyNames.Contains(cl.Name, StringComparer.InvariantCultureIgnoreCase);
- }
+ private static bool IsWantedLeanCodeAssembly(CompilationLibrary cl) => LeanCodeAssemblyNames.Contains(cl.Name);
private static readonly Assembly ExecutingAssembly = Assembly.GetExecutingAssembly();
@@ -49,21 +36,18 @@ private static bool IsWantedDefaultAssembly(CompilationLibrary cl)
Path.GetDirectoryName(ExecutingAssembly.Location)!
);
- public static readonly ImmutableList DefaultAssemblies = DependencyContext
- .Load(ExecutingAssembly)!
- .CompileLibraries.Where(cl =>
- IsWantedReferenceAssembly(cl) || IsWantedLeanCodeAssembly(cl) || IsWantedDefaultAssembly(cl)
- )
- .SelectMany(cl => cl.ResolveReferencePaths(Resolver))
- .Select(path => MetadataReference.CreateFromFile(path))
- .ToImmutableList();
+ public static readonly ImmutableList DefaultAssemblies =
+ [
+ .. DependencyContext
+ .Load(ExecutingAssembly)!
+ .CompileLibraries.Where(cl => IsWantedDefaultAssembly(cl) || IsWantedLeanCodeAssembly(cl))
+ .SelectMany(cl => cl.ResolveReferencePaths(Resolver))
+ .Select(path => MetadataReference.CreateFromFile(path)),
+ ];
public static Task<(CompiledContracts Compiled, List External)> CompileProjectsAsync(
IEnumerable projectPaths
- )
- {
- return CompileProjectsAsync(projectPaths, ImmutableDictionary.Empty);
- }
+ ) => CompileProjectsAsync(projectPaths, ImmutableDictionary.Empty);
public static async Task<(CompiledContracts Compiled, List External)> CompileProjectsAsync(
IEnumerable projectPaths,
@@ -121,7 +105,7 @@ public static async Task CompileGlobAsync(Matcher matcher, Di
public static CompiledContracts CompileCode(string contractText, string name)
{
var contractTree = CSharpSyntaxTree.ParseText(contractText);
- return CompileTrees(new() { contractTree }, name);
+ return CompileTrees([contractTree], name);
}
private static CompiledContracts CompileTrees(List trees, string name)
@@ -135,14 +119,12 @@ private static CompiledContracts CompileTrees(List trees, string nam
return Compile(compilation, name);
}
- private static CSharpCompilationOptions PrepareCompilationOptions()
- {
- return new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
+ private static CSharpCompilationOptions PrepareCompilationOptions() =>
+ new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
.WithConcurrentBuild(true)
.WithAllowUnsafe(false)
.WithNullableContextOptions(NullableContextOptions.Annotations)
.WithPlatform(Platform.AnyCpu);
- }
[System.Diagnostics.CodeAnalysis.SuppressMessage(
"?",
@@ -186,10 +168,8 @@ private static List TryLoadEmbeddedContracts(IReadOnlyCollection { compilation }, name);
- }
+ private static CompiledContracts Compile(CSharpCompilation compilation, string name) =>
+ Compile([compilation], name);
private static CompiledContracts Compile(IReadOnlyCollection compilations, string name)
{
diff --git a/src/LeanCode.ContractsGenerator/Compilation/InvalidProjectException.cs b/src/LeanCode.ContractsGenerator/Compilation/InvalidProjectException.cs
index 801c345..4692fde 100644
--- a/src/LeanCode.ContractsGenerator/Compilation/InvalidProjectException.cs
+++ b/src/LeanCode.ContractsGenerator/Compilation/InvalidProjectException.cs
@@ -1,7 +1,3 @@
namespace LeanCode.ContractsGenerator.Compilation;
-public class InvalidProjectException : Exception
-{
- public InvalidProjectException(string msg)
- : base(msg) { }
-}
+public class InvalidProjectException(string msg) : Exception(msg);
diff --git a/src/LeanCode.ContractsGenerator/Compilation/MSBuild/LooseAssemblyVersionLoader.cs b/src/LeanCode.ContractsGenerator/Compilation/MSBuild/LooseAssemblyVersionLoader.cs
index 20e6122..58da352 100644
--- a/src/LeanCode.ContractsGenerator/Compilation/MSBuild/LooseAssemblyVersionLoader.cs
+++ b/src/LeanCode.ContractsGenerator/Compilation/MSBuild/LooseAssemblyVersionLoader.cs
@@ -11,16 +11,19 @@ namespace LeanCode.ContractsGenerator.Compilation.MSBuild;
internal static class LooseVersionAssemblyLoader
{
private static readonly Dictionary PathsToAssemblies = new(StringComparer.OrdinalIgnoreCase);
- private static readonly Dictionary NamesToAssemblies = new();
+ private static readonly Dictionary NamesToAssemblies = [];
+#if NET9_0_OR_GREATER
+ private static readonly Lock Guard = new();
+#else
private static readonly object Guard = new();
- private static readonly string[] Extensions = new[] { "ni.dll", "ni.exe", "dll", "exe" };
+#endif
+ private static readonly IReadOnlyCollection Extensions = ["ni.dll", "ni.exe", "dll", "exe"];
///
/// Register an assembly loader that will load assemblies with higher version than what was requested.
///
- public static void Register(string searchPath)
- {
+ public static void Register(string searchPath) =>
AssemblyLoadContext.Default.Resolving += (AssemblyLoadContext context, AssemblyName assemblyName) =>
{
lock (Guard)
@@ -33,7 +36,6 @@ public static void Register(string searchPath)
return TryResolveAssemblyFromPaths_NoLock(context, assemblyName, searchPath);
}
};
- }
private static Assembly TryResolveAssemblyFromPaths_NoLock(
AssemblyLoadContext context,
@@ -41,16 +43,16 @@ private static Assembly TryResolveAssemblyFromPaths_NoLock(
string searchPath
)
{
- foreach (
- var cultureSubfolder in string.IsNullOrEmpty(assemblyName.CultureName)
- // If no culture is specified, attempt to load directly from
- // the known dependency paths.
- ? new[] { string.Empty }
- // Search for satellite assemblies in culture subdirectories
- // of the assembly search directories, but fall back to the
- // bare search directory if that fails.
- : new[] { assemblyName.CultureName, string.Empty }
- )
+ Span cultureSubfolders = string.IsNullOrEmpty(assemblyName.CultureName)
+ // If no culture is specified, attempt to load directly from
+ // the known dependency paths.
+ ? [string.Empty]
+ // Search for satellite assemblies in culture subdirectories
+ // of the assembly search directories, but fall back to the
+ // bare search directory if that fails.
+ : [assemblyName.CultureName, string.Empty];
+
+ foreach (var cultureSubfolder in cultureSubfolders)
{
foreach (var extension in Extensions)
{
diff --git a/src/LeanCode.ContractsGenerator/Compilation/MSBuild/MSBuildHelper.cs b/src/LeanCode.ContractsGenerator/Compilation/MSBuild/MSBuildHelper.cs
index d0ce259..ef6f0a4 100644
--- a/src/LeanCode.ContractsGenerator/Compilation/MSBuild/MSBuildHelper.cs
+++ b/src/LeanCode.ContractsGenerator/Compilation/MSBuild/MSBuildHelper.cs
@@ -14,7 +14,7 @@ namespace LeanCode.ContractsGenerator.Compilation.MSBuild;
public static class MSBuildHelper
{
- private static readonly string[] RestoreTarget = new string[] { "Restore" };
+ private static readonly string[] RestoreTarget = ["Restore"];
private static readonly ImmutableDictionary GlobalProperties = ImmutableDictionary.CreateRange(
new Dictionary
diff --git a/src/LeanCode.ContractsGenerator/Compilation/ProjectLoader.cs b/src/LeanCode.ContractsGenerator/Compilation/ProjectLoader.cs
index d8024ba..1231f6c 100644
--- a/src/LeanCode.ContractsGenerator/Compilation/ProjectLoader.cs
+++ b/src/LeanCode.ContractsGenerator/Compilation/ProjectLoader.cs
@@ -6,15 +6,10 @@
namespace LeanCode.ContractsGenerator.Compilation;
-public sealed class ProjectLoader : IDisposable
+public sealed class ProjectLoader(ImmutableDictionary properties) : IDisposable
{
- private readonly List projects = new();
- private readonly MSBuildWorkspace msbuildWorkspace;
-
- public ProjectLoader(ImmutableDictionary properties)
- {
- msbuildWorkspace = MSBuildHelper.CreateWorkspace(properties);
- }
+ private readonly MSBuildWorkspace msbuildWorkspace = MSBuildHelper.CreateWorkspace(properties);
+ private readonly List projects = [];
public async Task LoadProjectsAsync(IEnumerable projectPaths)
{
diff --git a/src/LeanCode.ContractsGenerator/Generation/ContractsGenerator.cs b/src/LeanCode.ContractsGenerator/Generation/ContractsGenerator.cs
index e6fffe3..92563d7 100644
--- a/src/LeanCode.ContractsGenerator/Generation/ContractsGenerator.cs
+++ b/src/LeanCode.ContractsGenerator/Generation/ContractsGenerator.cs
@@ -5,23 +5,15 @@
namespace LeanCode.ContractsGenerator.Generation;
-public class ContractsGenerator
+public class ContractsGenerator(CompiledContracts contracts)
{
- private readonly CompiledContracts contracts;
-
- private readonly TypeRefFactory typeRef;
-
- public ContractsGenerator(CompiledContracts contracts)
- {
- this.contracts = contracts;
-
- typeRef = new(contracts);
- }
+ private readonly TypeRefFactory typeRef = new(contracts);
public Export Generate()
{
var export = GenerateCore();
- return Analyze(export);
+ Analyze(export);
+ return export;
}
public Export Generate(List externalContracts, bool excludeExternalContractsFromOutput)
@@ -56,17 +48,14 @@ private Export GenerateCore()
return export;
}
- private static Export Analyze(Export export)
+ private static void Analyze(Export export)
{
var errors = new Analyzers.AllAnalyzers().Analyze(export).ToList();
+
if (errors.Count > 0)
{
throw new AnalyzeFailedException(errors);
}
- else
- {
- return export;
- }
}
private Statement? ProcessType(INamedTypeSymbol? symbol)
@@ -159,57 +148,38 @@ void MapProperties(INamedTypeSymbol symbol, TypeDescriptor descriptor)
}
}
- private bool IsNotIgnored([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] INamedTypeSymbol? symbol)
- {
- return !IsIgnored(symbol);
- }
+ private bool IsNotIgnored([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] INamedTypeSymbol? symbol) =>
+ !IsIgnored(symbol);
- private bool IsIgnored([System.Diagnostics.CodeAnalysis.NotNullWhen(false)] INamedTypeSymbol? symbol)
- {
- return symbol is null
- || symbol.SpecialType == SpecialType.System_Object
- || symbol.SpecialType == SpecialType.System_ValueType
- || symbol.SpecialType == SpecialType.System_Enum
- || ErrorCodes.IsErrorCode(symbol)
- || contracts.Types.IsProduceNotificationType(symbol)
- || contracts.Types.IsAttributeUsageType(symbol)
- || contracts.Types.IsRecordEquatable(symbol);
- }
+ private bool IsIgnored([System.Diagnostics.CodeAnalysis.NotNullWhen(false)] INamedTypeSymbol? symbol) =>
+ symbol is null
+ || symbol.SpecialType == SpecialType.System_Object
+ || symbol.SpecialType == SpecialType.System_ValueType
+ || symbol.SpecialType == SpecialType.System_Enum
+ || ErrorCodes.IsErrorCode(symbol)
+ || contracts.Types.IsProduceNotificationType(symbol)
+ || contracts.Types.IsAttributeUsageType(symbol)
+ || contracts.Types.IsRecordEquatable(symbol);
- private bool IsExcluded(ISymbol symbol)
- {
- return (symbol is IPropertySymbol ps && ContractTypes.IsRecordEqualityContract(ps))
- || symbol.GetAttributes().Any(a => contracts.Types.IsExcludeFromContractsGenerationType(a.AttributeClass));
- }
+ private bool IsExcluded(ISymbol symbol) =>
+ (symbol is IPropertySymbol ps && ContractTypes.IsRecordEqualityContract(ps))
+ || symbol.GetAttributes().Any(a => contracts.Types.IsExcludeFromContractsGenerationType(a.AttributeClass));
- private static HashSet GatherBaseProperties(INamedTypeSymbol ns)
- {
- return ns
- .AllInterfaces.SelectMany(i => i.GetMembers())
- .OfType()
- .Select(p => p.Name)
- .ToHashSet();
- }
+ private static HashSet GatherBaseProperties(INamedTypeSymbol ns) =>
+ [.. ns.AllInterfaces.SelectMany(i => i.GetMembers()).OfType().Select(p => p.Name)];
- private static bool AlreadyImplemented(IPropertySymbol prop, HashSet baseProps)
- {
- return baseProps.Contains(prop.Name);
- }
+ private static bool AlreadyImplemented(IPropertySymbol prop, HashSet baseProps) =>
+ baseProps.Contains(prop.Name);
- private GenericParameter ToParam(ITypeParameterSymbol ts)
- {
- return new() { Name = ts.Name };
- }
+ private GenericParameter ToParam(ITypeParameterSymbol ts) => new() { Name = ts.Name };
- private ConstantRef ToConstant(IFieldSymbol fs)
- {
- return new()
+ private ConstantRef ToConstant(IFieldSymbol fs) =>
+ new()
{
Name = fs.Name,
Value = fs.ConstantValue.ToValueRef(),
Comment = fs.GetComments(),
};
- }
private PropertyRef ToProperty(IPropertySymbol ps)
{
@@ -282,7 +252,7 @@ static AttributeArgument ToPositionalArgument(object? v, int i)
static IEnumerable
diff --git a/src/LeanCode.ContractsGenerator/Program.cs b/src/LeanCode.ContractsGenerator/Program.cs
index af8bdc4..79fb6a8 100644
--- a/src/LeanCode.ContractsGenerator/Program.cs
+++ b/src/LeanCode.ContractsGenerator/Program.cs
@@ -2,7 +2,6 @@
using Google.Protobuf;
using LeanCode.ContractsGenerator.Compilation;
using LeanCode.ContractsGenerator.Generation;
-using Microsoft.CodeAnalysis;
using Microsoft.Extensions.FileSystemGlobbing;
namespace LeanCode.ContractsGenerator;
@@ -44,7 +43,7 @@ public class ProjectOptions : IOptions
MetaValue = "FILE",
HelpText = "The project file with contracts. To pass multiple projects, separate the values with space."
)]
- public IEnumerable ProjectFiles { get; set; } = Array.Empty();
+ public IEnumerable ProjectFiles { get; set; } = [];
}
[Verb("file", HelpText = "Generate contracts from a single file.")]
@@ -70,7 +69,7 @@ public class PathOptions : IOptions
MetaValue = "PATTERN",
HelpText = "Include files from glob pattern. To pass multiple patterns, separate them with space."
)]
- public IEnumerable Include { get; set; } = Array.Empty();
+ public IEnumerable Include { get; set; } = [];
[Option(
'e',
@@ -79,7 +78,7 @@ public class PathOptions : IOptions
MetaValue = "PATTERN",
HelpText = "Exclude files from glob pattern. Has higher precedence than includes. To pass multiple patterns, separate them with space."
)]
- public IEnumerable Exclude { get; set; } = Array.Empty();
+ public IEnumerable Exclude { get; set; } = [];
[Option(
'd',
@@ -227,33 +226,8 @@ private static async Task WriteToFileAsync(Export generated, string filepath)
private static async Task WriteToStdoutAsync(Export generated)
{
- await using var outputStream = System.Console.OpenStandardOutput();
+ await using var outputStream = Console.OpenStandardOutput();
using var codedOutput = new CodedOutputStream(outputStream, true);
generated.WriteTo(codedOutput);
}
-
- private static string FormatLocation(Location location)
- {
- var lineSpan = location.GetMappedLineSpan();
- if (lineSpan.Path is not null)
- {
- return lineSpan.Path
- + "@"
- + (lineSpan.StartLinePosition.Line + 1)
- + ":"
- + (lineSpan.StartLinePosition.Character + 1);
- }
- else if (location.IsInSource)
- {
- return location.Kind + "(" + location.SourceTree?.FilePath + location.SourceSpan.ToString() + ")";
- }
- else if (location.IsInMetadata && location.MetadataModule is not null)
- {
- return location.Kind + "(" + location.MetadataModule.Name + ")";
- }
- else
- {
- return location.Kind.ToString();
- }
- }
}