Simplify PatternMatchingUtility by removing expression trees#1766
Simplify PatternMatchingUtility by removing expression trees#1766
Conversation
1bfb55b to
8547c2c
Compare
There was a problem hiding this comment.
Pull request overview
This PR simplifies PatternMatchingUtility by replacing the prior expression-tree/reflection approach with straightforward, prebuilt closures for pattern matching. This reduces runtime complexity and removes failure modes from reflection lookups, while also making empty pattern lists safe to handle.
Changes:
- Replaced expression-tree compiled predicate generation with a list of simple per-pattern match delegates (closures).
- Added support for
*foo*“contains” patterns, and ensured empty pattern lists return a matcher that never matches (instead of throwing). - Consolidated and expanded unit test coverage to cover more pattern variants, multiple-pattern OR behavior, and empty pattern lists.
Show a summary per file
| File | Description |
|---|---|
| src/Microsoft.ComponentDetection.Common/PatternMatchingUtility.cs | Removes expression trees/reflection and implements matching via direct span-based closures (including *foo* contains and empty pattern handling). |
| test/Microsoft.ComponentDetection.Common.Tests/PatternMatchingUtilityTests.cs | Updates tests to data-drive single-pattern cases, and adds coverage for multi-pattern and empty-pattern behavior. |
Copilot's findings
- Files reviewed: 2/2 changed files
- Comments generated: 0 new
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1766 +/- ##
============================
============================
☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
👋 Hi! It looks like you modified some files in the
If none of the above scenarios apply, feel free to ignore this comment 🙂 |
Replaces the expression tree and reflection-based implementation in
PatternMatchingUtilitywith plain closures.The old code used
Expression.Lambda,Expression.Call, and four reflectionGetMethodlookups to build a compiled delegate at runtime. This was unnecessary given the small, static pattern lists from detectorSearchPatterns(typically 1-3 entries). The reflection calls had no null checks and would throw cryptic errors if the API surface changed. CallingAggregateon an empty pattern list would throwInvalidOperationException.The new version calls the same
ReadOnlySpan<char>extension methods directly from closures. It also handles*foo*(contains) patterns, which the old code silently treated as exact matches.