diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0c57371d3..2726a126b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,28 @@
Release Notes
====
+# 02-17-2024
+DotNext 5.0.2
+* Fixed XML docs
+
+DotNext.Metaprogramming 5.0.2
+* Fixed [223](https://github.com/dotnet/dotNext/issues/223)
+
+DotNext.Unsafe 5.0.2
+* Updated dependencies
+
+DotNext.Threading 5.0.2
+* Added correct validation for maximum possible timeout for all `WaitAsync` methods
+
+DotNext.IO 5.0.2
+* Updated dependencies
+
+DotNext.Net.Cluster 5.0.2
+* Prevent indexing of WAL files on Windows
+
+DotNext.AspNetCore.Cluster 5.0.2
+* Updated dependencies
+
# 01-23-2024
DotNext 5.0.1
* Smallish performance improvements of dynamic buffers
diff --git a/README.md b/README.md
index b596fdf44..e11bc6c5d 100644
--- a/README.md
+++ b/README.md
@@ -44,30 +44,27 @@ All these things are implemented in 100% managed code on top of existing .NET AP
* [NuGet Packages](https://www.nuget.org/profiles/rvsakno)
# What's new
-Release Date: 01-23-2024
+Release Date: 02-17-2024
-DotNext 5.0.1
-* Smallish performance improvements of dynamic buffers
+DotNext 5.0.2
+* Fixed XML docs
-DotNext.Metaprogramming 5.0.1
-* Updated dependencies
+DotNext.Metaprogramming 5.0.2
+* Fixed [223](https://github.com/dotnet/dotNext/issues/223)
-DotNext.Unsafe 5.0.1
+DotNext.Unsafe 5.0.2
* Updated dependencies
-DotNext.Threading 5.0.1
-* Updated dependencies
+DotNext.Threading 5.0.2
+* Added correct validation for maximum possible timeout for all `WaitAsync` methods
-DotNext.IO 5.0.1
-* Improved performance of `FileWriter` and `FileBufferingWriter` classes by utilizing Scatter/Gather IO
-* Reduced memory allocations required by async methods of `FileWriter` and `FileBufferingWriter` classes
+DotNext.IO 5.0.2
* Updated dependencies
-DotNext.Net.Cluster 5.0.1
-* Improved IO performance of Persistent WAL due to related improvements in DotNext.IO library
-* Updated dependencies
+DotNext.Net.Cluster 5.0.2
+* Prevent indexing of WAL files on Windows
-DotNext.AspNetCore.Cluster 5.0.1
+DotNext.AspNetCore.Cluster 5.0.2
* Updated dependencies
Changelog for previous versions located [here](./CHANGELOG.md).
diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
index 8ce0e4022..4b1b87523 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -19,7 +19,7 @@
-
+
@@ -27,14 +27,14 @@
-
+
-
-
+
+
\ No newline at end of file
diff --git a/src/DotNext.IO/DotNext.IO.csproj b/src/DotNext.IO/DotNext.IO.csproj
index 719897c8e..3eebc2074 100644
--- a/src/DotNext.IO/DotNext.IO.csproj
+++ b/src/DotNext.IO/DotNext.IO.csproj
@@ -11,7 +11,7 @@
.NET Foundation and Contributors
.NEXT Family of Libraries
- 5.0.1
+ 5.0.2
DotNext.IO
MIT
diff --git a/src/DotNext.Metaprogramming/DotNext.Metaprogramming.csproj b/src/DotNext.Metaprogramming/DotNext.Metaprogramming.csproj
index 9cbc9292f..e9e1ad8e0 100644
--- a/src/DotNext.Metaprogramming/DotNext.Metaprogramming.csproj
+++ b/src/DotNext.Metaprogramming/DotNext.Metaprogramming.csproj
@@ -8,7 +8,7 @@
true
false
nullablePublicOnly
- 5.0.1
+ 5.0.2
.NET Foundation
.NEXT Family of Libraries
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/AsyncResultExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/AsyncResultExpression.cs
index 730bc4471..0a1ffb1bb 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/AsyncResultExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/AsyncResultExpression.cs
@@ -60,6 +60,10 @@ public AsyncResultExpression(bool valueTask)
///
public override Type Type => taskType;
+ // indicates that AsyncResult cannot throw exception so it can be inlined
+ internal bool IsSimpleResult
+ => AsyncResult is ConstantExpression or ParameterExpression or DefaultExpression;
+
///
/// Translates this expression into predefined set of expressions
/// using Lowering technique.
@@ -103,4 +107,7 @@ protected override AsyncResultExpression VisitChildren(ExpressionVisitor visitor
var expression = visitor.Visit(AsyncResult);
return ReferenceEquals(expression, AsyncResult) ? this : new(expression, taskType);
}
+
+ internal AsyncResultExpression Update(Expression asyncResult)
+ => new(asyncResult, taskType);
}
\ No newline at end of file
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/CollectionAccessExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/CollectionAccessExpression.cs
index 90ac36a39..86f4787a3 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/CollectionAccessExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/CollectionAccessExpression.cs
@@ -138,11 +138,11 @@ public override Expression Reduce()
if (indexer is null)
result = ArrayAccess(temp ?? Collection, Index);
else if (count is null)
- result = MakeIndex(temp ?? Collection, indexer, new[] { Index.Reduce() });
+ result = MakeIndex(temp ?? Collection, indexer, [Index.Reduce()]);
else
- result = MakeIndex(temp ?? Collection, indexer, new[] { MakeIndex(temp ?? Collection, count, Index) });
+ result = MakeIndex(temp ?? Collection, indexer, [MakeIndex(temp ?? Collection, count, Index)]);
- return temp is null ? result : Block(Type, new[] { temp }, Assign(temp, Collection), result);
+ return temp is null ? result : Block(Type, [temp], Assign(temp, Collection), result);
}
///
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/ExpressionBuilder.cs b/src/DotNext.Metaprogramming/Linq/Expressions/ExpressionBuilder.cs
index 172c2fcb5..9ad3e4eed 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/ExpressionBuilder.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/ExpressionBuilder.cs
@@ -1206,7 +1206,7 @@ internal static Expression AddEpilogue(this Expression expression, bool inferTyp
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, typeof(Activator))]
public static MethodCallExpression New(this Expression type, params Expression[] args)
{
- var activate = typeof(Activator).GetMethod(nameof(Activator.CreateInstance), new[] { typeof(Type), typeof(object[]) });
+ var activate = typeof(Activator).GetMethod(nameof(Activator.CreateInstance), [typeof(Type), typeof(object[])]);
Debug.Assert(activate is not null);
return Expression.Call(activate, type, Expression.NewArrayInit(typeof(object), args));
}
@@ -1456,9 +1456,9 @@ public static Expression AsOptional(this Expression expression)
public static Expression AsResult(this Expression expression)
{
var exception = Expression.Parameter(typeof(Exception));
- var ctor = typeof(Result<>).MakeGenericType(expression.Type).GetConstructor(new[] { expression.Type });
+ var ctor = typeof(Result<>).MakeGenericType(expression.Type).GetConstructor([expression.Type]);
Debug.Assert(ctor?.DeclaringType is not null);
- var fallbackCtor = ctor.DeclaringType.GetConstructor(new[] { typeof(Exception) });
+ var fallbackCtor = ctor.DeclaringType.GetConstructor([typeof(Exception)]);
Debug.Assert(fallbackCtor is not null);
return Expression.TryCatch(
Expression.New(ctor, expression),
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/InterpolationExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/InterpolationExpression.cs
index 76d983426..aa8f1b3f8 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/InterpolationExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/InterpolationExpression.cs
@@ -105,19 +105,19 @@ private Expression MakePlainString()
case 0:
return Constant(Format);
case 1:
- var formatMethod = typeof(string).GetMethod(nameof(string.Format), new[] { typeof(IFormatProvider), typeof(string), typeof(object) });
+ var formatMethod = typeof(string).GetMethod(nameof(string.Format), [typeof(IFormatProvider), typeof(string), typeof(object)]);
Debug.Assert(formatMethod is not null);
return Call(formatMethod, FormatProvider, Constant(Format), arguments[0]);
case 2:
- formatMethod = typeof(string).GetMethod(nameof(string.Format), new[] { typeof(IFormatProvider), typeof(string), typeof(object), typeof(object) });
+ formatMethod = typeof(string).GetMethod(nameof(string.Format), [typeof(IFormatProvider), typeof(string), typeof(object), typeof(object)]);
Debug.Assert(formatMethod is not null);
return Call(formatMethod, FormatProvider, Constant(Format), FormatProvider, arguments[0], arguments[1]);
case 3:
- formatMethod = typeof(string).GetMethod(nameof(string.Format), new[] { typeof(IFormatProvider), typeof(string), typeof(object), typeof(object), typeof(object) });
+ formatMethod = typeof(string).GetMethod(nameof(string.Format), [typeof(IFormatProvider), typeof(string), typeof(object), typeof(object), typeof(object)]);
Debug.Assert(formatMethod is not null);
return Call(formatMethod, FormatProvider, Constant(Format), FormatProvider, arguments[0], arguments[1], arguments[2]);
default:
- formatMethod = typeof(string).GetMethod(nameof(string.Format), new[] { typeof(IFormatProvider), typeof(string), typeof(object[]) });
+ formatMethod = typeof(string).GetMethod(nameof(string.Format), [typeof(IFormatProvider), typeof(string), typeof(object[])]);
Debug.Assert(formatMethod is not null);
return Call(formatMethod, FormatProvider, Constant(Format), FormatProvider, NewArrayInit(typeof(object), arguments));
}
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/ItemIndexExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/ItemIndexExpression.cs
index 0aafdb835..1369ac13c 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/ItemIndexExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/ItemIndexExpression.cs
@@ -74,7 +74,7 @@ internal static Expression GetOffset(Expression index, Expression count)
/// Translated expression.
public override Expression Reduce()
{
- ConstructorInfo? ctor = typeof(Index).GetConstructor(new[] { typeof(int), typeof(bool) });
+ ConstructorInfo? ctor = typeof(Index).GetConstructor([typeof(int), typeof(bool)]);
Debug.Assert(ctor is not null);
return New(ctor, conversionRequired ? Convert(Value, typeof(int)) : Value, Constant(IsFromEnd));
}
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/LockExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/LockExpression.cs
index 36252f1fb..e360d689e 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/LockExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/LockExpression.cs
@@ -94,9 +94,9 @@ public Expression Body
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, typeof(Monitor))]
public override Expression Reduce()
{
- var monitorEnter = typeof(Monitor).GetMethod(nameof(Monitor.Enter), new[] { typeof(object) });
+ var monitorEnter = typeof(Monitor).GetMethod(nameof(Monitor.Enter), [typeof(object)]);
Debug.Assert(monitorEnter is not null);
- var monitorExit = typeof(Monitor).GetMethod(nameof(Monitor.Exit), new[] { typeof(object) });
+ var monitorExit = typeof(Monitor).GetMethod(nameof(Monitor.Exit), [typeof(object)]);
Debug.Assert(monitorExit is not null);
var body = TryFinally(Body, Call(monitorExit, SyncRoot));
return assignment is null ?
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/MetaExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/MetaExpression.cs
index 8122eb1a7..37b2245a3 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/MetaExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/MetaExpression.cs
@@ -70,7 +70,7 @@ private static Expression ToExpression(DynamicMetaObject arg, out BindingRestric
}
}
- return Expression.Call(typeof(ExpressionBuilder), nameof(ExpressionBuilder.Const), new[] { arg.Expression.Type }, arg.Expression);
+ return Expression.Call(typeof(ExpressionBuilder), nameof(ExpressionBuilder.Const), [arg.Expression.Type], arg.Expression);
}
private static IReadOnlyList ToExpressions(DynamicMetaObject[] args, out BindingRestrictions restrictions)
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/MutationExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/MutationExpression.cs
index b71612d15..0d602e79b 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/MutationExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/MutationExpression.cs
@@ -95,13 +95,13 @@ public override Expression Reduce()
if (Bindings.Count > 0)
{
var tempVar = Parameter(Type, "copy");
- ICollection statements = new List(Bindings.Count + 2) { Assign(tempVar, result) };
+ List statements = new(Bindings.Count + 2) { Assign(tempVar, result) };
foreach (var binding in Bindings)
statements.Add(Assign(MakeMemberAccess(tempVar, binding.Member), binding.Expression));
statements.Add(tempVar);
- result = Block(tempVar.Type, new[] { tempVar }, statements);
+ result = Block(tempVar.Type, [tempVar], statements);
}
return result;
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/NullCoalescingAssignmentExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/NullCoalescingAssignmentExpression.cs
index c35fe0eca..b0faa95be 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/NullCoalescingAssignmentExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/NullCoalescingAssignmentExpression.cs
@@ -84,7 +84,7 @@ public override Expression Reduce()
return Block(
Left.Type,
- new[] { localVar },
+ [localVar],
Assign(localVar, Left),
Assign(Left, Build(localVar, Right)),
localVar);
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/RangeExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/RangeExpression.cs
index 65a7f8600..a44c20af7 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/RangeExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/RangeExpression.cs
@@ -56,7 +56,7 @@ internal static Expression GetOffsetAndLength(Expression range, Expression lengt
/// Translated expression.
public override Expression Reduce()
{
- ConstructorInfo? ctor = typeof(Range).GetConstructor(new[] { typeof(Index), typeof(Index) });
+ ConstructorInfo? ctor = typeof(Range).GetConstructor([typeof(Index), typeof(Index)]);
Debug.Assert(ctor is not null);
return New(ctor, Start.Reduce(), End.Reduce());
}
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/RefAnyValExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/RefAnyValExpression.cs
index 7fa48cab0..b03c4e279 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/RefAnyValExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/RefAnyValExpression.cs
@@ -42,5 +42,5 @@ public RefAnyValExpression(ParameterExpression typedRef, Type referenceType)
/// using Lowering technique.
///
/// Translated expression.
- public override Expression Reduce() => Call(typeof(Intrinsics), nameof(Intrinsics.AsRef), new[] { ReferenceType }, TypedReferenceVar);
+ public override Expression Reduce() => Call(typeof(Intrinsics), nameof(Intrinsics.AsRef), [ReferenceType], TypedReferenceVar);
}
\ No newline at end of file
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/SliceExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/SliceExpression.cs
index bb2fee5fb..68abb4b28 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/SliceExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/SliceExpression.cs
@@ -99,7 +99,7 @@ private static IEnumerable GetSliceMethods(Type collection)
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, typeof(RuntimeHelpers))]
private static MethodCallExpression SubArray(Expression array, Expression range)
{
- MethodInfo? subArray = typeof(RuntimeHelpers).GetMethod(nameof(RuntimeHelpers.GetSubArray), 1, new[] { Type.MakeGenericMethodParameter(0).MakeArrayType(), typeof(Range) });
+ MethodInfo? subArray = typeof(RuntimeHelpers).GetMethod(nameof(RuntimeHelpers.GetSubArray), 1, [Type.MakeGenericMethodParameter(0).MakeArrayType(), typeof(Range)]);
Debug.Assert(subArray is not null);
subArray = subArray.MakeGenericMethod(array.Type.GetElementType()!);
return Call(subArray, array, range.Reduce());
@@ -108,7 +108,7 @@ private static MethodCallExpression SubArray(Expression array, Expression range)
private static BlockExpression SubCollection(Expression collection, MethodInfo slice, PropertyInfo count, Expression range)
{
var offsetAndLengthCall = RangeExpression.GetOffsetAndLength(range, Property(collection, count), out var offsetAndLength, out var offsetField, out var lengthField);
- return Block(new[] { offsetAndLength }, Assign(offsetAndLength, offsetAndLengthCall), Call(collection, slice, offsetField, lengthField));
+ return Block([offsetAndLength], Assign(offsetAndLength, offsetAndLengthCall), Call(collection, slice, offsetField, lengthField));
}
///
@@ -127,7 +127,7 @@ public override Expression Reduce()
else
result = SubCollection(temp ?? Collection, slice, count, Range);
- return temp is null ? result : Block(Type, new[] { temp }, Assign(temp, Collection), result);
+ return temp is null ? result : Block(Type, [temp], Assign(temp, Collection), result);
}
///
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/WriteLineExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/WriteLineExpression.cs
index b8a4a37e3..49dfd35b7 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/WriteLineExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/WriteLineExpression.cs
@@ -60,7 +60,7 @@ private WriteLineExpression(Expression value, Kind kind)
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, typeof(TextWriter))]
private static MethodCallExpression WriteLineTo(MemberExpression stream, Expression value)
{
- MethodInfo? writeLineMethod = typeof(TextWriter).GetMethod(nameof(TextWriter.WriteLine), new[] { value.Type });
+ MethodInfo? writeLineMethod = typeof(TextWriter).GetMethod(nameof(TextWriter.WriteLine), [value.Type]);
// WriteLine method will always be resolved here because Type.DefaultBinder
// chooses TextWriter.WriteLine(object) if there is no exact match
@@ -91,7 +91,7 @@ private MethodCallExpression WriteLineToError()
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, typeof(System.Diagnostics.Debug))]
private MethodCallExpression WriteLineToDebug()
{
- var writeLineMethod = typeof(System.Diagnostics.Debug).GetMethod(nameof(System.Diagnostics.Debug.WriteLine), new[] { typeof(object) });
+ var writeLineMethod = typeof(System.Diagnostics.Debug).GetMethod(nameof(System.Diagnostics.Debug.WriteLine), [typeof(object)]);
System.Diagnostics.Debug.Assert(writeLineMethod is not null);
return Call(writeLineMethod, value.Type.IsValueType ? Convert(value, typeof(object)) : value);
}
diff --git a/src/DotNext.Metaprogramming/Metaprogramming/MatchBuilder.cs b/src/DotNext.Metaprogramming/Metaprogramming/MatchBuilder.cs
index 4ce80f4a9..1ceeabeb6 100644
--- a/src/DotNext.Metaprogramming/Metaprogramming/MatchBuilder.cs
+++ b/src/DotNext.Metaprogramming/Metaprogramming/MatchBuilder.cs
@@ -193,7 +193,7 @@ public MatchBuilder Case(string memberName, Expression memberValue, FuncThe action to be executed if object matches to the pattern.
/// this builder.
public MatchBuilder Case(string memberName1, Expression memberValue1, string memberName2, Expression memberValue2, Func body)
- => Case(StructuralPattern(new[] { (memberName1, memberValue1), (memberName2, memberValue2) }), value => body(Expression.PropertyOrField(value, memberName1), Expression.PropertyOrField(value, memberName2)));
+ => Case(StructuralPattern([(memberName1, memberValue1), (memberName2, memberValue2)]), value => body(Expression.PropertyOrField(value, memberName1), Expression.PropertyOrField(value, memberName2)));
///
/// Defines pattern matching based on structural matching.
@@ -207,7 +207,7 @@ public MatchBuilder Case(string memberName1, Expression memberValue1, string mem
/// The action to be executed if object matches to the pattern.
/// this builder.
public MatchBuilder Case(string memberName1, Expression memberValue1, string memberName2, Expression memberValue2, string memberName3, Expression memberValue3, Func body)
- => Case(StructuralPattern(new[] { (memberName1, memberValue1), (memberName2, memberValue2), (memberName3, memberValue3) }), value => body(Expression.PropertyOrField(value, memberName1), Expression.PropertyOrField(value, memberName2), Expression.PropertyOrField(value, memberName3)));
+ => Case(StructuralPattern([(memberName1, memberValue1), (memberName2, memberValue2), (memberName3, memberValue3)]), value => body(Expression.PropertyOrField(value, memberName1), Expression.PropertyOrField(value, memberName2), Expression.PropertyOrField(value, memberName3)));
private static (string, Expression) GetMemberPattern(object @this, string memberName, Type memberType, Func
+/// The total number of characters in known at compile-time.
+/// The number of placeholders.
[InterpolatedStringHandler]
[StructLayout(LayoutKind.Auto)]
-public struct InterpolatedStringTemplateBuilder
+public struct InterpolatedStringTemplateBuilder(int literalLength, int formattedCount)
{
[StructLayout(LayoutKind.Auto)]
private readonly struct Segment
@@ -95,20 +97,7 @@ internal void WriteTo(scoped ref int position, scoped ref BufferWriterSlim
}
}
- private readonly int literalLength, formattedCount;
- private List? segments;
-
- ///
- /// Initializes a new builder.
- ///
- /// The total number of characters in known at compile-time.
- /// The number of placeholders.
- public InterpolatedStringTemplateBuilder(int literalLength, int formattedCount)
- {
- segments = new(formattedCount);
- this.literalLength = literalLength;
- this.formattedCount = formattedCount;
- }
+ private List? segments = new(formattedCount);
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private List Segments => segments ??= [];
@@ -207,7 +196,7 @@ public readonly LambdaExpression Build()
// try-finally block to dispose the writer
expr = Expression.Block(statements);
expr = Expression.TryFinally(expr, Expression.Call(writerLocal, nameof(BufferWriterSlim.Dispose), []));
- expr = Expression.Block(new[] { preallocatedBufferLocal, writerLocal, handlerLocal }, expr);
+ expr = Expression.Block([preallocatedBufferLocal, writerLocal, handlerLocal], expr);
return Expression.Lambda(
expr,
diff --git a/src/DotNext.Metaprogramming/Runtime/CompilerServices/MoveNextExpression.cs b/src/DotNext.Metaprogramming/Runtime/CompilerServices/MoveNextExpression.cs
index 852a9b570..2e43ceb98 100644
--- a/src/DotNext.Metaprogramming/Runtime/CompilerServices/MoveNextExpression.cs
+++ b/src/DotNext.Metaprogramming/Runtime/CompilerServices/MoveNextExpression.cs
@@ -31,7 +31,7 @@ internal override Expression Reduce(ParameterExpression stateMachine)
{
const BindingFlags PublicInstanceFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
var genericParam = Type.MakeGenericMethodParameter(0).MakeByRefType();
- var moveNext = stateMachine.Type.GetMethod(nameof(AsyncStateMachine.MoveNext), 1, PublicInstanceFlags, null, new[] { genericParam, typeof(uint) }, null)!.MakeGenericMethod(awaiter.Type);
+ var moveNext = stateMachine.Type.GetMethod(nameof(AsyncStateMachine.MoveNext), 1, PublicInstanceFlags, null, [genericParam, typeof(uint)], null)!.MakeGenericMethod(awaiter.Type);
return stateMachine.Call(moveNext, awaiter, StateId);
}
}
\ No newline at end of file
diff --git a/src/DotNext.Metaprogramming/Runtime/CompilerServices/Statement.cs b/src/DotNext.Metaprogramming/Runtime/CompilerServices/Statement.cs
index 3067c0d75..34fd1ceff 100644
--- a/src/DotNext.Metaprogramming/Runtime/CompilerServices/Statement.cs
+++ b/src/DotNext.Metaprogramming/Runtime/CompilerServices/Statement.cs
@@ -40,13 +40,13 @@ internal void Insert(Expression expr)
internal readonly Expression Content;
internal Statement(Expression expression)
- : this(expression, Enumerable.Empty(), Enumerable.Empty())
+ : this(expression, [], [])
{
}
private Statement(Expression expression, IEnumerable prologue, IEnumerable epilogue)
{
- Content = expression ?? Empty();
+ Content = expression;
if (expression is Statement stmt)
{
InsertIntoHead(prologue, this.prologue = stmt.prologue);
@@ -57,19 +57,19 @@ private Statement(Expression expression, IEnumerable prologue, IEnum
this.prologue = new LinkedList(prologue);
this.epilogue = new LinkedList(epilogue);
}
- }
- private static void InsertIntoHead(IEnumerable source, LinkedList destination)
- {
- if (destination.First is null)
+ static void InsertIntoHead(IEnumerable source, LinkedList destination)
{
- destination.AddAll(source);
- }
- else
- {
- var first = destination.First;
- foreach (var expr in source)
- destination.AddBefore(first, expr);
+ if (destination.First is null)
+ {
+ destination.AddAll(source);
+ }
+ else
+ {
+ var first = destination.First;
+ foreach (var expr in source)
+ destination.AddBefore(first, expr);
+ }
}
}
@@ -78,43 +78,36 @@ private static void InsertIntoHead(IEnumerable source, LinkedList loop = loop.Update(loop.BreakLabel, loop.ContinueLabel, Wrap(loop.Body));
+ internal static LoopExpression Rewrite(LoopExpression loop)
+ => loop.Update(loop.BreakLabel, loop.ContinueLabel, Wrap(loop.Body));
- internal static void Rewrite(ref BlockExpression block)
- => block = block.Update(block.Variables, block.Expressions.Select(Wrap)!);
+ internal static BlockExpression Rewrite(BlockExpression block)
+ => block.Update(block.Variables, block.Expressions.Select(Wrap)!);
- internal static void Rewrite(ref SwitchExpression @switch)
- => @switch = @switch.Update(@switch.SwitchValue, @switch.Cases.Select(c => c.Update(c.TestValues, Wrap(c.Body))), Wrap(@switch.DefaultBody));
+ internal static SwitchExpression Rewrite(SwitchExpression @switch)
+ => @switch.Update(@switch.SwitchValue, @switch.Cases.Select(c => c.Update(c.TestValues, Wrap(c.Body))), Wrap(@switch.DefaultBody));
private static CodeInsertionPoint CaptureRewritePoint(LinkedList codeBlock)
- {
- if (codeBlock.First is null)
- return new CodeInsertionPoint(codeBlock);
-
- Debug.Assert(codeBlock.Last is not null);
- return new CodeInsertionPoint(codeBlock.Last);
- }
+ => codeBlock.Last is { } last ? new(last) : new(codeBlock);
internal DotNext.CodeInsertionPoint PrologueCodeInserter() => CaptureRewritePoint(prologue).Insert;
diff --git a/src/DotNext.Metaprogramming/Runtime/CompilerServices/VisitorContext.cs b/src/DotNext.Metaprogramming/Runtime/CompilerServices/VisitorContext.cs
index 7b08b9620..005a4e685 100644
--- a/src/DotNext.Metaprogramming/Runtime/CompilerServices/VisitorContext.cs
+++ b/src/DotNext.Metaprogramming/Runtime/CompilerServices/VisitorContext.cs
@@ -90,7 +90,8 @@ private void ContainsAwait()
foreach (var attr in attributes)
{
if (ReferenceEquals(ExpressionAttributes.Get(CurrentStatement), attr))
- return;
+ break;
+
attr.ContainsAwait = true;
}
}
diff --git a/src/DotNext.Tests/IO/Hashing/FNV1aTests.cs b/src/DotNext.Tests/IO/Hashing/FNV1aTests.cs
index ab9c00c77..d14f9869c 100644
--- a/src/DotNext.Tests/IO/Hashing/FNV1aTests.cs
+++ b/src/DotNext.Tests/IO/Hashing/FNV1aTests.cs
@@ -37,7 +37,7 @@ private static void HashTest(FNV1a algor
[Theory]
[InlineData(false)]
[InlineData(true)]
- public static void Hash128(bool salted) => HashTest(new FNV1a64(salted));
+ public static void Hash128(bool salted) => HashTest(new FNV1a128(salted));
[Fact]
public static void HashList()
diff --git a/src/DotNext.Tests/Metaprogramming/RegressionIssue17.cs b/src/DotNext.Tests/Metaprogramming/RegressionIssue17.cs
index e4c2f94c9..5456cee9e 100644
--- a/src/DotNext.Tests/Metaprogramming/RegressionIssue17.cs
+++ b/src/DotNext.Tests/Metaprogramming/RegressionIssue17.cs
@@ -40,13 +40,8 @@ private static Expression>> GetTestExpression(bo
});
}
- public class TestClass
+ public class TestClass(string testString)
{
- public TestClass(string testString)
- {
- TestString = testString;
- }
-
- public string TestString { get; set; }
+ public string TestString { get; set; } = testString;
}
}
\ No newline at end of file
diff --git a/src/DotNext.Tests/Metaprogramming/RegressionIssue223.cs b/src/DotNext.Tests/Metaprogramming/RegressionIssue223.cs
new file mode 100644
index 000000000..a2690d99e
--- /dev/null
+++ b/src/DotNext.Tests/Metaprogramming/RegressionIssue223.cs
@@ -0,0 +1,41 @@
+using System.Linq.Expressions;
+using System.Reflection;
+using DotNext.Linq.Expressions;
+
+namespace DotNext.Metaprogramming;
+
+using static Linq.Expressions.ExpressionBuilder;
+using static Metaprogramming.CodeGenerator;
+
+public sealed class RegressionIssue223 : Test
+{
+ [Fact]
+ public static async Task ThrowOnReturn()
+ {
+ var lambda = AsyncLambda>>(_ =>
+ {
+ Try(() =>
+ {
+ var methodInfo = new Func>(Throw).Method;
+ var methodResult = Expression.Call(null, methodInfo);
+
+ Return(methodResult.Await());
+ })
+ .Catch(typeof(Exception), _ =>
+ {
+ CallStatic(typeof(Console), nameof(Console.WriteLine), Expression.Constant("Exception caught"));
+ })
+ .End();
+ });
+
+ var action = lambda.Compile();
+
+ Equal(0, await action());
+
+ static async Task Throw()
+ {
+ await Task.Yield();
+ throw new InvalidOperationException("Exception was not caught");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/DotNext.Tests/Threading/SchedulerTests.cs b/src/DotNext.Tests/Threading/SchedulerTests.cs
index abb99f94a..89e42263e 100644
--- a/src/DotNext.Tests/Threading/SchedulerTests.cs
+++ b/src/DotNext.Tests/Threading/SchedulerTests.cs
@@ -51,4 +51,10 @@ public static void ScheduleCanceled()
True(Scheduler.ScheduleAsync(static (args, token) => ValueTask.CompletedTask, 42, DefaultTimeout, new(true)).Task.IsCanceled);
True(Scheduler.ScheduleAsync(static (args, token) => ValueTask.FromResult(42), 42, DefaultTimeout, new(true)).Task.IsCanceled);
}
+
+ [Fact]
+ public static void TooLargeTimeout()
+ {
+ Throws(static () => Scheduler.ScheduleAsync(static (args, token) => ValueTask.FromResult(args), 42, TimeSpan.FromMilliseconds(Timeout.MaxTimeoutParameterTicks + 1L)));
+ }
}
\ No newline at end of file
diff --git a/src/DotNext.Threading/DotNext.Threading.csproj b/src/DotNext.Threading/DotNext.Threading.csproj
index 14826210d..8794d3a67 100644
--- a/src/DotNext.Threading/DotNext.Threading.csproj
+++ b/src/DotNext.Threading/DotNext.Threading.csproj
@@ -7,7 +7,7 @@
true
true
nullablePublicOnly
- 5.0.1
+ 5.0.2
.NET Foundation and Contributors
.NEXT Family of Libraries
diff --git a/src/DotNext.Threading/Threading/AsyncAutoResetEvent.cs b/src/DotNext.Threading/Threading/AsyncAutoResetEvent.cs
index 89773589f..08d5e89c2 100644
--- a/src/DotNext.Threading/Threading/AsyncAutoResetEvent.cs
+++ b/src/DotNext.Threading/Threading/AsyncAutoResetEvent.cs
@@ -66,7 +66,7 @@ private void OnCompleted(DefaultWaitNode node)
///
/// Indicates whether this event is set.
///
- public bool IsSet => Volatile.Read(ref manager.Value);
+ public bool IsSet => Volatile.Read(in manager.Value);
///
/// Sets the state of this event to non signaled, causing consumers to wait asynchronously.
diff --git a/src/DotNext.Threading/Threading/AsyncCountdownEvent.cs b/src/DotNext.Threading/Threading/AsyncCountdownEvent.cs
index 87ac6a958..7a77e84b5 100644
--- a/src/DotNext.Threading/Threading/AsyncCountdownEvent.cs
+++ b/src/DotNext.Threading/Threading/AsyncCountdownEvent.cs
@@ -252,7 +252,7 @@ internal ValueTask SignalAndWaitAsync(out bool completedSynchronously, Tim
{
case Timeout.InfiniteTicks:
goto default;
- case < 0L:
+ case < 0L or > Timeout.MaxTimeoutParameterTicks:
task = ValueTask.FromException(new ArgumentOutOfRangeException(nameof(timeout)));
break;
case 0L:
diff --git a/src/DotNext.Threading/Threading/AsyncExchanger.cs b/src/DotNext.Threading/Threading/AsyncExchanger.cs
index 983771a76..a9294da03 100644
--- a/src/DotNext.Threading/Threading/AsyncExchanger.cs
+++ b/src/DotNext.Threading/Threading/AsyncExchanger.cs
@@ -111,7 +111,7 @@ public ValueTask ExchangeAsync(T value, TimeSpan timeout, CancellationToken t
{
case Timeout.InfiniteTicks:
goto default;
- case < 0L:
+ case < 0L or > Timeout.MaxTimeoutParameterTicks:
result = ValueTask.FromException(new ArgumentOutOfRangeException(nameof(timeout)));
break;
case 0L:
diff --git a/src/DotNext.Threading/Threading/AsyncTrigger.cs b/src/DotNext.Threading/Threading/AsyncTrigger.cs
index 31f2e7c4c..581a3333e 100644
--- a/src/DotNext.Threading/Threading/AsyncTrigger.cs
+++ b/src/DotNext.Threading/Threading/AsyncTrigger.cs
@@ -151,7 +151,7 @@ public ValueTask SignalAndWaitAsync(bool resumeAll, bool throwOnEmptyQueue
{
case Timeout.InfiniteTicks:
goto default;
- case < 0L:
+ case < 0L or > Timeout.MaxTimeoutParameterTicks:
task = ValueTask.FromException(new ArgumentOutOfRangeException(nameof(timeout)));
break;
case 0L:
diff --git a/src/DotNext.Threading/Threading/QueuedSynchronizer.cs b/src/DotNext.Threading/Threading/QueuedSynchronizer.cs
index 2faaec3a3..edd2d9b93 100644
--- a/src/DotNext.Threading/Threading/QueuedSynchronizer.cs
+++ b/src/DotNext.Threading/Threading/QueuedSynchronizer.cs
@@ -176,7 +176,7 @@ private protected ValueTask AcquireAsync(ref Valu
{
case Timeout.InfiniteTicks:
goto default;
- case < 0L:
+ case < 0L or > Timeout.MaxTimeoutParameterTicks:
task = ValueTask.FromException(new ArgumentOutOfRangeException("timeout"));
break;
case 0L: // attempt to acquire synchronously
@@ -248,7 +248,7 @@ private protected ValueTask TryAcquireAsync
{
case Timeout.InfiniteTicks:
goto default;
- case < 0L:
+ case < 0L or > Timeout.MaxTimeoutParameterTicks:
task = ValueTask.FromException(new ArgumentOutOfRangeException("timeout"));
break;
case 0L: // attempt to acquire synchronously
@@ -834,7 +834,7 @@ protected ValueTask TryAcquireAsync(TContext context, TimeSpan timeout, Ca
{
case Timeout.InfiniteTicks:
goto default;
- case < 0L:
+ case < 0L or > Timeout.MaxTimeoutParameterTicks:
task = ValueTask.FromException(new ArgumentOutOfRangeException(nameof(timeout)));
break;
case 0L:
@@ -896,7 +896,7 @@ protected ValueTask AcquireAsync(TContext context, TimeSpan timeout, Cancellatio
{
case Timeout.InfiniteTicks:
goto default;
- case < 0L:
+ case < 0L or > Timeout.MaxTimeoutParameterTicks:
task = ValueTask.FromException(new ArgumentOutOfRangeException(nameof(timeout)));
break;
case 0L:
diff --git a/src/DotNext.Threading/Threading/Scheduler.cs b/src/DotNext.Threading/Threading/Scheduler.cs
index 7061bb199..3af44921f 100644
--- a/src/DotNext.Threading/Threading/Scheduler.cs
+++ b/src/DotNext.Threading/Threading/Scheduler.cs
@@ -48,7 +48,7 @@ public static DelayedTask ScheduleAsync(Func throw new ArgumentOutOfRangeException(nameof(delay)),
+ < 0L and not Timeout.InfiniteTicks or > Timeout.MaxTimeoutParameterTicks => throw new ArgumentOutOfRangeException(nameof(delay)),
0L => new ImmediateTask(callback, args, token),
_ => DelayedTaskStateMachine.Start(callback, args, delay, token),
};
diff --git a/src/DotNext.Threading/Threading/Tasks/ManualResetCompletionSource.cs b/src/DotNext.Threading/Threading/Tasks/ManualResetCompletionSource.cs
index 0f3ebf20c..8a0105d98 100644
--- a/src/DotNext.Threading/Threading/Tasks/ManualResetCompletionSource.cs
+++ b/src/DotNext.Threading/Threading/Tasks/ManualResetCompletionSource.cs
@@ -272,7 +272,7 @@ private protected void OnCompleted(Action