Skip to content

Commit 3b400c4

Browse files
committed
BenMorris/NetArchTest#67 - add predicates: AreOfType, AreNotOfType and conditions: BeOfType, NotBeOfType
1 parent c32e42a commit 3b400c4

15 files changed

Lines changed: 328 additions & 244 deletions

File tree

src/NetArchTest.Rules/Condition_Names.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,30 @@
1-
using NetArchTest.Functions;
1+
using System;
2+
using NetArchTest.Functions;
23

34
namespace NetArchTest.Rules
45
{
56
public sealed partial class Condition
67
{
8+
/// <summary>
9+
/// Selects types that are exactly of given type. (inheritance is not considered)
10+
/// </summary>
11+
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
12+
public ConditionList BeOfType(params Type[] type)
13+
{
14+
AddFunctionCall((context, inputTypes) => FunctionDelegates.AreOfType(context, inputTypes, type, true));
15+
return CreateConditionList();
16+
}
17+
18+
/// <summary>
19+
/// Selects types that are not exactly of given type. (inheritance is not considered)
20+
/// </summary>
21+
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
22+
public ConditionList NotBeOfType(params Type[] type)
23+
{
24+
AddFunctionCall((context, inputTypes) => FunctionDelegates.AreOfType(context, inputTypes, type, false));
25+
return CreateConditionList();
26+
}
27+
728
/// <summary>
829
/// Selects types that have a specific name.
930
/// </summary>

src/NetArchTest.Rules/Condition_Special.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace NetArchTest.Rules
55
public sealed partial class Condition
66
{
77
/// <summary>
8-
/// Selects types that are immutable. (shallow immutability). It is stronger constraint than BeImmutableExternally()
8+
/// Selects types that are immutable, and their state cannot be changed after creation. (shallow immutability). Stronger constraint than AreImmutableExternally()
99
/// </summary>
1010
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
1111
public ConditionList BeImmutable()
@@ -25,7 +25,7 @@ public ConditionList BeMutable()
2525
}
2626

2727
/// <summary>
28-
/// Selects types that are immutable. (shallow external only immutability). It is waker constraint than BeImmutable()
28+
/// Selects types that are immutable from the outside of the given type. (shallow immutability). Weaker constraint than AreImmutable()
2929
/// </summary>
3030
/// <returns>An updated set of conditions that can be applied to a list of types.</returns>
3131
public ConditionList BeImmutableExternally()

src/NetArchTest.Rules/Extensions/Mono.Cecil/TypeDefinitionExtensions.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,25 @@ private static IEnumerable<TypeDefinition> EnumerateBaseClasses(this TypeDefinit
6666
/// <param name="typeDefinition">The type definition to convert.</param>
6767
/// <returns>The equivalent <see cref="Type"/> object instance.</returns>
6868
public static Type ToType(this TypeDefinition typeDefinition)
69+
{
70+
var fullName = RuntimeNameToReflectionName(typeDefinition.FullName);
71+
return Type.GetType(string.Concat(fullName, ", ", typeDefinition.Module.Assembly.FullName), true);
72+
}
73+
public static string RuntimeNameToReflectionName(this string cliName)
6974
{
7075
// Nested types have a forward slash that should be replaced with "+"
7176
// C++ template instantiations contain comma separator for template arguments,
7277
// getting address operators and pointer type designations which should be prefixed by backslash
73-
var fullName = typeDefinition.FullName.Replace("/", "+")
78+
var fullName = cliName.Replace("/", "+")
7479
.Replace(",", "\\,")
7580
.Replace("&", "\\&")
7681
.Replace("*", "\\*");
77-
return Type.GetType(string.Concat(fullName, ", ", typeDefinition.Module.Assembly.FullName), true);
82+
return fullName;
7883
}
7984

85+
86+
87+
8088
/// <summary>
8189
/// Tests whether a class is immutable, i.e. all public fields are readonly and properties have no set method
8290
/// </summary>

src/NetArchTest.Rules/Functions/FunctionDelegates_Names.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,21 @@ internal static partial class FunctionDelegates
1212
{
1313
// Name & Namespace
1414

15+
internal static IEnumerable<TypeSpec> AreOfType(FunctionSequenceExecutionContext context, IEnumerable<TypeSpec> input, Type[] types, bool condition)
16+
{
17+
var fullNames = new HashSet<string>(types.Select(x => x.FullName));
18+
if (condition)
19+
{
20+
return input.Where(c => HasFullName(c.Definition.FullName.RuntimeNameToReflectionName(), fullNames, context.UserOptions.Comparer));
21+
}
22+
else
23+
{
24+
return input.Where(c => !HasFullName(c.Definition.FullName.RuntimeNameToReflectionName(), fullNames, context.UserOptions.Comparer));
25+
}
26+
27+
static bool HasFullName(string typeName, HashSet<string> lookigFor, StringComparison comparer) => lookigFor.Contains(typeName);
28+
}
29+
1530
internal static IEnumerable<TypeSpec> HaveName(FunctionSequenceExecutionContext context, IEnumerable<TypeSpec> input, string[] names, bool condition)
1631
{
1732
var plainNames = names.Select(x => x.RemoveGenericPart()).ToArray();

src/NetArchTest.Rules/Predicate_Names.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,30 @@
1-
using NetArchTest.Functions;
1+
using System;
2+
using NetArchTest.Functions;
23

34
namespace NetArchTest.Rules
45
{
56
public sealed partial class Predicate
67
{
8+
/// <summary>
9+
/// Selects types that are exactly of given type. (inheritance is not considered)
10+
/// </summary>
11+
/// <returns>An updated set of predicates that can be applied to a list of types.</returns>
12+
public PredicateList AreOfType(params Type[] type)
13+
{
14+
AddFunctionCall((context, inputTypes) => FunctionDelegates.AreOfType(context, inputTypes, type, true));
15+
return CreatePredicateList();
16+
}
17+
18+
/// <summary>
19+
/// Selects types that are not exactly of given type. (inheritance is not considered)
20+
/// </summary>
21+
/// <returns>An updated set of predicates that can be applied to a list of types.</returns>
22+
public PredicateList AreNotOfType(params Type[] type)
23+
{
24+
AddFunctionCall((context, inputTypes) => FunctionDelegates.AreOfType(context, inputTypes, type, false));
25+
return CreatePredicateList();
26+
}
27+
728
/// <summary>
829
/// Selects types that have a specific name.
930
/// </summary>

src/NetArchTest.Rules/Predicate_Special.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace NetArchTest.Rules
55
public sealed partial class Predicate
66
{
77
/// <summary>
8-
/// Selects types that are immutable. (shallow immutability). It is stronger constraint than AreImmutableExternally()
8+
/// Selects types that are immutable, and their state cannot be changed after creation. (shallow immutability). Stronger constraint than AreImmutableExternally()
99
/// </summary>
1010
/// <returns>An updated set of predicates that can be applied to a list of types.</returns>
1111
public PredicateList AreImmutable()
@@ -25,7 +25,7 @@ public PredicateList AreMutable()
2525
}
2626

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

0 commit comments

Comments
 (0)