protected override void CollectBlockSpans( SyntaxToken previousToken, AccessorDeclarationSyntax accessorDeclaration, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { CSharpStructureHelpers.CollectCommentBlockSpans(accessorDeclaration, ref spans, options); // fault tolerance if (accessorDeclaration.Body == null || accessorDeclaration.Body.OpenBraceToken.IsMissing || accessorDeclaration.Body.CloseBraceToken.IsMissing) { return; } SyntaxNodeOrToken current = accessorDeclaration; var nextSibling = current.GetNextSibling(); // Check IsNode to compress blank lines after this node if it is the last child of the parent. // // All accessor kinds are grouped together in Metadata as Source. var compressEmptyLines = options.IsMetadataAsSource && (!nextSibling.IsNode || nextSibling.AsNode() is AccessorDeclarationSyntax); spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( accessorDeclaration, accessorDeclaration.Keyword, compressEmptyLines: compressEmptyLines, autoCollapse: true, type: BlockTypes.Member, isCollapsible: true)); }
internal sealed override async Task <ImmutableArray <BlockSpan> > GetBlockSpansWorkerAsync(Document document, int position) { var root = await document.GetSyntaxRootAsync(CancellationToken.None); var token = root.FindToken(position, findInsideTrivia: true); var node = token.Parent.FirstAncestorOrSelf <TSyntaxNode>(); Assert.NotNull(node); // We prefer ancestor nodes if the position is on the edge of the located node's span. while (node.Parent is TSyntaxNode) { if ((position == node.SpanStart && position == node.Parent.SpanStart) || (position == node.Span.End && position == node.Parent.Span.End)) { node = (TSyntaxNode)node.Parent; } else { break; } } var outliner = CreateProvider(); using var actualRegions = TemporaryArray <BlockSpan> .Empty; var options = BlockStructureOptions.From(document.Project); // Calculate previousToken for tests the same way it is derived in production code var previousToken = root.DescendantNodesAndTokens(descendIntoTrivia: true).TakeWhile(nodeOrToken => nodeOrToken != node).LastOrDefault(nodeOrToken => nodeOrToken.IsToken).AsToken(); outliner.CollectBlockSpans(previousToken, node, ref actualRegions.AsRef(), options, CancellationToken.None); // TODO: Determine why we get null outlining spans. return(actualRegions.ToImmutableAndClear()); }
protected override void CollectBlockSpans( SyntaxToken previousToken, DocumentationCommentTriviaSyntax documentationComment, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { var startPos = documentationComment.FullSpan.Start; // The trailing newline is included in XmlDocCommentSyntax, so we need to strip it. var endPos = documentationComment.SpanStart + documentationComment.ToString().TrimEnd().Length; var span = TextSpan.FromBounds(startPos, endPos); var bannerLength = options.MaximumBannerLength; var bannerText = CSharpFileBannerFacts.Instance.GetBannerText( documentationComment, bannerLength, cancellationToken); spans.Add(new BlockSpan( isCollapsible: true, textSpan: span, type: BlockTypes.Comment, bannerText: bannerText, autoCollapse: true)); }
protected override void CollectBlockSpans( SyntaxToken previousToken, EventDeclarationSyntax eventDeclaration, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { CSharpStructureHelpers.CollectCommentBlockSpans(eventDeclaration, ref spans, options); // fault tolerance if (eventDeclaration.AccessorList == null || eventDeclaration.AccessorList.IsMissing || eventDeclaration.AccessorList.OpenBraceToken.IsMissing || eventDeclaration.AccessorList.CloseBraceToken.IsMissing) { return; } SyntaxNodeOrToken current = eventDeclaration; var nextSibling = current.GetNextSibling(); // Check IsNode to compress blank lines after this node if it is the last child of the parent. // // Full events are grouped together with event field definitions in Metadata as Source. var compressEmptyLines = options.IsMetadataAsSource && (!nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.EventDeclaration) || nextSibling.IsKind(SyntaxKind.EventFieldDeclaration)); spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( eventDeclaration, eventDeclaration.Identifier, compressEmptyLines: compressEmptyLines, autoCollapse: true, type: BlockTypes.Member, isCollapsible: true)); }
public override async Task <FoldingRange[]?> HandleRequestAsync(FoldingRangeParams request, RequestContext context, CancellationToken cancellationToken) { var document = context.Document; if (document == null) { return(null); } var blockStructureService = document.Project.LanguageServices.GetService <BlockStructureService>(); if (blockStructureService == null) { return(Array.Empty <FoldingRange>()); } var options = BlockStructureOptions.From(document.Project); var blockStructure = await blockStructureService.GetBlockStructureAsync(document, options, cancellationToken).ConfigureAwait(false); if (blockStructure == null) { return(Array.Empty <FoldingRange>()); } var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); return(GetFoldingRanges(blockStructure, text)); }
protected override void CollectBlockSpans( SyntaxToken previousToken, AnonymousMethodExpressionSyntax anonymousMethod, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { // fault tolerance if (anonymousMethod.Block.IsMissing || anonymousMethod.Block.OpenBraceToken.IsMissing || anonymousMethod.Block.CloseBraceToken.IsMissing) { return; } var lastToken = CSharpStructureHelpers.GetLastInlineMethodBlockToken(anonymousMethod); if (lastToken.Kind() == SyntaxKind.None) { return; } var startToken = anonymousMethod.ParameterList != null ? anonymousMethod.ParameterList.GetLastToken(includeZeroWidth : true) : anonymousMethod.DelegateKeyword; spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( anonymousMethod, startToken, lastToken, compressEmptyLines: false, autoCollapse: false, type: BlockTypes.Expression, isCollapsible: true)); }
internal override async Task <ImmutableArray <BlockSpan> > GetBlockSpansWorkerAsync(Document document, int position) { var outliningService = document.GetLanguageService <BlockStructureService>(); var options = BlockStructureOptions.From(document.Project); return((await outliningService.GetBlockStructureAsync(document, options, CancellationToken.None)).Spans); }
protected override void CollectBlockSpans( SyntaxToken previousToken, OperatorDeclarationSyntax operatorDeclaration, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { CSharpStructureHelpers.CollectCommentBlockSpans(operatorDeclaration, ref spans, options); // fault tolerance if (operatorDeclaration.Body == null || operatorDeclaration.Body.OpenBraceToken.IsMissing || operatorDeclaration.Body.CloseBraceToken.IsMissing) { return; } SyntaxNodeOrToken current = operatorDeclaration; var nextSibling = current.GetNextSibling(); // Check IsNode to compress blank lines after this node if it is the last child of the parent. // // Whitespace between operators is collapsed in Metadata as Source. var compressEmptyLines = options.IsMetadataAsSource && (!nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.OperatorDeclaration)); spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( operatorDeclaration, operatorDeclaration.ParameterList.GetLastToken(includeZeroWidth: true), compressEmptyLines: compressEmptyLines, autoCollapse: true, type: BlockTypes.Member, isCollapsible: true)); }
protected override void CollectBlockSpans( SyntaxToken previousToken, DestructorDeclarationSyntax destructorDeclaration, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { CSharpStructureHelpers.CollectCommentBlockSpans(destructorDeclaration, ref spans, options); // fault tolerance if (destructorDeclaration.Body == null || destructorDeclaration.Body.OpenBraceToken.IsMissing || destructorDeclaration.Body.CloseBraceToken.IsMissing) { return; } spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( destructorDeclaration, destructorDeclaration.ParameterList.GetLastToken(includeZeroWidth: true), compressEmptyLines: false, autoCollapse: true, type: BlockTypes.Member, isCollapsible: true)); }
protected override void CollectBlockSpans( SyntaxToken previousToken, CompilationUnitSyntax compilationUnit, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { CSharpStructureHelpers.CollectCommentBlockSpans(compilationUnit, ref spans, options); // extern aliases and usings are outlined in a single region var externsAndUsings = new List <SyntaxNode>(); externsAndUsings.AddRange(compilationUnit.Externs); externsAndUsings.AddRange(compilationUnit.Usings); externsAndUsings.Sort((node1, node2) => node1.SpanStart.CompareTo(node2.SpanStart)); spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( externsAndUsings, compressEmptyLines: false, autoCollapse: true, type: BlockTypes.Imports, isCollapsible: true)); if (compilationUnit.Usings.Count > 0 || compilationUnit.Externs.Count > 0 || compilationUnit.Members.Count > 0 || compilationUnit.AttributeLists.Count > 0) { CSharpStructureHelpers.CollectCommentBlockSpans(compilationUnit.EndOfFileToken.LeadingTrivia, ref spans); } }
protected override void CollectBlockSpans( SyntaxToken previousToken, RegionDirectiveTriviaSyntax regionDirective, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { var match = regionDirective.GetMatchingDirective(cancellationToken); if (match != null) { // Always auto-collapse regions for Metadata As Source. These generated files only have one region at // the top of the file, which has content like the following: // // #region Assembly System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a // // C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.1.0\ref\netcoreapp3.1\System.Runtime.dll // #endregion // // For other files, auto-collapse regions based on the user option. var autoCollapse = options.IsMetadataAsSource || options.CollapseRegionsWhenCollapsingToDefinitions; spans.Add(new BlockSpan( isCollapsible: true, textSpan: TextSpan.FromBounds(regionDirective.SpanStart, match.Span.End), type: BlockTypes.PreprocessorRegion, bannerText: GetBannerText(regionDirective), autoCollapse: autoCollapse, isDefaultCollapsed: !options.IsMetadataAsSource)); } }
protected override void CollectBlockSpans( SyntaxToken previousToken, DocumentationCommentTriviaSyntax documentationComment, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { // In metadata as source we want to treat documentation comments slightly differently, and collapse them // to just "..." in front of the decalaration they're attached to. That happens in CSharpStructureHelper.CollectCommentBlockSpans // so we don't need to do anything here if (options.IsMetadataAsSource) { return; } var startPos = documentationComment.FullSpan.Start; // The trailing newline is included in XmlDocCommentSyntax, so we need to strip it. var endPos = documentationComment.SpanStart + documentationComment.ToString().TrimEnd().Length; var span = TextSpan.FromBounds(startPos, endPos); var bannerLength = options.MaximumBannerLength; var bannerText = CSharpFileBannerFacts.Instance.GetBannerText( documentationComment, bannerLength, cancellationToken); spans.Add(new BlockSpan( isCollapsible: true, textSpan: span, type: BlockTypes.Comment, bannerText: bannerText, autoCollapse: true)); }
protected override void CollectBlockSpans( SyntaxToken previousToken, BlockSyntax node, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { var parentKind = node.Parent.Kind(); // For most types of statements, just consider the block 'attached' to the // parent node. That means we'll show the parent node header when doing // things like hovering over the indent guide. // // This also works nicely as the close brace for these constructs will always // align with the start of these statements. if (IsNonBlockStatement(node.Parent) || parentKind == SyntaxKind.ElseClause) { var type = GetType(node.Parent); if (type != null) { spans.Add(new BlockSpan( isCollapsible: true, textSpan: GetTextSpan(node), hintSpan: GetHintSpan(node), type: type, autoCollapse: parentKind == SyntaxKind.LocalFunctionStatement && node.Parent.IsParentKind(SyntaxKind.GlobalStatement))); } } // Nested blocks aren't attached to anything. Just collapse them as is. // Switch sections are also special. Say you have the following: // // case 0: // { // // } // // We don't want to consider the block parented by the case, because // that would cause us to draw the following: // // case 0: // | { // | // | } // // Which would obviously be wonky. So in this case, we just use the // spanof the block alone, without consideration for the case clause. if (parentKind is SyntaxKind.Block or SyntaxKind.SwitchSection) { var type = GetType(node.Parent); spans.Add(new BlockSpan( isCollapsible: true, textSpan: node.Span, hintSpan: node.Span, type: type)); } }
public override void CollectBlockSpans( SyntaxTrivia trivia, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { CollectBlockSpans(trivia.SyntaxTree, trivia, ref spans, cancellationToken); }
protected override void CollectBlockSpans( SyntaxToken previousToken, EventFieldDeclarationSyntax eventFieldDeclaration, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { CSharpStructureHelpers.CollectCommentBlockSpans(eventFieldDeclaration, ref spans, options); }
private static async Task <ImmutableArray <BlockSpan> > GetSpansFromWorkspaceAsync( TestWorkspace workspace) { var hostDocument = workspace.Documents.First(); var document = workspace.CurrentSolution.GetDocument(hostDocument.Id); var outliningService = document.GetLanguageService <BlockStructureService>(); var options = BlockStructureOptions.From(document.Project); var structure = await outliningService.GetBlockStructureAsync(document, options, CancellationToken.None); return(structure.Spans); }
protected override void CollectBlockSpans( SyntaxToken previousToken, InitializerExpressionSyntax node, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { if (node.Parent is InitializerExpressionSyntax) { // We have something like: // // new Dictionary<int, string> // { // ... // { // ... // }, // ... // } // // In this case, we want to collapse the "{ ... }," (including the comma). var nextToken = node.CloseBraceToken.GetNextToken(); var end = nextToken.Kind() == SyntaxKind.CommaToken ? nextToken.Span.End : node.Span.End; spans.Add(new BlockSpan( isCollapsible: true, textSpan: TextSpan.FromBounds(node.SpanStart, end), hintSpan: TextSpan.FromBounds(node.SpanStart, end), type: BlockTypes.Expression)); } else { // Parent is something like: // // new Dictionary<int, string> { // ... // } // // The collapsed textspan should be from the > to the } // // However, the hint span should be the entire object creation. spans.Add(new BlockSpan( isCollapsible: true, textSpan: TextSpan.FromBounds(previousToken.Span.End, node.Span.End), hintSpan: node.Parent.Span, type: BlockTypes.Expression)); } }
protected override void CollectBlockSpans( SyntaxToken previousToken, SwitchStatementSyntax node, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { spans.Add(new BlockSpan( isCollapsible: true, textSpan: TextSpan.FromBounds((node.CloseParenToken != default) ? node.CloseParenToken.Span.End : node.Expression.Span.End, node.CloseBraceToken.Span.End), hintSpan: node.Span, type: BlockTypes.Conditional)); }
protected override void CollectBlockSpans( SyntaxToken previousToken, ArrowExpressionClauseSyntax node, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { spans.Add(new BlockSpan( isCollapsible: true, textSpan: TextSpan.FromBounds(previousToken.Span.End, node.Parent.Span.End), hintSpan: node.Parent.Span, type: BlockTypes.Nonstructural, autoCollapse: !node.IsParentKind(SyntaxKind.LocalFunctionStatement))); }
internal sealed override async Task <ImmutableArray <BlockSpan> > GetBlockSpansWorkerAsync(Document document, int position) { var root = await document.GetSyntaxRootAsync(); var trivia = root.FindTrivia(position, findInsideTrivia: true); var outliner = CreateProvider(); using var actualRegions = TemporaryArray <BlockSpan> .Empty; var options = BlockStructureOptions.From(document.Project); outliner.CollectBlockSpans(trivia, ref actualRegions.AsRef(), options, CancellationToken.None); // TODO: Determine why we get null outlining spans. return(actualRegions.ToImmutableAndClear()); }
protected override void CollectBlockSpans( SyntaxToken previousToken, NamespaceDeclarationSyntax namespaceDeclaration, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { // add leading comments CSharpStructureHelpers.CollectCommentBlockSpans(namespaceDeclaration, ref spans, options); if (!namespaceDeclaration.OpenBraceToken.IsMissing && !namespaceDeclaration.CloseBraceToken.IsMissing) { spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( namespaceDeclaration, namespaceDeclaration.Name.GetLastToken(includeZeroWidth: true), compressEmptyLines: false, autoCollapse: false, type: BlockTypes.Namespace, isCollapsible: true)); } // extern aliases and usings are outlined in a single region var externsAndUsings = Enumerable.Union <SyntaxNode>(namespaceDeclaration.Externs, namespaceDeclaration.Usings) .OrderBy(node => node.SpanStart) .ToList(); // add any leading comments before the extern aliases and usings if (externsAndUsings.Count > 0) { CSharpStructureHelpers.CollectCommentBlockSpans(externsAndUsings.First(), ref spans, options); } spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( externsAndUsings, compressEmptyLines: false, autoCollapse: true, type: BlockTypes.Imports, isCollapsible: true)); // finally, add any leading comments before the end of the namespace block if (!namespaceDeclaration.CloseBraceToken.IsMissing) { CSharpStructureHelpers.CollectCommentBlockSpans( namespaceDeclaration.CloseBraceToken.LeadingTrivia, ref spans); } }
protected override void CollectBlockSpans( SyntaxToken previousToken, LiteralExpressionSyntax node, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { if (node.IsKind(SyntaxKind.StringLiteralExpression) && !node.ContainsDiagnostics) { spans.Add(new BlockSpan( isCollapsible: true, textSpan: node.Span, hintSpan: node.Span, type: BlockTypes.Expression, autoCollapse: true, isDefaultCollapsed: false)); } }
protected override void CollectBlockSpans( SyntaxToken previousToken, TypeDeclarationSyntax typeDeclaration, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { CSharpStructureHelpers.CollectCommentBlockSpans(typeDeclaration, ref spans, options); if (!typeDeclaration.OpenBraceToken.IsMissing && !typeDeclaration.CloseBraceToken.IsMissing) { var lastToken = typeDeclaration.TypeParameterList == null ? typeDeclaration.Identifier : typeDeclaration.TypeParameterList.GetLastToken(includeZeroWidth: true); SyntaxNodeOrToken current = typeDeclaration; var nextSibling = current.GetNextSibling(); // Check IsNode to compress blank lines after this node if it is the last child of the parent. // // Collapse to Definitions doesn't collapse type nodes, but a Toggle All Outlining would collapse groups // of types to the compressed form of not showing blank lines. All kinds of types are grouped together // in Metadata as Source. var compressEmptyLines = options.IsMetadataAsSource && (!nextSibling.IsNode || nextSibling.AsNode() is BaseTypeDeclarationSyntax); spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( typeDeclaration, lastToken, compressEmptyLines: compressEmptyLines, autoCollapse: false, type: BlockTypes.Type, isCollapsible: true)); } // add any leading comments before the end of the type block if (!typeDeclaration.CloseBraceToken.IsMissing) { var leadingTrivia = typeDeclaration.CloseBraceToken.LeadingTrivia; CSharpStructureHelpers.CollectCommentBlockSpans(leadingTrivia, ref spans); } }
protected override void CollectBlockSpans( SyntaxToken previousToken, InterpolatedStringExpressionSyntax node, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { if (node.StringStartToken.IsMissing || node.StringEndToken.IsMissing) { return; } spans.Add(new BlockSpan( isCollapsible: true, textSpan: node.Span, hintSpan: node.Span, type: BlockTypes.Expression, autoCollapse: true, isDefaultCollapsed: false)); }
protected override void CollectBlockSpans( SyntaxToken previousToken, FileScopedNamespaceDeclarationSyntax fileScopedNamespaceDeclaration, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { // add leading comments CSharpStructureHelpers.CollectCommentBlockSpans(fileScopedNamespaceDeclaration, ref spans, options); // extern aliases and usings are outlined in a single region var externsAndUsings = Enumerable.Union <SyntaxNode>(fileScopedNamespaceDeclaration.Externs, fileScopedNamespaceDeclaration.Usings).ToImmutableArray(); // add any leading comments before the extern aliases and usings if (externsAndUsings.Any()) { CSharpStructureHelpers.CollectCommentBlockSpans(externsAndUsings.First(), ref spans, options); } spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( externsAndUsings, compressEmptyLines: false, autoCollapse: true, type: BlockTypes.Imports, isCollapsible: true, isDefaultCollapsed: options.CollapseImportsWhenFirstOpened)); }
protected override void CollectBlockSpans( SyntaxToken previousToken, EnumDeclarationSyntax enumDeclaration, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { CSharpStructureHelpers.CollectCommentBlockSpans(enumDeclaration, ref spans, options); if (!enumDeclaration.OpenBraceToken.IsMissing && !enumDeclaration.CloseBraceToken.IsMissing) { SyntaxNodeOrToken current = enumDeclaration; var nextSibling = current.GetNextSibling(); // Check IsNode to compress blank lines after this node if it is the last child of the parent. // // Whitespace between type declarations is collapsed in Metadata as Source. var compressEmptyLines = options.IsMetadataAsSource && (!nextSibling.IsNode || nextSibling.AsNode() is BaseTypeDeclarationSyntax); spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( enumDeclaration, enumDeclaration.Identifier, compressEmptyLines: compressEmptyLines, autoCollapse: false, type: BlockTypes.Member, isCollapsible: true)); } // add any leading comments before the end of the type block if (!enumDeclaration.CloseBraceToken.IsMissing) { var leadingTrivia = enumDeclaration.CloseBraceToken.LeadingTrivia; CSharpStructureHelpers.CollectCommentBlockSpans(leadingTrivia, ref spans); } }
protected override void CollectBlockSpans( SyntaxToken previousToken, SimpleLambdaExpressionSyntax lambdaExpression, ref TemporaryArray <BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken) { // fault tolerance if (lambdaExpression.Body.IsMissing) { return; } if (lambdaExpression.Body is not BlockSyntax lambdaBlock || lambdaBlock.OpenBraceToken.IsMissing || lambdaBlock.CloseBraceToken.IsMissing) { return; } var lastToken = CSharpStructureHelpers.GetLastInlineMethodBlockToken(lambdaExpression); if (lastToken.Kind() == SyntaxKind.None) { return; } spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( lambdaExpression, lambdaExpression.ArrowToken, lastToken, compressEmptyLines: false, autoCollapse: false, type: BlockTypes.Expression, isCollapsible: true)); }
internal override async Task <ImmutableArray <BlockSpan> > GetBlockSpansWorkerAsync(Document document, BlockStructureOptions options, int position) { var root = await document.GetSyntaxRootAsync(); var trivia = root.FindTrivia(position, findInsideTrivia: true); var token = trivia.Token; if (token.LeadingTrivia.Contains(trivia)) { return(CSharpStructureHelpers.CreateCommentBlockSpan(token.LeadingTrivia)); } else if (token.TrailingTrivia.Contains(trivia)) { return(CSharpStructureHelpers.CreateCommentBlockSpan(token.TrailingTrivia)); } throw Roslyn.Utilities.ExceptionUtilities.Unreachable; }
public override async Task <BlockStructure> GetBlockStructureAsync(Document document, BlockStructureOptions options, CancellationToken cancellationToken) { var blockStructure = await _service.GetBlockStructureAsync(document, cancellationToken).ConfigureAwait(false); if (blockStructure != null) { return(new BlockStructure(blockStructure.Spans.SelectAsArray(x => new BlockSpan(x.Type, x.IsCollapsible, x.TextSpan, x.HintSpan, x.BannerText, x.AutoCollapse, x.IsDefaultCollapsed)))); } else { return(null); } }