File: CSharpBlockFacts.cs
Web Access
Project: ..\..\..\src\CodeStyle\CSharp\Analyzers\Microsoft.CodeAnalysis.CSharp.CodeStyle.csproj (Microsoft.CodeAnalysis.CSharp.CodeStyle)
// 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 System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.LanguageService;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Roslyn.Utilities;
 
namespace Microsoft.CodeAnalysis.CSharp.LanguageService
{
    internal class CSharpBlockFacts : AbstractBlockFacts
    {
        public static readonly IBlockFacts Instance = new CSharpBlockFacts();
 
        public override bool IsScopeBlock([NotNullWhen(true)] SyntaxNode? node)
            => node.IsKind(SyntaxKind.Block);
 
        public override bool IsExecutableBlock([NotNullWhen(true)] SyntaxNode? node)
            => node is (kind: SyntaxKind.Block or SyntaxKind.SwitchSection or SyntaxKind.CompilationUnit);
 
        public override IReadOnlyList<SyntaxNode> GetExecutableBlockStatements(SyntaxNode? node)
        {
            return node switch
            {
                BlockSyntax block => block.Statements,
                SwitchSectionSyntax switchSection => switchSection.Statements,
                CompilationUnitSyntax compilationUnit => compilationUnit.Members.OfType<GlobalStatementSyntax>().SelectAsArray(globalStatement => globalStatement.Statement),
                _ => throw ExceptionUtilities.UnexpectedValue(node),
            };
        }
 
        public override SyntaxNode? FindInnermostCommonExecutableBlock(IEnumerable<SyntaxNode> nodes)
            => nodes.FindInnermostCommonNode(node => IsExecutableBlock(node));
 
        public override bool IsStatementContainer([NotNullWhen(true)] SyntaxNode? node)
            => IsExecutableBlock(node) || node.IsEmbeddedStatementOwner();
 
        public override IReadOnlyList<SyntaxNode> GetStatementContainerStatements(SyntaxNode? node)
        {
            if (IsExecutableBlock(node))
                return GetExecutableBlockStatements(node);
            else if (node.GetEmbeddedStatement() is { } embeddedStatement)
                return ImmutableArray.Create<SyntaxNode>(embeddedStatement);
            else
                return ImmutableArray<SyntaxNode>.Empty;
        }
    }
}