|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CodeGen
{
/// <summary>
/// Debug information maintained for each lambda.
/// </summary>
/// <remarks>
/// The information is emitted to PDB in Custom Debug Information record for a method containing the lambda.
/// </remarks>
[DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
internal struct LambdaDebugInfo : IEquatable<LambdaDebugInfo>
{
/// <summary>
/// The syntax offset of the syntax node declaring the lambda (lambda expression) or its body (lambda in a query).
/// </summary>
public readonly int SyntaxOffset;
/// <summary>
/// The ordinal of the closure frame the lambda belongs to, or
/// <see cref="StaticClosureOrdinal"/> if the lambda is static, or
/// <see cref="ThisOnlyClosureOrdinal"/> if the lambda is closed over "this" pointer only.
/// </summary>
public readonly int ClosureOrdinal;
public readonly DebugId LambdaId;
public const int StaticClosureOrdinal = -1;
public const int ThisOnlyClosureOrdinal = -2;
public const int MinClosureOrdinal = ThisOnlyClosureOrdinal;
public LambdaDebugInfo(int syntaxOffset, DebugId lambdaId, int closureOrdinal)
{
Debug.Assert(closureOrdinal >= MinClosureOrdinal);
SyntaxOffset = syntaxOffset;
ClosureOrdinal = closureOrdinal;
LambdaId = lambdaId;
}
public bool Equals(LambdaDebugInfo other)
{
return SyntaxOffset == other.SyntaxOffset
&& ClosureOrdinal == other.ClosureOrdinal
&& LambdaId.Equals(other.LambdaId);
}
public override bool Equals(object? obj)
{
return obj is LambdaDebugInfo && Equals((LambdaDebugInfo)obj);
}
public override int GetHashCode()
{
return Hash.Combine(ClosureOrdinal,
Hash.Combine(SyntaxOffset, LambdaId.GetHashCode()));
}
internal string GetDebuggerDisplay()
{
return
ClosureOrdinal == StaticClosureOrdinal ? $"({LambdaId.GetDebuggerDisplay()} @{SyntaxOffset}, static)" :
ClosureOrdinal == ThisOnlyClosureOrdinal ? $"(#{LambdaId.GetDebuggerDisplay()} @{SyntaxOffset}, this)" :
$"({LambdaId.GetDebuggerDisplay()} @{SyntaxOffset} in {ClosureOrdinal})";
}
}
}
|