File: FlowAnalysis\RegionReachableWalker.cs
Web Access
Project: src\src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj (Microsoft.CodeAnalysis.CSharp)
// 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.
 
#nullable disable
 
using Microsoft.CodeAnalysis.CSharp.Symbols;
 
namespace Microsoft.CodeAnalysis.CSharp
{
    /// <summary>
    /// A region analysis walker that computes whether or not the region completes normally.  It does this by determining
    /// if the point at which the region ends is reachable.
    /// </summary>
    internal class RegionReachableWalker : AbstractRegionControlFlowPass
    {
        internal static void Analyze(CSharpCompilation compilation, Symbol member, BoundNode node, BoundNode firstInRegion, BoundNode lastInRegion,
            out bool startPointIsReachable, out bool endPointIsReachable)
        {
            var walker = new RegionReachableWalker(compilation, member, node, firstInRegion, lastInRegion);
            var diagnostics = DiagnosticBag.GetInstance();
            bool badRegion = false;
            try
            {
                walker.Analyze(ref badRegion, diagnostics);
                startPointIsReachable = badRegion || walker._regionStartPointIsReachable.GetValueOrDefault(true);
                endPointIsReachable = badRegion || walker._regionEndPointIsReachable.GetValueOrDefault(walker.State.Alive);
            }
            finally
            {
                diagnostics.Free();
                walker.Free();
            }
        }
 
        private bool? _regionStartPointIsReachable;
        private bool? _regionEndPointIsReachable;
 
        private RegionReachableWalker(CSharpCompilation compilation, Symbol member, BoundNode node, BoundNode firstInRegion, BoundNode lastInRegion)
            : base(compilation, member, node, firstInRegion, lastInRegion)
        {
        }
 
        protected override void EnterRegion()
        {
            _regionStartPointIsReachable = this.State.Alive;
            base.EnterRegion();
        }
 
        protected override void LeaveRegion()
        {
            _regionEndPointIsReachable = this.State.Alive;
            base.LeaveRegion();
        }
    }
}