|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Immutable;
using System.Linq;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.DotnetRuntime.Extensions;
internal static partial class SyntaxValueProviderExtensions
{
/// <summary>
/// Wraps a grouping of nodes within a syntax tree so we can have value-semantics around them usable by the
/// incremental driver. Note: we do something very sneaky here. Specifically, as long as we have the same <see
/// cref="SyntaxTree"/> from before, then we know we must have the same nodes as before (since the nodes are
/// entirely determined from the text+options which is exactly what the syntax tree represents). Similarly, if the
/// syntax tree changes, we will always get different nodes (since they point back at the syntax tree). So we can
/// just use the syntax tree itself to determine value semantics here.
/// </summary>
private sealed class SyntaxNodeGrouping<TSyntaxNode> : IEquatable<SyntaxNodeGrouping<TSyntaxNode>>
where TSyntaxNode : SyntaxNode
{
public readonly SyntaxTree SyntaxTree;
public readonly ImmutableArray<TSyntaxNode> SyntaxNodes;
public SyntaxNodeGrouping(IGrouping<SyntaxTree, TSyntaxNode> grouping)
{
SyntaxTree = grouping.Key;
SyntaxNodes = grouping.OrderBy(static n => n.FullSpan.Start).ToImmutableArray();
}
public override int GetHashCode()
=> SyntaxTree.GetHashCode();
public override bool Equals(object? obj)
=> Equals(obj as SyntaxNodeGrouping<TSyntaxNode>);
public bool Equals(SyntaxNodeGrouping<TSyntaxNode>? obj)
=> this.SyntaxTree == obj?.SyntaxTree;
}
}
|