| File: FilterExpressionWrapper.cs | Web Access |
| Project: src\vstest\src\Microsoft.TestPlatform.Filter.Source\Microsoft.TestPlatform.Filter.Source.csproj (Microsoft.TestPlatform.Filter.Source) |
// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. #nullable enable using System; using System.Collections.Generic; #if IS_VSTEST_REPO using System.Diagnostics.CodeAnalysis; using System.Text.RegularExpressions; #endif #if !IS_VSTEST_REPO using Microsoft.CodeAnalysis; #endif #if IS_VSTEST_REPO using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; #endif namespace Microsoft.VisualStudio.TestPlatform.Common.Filtering; /// <summary> /// Class holds information related to filtering criteria. /// </summary> #if IS_VSTEST_REPO public class FilterExpressionWrapper #else [Embedded] internal sealed class FilterExpressionWrapper #endif { /// <summary> /// FilterExpression corresponding to filter criteria /// </summary> private readonly FilterExpression? _filterExpression; /// <remarks> /// Exposed for testing purpose. /// </remarks> internal readonly FastFilter? FastFilter; /// <summary> /// Initializes FilterExpressionWrapper with given filterString and options. /// </summary> #if IS_VSTEST_REPO public FilterExpressionWrapper(string filterString, FilterOptions? options) #else public FilterExpressionWrapper(string filterString) #endif { #if IS_VSTEST_REPO ValidateArg.NotNullOrEmpty(filterString, nameof(filterString)); #endif FilterString = filterString; #if IS_VSTEST_REPO FilterOptions = options; #endif try { // We prefer fast filter when it's available. _filterExpression = FilterExpression.Parse(filterString, out FastFilter); if (UseFastFilter) { _filterExpression = null; // Property value regex is only supported for fast filter, // so we ignore it if no fast filter is constructed. #if IS_VSTEST_REPO // TODO: surface an error message to user. var regexString = options?.FilterRegEx; if (!regexString.IsNullOrEmpty()) { TPDebug.Assert(options!.FilterRegExReplacement == null || options.FilterRegEx != null); FastFilter.PropertyValueRegex = new Regex(regexString, RegexOptions.Compiled); FastFilter.PropertyValueRegexReplacement = options.FilterRegExReplacement; } #endif } } catch (FormatException ex) { ParseError = ex.Message; } catch (ArgumentException ex) { FastFilter = null; ParseError = ex.Message; } } #if IS_VSTEST_REPO /// <summary> /// Initializes FilterExpressionWrapper with given filterString. /// </summary> public FilterExpressionWrapper(string filterString) : this(filterString, null) { } #endif #if IS_VSTEST_REPO [MemberNotNullWhen(true, nameof(FastFilter))] #endif private bool UseFastFilter => FastFilter != null; /// <summary> /// User specified filter criteria. /// </summary> public string FilterString { get; } #if IS_VSTEST_REPO /// <summary> /// User specified additional filter options. /// </summary> public FilterOptions? FilterOptions { get; } #endif /// <summary> /// Parsing error (if any), when parsing 'FilterString' with built-in parser. /// </summary> public string? ParseError { get; } /// <summary> /// Validate if underlying filter expression is valid for given set of supported properties. /// </summary> #if IS_VSTEST_REPO public string[]? ValidForProperties(IEnumerable<string>? supportedProperties, Func<string, TestProperty?>? propertyProvider) #else public string[]? ValidForProperties(IEnumerable<string>? supportedProperties) #endif => UseFastFilter ? FastFilter!.ValidForProperties(supportedProperties) #if IS_VSTEST_REPO : _filterExpression?.ValidForProperties(supportedProperties, propertyProvider); #else : _filterExpression?.ValidForProperties(supportedProperties); #endif /// <summary> /// Evaluate filterExpression with given propertyValueProvider. /// </summary> public bool Evaluate(Func<string, object?> propertyValueProvider) { #if IS_VSTEST_REPO ValidateArg.NotNull(propertyValueProvider, nameof(propertyValueProvider)); #endif return UseFastFilter ? FastFilter!.Evaluate(propertyValueProvider) : _filterExpression != null && _filterExpression.Evaluate(propertyValueProvider); } }