Skip to content

Commit 77e5222

Browse files
committed
switch to MarkPassingTypes algorithm
1 parent 8adc328 commit 77e5222

3 files changed

Lines changed: 47 additions & 45 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace System.Collections.Generic
6+
{
7+
internal static class IEnumerableExtensions
8+
{
9+
public static void ForEach<T>(this IEnumerable<T> list, Action<T> action)
10+
{
11+
foreach (T item in list)
12+
{
13+
action(item);
14+
}
15+
}
16+
}
17+
}

src/NetArchTest.Rules/FunctionSequence.cs

Lines changed: 30 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ namespace NetArchTest.Rules
1010
/// </summary>
1111
internal sealed class FunctionSequence
1212
{
13-
private readonly List<List<FunctionCall>> _groups;
13+
private readonly List<List<IFunctionCall>> _groups;
1414

1515

1616
/// <summary>
1717
/// Initializes a new instance of the <see cref="FunctionSequence"/> class.
1818
/// </summary>
1919
internal FunctionSequence()
2020
{
21-
_groups = new List<List<FunctionCall>>();
22-
_groups.Add(new List<FunctionCall>());
21+
_groups = new List<List<IFunctionCall>>();
22+
_groups.Add(new List<IFunctionCall>());
2323
}
2424

2525

@@ -36,7 +36,7 @@ internal void AddFunctionCall<T>(FunctionDelegates.FunctionDelegate<T> method, T
3636
/// </summary>
3737
internal void CreateGroup()
3838
{
39-
_groups.Add(new List<FunctionCall>());
39+
_groups.Add(new List<IFunctionCall>());
4040
}
4141

4242
/// <summary>
@@ -45,65 +45,39 @@ internal void CreateGroup()
4545
/// <returns>A list of types that are selected by the predicates (or not selected if optional reversing flag is passed).</returns>
4646
public IReadOnlyList<TypeSpec> ExecuteExtended(IEnumerable<TypeSpec> inputTypes, bool selected = true)
4747
{
48-
var resultSets = new List<List<TypeSpec>>();
48+
MarkPassingTypes(inputTypes);
4949

50-
// Execute each group of calls - each group represents a separate "or"
51-
foreach (var group in _groups)
52-
{
53-
var passingTypes = new List<TypeSpec>(inputTypes);
54-
55-
// Invoke the functions iteratively - functions within a group are treated as "and" statements
56-
foreach (var func in group)
57-
{
58-
var funcResults = func.FunctionDelegate.DynamicInvoke(passingTypes, func.Value, func.Condition) as IEnumerable<TypeSpec>;
59-
passingTypes = funcResults.ToList();
60-
}
61-
62-
if (passingTypes.Count > 0)
63-
{
64-
resultSets.Add(passingTypes);
65-
}
66-
}
67-
68-
if (selected)
69-
{
70-
// Return all the types that appear in at least one of the result sets
71-
return resultSets.SelectMany(list => list.Select(def => def)).Distinct().ToList();
72-
}
73-
else
74-
{
75-
// Return all the types that *do not* appear in at least one of the result sets
76-
var selectedTypes = resultSets.SelectMany(list => list.Select(def => def)).Distinct().Select(t => t.Definition.FullName);
77-
var notSelected = inputTypes.Where(t => !selectedTypes.Contains(t.Definition.FullName)).ToList();
78-
return notSelected;
79-
}
50+
return inputTypes.Where(x => x.IsSelected == selected).ToList();
8051
}
8152

8253
public IReadOnlyList<TypeSpec> Execute(IEnumerable<TypeSpec> inputTypes)
8354
{
84-
var resultSets = new List<IEnumerable<TypeSpec>>();
85-
55+
MarkPassingTypes(inputTypes);
56+
57+
return inputTypes.Where(x => x.IsSelected == true).ToList();
58+
}
59+
private void MarkPassingTypes(IEnumerable<TypeSpec> inputTypes)
60+
{
61+
inputTypes.ForEach(x => x.IsSelected = false);
62+
8663
foreach (var group in _groups)
8764
{
8865
IEnumerable<TypeSpec> passingTypes = inputTypes;
89-
66+
9067
foreach (var func in group)
9168
{
92-
var funcResults = func.FunctionDelegate.DynamicInvoke(passingTypes, func.Value, func.Condition) as IEnumerable<TypeSpec>;
69+
var funcResults = func.Execute(passingTypes);
9370
passingTypes = funcResults;
9471
}
9572

96-
resultSets.Add(passingTypes);
73+
passingTypes.ForEach(x => x.IsSelected = true);
9774
}
98-
99-
return resultSets.SelectMany(list => list.Select(def => def)).Distinct().ToList();
10075
}
10176

102-
10377
/// <summary>
10478
/// Represents a single function call.
10579
/// </summary>
106-
internal class FunctionCall
80+
internal class FunctionCall : IFunctionCall
10781
{
10882
/// <summary>
10983
/// Initializes a new instance of the <see cref="FunctionCall"/> class.
@@ -115,6 +89,13 @@ internal FunctionCall(Delegate func, object value, bool condition)
11589
this.Condition = condition;
11690
}
11791

92+
93+
public IEnumerable<TypeSpec> Execute(IEnumerable<TypeSpec> inputTypes)
94+
{
95+
return FunctionDelegate.DynamicInvoke(inputTypes, Value, Condition) as IEnumerable<TypeSpec>;
96+
}
97+
98+
11899
/// <summary>
119100
/// A delegate for a function call.
120101
/// </summary>
@@ -131,5 +112,10 @@ internal FunctionCall(Delegate func, object value, bool condition)
131112
public bool Condition { get; private set; }
132113

133114
}
115+
116+
internal interface IFunctionCall
117+
{
118+
IEnumerable<TypeSpec> Execute(IEnumerable<TypeSpec> inputTypes);
119+
}
134120
}
135121
}

src/NetArchTest.Rules/Predicate.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,6 @@ public PredicateList AreNotNestedPrivate()
421421
return new PredicateList(_types, _sequence);
422422
}
423423

424-
425424
/// <summary>
426425
/// Selects types that have public scope.
427426
/// </summary>

0 commit comments

Comments
 (0)