// 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; using System.Collections.Immutable; using System.Threading.Tasks; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.PooledObjects; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Structure { /// /// Note: this type is for subclassing by the VB and C# provider only. /// It presumes that the language supports Syntax Trees. /// internal abstract class AbstractBlockStructureProvider : BlockStructureProvider { private readonly ImmutableDictionary> _nodeProviderMap; private readonly ImmutableDictionary> _triviaProviderMap; protected AbstractBlockStructureProvider( ImmutableDictionary> defaultNodeOutlinerMap, ImmutableDictionary> defaultTriviaOutlinerMap) { _nodeProviderMap = defaultNodeOutlinerMap; _triviaProviderMap = defaultTriviaOutlinerMap; } /// /// Keep in sync with /// public override void ProvideBlockStructure(BlockStructureContext context) { try { var syntaxRoot = context.Document.GetSyntaxRootSynchronously(context.CancellationToken); ProvideBlockStructureWorker(context, syntaxRoot); } catch (Exception e) when (FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } } /// /// Keep in sync with /// public override async Task ProvideBlockStructureAsync(BlockStructureContext context) { try { var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); ProvideBlockStructureWorker(context, syntaxRoot); } catch (Exception e) when (FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } } private void ProvideBlockStructureWorker( BlockStructureContext context, SyntaxNode syntaxRoot) { using var _ = ArrayBuilder.GetInstance(out var spans); BlockSpanCollector.CollectBlockSpans( context.Document, syntaxRoot, _nodeProviderMap, _triviaProviderMap, spans, context.CancellationToken); foreach (var span in spans) { context.AddBlockSpan(span); } } } }