Skip to content

Commit

Permalink
BenMorris/NetArchTest#67 - add predicates: AreOfType, AreNotOfType an…
Browse files Browse the repository at this point in the history
…d conditions: BeOfType, NotBeOfType
  • Loading branch information
NeVeSpl committed Nov 23, 2023
1 parent c32e42a commit 3b400c4
Show file tree
Hide file tree
Showing 15 changed files with 328 additions and 244 deletions.
23 changes: 22 additions & 1 deletion src/NetArchTest.Rules/Condition_Names.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
using NetArchTest.Functions;
using System;
using NetArchTest.Functions;

namespace NetArchTest.Rules
{
public sealed partial class Condition
{
/// <summary>
/// Selects types that are exactly of given type. (inheritance is not considered)
/// </summary>
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
public ConditionList BeOfType(params Type[] type)
{
AddFunctionCall((context, inputTypes) => FunctionDelegates.AreOfType(context, inputTypes, type, true));
return CreateConditionList();
}

/// <summary>
/// Selects types that are not exactly of given type. (inheritance is not considered)
/// </summary>
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
public ConditionList NotBeOfType(params Type[] type)
{
AddFunctionCall((context, inputTypes) => FunctionDelegates.AreOfType(context, inputTypes, type, false));
return CreateConditionList();
}

/// <summary>
/// Selects types that have a specific name.
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions src/NetArchTest.Rules/Condition_Special.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace NetArchTest.Rules
public sealed partial class Condition
{
/// <summary>
/// Selects types that are immutable. (shallow immutability). It is stronger constraint than BeImmutableExternally()
/// Selects types that are immutable, and their state cannot be changed after creation. (shallow immutability). Stronger constraint than AreImmutableExternally()
/// </summary>
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
public ConditionList BeImmutable()
Expand All @@ -25,7 +25,7 @@ public ConditionList BeMutable()
}

/// <summary>
/// Selects types that are immutable. (shallow external only immutability). It is waker constraint than BeImmutable()
/// Selects types that are immutable from the outside of the given type. (shallow immutability). Weaker constraint than AreImmutable()
/// </summary>
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
public ConditionList BeImmutableExternally()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,25 @@ private static IEnumerable<TypeDefinition> EnumerateBaseClasses(this TypeDefinit
/// <param name="typeDefinition">The type definition to convert.</param>
/// <returns>The equivalent <see cref="Type"/> object instance.</returns>
public static Type ToType(this TypeDefinition typeDefinition)
{
var fullName = RuntimeNameToReflectionName(typeDefinition.FullName);
return Type.GetType(string.Concat(fullName, ", ", typeDefinition.Module.Assembly.FullName), true);
}
public static string RuntimeNameToReflectionName(this string cliName)
{
// Nested types have a forward slash that should be replaced with "+"
// C++ template instantiations contain comma separator for template arguments,
// getting address operators and pointer type designations which should be prefixed by backslash
var fullName = typeDefinition.FullName.Replace("/", "+")
var fullName = cliName.Replace("/", "+")
.Replace(",", "\\,")
.Replace("&", "\\&")
.Replace("*", "\\*");
return Type.GetType(string.Concat(fullName, ", ", typeDefinition.Module.Assembly.FullName), true);
return fullName;
}




/// <summary>
/// Tests whether a class is immutable, i.e. all public fields are readonly and properties have no set method
/// </summary>
Expand Down
15 changes: 15 additions & 0 deletions src/NetArchTest.Rules/Functions/FunctionDelegates_Names.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@ internal static partial class FunctionDelegates
{
// Name & Namespace

internal static IEnumerable<TypeSpec> AreOfType(FunctionSequenceExecutionContext context, IEnumerable<TypeSpec> input, Type[] types, bool condition)
{
var fullNames = new HashSet<string>(types.Select(x => x.FullName));
if (condition)
{
return input.Where(c => HasFullName(c.Definition.FullName.RuntimeNameToReflectionName(), fullNames, context.UserOptions.Comparer));
}
else
{
return input.Where(c => !HasFullName(c.Definition.FullName.RuntimeNameToReflectionName(), fullNames, context.UserOptions.Comparer));
}

static bool HasFullName(string typeName, HashSet<string> lookigFor, StringComparison comparer) => lookigFor.Contains(typeName);
}

internal static IEnumerable<TypeSpec> HaveName(FunctionSequenceExecutionContext context, IEnumerable<TypeSpec> input, string[] names, bool condition)
{
var plainNames = names.Select(x => x.RemoveGenericPart()).ToArray();
Expand Down
23 changes: 22 additions & 1 deletion src/NetArchTest.Rules/Predicate_Names.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
using NetArchTest.Functions;
using System;
using NetArchTest.Functions;

namespace NetArchTest.Rules
{
public sealed partial class Predicate
{
/// <summary>
/// Selects types that are exactly of given type. (inheritance is not considered)
/// </summary>
/// <returns>An updated set of predicates that can be applied to a list of types.</returns>
public PredicateList AreOfType(params Type[] type)
{
AddFunctionCall((context, inputTypes) => FunctionDelegates.AreOfType(context, inputTypes, type, true));
return CreatePredicateList();
}

/// <summary>
/// Selects types that are not exactly of given type. (inheritance is not considered)
/// </summary>
/// <returns>An updated set of predicates that can be applied to a list of types.</returns>
public PredicateList AreNotOfType(params Type[] type)
{
AddFunctionCall((context, inputTypes) => FunctionDelegates.AreOfType(context, inputTypes, type, false));
return CreatePredicateList();
}

/// <summary>
/// Selects types that have a specific name.
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions src/NetArchTest.Rules/Predicate_Special.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace NetArchTest.Rules
public sealed partial class Predicate
{
/// <summary>
/// Selects types that are immutable. (shallow immutability). It is stronger constraint than AreImmutableExternally()
/// Selects types that are immutable, and their state cannot be changed after creation. (shallow immutability). Stronger constraint than AreImmutableExternally()
/// </summary>
/// <returns>An updated set of predicates that can be applied to a list of types.</returns>
public PredicateList AreImmutable()
Expand All @@ -25,7 +25,7 @@ public PredicateList AreMutable()
}

/// <summary>
/// Selects types that are immutable. (shallow external only immutability). It is waker constraint than AreImmutable()
/// Selects types that are immutable from the outside of the given type. (shallow immutability). Weaker constraint than AreImmutable()
/// </summary>
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
public PredicateList AreImmutableExternally()
Expand Down
Loading

0 comments on commit 3b400c4

Please # to comment.