File: EditAndContinue\ActiveStatement.cs
Web Access
Project: src\src\Features\Core\Portable\Microsoft.CodeAnalysis.Features.csproj (Microsoft.CodeAnalysis.Features)
// 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.Diagnostics;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.Contracts.EditAndContinue;
 
namespace Microsoft.CodeAnalysis.EditAndContinue;
 
/// <summary>
/// Represents an instruction range in the code that contains an active instruction of at least one thread and that is delimited by consecutive sequence points.
/// More than one thread can share the same instance of <see cref="ActiveStatement"/>.
/// </summary>
[DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
internal sealed class ActiveStatement
{
    /// <summary>
    /// Ordinal of the active statement within the set of all active statements.
    /// </summary>
    public readonly ActiveStatementId Id;
 
    /// <summary>
    /// The instruction of the active statement that is being executed.
    /// The executing version of the method might be several generations old.
    /// E.g. when the thread is executing an exception handling region and hasn't been remapped yet.
    /// </summary>
    public readonly ManagedInstructionId InstructionId;
 
    /// <summary>
    /// The current source span.
    /// </summary>
    public readonly SourceFileSpan FileSpan;
 
    /// <summary>
    /// Aggregated across all threads.
    /// </summary>
    public readonly ActiveStatementFlags Flags;
 
    public ActiveStatement(ActiveStatementId id, ActiveStatementFlags flags, SourceFileSpan span, ManagedInstructionId instructionId)
    {
        Id = id;
        Flags = flags;
        FileSpan = span;
        InstructionId = instructionId;
 
        // IsStale implies !IsMethodUpToDate
        Debug.Assert(!IsStale || !IsMethodUpToDate);
    }
 
    public ActiveStatement WithSpan(LinePositionSpan span)
        => WithFileSpan(FileSpan.WithSpan(span));
 
    public ActiveStatement WithFileSpan(SourceFileSpan span)
        => new(Id, Flags, span, InstructionId);
 
    public ActiveStatement WithFlags(ActiveStatementFlags flags)
        => new(Id, flags, FileSpan, InstructionId);
 
    public LinePositionSpan Span
        => FileSpan.Span;
 
    public string FilePath
        => FileSpan.Path;
 
    /// <summary>
    /// True if at least one of the threads whom this active statement belongs to is in a leaf frame.
    /// </summary>
    public bool IsLeaf
        => (Flags & ActiveStatementFlags.LeafFrame) != 0;
 
    /// <summary>
    /// True if at least one of the threads whom this active statement belongs to is in a non-leaf frame.
    /// </summary>
    public bool IsNonLeaf
        => (Flags & ActiveStatementFlags.NonLeafFrame) != 0;
 
    /// <summary>
    /// True if the active statement is located in a version of the method that's not the latest version of the method.
    /// </summary>
    public bool IsMethodUpToDate
        => (Flags & ActiveStatementFlags.MethodUpToDate) != 0;
 
    /// <summary>
    /// True if the active statement is located in a version of the method that precedes a later version that was created by Hot Reload update.
    /// </summary>
    public bool IsStale
        => (Flags & ActiveStatementFlags.Stale) != 0;
 
    private string GetDebuggerDisplay()
        => $"{Id}: {Span}";
}