| File: BraceMatching\AbstractDirectiveTriviaBraceMatcher.cs | Web Access |
| Project: src\roslyn\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.Immutable; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.BraceMatching; internal abstract class AbstractDirectiveTriviaBraceMatcher<TDirectiveTriviaSyntax, TIfDirectiveTriviaSyntax, TElseIfDirectiveTriviaSyntax, TElseDirectiveTriviaSyntax, TEndIfDirectiveTriviaSyntax, TRegionDirectiveTriviaSyntax, TEndRegionDirectiveTriviaSyntax> : IBraceMatcher where TDirectiveTriviaSyntax : SyntaxNode where TIfDirectiveTriviaSyntax : TDirectiveTriviaSyntax where TElseIfDirectiveTriviaSyntax : TDirectiveTriviaSyntax where TElseDirectiveTriviaSyntax : TDirectiveTriviaSyntax where TEndIfDirectiveTriviaSyntax : TDirectiveTriviaSyntax where TRegionDirectiveTriviaSyntax : TDirectiveTriviaSyntax where TEndRegionDirectiveTriviaSyntax : TDirectiveTriviaSyntax { protected abstract ImmutableArray<TDirectiveTriviaSyntax> GetMatchingConditionalDirectives(TDirectiveTriviaSyntax directive, CancellationToken cancellationToken); protected abstract TDirectiveTriviaSyntax? GetMatchingDirective(TDirectiveTriviaSyntax directive, CancellationToken cancellationToken); internal abstract TextSpan GetSpanForTagging(TDirectiveTriviaSyntax directive); public async Task<BraceMatchingResult?> FindBracesAsync(Document document, int position, BraceMatchingOptions options, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var token = root.FindToken(position, findInsideTrivia: true); if (token.Parent is not TDirectiveTriviaSyntax directive) { return null; } TDirectiveTriviaSyntax? matchingDirective = null; if (directive is TIfDirectiveTriviaSyntax or TElseIfDirectiveTriviaSyntax or TElseDirectiveTriviaSyntax or TEndIfDirectiveTriviaSyntax) { // #if/#elif/#else/#endif directive cases. var matchingDirectives = GetMatchingConditionalDirectives(directive, cancellationToken); if (matchingDirectives.Length > 0) matchingDirective = matchingDirectives[(matchingDirectives.IndexOf(directive) + 1) % matchingDirectives.Length]; } else if (directive is TRegionDirectiveTriviaSyntax or TEndRegionDirectiveTriviaSyntax) { matchingDirective = GetMatchingDirective(directive, cancellationToken); } if (matchingDirective == null) { // one line directives, that do not have a matching begin/end directive pair. return null; } return new BraceMatchingResult( LeftSpan: GetSpanForTagging(directive), RightSpan: GetSpanForTagging(matchingDirective)); } }