diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/GreenNodeExtensions.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/GreenNodeExtensions.cs index 1ea13b6c678..ccf55bf34d3 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/GreenNodeExtensions.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/GreenNodeExtensions.cs @@ -3,9 +3,9 @@ #nullable disable -using System.Collections.Generic; using System.Collections.Immutable; using System.Runtime.InteropServices; +using Microsoft.AspNetCore.Razor.PooledObjects; namespace Microsoft.AspNetCore.Razor.Language.Syntax; @@ -25,31 +25,27 @@ internal static InternalSyntax.SyntaxList ToGreenList(this GreenNode node) public static TNode WithAnnotationsGreen(this TNode node, params SyntaxAnnotation[] annotations) where TNode : GreenNode { - var newAnnotations = new List(); - foreach (var candidate in annotations) + if (annotations.Length == 0) { - if (!newAnnotations.Contains(candidate)) + var existingAnnotations = node.GetAnnotations(); + if (existingAnnotations != null && existingAnnotations.Length > 0) { - newAnnotations.Add(candidate); + node = (TNode)node.SetAnnotations(null); } + + return node; } - if (newAnnotations.Count == 0) + using var newAnnotations = new PooledArrayBuilder(annotations.Length); + foreach (var candidate in annotations) { - var existingAnnotations = node.GetAnnotations(); - if (existingAnnotations == null || existingAnnotations.Length == 0) - { - return node; - } - else + if (!newAnnotations.Contains(candidate)) { - return (TNode)node.SetAnnotations(null); + newAnnotations.Add(candidate); } } - else - { - return (TNode)node.SetAnnotations(newAnnotations.ToArray()); - } + + return (TNode)node.SetAnnotations(newAnnotations.ToArray()); } public static TNode WithDiagnosticsGreen(this TNode node, RazorDiagnostic[] diagnostics) diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs index 5ac77c7dfe7..e4a5a1ca7e3 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs @@ -832,6 +832,51 @@ public readonly bool All(TArg arg, Func predicate) return true; } + /// + /// Searches for the specified item. + /// + /// The item to search for. + /// The 0-based index where the item was found; or -1 if it could not be found. + public readonly int IndexOf(T item) + => IndexOf(item, EqualityComparer.Default); + + /// + /// Searches for the specified item. + /// + /// The item to search for. + /// The equality comparer to use in the search. + /// The 0-based index where the item was found; or -1 if it could not be found. + public readonly int IndexOf(T item, IEqualityComparer comparer) + { + var n = Count; + for (var i = 0; i < n; i++) + { + if (comparer.Equals(this[i], item)) + { + return i; + } + } + + return -1; + } + + /// + /// Determines whether the specified item exists in this collection. + /// + /// The item to search for. + /// true if an equal value was found in this collection; false otherwise. + public readonly bool Contains(T item) + => Contains(item, EqualityComparer.Default); + + /// + /// Determines whether the specified item exists in this collection. + /// + /// The item to search for. + /// The equality comparer to use in the search. + /// true if an equal value was found in this collection; false otherwise. + public readonly bool Contains(T item, IEqualityComparer comparer) + => IndexOf(item, comparer) >= 0; + /// /// Returns the first element in this builder. ///