File: EditAndContinue\MemberBody.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.Collections.Generic;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.Text;
 
namespace Microsoft.CodeAnalysis.EditAndContinue;
 
internal abstract class MemberBody : DeclarationBody
{
    /// <summary>
    /// A minimal span that contains all possible breakpoint spans of <see cref="MemberBody"/>.
    /// </summary>
    public abstract TextSpan Envelope { get; }
 
    /// <summary>
    /// True if <paramref name="span"/> belongs to the <see cref="MemberBody"/>.
    /// </summary>
    public bool ContainsActiveStatementSpan(TextSpan span)
        => Envelope.Contains(span) && !IsExcludedActiveStatementSpanWithinEnvelope(span);
 
    /// <summary>
    /// True for <paramref name="span"/> within <see cref="Envelope"/> does not belong to the body.
    /// </summary>
    public virtual bool IsExcludedActiveStatementSpanWithinEnvelope(TextSpan span)
        => false;
 
    /// <summary>
    /// All tokens of the body that may be part of an active statement.
    /// </summary>
    public abstract IEnumerable<SyntaxToken>? GetActiveTokens();
 
    /// <summary>
    /// Finds an active statement at given span within this body and the corresponding partner statement in 
    /// <paramref name="partnerDeclarationBody"/>, if specified. Only called with <paramref name="partnerDeclarationBody"/> when
    /// the body does not have any non-trivial changes and thus the correpsonding active statement is always found in the partner body.
    /// </summary>
    public abstract SyntaxNode FindStatementAndPartner(TextSpan span, MemberBody? partnerDeclarationBody, out SyntaxNode? partnerStatement, out int statementPart);
 
    public SyntaxNode FindStatement(TextSpan span, out int statementPart)
        => FindStatementAndPartner(span, partnerDeclarationBody: null, out _, out statementPart);
 
    public IEnumerable<int> GetOverlappingActiveStatementIndices(ImmutableArray<UnmappedActiveStatement> statements)
    {
        var envelope = Envelope;
 
        var range = ActiveStatementsMap.GetSpansStartingInSpan(
            envelope.Start,
            envelope.End,
            statements,
            startPositionComparer: (x, y) => x.UnmappedSpan.Start.CompareTo(y));
 
        for (var i = range.Start.Value; i < range.End.Value; i++)
        {
            var span = statements[i].UnmappedSpan;
            if (envelope.Contains(span) && !IsExcludedActiveStatementSpanWithinEnvelope(span))
            {
                yield return i;
            }
        }
    }
}