Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
474 changes: 7 additions & 467 deletions src/Cuemon.Core/ActionFactory.cs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/Cuemon.Core/BinaryPrefix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public sealed class BinaryPrefix : PrefixMultiple
/// Initializes a new instance of the <see cref="BinaryPrefix"/> struct.
/// </summary>
/// <param name="name">The name of the binary prefix.</param>
/// <param name="symbol">The symbol of the the binary prefix.</param>
/// <param name="symbol">The symbol of the binary prefix.</param>
/// <param name="exponent">The number that specifies a power.</param>
public BinaryPrefix(string name, string symbol, double exponent) : base(name, symbol, 2, exponent)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Cuemon.Core/DecimalPrefix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public sealed class DecimalPrefix : PrefixMultiple
/// Initializes a new instance of the <see cref="DecimalPrefix"/> struct.
/// </summary>
/// <param name="name">The name of the decimal prefix.</param>
/// <param name="symbol">The symbol of the the decimal prefix.</param>
/// <param name="symbol">The symbol of the decimal prefix.</param>
/// <param name="exponent">The number that specifies a power.</param>
public DecimalPrefix(string name, string symbol, double exponent) : base(name, symbol, 10, exponent)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static class AssemblyDecoratorExtensions
/// Determines whether the underlying <see cref="Assembly"/> of the <paramref name="decorator"/> is a debug build.
/// </summary>
/// <param name="decorator">The <see cref="IDecorator{T}"/> to extend.</param>
/// <returns><c>true</c> if the the underlying <see cref="Assembly"/> of the <paramref name="decorator"/> is a debug build; otherwise, <c>false</c>.</returns>
/// <returns><c>true</c> if the underlying <see cref="Assembly"/> of the <paramref name="decorator"/> is a debug build; otherwise, <c>false</c>.</returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="decorator"/> cannot be null.
/// </exception>
Expand Down
493 changes: 7 additions & 486 deletions src/Cuemon.Core/FuncFactory.cs

Large diffs are not rendered by default.

169 changes: 33 additions & 136 deletions src/Cuemon.Core/GlobalSuppressions.cs

Large diffs are not rendered by default.

1,272 changes: 1,272 additions & 0 deletions src/Cuemon.Core/MutableTuple.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,25 @@ namespace Cuemon
/// <summary>
/// Provides a base-class for delegate based factories.
/// </summary>
/// <typeparam name="TTuple">The type of the n-tuple representation of a <see cref="Template"/>.</typeparam>
public abstract class TemplateFactory<TTuple> where TTuple : Template
/// <typeparam name="TTuple">The type of the n-tuple representation of a <see cref="MutableTuple"/>.</typeparam>
public abstract class MutableTupleFactory<TTuple> where TTuple : MutableTuple
{
/// <summary>
/// Initializes a new instance of the <see cref="TemplateFactory{T}"/> class.
/// Initializes a new instance of the <see cref="MutableTupleFactory{TTuple}"/> class.
/// </summary>
/// <param name="tuple">Then-tuple representation of a <see cref="Template"/>.</param>
/// <param name="tuple">The n-tuple representation of a <see cref="MutableTuple"/>.</param>
/// <param name="hasDelegate"><c>true</c> if this instance has a valid delegate; otherwise, <c>false</c>.</param>
protected TemplateFactory(TTuple tuple, bool hasDelegate)
protected MutableTupleFactory(TTuple tuple, bool hasDelegate)
{
Validator.ThrowIfNull(tuple);
GenericArguments = tuple;
HasDelegate = hasDelegate;
}

/// <summary>
/// Gets a n-tuple representation of a <see cref="Template"/> that represents the generic arguments passed to this instance.
/// Gets a n-tuple representation of a <see cref="MutableTuple"/> that represents the generic arguments passed to this instance.
/// </summary>
/// <value>The n-tuple representation of a <see cref="Template"/> that represents the generic arguments passed to this instance.</value>
/// <value>The n-tuple representation of a <see cref="MutableTuple"/> that represents the generic arguments passed to this instance.</value>
public TTuple GenericArguments { get; }

/// <summary>
Expand Down Expand Up @@ -67,10 +67,10 @@ protected void ThrowIfNoValidDelegate(bool delegateIsNull)
}

/// <summary>
/// Creates a shallow copy of the current <see cref="TemplateFactory{TTuple}"/> object.
/// Creates a shallow copy of the current <see cref="MutableTupleFactory{TTuple}"/> object.
/// </summary>
/// <returns>A new <see cref="TemplateFactory{TTuple}"/> implementation that is a copy of this instance.</returns>
/// <returns>A new <see cref="MutableTupleFactory{TTuple}"/> implementation that is a copy of this instance.</returns>
/// <remarks>When thread safety is required this is the method to invoke.</remarks>
public abstract TemplateFactory<TTuple> Clone();
public abstract MutableTupleFactory<TTuple> Clone();
}
}
}
28 changes: 14 additions & 14 deletions src/Cuemon.Core/Patterns.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,8 @@ public static TResult SafeInvoke<TResult>(Func<TResult> initializer, Func<TResul
{
Validator.ThrowIfNull(initializer);
Validator.ThrowIfNull(tester);
var f1 = FuncFactory.Create(tester, default);
var f2 = ActionFactory.Create(catcher, default);
var f1 = new FuncFactory<MutableTuple<TResult>, TResult>(tuple => tester(tuple.Arg1), new MutableTuple<TResult>(default), tester);
var f2 = new ActionFactory<MutableTuple<Exception>>(tuple => catcher?.Invoke(tuple.Arg1), new MutableTuple<Exception>(default), catcher);
return SafeInvokeCore(f1, initializer, f2);
}

Expand All @@ -233,8 +233,8 @@ public static TResult SafeInvoke<T, TResult>(Func<TResult> initializer, Func<TRe
{
Validator.ThrowIfNull(initializer);
Validator.ThrowIfNull(tester);
var f1 = FuncFactory.Create(tester, default, arg);
var f2 = ActionFactory.Create(catcher, default, arg);
var f1 = new FuncFactory<MutableTuple<TResult, T>, TResult>(tuple => tester(tuple.Arg1, tuple.Arg2), new MutableTuple<TResult, T>(default, arg), tester);
var f2 = new ActionFactory<MutableTuple<Exception, T>>(tuple => catcher?.Invoke(tuple.Arg1, tuple.Arg2), new MutableTuple<Exception, T>(default, arg), catcher);
return SafeInvokeCore(f1, initializer, f2);
}

Expand All @@ -254,8 +254,8 @@ public static TResult SafeInvoke<T1, T2, TResult>(Func<TResult> initializer, Fun
{
Validator.ThrowIfNull(initializer);
Validator.ThrowIfNull(tester);
var f1 = FuncFactory.Create(tester, default, arg1, arg2);
var f2 = ActionFactory.Create(catcher, default, arg1, arg2);
var f1 = new FuncFactory<MutableTuple<TResult, T1, T2>, TResult>(tuple => tester(tuple.Arg1, tuple.Arg2, tuple.Arg3), new MutableTuple<TResult, T1, T2>(default, arg1, arg2), tester);
var f2 = new ActionFactory<MutableTuple<Exception, T1, T2>>(tuple => catcher?.Invoke(tuple.Arg1, tuple.Arg2, tuple.Arg3), new MutableTuple<Exception, T1, T2>(default, arg1, arg2), catcher);
return SafeInvokeCore(f1, initializer, f2);
}

Expand All @@ -277,8 +277,8 @@ public static TResult SafeInvoke<T1, T2, T3, TResult>(Func<TResult> initializer,
{
Validator.ThrowIfNull(initializer);
Validator.ThrowIfNull(tester);
var f1 = FuncFactory.Create(tester, default, arg1, arg2, arg3);
var f2 = ActionFactory.Create(catcher, default, arg1, arg2, arg3);
var f1 = new FuncFactory<MutableTuple<TResult, T1, T2, T3>, TResult>(tuple => tester(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4), new MutableTuple<TResult, T1, T2, T3>(default, arg1, arg2, arg3), tester);
var f2 = new ActionFactory<MutableTuple<Exception, T1, T2, T3>>(tuple => catcher?.Invoke(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4), new MutableTuple<Exception, T1, T2, T3>(default, arg1, arg2, arg3), catcher);
return SafeInvokeCore(f1, initializer, f2);
}

Expand All @@ -302,8 +302,8 @@ public static TResult SafeInvoke<T1, T2, T3, T4, TResult>(Func<TResult> initiali
{
Validator.ThrowIfNull(initializer);
Validator.ThrowIfNull(tester);
var f1 = FuncFactory.Create(tester, default, arg1, arg2, arg3, arg4);
var f2 = ActionFactory.Create(catcher, default, arg1, arg2, arg3, arg4);
var f1 = new FuncFactory<MutableTuple<TResult, T1, T2, T3, T4>, TResult>(tuple => tester(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, tuple.Arg5), new MutableTuple<TResult, T1, T2, T3, T4>(default, arg1, arg2, arg3, arg4), tester);
var f2 = new ActionFactory<MutableTuple<Exception, T1, T2, T3, T4>>(tuple => catcher?.Invoke(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, tuple.Arg5), new MutableTuple<Exception, T1, T2, T3, T4>(default, arg1, arg2, arg3, arg4), catcher);
return SafeInvokeCore(f1, initializer, f2);
}

Expand All @@ -329,15 +329,15 @@ public static TResult SafeInvoke<T1, T2, T3, T4, T5, TResult>(Func<TResult> init
{
Validator.ThrowIfNull(initializer);
Validator.ThrowIfNull(tester);
var f1 = FuncFactory.Create(tester, default, arg1, arg2, arg3, arg4, arg5);
var f2 = ActionFactory.Create(catcher, default, arg1, arg2, arg3, arg4, arg5);
var f1 = new FuncFactory<MutableTuple<TResult, T1, T2, T3, T4, T5>, TResult>(tuple => tester(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, tuple.Arg5, tuple.Arg6), new MutableTuple<TResult, T1, T2, T3, T4, T5>(default, arg1, arg2, arg3, arg4, arg5), tester);
var f2 = new ActionFactory<MutableTuple<Exception, T1, T2, T3, T4, T5>>(tuple => catcher?.Invoke(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, tuple.Arg5, tuple.Arg6), new MutableTuple<Exception, T1, T2, T3, T4, T5>(default, arg1, arg2, arg3, arg4, arg5), catcher);
Comment on lines +332 to +333
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Potential index mismatch in tuple arguments

In the SafeInvoke<T1, T2, T3, T4, T5, TResult> method, there appears to be an off-by-one error in accessing tuple arguments.

Details:

  • The MutableTuple<TResult, T1, T2, T3, T4, T5> should have arguments Arg1 to Arg6.

  • In the lambda expression:

    tuple => tester(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, tuple.Arg5, tuple.Arg6)

    tuple.Arg6 corresponds to T5, but MutableTuple<TResult, T1, T2, T3, T4, T5> defines only six arguments, with Arg1 being TResult and Arg6 being T5.

  • Similarly, in the new MutableTuple initialization:

    new MutableTuple<TResult, T1, T2, T3, T4, T5>(default, arg1, arg2, arg3, arg4, arg5)

    The arguments align with Arg1 to Arg6, but it's crucial to ensure that the mapping is correct.

Suggested Fix:

Verify that the MutableTuple class properly defines Arg1 to Arg6 and that the arguments correspond correctly to the expected types. Ensure that tuple.Arg6 is valid and maps to T5.

return SafeInvokeCore(f1, initializer, f2);
}

private static TResult SafeInvokeCore<TTester, TResult, TCatcher>(FuncFactory<TTester, TResult> testerFactory, Func<TResult> initializer, ActionFactory<TCatcher> catcherFactory)
where TResult : class, IDisposable
where TTester : Template<TResult>
where TCatcher : Template<Exception>
where TTester : MutableTuple<TResult>
where TCatcher : MutableTuple<Exception>
Comment on lines +339 to +340
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Generic constraints may be too restrictive in SafeInvokeCore

The generic constraints on TTester and TCatcher might not accommodate all MutableTuple variations used.

Details:

  • The constraints:

    where TTester : MutableTuple<TResult>
    where TCatcher : MutableTuple<Exception>

    limit TTester and TCatcher to specific MutableTuple types.

  • For cases where TTester and TCatcher are instantiated with additional generic parameters (e.g., MutableTuple<TResult, T1, T2>), these constraints may cause compilation errors.

Suggested Fix:

Adjust the generic constraints to accept any MutableTuple regardless of the number of generic parameters. One approach is to constrain them to a non-generic base class or interface that all MutableTuple variants inherit from.

where TTester : IMutableTuple
where TCatcher : IMutableTuple

Ensure that such a base class or interface (IMutableTuple) exists and that all MutableTuple types implement or inherit from it.

{
TResult result = null;
try
Expand Down
2 changes: 1 addition & 1 deletion src/Cuemon.Core/PrefixMultiple.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public abstract class PrefixMultiple : IPrefixMultiple
/// Initializes a new instance of the <see cref="PrefixMultiple"/> struct.
/// </summary>
/// <param name="name">The name of the binary unit.</param>
/// <param name="symbol">The symbol of the the unit prefix.</param>
/// <param name="symbol">The symbol of the unit prefix.</param>
/// <param name="value">The number to be raised to a power.</param>
/// <param name="exponent">The number that specifies a power.</param>
protected PrefixMultiple(string name, string symbol, double value, double exponent)
Expand Down
14 changes: 7 additions & 7 deletions src/Cuemon.Core/Reflection/ActivatorFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static class ActivatorFactory
/// <seealso cref="Activator.CreateInstance(Type, BindingFlags, Binder, object[], CultureInfo)"/>.
public static TInstance CreateInstance<TInstance>(Action<ActivatorOptions> setup = null)
{
var factory = FuncFactory.Create<TInstance>(null);
var factory = new FuncFactory<MutableTuple, TInstance>(null, new MutableTuple());
return CreateInstanceCore(factory, setup);
}

Expand All @@ -33,7 +33,7 @@ public static TInstance CreateInstance<TInstance>(Action<ActivatorOptions> setup
/// <seealso cref="Activator.CreateInstance(Type, BindingFlags, Binder, object[], CultureInfo)"/>.
public static TInstance CreateInstance<T, TInstance>(T arg, Action<ActivatorOptions> setup = null)
{
var factory = FuncFactory.Create<T, TInstance>(null, arg);
var factory = new FuncFactory<MutableTuple<T>, TInstance>(null, new MutableTuple<T>(arg));
return CreateInstanceCore(factory, setup);
}

Expand All @@ -50,7 +50,7 @@ public static TInstance CreateInstance<T, TInstance>(T arg, Action<ActivatorOpti
/// <seealso cref="Activator.CreateInstance(Type, BindingFlags, Binder, object[], CultureInfo)"/>.
public static TInstance CreateInstance<T1, T2, TInstance>(T1 arg1, T2 arg2, Action<ActivatorOptions> setup = null)
{
var factory = FuncFactory.Create<T1, T2, TInstance>(null, arg1, arg2);
var factory = new FuncFactory<MutableTuple<T1, T2>, TInstance>(null, new MutableTuple<T1, T2>(arg1, arg2));
return CreateInstanceCore(factory, setup);
}

Expand All @@ -69,7 +69,7 @@ public static TInstance CreateInstance<T1, T2, TInstance>(T1 arg1, T2 arg2, Acti
/// <seealso cref="Activator.CreateInstance(Type, BindingFlags, Binder, object[], CultureInfo)"/>.
public static TInstance CreateInstance<T1, T2, T3, TInstance>(T1 arg1, T2 arg2, T3 arg3, Action<ActivatorOptions> setup = null)
{
var factory = FuncFactory.Create<T1, T2, T3, TInstance>(null, arg1, arg2, arg3);
var factory = new FuncFactory<MutableTuple<T1, T2, T3>, TInstance>(null, new MutableTuple<T1, T2, T3>(arg1, arg2, arg3));
return CreateInstanceCore(factory, setup);
}

Expand All @@ -90,7 +90,7 @@ public static TInstance CreateInstance<T1, T2, T3, TInstance>(T1 arg1, T2 arg2,
/// <seealso cref="Activator.CreateInstance(Type, BindingFlags, Binder, object[], CultureInfo)"/>.
public static TInstance CreateInstance<T1, T2, T3, T4, TInstance>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, Action<ActivatorOptions> setup = null)
{
var factory = FuncFactory.Create<T1, T2, T3, T4, TInstance>(null, arg1, arg2, arg3, arg4);
var factory = new FuncFactory<MutableTuple<T1, T2, T3, T4>, TInstance>(null, new MutableTuple<T1, T2, T3, T4>(arg1, arg2, arg3, arg4));
return CreateInstanceCore(factory, setup);
}

Expand All @@ -113,11 +113,11 @@ public static TInstance CreateInstance<T1, T2, T3, T4, TInstance>(T1 arg1, T2 ar
/// <seealso cref="Activator.CreateInstance(Type, BindingFlags, Binder, object[], CultureInfo)"/>.
public static TInstance CreateInstance<T1, T2, T3, T4, T5, TInstance>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, Action<ActivatorOptions> setup = null)
{
var factory = FuncFactory.Create<T1, T2, T3, T4, T5, TInstance>(null, arg1, arg2, arg3, arg4, arg5);
var factory = new FuncFactory<MutableTuple<T1, T2, T3, T4, T5>, TInstance>(null, new MutableTuple<T1, T2, T3, T4, T5>(arg1, arg2, arg3, arg4, arg5));
return CreateInstanceCore(factory, setup);
}

private static TInstance CreateInstanceCore<TTuple, TInstance>(FuncFactory<TTuple, TInstance> factory, Action<ActivatorOptions> setup = null) where TTuple : Template
private static TInstance CreateInstanceCore<TTuple, TInstance>(FuncFactory<TTuple, TInstance> factory, Action<ActivatorOptions> setup = null) where TTuple : MutableTuple
{
var options = Patterns.Configure(setup);
return (TInstance)Activator.CreateInstance(typeof(TInstance), options.Flags, options.Binder, factory.GenericArguments.ToArray(), options.FormatProvider as CultureInfo);
Comment on lines +120 to 123
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Remaining references to Template found. Please review and update them accordingly:

  • src/Cuemon.Extensions.AspNetCore.Mvc/Rendering/HtmlHelperExtensions.cs:
    • Line X: private static void UseWhenCore(IHtmlHelper helper, string template, string target, Action whenMatchDelegate, string routeTarget, string routeTemplate)
    • Line Y: var viewTemplate = template == null ? null : helper.ViewContext.RouteData.Values[routeTemplate] as string;
    • Line Z: var match = viewTemplate?.Equals(te, StringComparison.OrdinalIgnoreCase) ?? true;
  • test/Cuemon.Core.Tests/Assets/UnmanagedDisposable.cs:
    • Line A: IntPtr hTemplateFile);
🔗 Analysis chain

Constraint change to MutableTuple in CreateInstanceCore method is appropriate.

Changing the type constraint from Template to MutableTuple aligns with the overall refactoring strategy. This alteration ensures that CreateInstanceCore operates correctly with the updated tuple types.

Please confirm that all references to Template have been replaced and that MutableTuple provides the necessary functionality previously handled by Template.

To verify, you can run the following script:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify there are no remaining references to 'Template' in the codebase.

# Test: Search for 'Template' references. Expect: No matches.
rg --type cs 'Template'

Length of output: 705

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public HierarchySerializer(object source, Action<ObjectHierarchyOptions> setup =
/// <summary>
/// Gets the result of the <see cref="IHierarchy{T}"/>.
/// </summary>
/// <value>The converted nodes of the the by constructor defined source object.</value>
/// <value>The converted nodes of the by constructor defined source object.</value>
public IHierarchy<object> Nodes { get; }

/// <summary>
Expand Down
Loading