diff --git a/src/Build/Definition/ProjectItem.cs b/src/Build/Definition/ProjectItem.cs index 645f8810cc0..cfc17374cb3 100644 --- a/src/Build/Definition/ProjectItem.cs +++ b/src/Build/Definition/ProjectItem.cs @@ -1020,11 +1020,11 @@ public ProjectItem CreateItem(string evaluatedIncludeEscaped, string evaluatedIn /// /// Applies the supplied metadata to the destination item. /// - public void SetMetadata(IEnumerable> metadata, IEnumerable destinationItems) + public void SetMetadata(IEnumerable> metadata, IEnumerable destinationItems) { foreach (IItem item in destinationItems) { - foreach (Pair metadatum in metadata) + foreach (KeyValuePair metadatum in metadata) { item.SetMetadata(metadatum.Key, metadatum.Value); } diff --git a/src/Build/Evaluation/Evaluator.cs b/src/Build/Evaluation/Evaluator.cs index f5db7b9d74a..9f298203fa4 100644 --- a/src/Build/Evaluation/Evaluator.cs +++ b/src/Build/Evaluation/Evaluator.cs @@ -92,7 +92,7 @@ internal class Evaluator /// Key is the directory of the file importing the usingTask, which is needed /// to handle any relative paths in the usingTask. /// - private readonly List> _usingTaskElements; + private readonly List> _usingTaskElements; /// /// List of ProjectTargetElement's traversing into imports. @@ -249,7 +249,7 @@ private Evaluator( _data = data; _itemGroupElements = new List(); _itemDefinitionGroupElements = new List(); - _usingTaskElements = new List>(); + _usingTaskElements = new List>(); _targetElements = new List(); _importsSeen = new Dictionary(StringComparer.OrdinalIgnoreCase); _initialTargetsList = new List(); @@ -913,7 +913,7 @@ private void PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) EvaluateImportGroupElement(currentProjectOrImport.DirectoryPath, importGroup); break; case ProjectUsingTaskElement usingTask: - _usingTaskElements.Add(new Pair(currentProjectOrImport.DirectoryPath, usingTask)); + _usingTaskElements.Add(new KeyValuePair(currentProjectOrImport.DirectoryPath, usingTask)); break; case ProjectChooseElement choose: EvaluateChooseElement(choose); diff --git a/src/Build/Evaluation/Expander.cs b/src/Build/Evaluation/Expander.cs index fbfd660d303..c998910190e 100644 --- a/src/Build/Evaluation/Expander.cs +++ b/src/Build/Evaluation/Expander.cs @@ -616,7 +616,7 @@ internal bool ExpandExpressionCapture( ExpanderOptions options, bool includeNullEntries, out bool isTransformExpression, - out List> itemsFromCapture) + out List> itemsFromCapture) { return ItemExpander.ExpandExpressionCapture(this, expressionCapture, _items, elementLocation, options, includeNullEntries, out isTransformExpression, out itemsFromCapture); } @@ -1742,7 +1742,7 @@ private static class ItemExpander /// Execute the list of transform functions. /// /// class, IItem. - internal static IEnumerable> Transform(Expander expander, bool includeNullEntries, Stack> transformFunctionStack, IEnumerable> itemsOfType) + internal static IEnumerable> Transform(Expander expander, bool includeNullEntries, Stack> transformFunctionStack, IEnumerable> itemsOfType) where S : class, IItem { // If we have transforms on our stack, then we'll execute those first @@ -1751,7 +1751,7 @@ internal static IEnumerable> Transform(Expander expande { TransformFunction function = transformFunctionStack.Pop(); - foreach (Pair item in Transform(expander, includeNullEntries, transformFunctionStack, function.Execute(expander, includeNullEntries, itemsOfType))) + foreach (KeyValuePair item in Transform(expander, includeNullEntries, transformFunctionStack, function.Execute(expander, includeNullEntries, itemsOfType))) { yield return item; } @@ -1760,7 +1760,7 @@ internal static IEnumerable> Transform(Expander expande { // When we have no more tranforms on the stack, iterate over the items // that we have to return them - foreach (Pair item in itemsOfType) + foreach (KeyValuePair item in itemsOfType) { yield return item; } @@ -1893,7 +1893,7 @@ internal static IList ExpandExpressionCaptureIntoItems( return result; } - List> itemsFromCapture; + List> itemsFromCapture; brokeEarlyNonEmpty = ExpandExpressionCapture(expander, expressionCapture, items, elementLocation /* including null items */, options, true, out isTransformExpression, out itemsFromCapture); if (brokeEarlyNonEmpty) @@ -1959,7 +1959,7 @@ internal static bool ExpandExpressionCapture( ExpanderOptions options, bool includeNullEntries, out bool isTransformExpression, - out List> itemsFromCapture) + out List> itemsFromCapture) where S : class, IItem { ErrorUtilities.VerifyThrow(evaluatedItems != null, "Cannot expand items without providing items"); @@ -1980,7 +1980,7 @@ internal static bool ExpandExpressionCapture( if (!ChangeWaves.AreFeaturesEnabled(ChangeWaves.Wave17_6) || expressionCapture.Captures?.Any(capture => string.Equals(capture.FunctionName, "AnyHaveMetadataValue", StringComparison.OrdinalIgnoreCase)) != true) { - itemsFromCapture = new List>(); + itemsFromCapture = new List>(); return false; } } @@ -1991,7 +1991,7 @@ internal static bool ExpandExpressionCapture( isTransformExpression = true; } - itemsFromCapture = new List>(itemsOfType.Count); + itemsFromCapture = new List>(itemsOfType.Count); if (!isTransformExpression) { @@ -2003,7 +2003,7 @@ internal static bool ExpandExpressionCapture( return true; } - itemsFromCapture.Add(new Pair(item.EvaluatedIncludeEscaped, item)); + itemsFromCapture.Add(new KeyValuePair(item.EvaluatedIncludeEscaped, item)); } } else @@ -2011,7 +2011,7 @@ internal static bool ExpandExpressionCapture( Stack> transformFunctionStack = PrepareTransformStackFromMatch(elementLocation, expressionCapture); // iterate over the tranform chain, creating the final items from its results - foreach (Pair itemTuple in Transform(expander, includeNullEntries, transformFunctionStack, IntrinsicItemFunctions.GetItemPairEnumerable(itemsOfType))) + foreach (KeyValuePair itemTuple in Transform(expander, includeNullEntries, transformFunctionStack, IntrinsicItemFunctions.GetItemPairEnumerable(itemsOfType))) { if (!string.IsNullOrEmpty(itemTuple.Key) && (options & ExpanderOptions.BreakOnNotEmpty) != 0) { @@ -2026,7 +2026,7 @@ internal static bool ExpandExpressionCapture( { var joinedItems = string.Join(expressionCapture.Separator, itemsFromCapture.Select(i => i.Key)); itemsFromCapture.Clear(); - itemsFromCapture.Add(new Pair(joinedItems, null)); + itemsFromCapture.Add(new KeyValuePair(joinedItems, null)); } return false; // did not break early @@ -2144,7 +2144,7 @@ private static bool ExpandExpressionCaptureIntoStringBuilder( ExpanderOptions options) where S : class, IItem { - List> itemsFromCapture; + List> itemsFromCapture; bool throwaway; var brokeEarlyNonEmpty = ExpandExpressionCapture(expander, capture, evaluatedItems, elementLocation /* including null items */, options, true, out throwaway, out itemsFromCapture); @@ -2205,7 +2205,7 @@ internal static class IntrinsicItemFunctions /// Delegate that represents the signature of all item transformation functions /// This is used to support calling the functions by name. /// - public delegate IEnumerable> ItemTransformFunction(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments); + public delegate IEnumerable> ItemTransformFunction(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments); /// /// Get a delegate to the given item transformation function by supplying the name and the @@ -2268,7 +2268,7 @@ internal static ItemTransformFunction GetItemTransformFunction(IElementLocation /// Create an enumerator from a base IEnumerable of items into an enumerable /// of transformation result which includes the new itemspec and the base item. /// - internal static IEnumerable> GetItemPairEnumerable(IEnumerable itemsOfType) + internal static IEnumerable> GetItemPairEnumerable(IEnumerable itemsOfType) { // iterate over the items, and yield out items in the tuple format foreach (var item in itemsOfType) @@ -2281,12 +2281,12 @@ internal static IEnumerable> GetItemPairEnumerable(IEnumerable(resultantItem, item); + yield return new KeyValuePair(resultantItem, item); } } else { - yield return new Pair(item.EvaluatedIncludeEscaped, item); + yield return new KeyValuePair(item.EvaluatedIncludeEscaped, item); } } } @@ -2294,20 +2294,20 @@ internal static IEnumerable> GetItemPairEnumerable(IEnumerable /// Intrinsic function that returns the number of items in the list. /// - internal static IEnumerable> Count(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> Count(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { - yield return new Pair(Convert.ToString(itemsOfType.Count(), CultureInfo.InvariantCulture), null /* no base item */); + yield return new KeyValuePair(Convert.ToString(itemsOfType.Count(), CultureInfo.InvariantCulture), null /* no base item */); } /// /// Intrinsic function that returns the specified built-in modifer value of the items in itemsOfType /// Tuple is {current item include, item under transformation}. /// - internal static IEnumerable> ItemSpecModifierFunction(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> ItemSpecModifierFunction(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments == null || arguments.Length == 0, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); - foreach (Pair item in itemsOfType) + foreach (KeyValuePair item in itemsOfType) { // If the item include has become empty, // this is the end of the pipeline for this item @@ -2339,11 +2339,11 @@ internal static IEnumerable> ItemSpecModifierFunction(Expander

(result, item.Value); + yield return new KeyValuePair(result, item.Value); } else if (includeNullEntries) { - yield return new Pair(null, item.Value); + yield return new KeyValuePair(null, item.Value); } } } @@ -2351,11 +2351,11 @@ internal static IEnumerable> ItemSpecModifierFunction(Expander

/// Intrinsic function that returns the subset of items that actually exist on disk. /// - internal static IEnumerable> Exists(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> Exists(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments == null || arguments.Length == 0, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); - foreach (Pair item in itemsOfType) + foreach (KeyValuePair item in itemsOfType) { if (String.IsNullOrEmpty(item.Key)) { @@ -2398,13 +2398,13 @@ internal static IEnumerable> Exists(Expander expander, IEl ///

/// Intrinsic function that combines the existing paths of the input items with a given relative path. /// - internal static IEnumerable> Combine(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> Combine(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments?.Length == 1, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); string relativePath = arguments[0]; - foreach (Pair item in itemsOfType) + foreach (KeyValuePair item in itemsOfType) { if (String.IsNullOrEmpty(item.Key)) { @@ -2415,14 +2415,14 @@ internal static IEnumerable> Combine(Expander expander, IE string unescapedPath = EscapingUtilities.UnescapeAll(item.Key); string combinedPath = Path.Combine(unescapedPath, relativePath); string escapedPath = EscapingUtilities.Escape(combinedPath); - yield return new Pair(escapedPath, null); + yield return new KeyValuePair(escapedPath, null); } } /// /// Intrinsic function that returns all ancestor directories of the given items. /// - internal static IEnumerable> GetPathsOfAllDirectoriesAbove(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> GetPathsOfAllDirectoriesAbove(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments == null || arguments.Length == 0, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); @@ -2430,7 +2430,7 @@ internal static IEnumerable> GetPathsOfAllDirectoriesAbove(Expan SortedSet directories = new SortedSet(StringComparer.OrdinalIgnoreCase); - foreach (Pair item in itemsOfType) + foreach (KeyValuePair item in itemsOfType) { if (String.IsNullOrEmpty(item.Key)) { @@ -2490,7 +2490,7 @@ internal static IEnumerable> GetPathsOfAllDirectoriesAbove(Expan foreach (string directoryPath in directories) { string escapedDirectoryPath = EscapingUtilities.Escape(directoryPath); - yield return new Pair(escapedDirectoryPath, null); + yield return new KeyValuePair(escapedDirectoryPath, null); } } @@ -2498,13 +2498,13 @@ internal static IEnumerable> GetPathsOfAllDirectoriesAbove(Expan /// Intrinsic function that returns the DirectoryName of the items in itemsOfType /// UNDONE: This can be removed in favor of a built-in %(DirectoryName) metadata in future. /// - internal static IEnumerable> DirectoryName(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> DirectoryName(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments == null || arguments.Length == 0, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); Dictionary directoryNameTable = new Dictionary(StringComparer.OrdinalIgnoreCase); - foreach (Pair item in itemsOfType) + foreach (KeyValuePair item in itemsOfType) { // If the item include has become empty, // this is the end of the pipeline for this item @@ -2553,11 +2553,11 @@ internal static IEnumerable> DirectoryName(Expander expand if (!String.IsNullOrEmpty(directoryName)) { // return a result through the enumerator - yield return new Pair(directoryName, item.Value); + yield return new KeyValuePair(directoryName, item.Value); } else if (includeNullEntries) { - yield return new Pair(null, item.Value); + yield return new KeyValuePair(null, item.Value); } } } @@ -2565,13 +2565,13 @@ internal static IEnumerable> DirectoryName(Expander expand /// /// Intrinsic function that returns the contents of the metadata in specified in argument[0]. /// - internal static IEnumerable> Metadata(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> Metadata(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments?.Length == 1, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); string metadataName = arguments[0]; - foreach (Pair item in itemsOfType) + foreach (KeyValuePair item in itemsOfType) { if (item.Value != null) { @@ -2598,18 +2598,18 @@ internal static IEnumerable> Metadata(Expander expander, I foreach (string itemSpec in splits) { // return a result through the enumerator - yield return new Pair(itemSpec, item.Value); + yield return new KeyValuePair(itemSpec, item.Value); } } else { // return a result through the enumerator - yield return new Pair(metadataValue, item.Value); + yield return new KeyValuePair(metadataValue, item.Value); } } else if (metadataValue != String.Empty && includeNullEntries) { - yield return new Pair(metadataValue, item.Value); + yield return new KeyValuePair(metadataValue, item.Value); } } } @@ -2619,7 +2619,7 @@ internal static IEnumerable> Metadata(Expander expander, I /// Intrinsic function that returns only the items from itemsOfType that have distinct Item1 in the Tuple /// Using a case sensitive comparison. /// - internal static IEnumerable> DistinctWithCase(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> DistinctWithCase(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { return DistinctWithComparer(expander, elementLocation, includeNullEntries, functionName, itemsOfType, arguments, StringComparer.Ordinal); } @@ -2628,7 +2628,7 @@ internal static IEnumerable> DistinctWithCase(Expander exp /// Intrinsic function that returns only the items from itemsOfType that have distinct Item1 in the Tuple /// Using a case insensitive comparison. /// - internal static IEnumerable> Distinct(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> Distinct(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { return DistinctWithComparer(expander, elementLocation, includeNullEntries, functionName, itemsOfType, arguments, StringComparer.OrdinalIgnoreCase); } @@ -2637,20 +2637,18 @@ internal static IEnumerable> Distinct(Expander expander, I /// Intrinsic function that returns only the items from itemsOfType that have distinct Item1 in the Tuple /// Using a case insensitive comparison. /// - internal static IEnumerable> DistinctWithComparer(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments, StringComparer comparer) + internal static IEnumerable> DistinctWithComparer(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments, StringComparer comparer) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments == null || arguments.Length == 0, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); // This dictionary will ensure that we only return one result per unique itemspec - Dictionary seenItems = new Dictionary(comparer); + HashSet seenItems = new HashSet(comparer); - foreach (Pair item in itemsOfType) + foreach (KeyValuePair item in itemsOfType) { - if (item.Key != null && !seenItems.ContainsKey(item.Key)) + if (item.Key != null && seenItems.Add(item.Key)) { - seenItems[item.Key] = item.Value; - - yield return new Pair(item.Key, item.Value); + yield return item; } } } @@ -2658,23 +2656,20 @@ internal static IEnumerable> DistinctWithComparer(Expander /// /// Intrinsic function reverses the item list. /// - internal static IEnumerable> Reverse(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> Reverse(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments == null || arguments.Length == 0, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); - foreach (Pair item in itemsOfType.Reverse()) - { - yield return new Pair(item.Key, item.Value); - } + return itemsOfType.Reverse(); } /// /// Intrinsic function that transforms expressions like the %(foo) in @(Compile->'%(foo)'). /// - internal static IEnumerable> ExpandQuotedExpressionFunction(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> ExpandQuotedExpressionFunction(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments?.Length == 1, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); - foreach (Pair item in itemsOfType) + foreach (KeyValuePair item in itemsOfType) { MetadataMatchEvaluator matchEvaluator; string include = null; @@ -2697,11 +2692,11 @@ internal static IEnumerable> ExpandQuotedExpressionFunction(Expa // We pass in the existing item so we can copy over its metadata if (!string.IsNullOrEmpty(include)) { - yield return new Pair(include, item.Value); + yield return new KeyValuePair(include, item.Value); } else if (includeNullEntries) { - yield return new Pair(null, item.Value); + yield return new KeyValuePair(null, item.Value); } } } @@ -2710,17 +2705,17 @@ internal static IEnumerable> ExpandQuotedExpressionFunction(Expa /// Intrinsic function that transforms expressions by invoking methods of System.String on the itemspec /// of the item in the pipeline. /// - internal static IEnumerable> ExecuteStringFunction( + internal static IEnumerable> ExecuteStringFunction( Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, - IEnumerable> itemsOfType, + IEnumerable> itemsOfType, string[] arguments) { // Transform: expression is like @(Compile->'%(foo)'), so create completely new items, // using the Include from the source items - foreach (Pair item in itemsOfType) + foreach (KeyValuePair item in itemsOfType) { Function

function = new Function

( typeof(string), @@ -2740,11 +2735,11 @@ internal static IEnumerable> ExecuteStringFunction( // We pass in the existing item so we can copy over its metadata if (include.Length > 0) { - yield return new Pair(include, item.Value); + yield return new KeyValuePair(include, item.Value); } else if (includeNullEntries) { - yield return new Pair(null, item.Value); + yield return new KeyValuePair(null, item.Value); } } } @@ -2752,15 +2747,15 @@ internal static IEnumerable> ExecuteStringFunction( ///

/// Intrinsic function that returns the items from itemsOfType with their metadata cleared, i.e. only the itemspec is retained. /// - internal static IEnumerable> ClearMetadata(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> ClearMetadata(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments == null || arguments.Length == 0, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); - foreach (Pair item in itemsOfType) + foreach (KeyValuePair item in itemsOfType) { if (includeNullEntries || item.Key != null) { - yield return new Pair(item.Key, null); + yield return new KeyValuePair(item.Key, null); } } } @@ -2769,13 +2764,13 @@ internal static IEnumerable> ClearMetadata(Expander expand /// Intrinsic function that returns only those items that have a not-blank value for the metadata specified /// Using a case insensitive comparison. /// - internal static IEnumerable> HasMetadata(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> HasMetadata(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments?.Length == 1, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); string metadataName = arguments[0]; - foreach (Pair item in itemsOfType) + foreach (KeyValuePair item in itemsOfType) { string metadataValue = null; @@ -2794,7 +2789,7 @@ internal static IEnumerable> HasMetadata(Expander expander if (!string.IsNullOrEmpty(metadataValue)) { // return a result through the enumerator - yield return new Pair(item.Key, item.Value); + yield return item; } } } @@ -2803,14 +2798,14 @@ internal static IEnumerable> HasMetadata(Expander expander /// Intrinsic function that returns only those items have the given metadata value /// Using a case insensitive comparison. /// - internal static IEnumerable> WithMetadataValue(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> WithMetadataValue(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments?.Length == 2, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); string metadataName = arguments[0]; string metadataValueToFind = arguments[1]; - foreach (Pair item in itemsOfType) + foreach (KeyValuePair item in itemsOfType) { string metadataValue = null; @@ -2827,7 +2822,7 @@ internal static IEnumerable> WithMetadataValue(Expander ex if (metadataValue != null && String.Equals(metadataValue, metadataValueToFind, StringComparison.OrdinalIgnoreCase)) { // return a result through the enumerator - yield return new Pair(item.Key, item.Value); + yield return item; } } } @@ -2836,14 +2831,14 @@ internal static IEnumerable> WithMetadataValue(Expander ex /// Intrinsic function that returns those items don't have the given metadata value /// Using a case insensitive comparison. /// - internal static IEnumerable> WithoutMetadataValue(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> WithoutMetadataValue(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments?.Length == 2, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); string metadataName = arguments[0]; string metadataValueToFind = arguments[1]; - foreach (Pair item in itemsOfType) + foreach (KeyValuePair item in itemsOfType) { string metadataValue = null; @@ -2860,7 +2855,7 @@ internal static IEnumerable> WithoutMetadataValue(Expander if (!String.Equals(metadataValue, metadataValueToFind, StringComparison.OrdinalIgnoreCase)) { // return a result through the enumerator - yield return new Pair(item.Key, item.Value); + yield return item; } } } @@ -2869,7 +2864,7 @@ internal static IEnumerable> WithoutMetadataValue(Expander /// Intrinsic function that returns a boolean to indicate if any of the items have the given metadata value /// Using a case insensitive comparison. /// - internal static IEnumerable> AnyHaveMetadataValue(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> AnyHaveMetadataValue(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments?.Length == 2, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); @@ -2877,7 +2872,7 @@ internal static IEnumerable> AnyHaveMetadataValue(Expander string metadataValueToFind = arguments[1]; bool metadataFound = false; - foreach (Pair item in itemsOfType) + foreach (KeyValuePair item in itemsOfType) { if (item.Value != null) { @@ -2898,7 +2893,7 @@ internal static IEnumerable> AnyHaveMetadataValue(Expander metadataFound = true; // return a result through the enumerator - yield return new Pair("true", item.Value); + yield return new KeyValuePair("true", item.Value); // break out as soon as we found a match yield break; @@ -2909,7 +2904,7 @@ internal static IEnumerable> AnyHaveMetadataValue(Expander if (!metadataFound) { // We did not locate an item with the required metadata - yield return new Pair("false", null); + yield return new KeyValuePair("false", null); } } } @@ -2971,7 +2966,7 @@ public IElementLocation ElementLocation /// /// Execute this transform function with the arguments contained within this TransformFunction instance. /// - public IEnumerable> Execute(Expander expander, bool includeNullEntries, IEnumerable> itemsOfType) + public IEnumerable> Execute(Expander expander, bool includeNullEntries, IEnumerable> itemsOfType) { // Execute via the delegate return _transform(expander, _elementLocation, includeNullEntries, _functionName, itemsOfType, _arguments); diff --git a/src/Build/Evaluation/IItemFactory.cs b/src/Build/Evaluation/IItemFactory.cs index 2125968bf6c..986386cd7a0 100644 --- a/src/Build/Evaluation/IItemFactory.cs +++ b/src/Build/Evaluation/IItemFactory.cs @@ -68,6 +68,6 @@ ProjectItemElement ItemElement /// /// Applies the supplied metadata to the destination items. /// - void SetMetadata(IEnumerable> metadata, IEnumerable destinationItems); + void SetMetadata(IEnumerable> metadata, IEnumerable destinationItems); } } diff --git a/src/Build/Evaluation/LazyItemEvaluator.ItemFactoryWrapper.cs b/src/Build/Evaluation/LazyItemEvaluator.ItemFactoryWrapper.cs index 722d467c342..99c7166189b 100644 --- a/src/Build/Evaluation/LazyItemEvaluator.ItemFactoryWrapper.cs +++ b/src/Build/Evaluation/LazyItemEvaluator.ItemFactoryWrapper.cs @@ -75,7 +75,7 @@ public I CreateItem(string include, I baseItem, string definingProject) return _wrappedItemFactory.CreateItem(include, baseItem, definingProject); } - public void SetMetadata(IEnumerable> metadata, IEnumerable destinationItems) + public void SetMetadata(IEnumerable> metadata, IEnumerable destinationItems) { SetItemElement(); _wrappedItemFactory.SetMetadata(metadata, destinationItems); diff --git a/src/Build/Evaluation/LazyItemEvaluator.LazyItemOperation.cs b/src/Build/Evaluation/LazyItemEvaluator.LazyItemOperation.cs index 43fffb961a6..fe8b1805bab 100644 --- a/src/Build/Evaluation/LazyItemEvaluator.LazyItemOperation.cs +++ b/src/Build/Evaluation/LazyItemEvaluator.LazyItemOperation.cs @@ -230,7 +230,7 @@ protected void DecorateItemsWithMetadata(IEnumerable itemBa _expander.Metadata = metadataTable; // Also keep a list of everything so we can get the predecessor objects correct. - List> metadataList = new(metadata.Length); + List> metadataList = new(metadata.Length); foreach (var metadataElement in metadata) { @@ -252,7 +252,7 @@ protected void DecorateItemsWithMetadata(IEnumerable itemBa evaluatedValue = FileUtilities.MaybeAdjustFilePath(evaluatedValue, metadataElement.ContainingProject.DirectoryPath); metadataTable.SetValue(metadataElement, evaluatedValue); - metadataList.Add(new Pair(metadataElement, evaluatedValue)); + metadataList.Add(new KeyValuePair(metadataElement, evaluatedValue)); } // Apply those metadata to each item diff --git a/src/Build/Instance/ProjectItemInstance.cs b/src/Build/Instance/ProjectItemInstance.cs index 4db93ab3bb0..cf6fc186770 100644 --- a/src/Build/Instance/ProjectItemInstance.cs +++ b/src/Build/Instance/ProjectItemInstance.cs @@ -2007,7 +2007,7 @@ public ProjectItemInstance CreateItem(string evaluatedInclude, string evaluatedI /// /// Applies the supplied metadata to the destination item. /// - public void SetMetadata(IEnumerable> metadataList, IEnumerable destinationItems) + public void SetMetadata(IEnumerable> metadataList, IEnumerable destinationItems) { // Set up a single dictionary that can be applied to all the items CopyOnWritePropertyDictionary metadata = new CopyOnWritePropertyDictionary(); @@ -2172,7 +2172,7 @@ public TaskItem CreateItem(string includeEscaped, string includeBeforeWildcardEx /// /// Applies the supplied metadata to the destination item. /// - public void SetMetadata(IEnumerable> metadata, IEnumerable destinationItems) + public void SetMetadata(IEnumerable> metadata, IEnumerable destinationItems) { // Not difficult to implement, but we do not expect to go here. ErrorUtilities.ThrowInternalErrorUnreachable(); diff --git a/src/Build/Logging/ProfilerLogger.cs b/src/Build/Logging/ProfilerLogger.cs index a67d513a099..7f12efba35c 100644 --- a/src/Build/Logging/ProfilerLogger.cs +++ b/src/Build/Logging/ProfilerLogger.cs @@ -219,7 +219,7 @@ private static Dictionary PruneSmallItems( // Let's build an index of profiled locations by id, to speed up subsequent queries var idTable = aggregatedLocations.ToDictionary(pair => pair.Key.Id, - pair => new Pair(pair.Key, pair.Value)); + pair => new KeyValuePair(pair.Key, pair.Value)); // We want to keep all evaluation pass entries plus the big enough regular entries foreach (var prunedPair in aggregatedLocations.Where(pair => @@ -237,7 +237,7 @@ private static Dictionary PruneSmallItems( /// /// Finds the first ancestor of parentId (which could be itself) that is either an evaluation pass location or a big enough profiled data. /// - private static long? FindBigEnoughParentId(IDictionary> idTable, + private static long? FindBigEnoughParentId(IDictionary> idTable, long? parentId) { // The parent id is null, which means the item was pointing to an evaluation pass item. So we keep it as is. diff --git a/src/Build/Microsoft.Build.csproj b/src/Build/Microsoft.Build.csproj index 9a5b1175b0e..1ae94c41fb7 100644 --- a/src/Build/Microsoft.Build.csproj +++ b/src/Build/Microsoft.Build.csproj @@ -86,9 +86,6 @@ SharedUtilities\NGen.cs - - SharedUtilities\Pair.cs - BackEnd\Components\RequestBuilder\IntrinsicTasks\PropertyParser.cs True diff --git a/src/Shared/Pair.cs b/src/Shared/Pair.cs deleted file mode 100644 index ef5073b4835..00000000000 --- a/src/Shared/Pair.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics.CodeAnalysis; - -#nullable disable - -namespace Microsoft.Build.Shared -{ - /// - /// This struct is functionally identical to KeyValuePair, but avoids - /// CA908 warnings (types that in ngen images that will JIT). - /// Instead of generic collections of KeyValuePair, use Pair. - /// - /// - /// This trick is based on advice from - /// http://sharepoint/sites/codeanalysis/Wiki%20Pages/Rule%20-%20Avoid%20Types%20That%20Require%20JIT%20Compilation%20In%20Precompiled%20Assemblies.aspx. - /// It works because although this is a value type, it is not defined in mscorlib. - /// - /// Key - /// Value - [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes", Justification = "Not possible as Equals cannot be implemented on the struct members")] - internal struct Pair - { - /// - /// Key - /// - private TKey _key; - - /// - /// Value - /// - private TValue _value; - - /// - /// Constructor - /// - public Pair(TKey key, TValue value) - { - _key = key; - _value = value; - } - - /// - /// Key - /// - internal readonly TKey Key - { - get { return _key; } - } - - /// - /// Value - /// - internal readonly TValue Value - { - get { return _value; } - } - } -} diff --git a/src/Shared/Tracing.cs b/src/Shared/Tracing.cs index d26f7127305..a71f01f150d 100644 --- a/src/Shared/Tracing.cs +++ b/src/Shared/Tracing.cs @@ -141,7 +141,6 @@ internal static void List(IEnumerable items) /// Dump all the named counters, if any /// [Conditional("DEBUG")] - [SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Justification = "Debug only")] internal static void Dump() { if (s_counts.Count > 0)