Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -25,31 +25,27 @@ internal static InternalSyntax.SyntaxList<T> ToGreenList<T>(this GreenNode node)

public static TNode WithAnnotationsGreen<TNode>(this TNode node, params SyntaxAnnotation[] annotations) where TNode : GreenNode
{
var newAnnotations = new List<SyntaxAnnotation>();
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<SyntaxAnnotation>(annotations.Length);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to use a pooled hash set here instead?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to ask the same question, but looking around it seems like the number of annotations is unlikely to ever be more than one. Unless I've misunderstood their use.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely possible, but I figured these collections are usually small enough that an array might be the better choice, even with the Contains usage.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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<TNode>(this TNode node, RazorDiagnostic[] diagnostics)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,51 @@ public readonly bool All<TArg>(TArg arg, Func<T, TArg, bool> predicate)
return true;
}

/// <summary>
/// Searches for the specified item.
/// </summary>
/// <param name="item">The item to search for.</param>
/// <returns>The 0-based index where the item was found; or -1 if it could not be found.</returns>
public readonly int IndexOf(T item)
=> IndexOf(item, EqualityComparer<T>.Default);

/// <summary>
/// Searches for the specified item.
/// </summary>
/// <param name="item">The item to search for.</param>
/// <param name="comparer">The equality comparer to use in the search.</param>
/// <returns>The 0-based index where the item was found; or -1 if it could not be found.</returns>
public readonly int IndexOf(T item, IEqualityComparer<T> comparer)
{
var n = Count;
for (var i = 0; i < n; i++)
{
if (comparer.Equals(this[i], item))
{
return i;
}
}

return -1;
}

/// <summary>
/// Determines whether the specified item exists in this collection.
/// </summary>
/// <param name="item">The item to search for.</param>
/// <returns><c>true</c> if an equal value was found in this collection; <c>false</c> otherwise.</returns>
public readonly bool Contains(T item)
=> Contains(item, EqualityComparer<T>.Default);

/// <summary>
/// Determines whether the specified item exists in this collection.
/// </summary>
/// <param name="item">The item to search for.</param>
/// <param name="comparer">The equality comparer to use in the search.</param>
/// <returns><c>true</c> if an equal value was found in this collection; <c>false</c> otherwise.</returns>
public readonly bool Contains(T item, IEqualityComparer<T> comparer)
=> IndexOf(item, comparer) >= 0;

/// <summary>
/// Returns the first element in this builder.
/// </summary>
Expand Down