Skip to content

Commit 1bfb55b

Browse files
committed
Replace expression tree pattern matching with closures
1 parent 97f3d73 commit 1bfb55b

File tree

1 file changed

+19
-38
lines changed

1 file changed

+19
-38
lines changed
Lines changed: 19 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,37 @@
1-
#nullable disable
21
namespace Microsoft.ComponentDetection.Common;
32

43
using System;
54
using System.Collections.Generic;
65
using System.Linq;
7-
using System.Linq.Expressions;
8-
using System.Reflection;
96

107
public static class PatternMatchingUtility
118
{
129
public delegate bool FilePatternMatcher(ReadOnlySpan<char> span);
1310

1411
public static FilePatternMatcher GetFilePatternMatcher(IEnumerable<string> patterns)
1512
{
16-
var ordinalComparison = Expression.Constant(StringComparison.Ordinal, typeof(StringComparison));
17-
var asSpan = typeof(MemoryExtensions).GetMethod("AsSpan", BindingFlags.Public | BindingFlags.Static, null, CallingConventions.Standard, [typeof(string)], []);
18-
var equals = typeof(MemoryExtensions).GetMethod("Equals", BindingFlags.Public | BindingFlags.Static, null, CallingConventions.Standard, [typeof(ReadOnlySpan<char>), typeof(ReadOnlySpan<char>), typeof(StringComparison)], []);
19-
var startsWith = typeof(MemoryExtensions).GetMethod("StartsWith", BindingFlags.Public | BindingFlags.Static, null, CallingConventions.Standard, [typeof(ReadOnlySpan<char>), typeof(ReadOnlySpan<char>), typeof(StringComparison)], []);
20-
var endsWith = typeof(MemoryExtensions).GetMethod("EndsWith", BindingFlags.Public | BindingFlags.Static, null, CallingConventions.Standard, [typeof(ReadOnlySpan<char>), typeof(ReadOnlySpan<char>), typeof(StringComparison)], []);
21-
22-
var predicates = new List<Expression>();
23-
var left = Expression.Parameter(typeof(ReadOnlySpan<char>), "fileName");
24-
25-
foreach (var pattern in patterns)
13+
var matchers = patterns.Select<string, FilePatternMatcher>(pattern => pattern switch
2614
{
27-
if (pattern.StartsWith('*'))
28-
{
29-
var match = Expression.Constant(pattern[1..], typeof(string));
30-
var right = Expression.Call(null, asSpan, match);
31-
var combine = Expression.Call(null, endsWith, left, right, ordinalComparison);
32-
predicates.Add(combine);
33-
}
34-
else if (pattern.EndsWith('*'))
35-
{
36-
var match = Expression.Constant(pattern[..^1], typeof(string));
37-
var right = Expression.Call(null, asSpan, match);
38-
var combine = Expression.Call(null, startsWith, left, right, ordinalComparison);
39-
predicates.Add(combine);
40-
}
41-
else
15+
_ when pattern.StartsWith('*') && pattern.EndsWith('*') =>
16+
span => span.Contains(pattern.AsSpan(1, pattern.Length - 2), StringComparison.Ordinal),
17+
_ when pattern.StartsWith('*') =>
18+
span => span.EndsWith(pattern.AsSpan(1), StringComparison.Ordinal),
19+
_ when pattern.EndsWith('*') =>
20+
span => span.StartsWith(pattern.AsSpan(0, pattern.Length - 1), StringComparison.Ordinal),
21+
_ => span => span.Equals(pattern.AsSpan(), StringComparison.Ordinal),
22+
}).ToList();
23+
24+
return span =>
25+
{
26+
foreach (var matcher in matchers)
4227
{
43-
var match = Expression.Constant(pattern, typeof(string));
44-
var right = Expression.Call(null, asSpan, match);
45-
var combine = Expression.Call(null, equals, left, right, ordinalComparison);
46-
predicates.Add(combine);
28+
if (matcher(span))
29+
{
30+
return true;
31+
}
4732
}
48-
}
49-
50-
var aggregateExpression = predicates.Aggregate(Expression.OrElse);
51-
52-
var func = Expression.Lambda<FilePatternMatcher>(aggregateExpression, left).Compile();
5333

54-
return func;
34+
return false;
35+
};
5536
}
5637
}

0 commit comments

Comments
 (0)