From e4e1e2027d3c520fe3ce00288732c4c8fa38bf7c Mon Sep 17 00:00:00 2001 From: CyrusNajmabadi Date: Wed, 14 Sep 2016 17:53:52 -0700 Subject: [PATCH] Implement indent guides for the current set of nodes we have outlining for in C# and VB. --- .../Structure/CommentStructureTests.cs | 4 +- src/EditorFeatures/Core/EditorFeatures.csproj | 2 +- ...stractStructureTaggerProvider.RegionTag.cs | 143 ----------------- .../AbstractStructureTaggerProvider.cs | 2 - .../Structure/RoslynOutliningRegionTag.cs | 148 ++++++++++++++++++ .../VisualStudio14StructureTaggerProvider.cs | 6 +- .../Next/EditorFeatures.Next.csproj | 1 + .../Next/Structure/BlockContextProvider.cs | 73 +++++++++ .../VisualStudio15StructureTaggerProvider.cs | 75 ++++++++- .../Structure/CSharpStructureHelpers.cs | 120 +++++++++----- .../AccessorDeclarationStructureProvider.cs | 8 +- ...nymousMethodExpressionStructureProvider.cs | 6 +- .../CompilationUnitStructureProvider.cs | 8 +- ...ConstructorDeclarationStructureProvider.cs | 8 +- ...ionOperatorDeclarationStructureProvider.cs | 8 +- .../DelegateDeclarationStructureProvider.cs | 2 +- .../DestructorDeclarationStructureProvider.cs | 8 +- .../EnumDeclarationStructureProvider.cs | 10 +- .../EventDeclarationStructureProvider.cs | 8 +- .../EventFieldDeclarationStructureProvider.cs | 2 +- .../FieldDeclarationStructureProvider.cs | 2 +- .../IndexerDeclarationStructureProvider.cs | 8 +- .../MethodDeclarationStructureProvider.cs | 8 +- .../NamespaceDeclarationStructureProvider.cs | 16 +- .../OperatorDeclarationStructureProvider.cs | 8 +- ...esizedLambdaExpressionStructureProvider.cs | 6 +- .../PropertyDeclarationStructureProvider.cs | 8 +- ...SimpleLambdaExpressionStructureProvider.cs | 6 +- .../TypeDeclarationStructureProvider.cs | 15 +- .../Core/Portable/Structure/BlockTypes.cs | 55 ++++--- .../AccessorDeclarationStructureProvider.vb | 5 +- .../CompilationUnitStructureProvider.vb | 4 +- ...ConstructorDeclarationStructureProvider.vb | 5 +- .../DisabledTextTriviaStructureProvider.vb | 9 +- .../DocumentationCommentStructureProvider.vb | 5 +- .../EnumDeclarationStructureProvider.vb | 5 +- .../EventDeclarationStructureProvider.vb | 5 +- ...etadataRegionDirectiveStructureProvider.vb | 10 +- .../MethodDeclarationStructureProvider.vb | 5 +- .../MultilineLambdaStructureProvider.vb | 5 +- .../NamespaceDeclarationStructureProvider.vb | 5 +- .../OperatorDeclarationStructureProvider.vb | 5 +- .../PropertyDeclarationStructureProvider.vb | 5 +- .../RegionDirectiveStructureProvider.vb | 13 +- .../TypeDeclarationStructureProvider.vb | 10 +- .../XmlExpressionStructureProvider.vb | 5 +- .../Structure/VisualBasicStructureHelpers.vb | 47 ++++-- .../Core/Portable/Workspaces.csproj | 1 + 48 files changed, 604 insertions(+), 319 deletions(-) delete mode 100644 src/EditorFeatures/Core/Implementation/Structure/AbstractStructureTaggerProvider.RegionTag.cs create mode 100644 src/EditorFeatures/Core/Implementation/Structure/RoslynOutliningRegionTag.cs create mode 100644 src/EditorFeatures/Next/Structure/BlockContextProvider.cs diff --git a/src/EditorFeatures/CSharpTest/Structure/CommentStructureTests.cs b/src/EditorFeatures/CSharpTest/Structure/CommentStructureTests.cs index 6d051bcd755..7dffc08cf0e 100644 --- a/src/EditorFeatures/CSharpTest/Structure/CommentStructureTests.cs +++ b/src/EditorFeatures/CSharpTest/Structure/CommentStructureTests.cs @@ -24,11 +24,11 @@ internal override async Task GetBlockSpansAsync(Document document, if (token.LeadingTrivia.Contains(trivia)) { - return CSharpStructureHelpers.CreateCommentRegions(token.LeadingTrivia).ToArray(); + return CSharpStructureHelpers.CreateCommentBlockSpan(token.LeadingTrivia).ToArray(); } else if (token.TrailingTrivia.Contains(trivia)) { - return CSharpStructureHelpers.CreateCommentRegions(token.TrailingTrivia).ToArray(); + return CSharpStructureHelpers.CreateCommentBlockSpan(token.TrailingTrivia).ToArray(); } else { diff --git a/src/EditorFeatures/Core/EditorFeatures.csproj b/src/EditorFeatures/Core/EditorFeatures.csproj index 2a952224843..dca8ccd56ca 100644 --- a/src/EditorFeatures/Core/EditorFeatures.csproj +++ b/src/EditorFeatures/Core/EditorFeatures.csproj @@ -568,7 +568,7 @@ - + diff --git a/src/EditorFeatures/Core/Implementation/Structure/AbstractStructureTaggerProvider.RegionTag.cs b/src/EditorFeatures/Core/Implementation/Structure/AbstractStructureTaggerProvider.RegionTag.cs deleted file mode 100644 index ab4ae668f5c..00000000000 --- a/src/EditorFeatures/Core/Implementation/Structure/AbstractStructureTaggerProvider.RegionTag.cs +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Windows.Media; -using Microsoft.CodeAnalysis.Editor.Shared.Extensions; -using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -using Microsoft.CodeAnalysis.Structure; -using Microsoft.CodeAnalysis.Text.Shared.Extensions; -using Microsoft.VisualStudio.Text; -using Microsoft.VisualStudio.Text.Editor; -using Microsoft.VisualStudio.Text.Projection; -using Microsoft.VisualStudio.Text.Tagging; - -namespace Microsoft.CodeAnalysis.Editor.Implementation.Structure -{ - internal abstract partial class AbstractStructureTaggerProvider - { - // Our implementation of an outlining region tag. The collapsedHintForm - // is dynamically created using an elision buffer over the actual text - // we are collapsing. - protected class RegionTag : IOutliningRegionTag - { - private const string Ellipsis = "..."; - private const int MaxPreviewText = 1000; - - private readonly AbstractStructureTaggerProvider _provider; - - private readonly ITextBuffer _subjectBuffer; - private readonly ITrackingSpan _hintSpan; - - public bool IsDefaultCollapsed => BlockSpan.IsDefaultCollapsed; - public bool IsImplementation => BlockSpan.AutoCollapse; - public object CollapsedForm => BlockSpan.BannerText; - - protected readonly BlockSpan BlockSpan; - - public RegionTag( - AbstractStructureTaggerProvider provider, - ITextSnapshot snapshot, - BlockSpan outliningSpan) - { - _provider = provider; - _subjectBuffer = snapshot.TextBuffer; - BlockSpan = outliningSpan; - - _hintSpan = snapshot.CreateTrackingSpan(BlockSpan.HintSpan.ToSpan(), SpanTrackingMode.EdgeExclusive); - } - - public object CollapsedHintForm => - new ViewHostingControl(CreateElisionBufferView, CreateElisionBuffer); - - private IWpfTextView CreateElisionBufferView(ITextBuffer finalBuffer) - { - var roles = _provider.TextEditorFactoryService.CreateTextViewRoleSet(OutliningRegionTextViewRole); - var view = _provider.TextEditorFactoryService.CreateTextView(finalBuffer, roles); - - view.Background = Brushes.Transparent; - - view.SizeToFit(); - - // Zoom out a bit to shrink the text. - view.ZoomLevel *= 0.75; - - return view; - } - - private ITextBuffer CreateElisionBuffer() - { - // Remove any starting whitespace. - var span = TrimStartingNewlines(_hintSpan.GetSpan(_subjectBuffer.CurrentSnapshot)); - - // Trim the length if it's too long. - var shortSpan = span; - if (span.Length > MaxPreviewText) - { - shortSpan = ComputeShortSpan(span); - } - - // Create an elision buffer for that span, also trimming the - // leading whitespace. - var elisionBuffer = CreateElisionBufferWithoutIndentation(_subjectBuffer, shortSpan); - var finalBuffer = elisionBuffer; - - // If we trimmed the length, then make a projection buffer that - // has the above elision buffer and follows it with "..." - if (span.Length != shortSpan.Length) - { - finalBuffer = CreateTrimmedProjectionBuffer(elisionBuffer); - } - - return finalBuffer; - } - - private ITextBuffer CreateTrimmedProjectionBuffer(ITextBuffer elisionBuffer) - { - // The elision buffer is too long. We've already trimmed it, but now we want to add - // a "..." to it. We do that by creating a projection of both the elision buffer and - // a new text buffer wrapping the ellipsis. - var elisionSpan = elisionBuffer.CurrentSnapshot.GetFullSpan(); - - var sourceSpans = new List() - { - elisionSpan.Snapshot.CreateTrackingSpan(elisionSpan, SpanTrackingMode.EdgeExclusive), - Ellipsis - }; - - var projectionBuffer = _provider.ProjectionBufferFactoryService.CreateProjectionBuffer( - projectionEditResolver: null, - sourceSpans: sourceSpans, - options: ProjectionBufferOptions.None); - - return projectionBuffer; - } - - private Span ComputeShortSpan(Span span) - { - var endIndex = span.Start + MaxPreviewText; - var line = _subjectBuffer.CurrentSnapshot.GetLineFromPosition(endIndex); - - return Span.FromBounds(span.Start, line.EndIncludingLineBreak); - } - - private Span TrimStartingNewlines(Span span) - { - while (span.Length > 1 && char.IsWhiteSpace(_subjectBuffer.CurrentSnapshot[span.Start])) - { - span = new Span(span.Start + 1, span.Length - 1); - } - - return span; - } - - private ITextBuffer CreateElisionBufferWithoutIndentation( - ITextBuffer dataBuffer, Span shortHintSpan) - { - return _provider.ProjectionBufferFactoryService.CreateElisionBufferWithoutIndentation( - _provider.EditorOptionsFactoryService.GlobalOptions, - contentType: null, - exposedSpans: new SnapshotSpan(dataBuffer.CurrentSnapshot, shortHintSpan)); - } - } - } -} \ No newline at end of file diff --git a/src/EditorFeatures/Core/Implementation/Structure/AbstractStructureTaggerProvider.cs b/src/EditorFeatures/Core/Implementation/Structure/AbstractStructureTaggerProvider.cs index 46e071b61f3..4a8aae32a56 100644 --- a/src/EditorFeatures/Core/Implementation/Structure/AbstractStructureTaggerProvider.cs +++ b/src/EditorFeatures/Core/Implementation/Structure/AbstractStructureTaggerProvider.cs @@ -34,8 +34,6 @@ internal abstract partial class AbstractStructureTaggerProvider : IEqualityComparer where TRegionTag : class, ITag { - public const string OutliningRegionTextViewRole = nameof(OutliningRegionTextViewRole); - private static IComparer s_blockSpanComparer = Comparer.Create((s1, s2) => s1.TextSpan.Start - s2.TextSpan.Start); diff --git a/src/EditorFeatures/Core/Implementation/Structure/RoslynOutliningRegionTag.cs b/src/EditorFeatures/Core/Implementation/Structure/RoslynOutliningRegionTag.cs new file mode 100644 index 00000000000..d141b6f57a7 --- /dev/null +++ b/src/EditorFeatures/Core/Implementation/Structure/RoslynOutliningRegionTag.cs @@ -0,0 +1,148 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Windows.Media; +using Microsoft.CodeAnalysis.Editor.Shared.Extensions; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.Structure; +using Microsoft.CodeAnalysis.Text.Shared.Extensions; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Editor; +using Microsoft.VisualStudio.Text.Projection; +using Microsoft.VisualStudio.Text.Tagging; + +namespace Microsoft.CodeAnalysis.Editor.Implementation.Structure +{ + // Our implementation of an outlining region tag. The collapsedHintForm + // is dynamically created using an elision buffer over the actual text + // we are collapsing. + internal class RoslynOutliningRegionTag : IOutliningRegionTag + { + private const string OutliningRegionTextViewRole = nameof(OutliningRegionTextViewRole); + + private const string Ellipsis = "..."; + private const int MaxPreviewText = 1000; + + private readonly ITextEditorFactoryService _textEditorFactoryService; + private readonly IProjectionBufferFactoryService _projectionBufferFactoryService; + private readonly IEditorOptionsFactoryService _editorOptionsFactoryService; + + private readonly ITextBuffer _subjectBuffer; + private readonly ITrackingSpan _hintSpan; + + public bool IsDefaultCollapsed => BlockSpan.IsDefaultCollapsed; + public bool IsImplementation => BlockSpan.AutoCollapse; + public object CollapsedForm => BlockSpan.BannerText; + + protected readonly BlockSpan BlockSpan; + + public RoslynOutliningRegionTag( + ITextEditorFactoryService textEditorFactoryService, + IProjectionBufferFactoryService projectionBufferFactoryService, + IEditorOptionsFactoryService editorOptionsFactoryService, + ITextSnapshot snapshot, + BlockSpan outliningSpan) + { + _textEditorFactoryService = textEditorFactoryService; + _projectionBufferFactoryService = projectionBufferFactoryService; + _editorOptionsFactoryService = editorOptionsFactoryService; + _subjectBuffer = snapshot.TextBuffer; + BlockSpan = outliningSpan; + + _hintSpan = snapshot.CreateTrackingSpan(BlockSpan.HintSpan.ToSpan(), SpanTrackingMode.EdgeExclusive); + } + + public object CollapsedHintForm => + new ViewHostingControl(CreateElisionBufferView, CreateElisionBuffer); + + private IWpfTextView CreateElisionBufferView(ITextBuffer finalBuffer) + { + var roles = _textEditorFactoryService.CreateTextViewRoleSet(OutliningRegionTextViewRole); + var view = _textEditorFactoryService.CreateTextView(finalBuffer, roles); + + view.Background = Brushes.Transparent; + + view.SizeToFit(); + + // Zoom out a bit to shrink the text. + view.ZoomLevel *= 0.75; + + return view; + } + + private ITextBuffer CreateElisionBuffer() + { + // Remove any starting whitespace. + var span = TrimStartingNewlines(_hintSpan.GetSpan(_subjectBuffer.CurrentSnapshot)); + + // Trim the length if it's too long. + var shortSpan = span; + if (span.Length > MaxPreviewText) + { + shortSpan = ComputeShortSpan(span); + } + + // Create an elision buffer for that span, also trimming the + // leading whitespace. + var elisionBuffer = CreateElisionBufferWithoutIndentation(_subjectBuffer, shortSpan); + var finalBuffer = elisionBuffer; + + // If we trimmed the length, then make a projection buffer that + // has the above elision buffer and follows it with "..." + if (span.Length != shortSpan.Length) + { + finalBuffer = CreateTrimmedProjectionBuffer(elisionBuffer); + } + + return finalBuffer; + } + + private ITextBuffer CreateTrimmedProjectionBuffer(ITextBuffer elisionBuffer) + { + // The elision buffer is too long. We've already trimmed it, but now we want to add + // a "..." to it. We do that by creating a projection of both the elision buffer and + // a new text buffer wrapping the ellipsis. + var elisionSpan = elisionBuffer.CurrentSnapshot.GetFullSpan(); + + var sourceSpans = new List() + { + elisionSpan.Snapshot.CreateTrackingSpan(elisionSpan, SpanTrackingMode.EdgeExclusive), + Ellipsis + }; + + var projectionBuffer = _projectionBufferFactoryService.CreateProjectionBuffer( + projectionEditResolver: null, + sourceSpans: sourceSpans, + options: ProjectionBufferOptions.None); + + return projectionBuffer; + } + + private Span ComputeShortSpan(Span span) + { + var endIndex = span.Start + MaxPreviewText; + var line = _subjectBuffer.CurrentSnapshot.GetLineFromPosition(endIndex); + + return Span.FromBounds(span.Start, line.EndIncludingLineBreak); + } + + private Span TrimStartingNewlines(Span span) + { + while (span.Length > 1 && char.IsWhiteSpace(_subjectBuffer.CurrentSnapshot[span.Start])) + { + span = new Span(span.Start + 1, span.Length - 1); + } + + return span; + } + + private ITextBuffer CreateElisionBufferWithoutIndentation( + ITextBuffer dataBuffer, Span shortHintSpan) + { + return _projectionBufferFactoryService.CreateElisionBufferWithoutIndentation( + _editorOptionsFactoryService.GlobalOptions, + contentType: null, + exposedSpans: new SnapshotSpan(dataBuffer.CurrentSnapshot, shortHintSpan)); + } + } +} \ No newline at end of file diff --git a/src/EditorFeatures/Core/Implementation/Structure/VisualStudio14StructureTaggerProvider.cs b/src/EditorFeatures/Core/Implementation/Structure/VisualStudio14StructureTaggerProvider.cs index 12a18ac45c0..3fc9cb4d603 100644 --- a/src/EditorFeatures/Core/Implementation/Structure/VisualStudio14StructureTaggerProvider.cs +++ b/src/EditorFeatures/Core/Implementation/Structure/VisualStudio14StructureTaggerProvider.cs @@ -55,7 +55,11 @@ public override int GetHashCode(IOutliningRegionTag obj) protected override IOutliningRegionTag CreateTag( IOutliningRegionTag parentTag, ITextSnapshot snapshot, BlockSpan region) { - return new RegionTag(this, snapshot, region); + return new RoslynOutliningRegionTag( + this.TextEditorFactoryService, + this.ProjectionBufferFactoryService, + this.EditorOptionsFactoryService, + snapshot, region); } } } \ No newline at end of file diff --git a/src/EditorFeatures/Next/EditorFeatures.Next.csproj b/src/EditorFeatures/Next/EditorFeatures.Next.csproj index 260d46a231c..cceaf345eb5 100644 --- a/src/EditorFeatures/Next/EditorFeatures.Next.csproj +++ b/src/EditorFeatures/Next/EditorFeatures.Next.csproj @@ -71,6 +71,7 @@ + diff --git a/src/EditorFeatures/Next/Structure/BlockContextProvider.cs b/src/EditorFeatures/Next/Structure/BlockContextProvider.cs new file mode 100644 index 00000000000..cc147dba261 --- /dev/null +++ b/src/EditorFeatures/Next/Structure/BlockContextProvider.cs @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.ComponentModel.Composition; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Editor.Implementation.Structure; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Adornments; +using Microsoft.VisualStudio.Text.Editor; +using Microsoft.VisualStudio.Text.Tagging; +using Microsoft.VisualStudio.Utilities; +using Roslyn.Utilities; + +namespace Microsoft.CodeAnalysis.Editor.Structure +{ + [Name(nameof(RoslynBlockContextProvider)), Order] + [Export(typeof(IBlockContextProvider))] + [ContentType(ContentTypeNames.RoslynContentType)] + internal class RoslynBlockContextProvider : ForegroundThreadAffinitizedObject, IBlockContextProvider + { + public Task TryCreateBlockContextSourceAsync( + ITextBuffer textBuffer, CancellationToken token) + { + this.AssertIsForeground(); + + var result = textBuffer.Properties.GetOrCreateSingletonProperty( + () => new BlockContextSource()); + return Task.FromResult(result); + } + + private class BlockContextSource : IBlockContextSource + { + public void Dispose() + { + } + + public Task GetBlockContextAsync( + IBlockTag blockTag, ITextView view, CancellationToken token) + { + if (blockTag is RoslynOutliningRegionTag) + { + var result = new RoslynBlockContext(blockTag, view); + return Task.FromResult(result); + } + + return SpecializedTasks.Default(); + } + } + + private class RoslynBlockContext : ForegroundThreadAffinitizedObject, IBlockContext + { + public IBlockTag BlockTag { get; } + + public ITextView TextView { get; } + + public RoslynBlockContext(IBlockTag blockTag, ITextView textView) + { + BlockTag = blockTag; + TextView = textView; + } + + public object Content + { + get + { + this.AssertIsForeground(); + return BlockTag.CollapsedHintForm; + } + } + } + } +} \ No newline at end of file diff --git a/src/EditorFeatures/Next/Structure/VisualStudio15StructureTaggerProvider.cs b/src/EditorFeatures/Next/Structure/VisualStudio15StructureTaggerProvider.cs index b38a85058ad..acc0b8ca3bb 100644 --- a/src/EditorFeatures/Next/Structure/VisualStudio15StructureTaggerProvider.cs +++ b/src/EditorFeatures/Next/Structure/VisualStudio15StructureTaggerProvider.cs @@ -20,7 +20,7 @@ namespace Microsoft.CodeAnalysis.Editor.Structure [Export(typeof(VisualStudio15StructureTaggerProvider))] [TagType(typeof(IBlockTag))] [ContentType(ContentTypeNames.RoslynContentType)] - internal partial class VisualStudio15StructureTaggerProvider : + internal partial class VisualStudio15StructureTaggerProvider : AbstractStructureTaggerProvider { [ImportingConstructor] @@ -49,31 +49,90 @@ public override int GetHashCode(IBlockTag obj) protected override IBlockTag CreateTag( IBlockTag parentTag, ITextSnapshot snapshot, BlockSpan region) { - return new RoslynRegionTag(this, parentTag, snapshot, region); + return new RoslynBlockTag( + this.TextEditorFactoryService, + this.ProjectionBufferFactoryService, + this.EditorOptionsFactoryService, + parentTag, snapshot, region); } - private class RoslynRegionTag : RegionTag, IBlockTag + private class RoslynBlockTag : RoslynOutliningRegionTag, IBlockTag { public IBlockTag Parent { get; } public int Level { get; } public SnapshotSpan Span { get; } public SnapshotSpan StatementSpan { get; } - public string Type => BlockSpan.Type; + public string Type => ConvertType(BlockSpan.Type); + public bool IsCollapsible => true; - public RoslynRegionTag( - AbstractStructureTaggerProvider provider, + public RoslynBlockTag( + ITextEditorFactoryService textEditorFactoryService, + IProjectionBufferFactoryService projectionBufferFactoryService, + IEditorOptionsFactoryService editorOptionsFactoryService, IBlockTag parent, ITextSnapshot snapshot, - BlockSpan outliningSpan) : - base(provider, snapshot, outliningSpan) + BlockSpan outliningSpan) : + base(textEditorFactoryService, + projectionBufferFactoryService, + editorOptionsFactoryService, + snapshot, outliningSpan) { Parent = parent; Level = parent == null ? 0 : parent.Level + 1; Span = outliningSpan.TextSpan.ToSnapshotSpan(snapshot); StatementSpan = outliningSpan.HintSpan.ToSnapshotSpan(snapshot); } + + private string ConvertType(string type) + { + switch (type) + { + // Basic types. + case BlockTypes.Structural: return PredefinedStructureTypes.Structural; + case BlockTypes.Nonstructural: return PredefinedStructureTypes.Nonstructural; + + // Top level declarations. Note that Enum is not currently supported + // and that we map Module down to Class. + case BlockTypes.Namespace: return PredefinedStructureTypes.Namespace; + case BlockTypes.Structure: return PredefinedStructureTypes.Struct; + case BlockTypes.Interface: return PredefinedStructureTypes.Interface; + case BlockTypes.Module: + case BlockTypes.Class: return PredefinedStructureTypes.Class; + + // Member declarations + case BlockTypes.Accessor: return PredefinedStructureTypes.AccessorBlock; + case BlockTypes.Constructor: return PredefinedStructureTypes.Constructor; + case BlockTypes.Destructor: return PredefinedStructureTypes.Destructor; + case BlockTypes.Method: return PredefinedStructureTypes.Method; + case BlockTypes.Operator: return PredefinedStructureTypes.Operator; + + // Map events/indexers/properties all to the 'property' type. + case BlockTypes.Event: + case BlockTypes.Indexer: + case BlockTypes.Property: return PredefinedStructureTypes.PropertyBlock; + + // Statements + case BlockTypes.Case: return PredefinedStructureTypes.Case; + case BlockTypes.Conditional: return PredefinedStructureTypes.Conditional; + case BlockTypes.Lock: return PredefinedStructureTypes.Lock; + case BlockTypes.Loop: return PredefinedStructureTypes.Loop; + case BlockTypes.TryCatchFinally: return PredefinedStructureTypes.TryCatchFinally; + case BlockTypes.Standalone: return PredefinedStructureTypes.Standalone; + + // Expressions + case BlockTypes.AnonymousMethod: return PredefinedStructureTypes.AnonymousMethodBlock; + + // These types don't currently map to any editor types. Just make them + // the 'Unknown' type for now. + case BlockTypes.Enum: + case BlockTypes.Other: + case BlockTypes.Xml: + default: + return PredefinedStructureTypes.Unknown; + } + } } } } \ No newline at end of file diff --git a/src/Features/CSharp/Portable/Structure/CSharpStructureHelpers.cs b/src/Features/CSharp/Portable/Structure/CSharpStructureHelpers.cs index 75d765bb78a..888f5ab04ec 100644 --- a/src/Features/CSharp/Portable/Structure/CSharpStructureHelpers.cs +++ b/src/Features/CSharp/Portable/Structure/CSharpStructureHelpers.cs @@ -133,7 +133,8 @@ private static string GetCommentBannerText(SyntaxTrivia comment) } } - private static BlockSpan CreateCommentRegion(SyntaxTrivia startComment, SyntaxTrivia endComment) + private static BlockSpan CreateCommentBlockSpan( + SyntaxTrivia startComment, SyntaxTrivia endComment) { var span = TextSpan.FromBounds(startComment.SpanStart, endComment.Span.End); @@ -142,18 +143,20 @@ private static BlockSpan CreateCommentRegion(SyntaxTrivia startComment, SyntaxTr textSpan: span, hintSpan: span, bannerText: GetCommentBannerText(startComment), - autoCollapse: true); + autoCollapse: true, + type: BlockTypes.Nonstructural); } // For testing purposes - internal static ImmutableArray CreateCommentRegions(SyntaxTriviaList triviaList) + internal static ImmutableArray CreateCommentBlockSpan( + SyntaxTriviaList triviaList) { var result = ImmutableArray.CreateBuilder(); - CollectCommentRegions(triviaList, result); + CollectCommentBlockSpans(triviaList, result); return result.ToImmutable(); } - public static void CollectCommentRegions( + public static void CollectCommentBlockSpans( SyntaxTriviaList triviaList, ImmutableArray.Builder spans) { if (triviaList.Count > 0) @@ -165,7 +168,7 @@ internal static ImmutableArray CreateCommentRegions(SyntaxTriviaList { if (startComment != null) { - var singleLineCommentGroupRegion = CreateCommentRegion(startComment.Value, endComment.Value); + var singleLineCommentGroupRegion = CreateCommentBlockSpan(startComment.Value, endComment.Value); spans.Add(singleLineCommentGroupRegion); startComment = null; endComment = null; @@ -186,7 +189,7 @@ internal static ImmutableArray CreateCommentRegions(SyntaxTriviaList { completeSingleLineCommentGroup(); - var multilineCommentRegion = CreateCommentRegion(trivia, trivia); + var multilineCommentRegion = CreateCommentBlockSpan(trivia, trivia); spans.Add(multilineCommentRegion); } else if (!trivia.MatchesKind(SyntaxKind.WhitespaceTrivia, @@ -201,7 +204,7 @@ internal static ImmutableArray CreateCommentRegions(SyntaxTriviaList } } - public static void CollectCommentRegions( + public static void CollectCommentBlockSpans( SyntaxNode node, ImmutableArray.Builder spans) { if (node == null) @@ -211,43 +214,62 @@ internal static ImmutableArray CreateCommentRegions(SyntaxTriviaList var triviaList = node.GetLeadingTrivia(); - CollectCommentRegions(triviaList, spans); + CollectCommentBlockSpans(triviaList, spans); } - private static BlockSpan CreateRegion(TextSpan textSpan, string bannerText, bool autoCollapse) + private static BlockSpan CreateBlockSpan( + TextSpan textSpan, string bannerText, bool autoCollapse, + string type, bool isCollapsible) { - return CreateRegion(textSpan, textSpan, bannerText, autoCollapse); + return CreateBlockSpan( + textSpan, textSpan, bannerText, autoCollapse, type, isCollapsible); } - private static BlockSpan CreateRegion(TextSpan textSpan, TextSpan hintSpan, string bannerText, bool autoCollapse) + private static BlockSpan CreateBlockSpan( + TextSpan textSpan, TextSpan hintSpan, + string bannerText, bool autoCollapse, + string type, bool isCollapsible) { return new BlockSpan( - isCollapsible: true, textSpan: textSpan, hintSpan: hintSpan, bannerText: bannerText, - autoCollapse: autoCollapse); + autoCollapse: autoCollapse, + type: type, + isCollapsible: isCollapsible); } - public static BlockSpan CreateRegion(SyntaxNode node, string bannerText, bool autoCollapse) + public static BlockSpan CreateBlockSpan( + SyntaxNode node, string bannerText, bool autoCollapse, + string type, bool isCollapsible) { - return CreateRegion( + return CreateBlockSpan( node.Span, bannerText, - autoCollapse); + autoCollapse, + type, + isCollapsible); } - public static BlockSpan CreateRegion(SyntaxNode node, SyntaxToken syntaxToken, string bannerText, bool autoCollapse) + public static BlockSpan CreateBlockSpan( + SyntaxNode node, SyntaxToken syntaxToken, + string bannerText, bool autoCollapse, + string type, bool isCollapsible) { - return CreateRegion( + return CreateBlockSpan( node, syntaxToken, node.GetLastToken(), bannerText, - autoCollapse); + autoCollapse, + type, + isCollapsible); } - public static BlockSpan CreateRegion(SyntaxNode node, SyntaxToken startToken, int endPos, string bannerText, bool autoCollapse) + public static BlockSpan CreateBlockSpan( + SyntaxNode node, SyntaxToken startToken, + int endPos, string bannerText, bool autoCollapse, + string type, bool isCollapsible) { // If the SyntaxToken is actually missing, don't attempt to create an outlining region. if (startToken.IsMissing) @@ -262,55 +284,75 @@ public static BlockSpan CreateRegion(SyntaxNode node, SyntaxToken startToken, in var span = TextSpan.FromBounds(GetCollapsibleStart(startToken), endPos); var hintSpan = TextSpan.FromBounds(node.SpanStart, endPos); - return CreateRegion( + return CreateBlockSpan( span, hintSpan, bannerText, - autoCollapse); + autoCollapse, + type, + isCollapsible); } - public static BlockSpan CreateRegion(SyntaxNode node, SyntaxToken startToken, SyntaxToken endToken, string bannerText, bool autoCollapse) + public static BlockSpan CreateBlockSpan( + SyntaxNode node, SyntaxToken startToken, + SyntaxToken endToken, string bannerText, bool autoCollapse, + string type, bool isCollapsible) { - return CreateRegion( + return CreateBlockSpan( node, startToken, GetCollapsibleEnd(endToken), bannerText, - autoCollapse); + autoCollapse, + type, + isCollapsible); } - public static BlockSpan CreateRegion(SyntaxNode node, bool autoCollapse) + public static BlockSpan CreateBlockSpan( + SyntaxNode node, bool autoCollapse, string type, bool isCollapsible) { - return CreateRegion( + return CreateBlockSpan( node, bannerText: Ellipsis, - autoCollapse: autoCollapse); + autoCollapse: autoCollapse, + type: type, + isCollapsible: isCollapsible); } // Adds everything after 'syntaxToken' up to and including the end // of node as a region. The snippet to display is just "..." - public static BlockSpan CreateRegion(SyntaxNode node, SyntaxToken syntaxToken, bool autoCollapse) + public static BlockSpan CreateBlockSpan( + SyntaxNode node, SyntaxToken syntaxToken, + bool autoCollapse, string type, bool isCollapsible) { - return CreateRegion( + return CreateBlockSpan( node, syntaxToken, bannerText: Ellipsis, - autoCollapse: autoCollapse); + autoCollapse: autoCollapse, + type: type, + isCollapsible: isCollapsible); } // Adds everything after 'syntaxToken' up to and including the end // of node as a region. The snippet to display is just "..." - public static BlockSpan CreateRegion(SyntaxNode node, SyntaxToken startToken, SyntaxToken endToken, bool autoCollapse) + public static BlockSpan CreateBlockSpan( + SyntaxNode node, SyntaxToken startToken, SyntaxToken endToken, + bool autoCollapse, string type, bool isCollapsible) { - return CreateRegion( + return CreateBlockSpan( node, startToken, endToken, bannerText: Ellipsis, - autoCollapse: autoCollapse); + autoCollapse: autoCollapse, + type: type, + isCollapsible: isCollapsible); } // Adds the span surrounding the syntax list as a region. The // snippet shown is the text from the first line of the first // node in the list. - public static BlockSpan CreateRegion(IEnumerable syntaxList, bool autoCollapse) + public static BlockSpan CreateBlockSpan( + IEnumerable syntaxList, bool autoCollapse, + string type, bool isCollapsible) { if (syntaxList.IsEmpty()) { @@ -329,11 +371,13 @@ public static BlockSpan CreateRegion(IEnumerable syntaxList, bool au ? end : hintSpanStart; - return CreateRegion( + return CreateBlockSpan( textSpan: TextSpan.FromBounds(spanStart, spanEnd), hintSpan: TextSpan.FromBounds(hintSpanStart, hintSpanEnd), bannerText: Ellipsis, - autoCollapse: autoCollapse); + autoCollapse: autoCollapse, + type: type, + isCollapsible: isCollapsible); } } } \ No newline at end of file diff --git a/src/Features/CSharp/Portable/Structure/Providers/AccessorDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/AccessorDeclarationStructureProvider.cs index e0c4ccc8939..066741cbe82 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/AccessorDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/AccessorDeclarationStructureProvider.cs @@ -14,7 +14,7 @@ internal class AccessorDeclarationStructureProvider : AbstractSyntaxNodeStructur ImmutableArray.Builder spans, CancellationToken cancellationToken) { - CSharpStructureHelpers.CollectCommentRegions(accessorDeclaration, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(accessorDeclaration, spans); // fault tolerance if (accessorDeclaration.Body == null || @@ -24,10 +24,12 @@ internal class AccessorDeclarationStructureProvider : AbstractSyntaxNodeStructur return; } - spans.Add(CSharpStructureHelpers.CreateRegion( + spans.Add(CSharpStructureHelpers.CreateBlockSpan( accessorDeclaration, accessorDeclaration.Keyword, - autoCollapse: true)); + autoCollapse: true, + type: BlockTypes.Accessor, + isCollapsible: true)); } } } diff --git a/src/Features/CSharp/Portable/Structure/Providers/AnonymousMethodExpressionStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/AnonymousMethodExpressionStructureProvider.cs index e2c1e1d4834..00a600268d0 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/AnonymousMethodExpressionStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/AnonymousMethodExpressionStructureProvider.cs @@ -32,11 +32,13 @@ internal class AnonymousMethodExpressionStructureProvider : AbstractSyntaxNodeSt ? anonymousMethod.ParameterList.GetLastToken(includeZeroWidth: true) : anonymousMethod.DelegateKeyword; - spans.Add(CSharpStructureHelpers.CreateRegion( + spans.Add(CSharpStructureHelpers.CreateBlockSpan( anonymousMethod, startToken, lastToken, - autoCollapse: false)); + autoCollapse: false, + type: BlockTypes.AnonymousMethod, + isCollapsible: true)); } } } diff --git a/src/Features/CSharp/Portable/Structure/Providers/CompilationUnitStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/CompilationUnitStructureProvider.cs index 3985a501b5f..8ef02d8a72b 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/CompilationUnitStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/CompilationUnitStructureProvider.cs @@ -15,7 +15,7 @@ internal class CompilationUnitStructureProvider : AbstractSyntaxNodeStructurePro ImmutableArray.Builder spans, CancellationToken cancellationToken) { - CSharpStructureHelpers.CollectCommentRegions(compilationUnit, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(compilationUnit, spans); // extern aliases and usings are outlined in a single region var externsAndUsings = new List(); @@ -23,14 +23,16 @@ internal class CompilationUnitStructureProvider : AbstractSyntaxNodeStructurePro externsAndUsings.AddRange(compilationUnit.Usings); externsAndUsings.Sort((node1, node2) => node1.SpanStart.CompareTo(node2.SpanStart)); - spans.Add(CSharpStructureHelpers.CreateRegion(externsAndUsings, autoCollapse: true)); + spans.Add(CSharpStructureHelpers.CreateBlockSpan( + externsAndUsings, autoCollapse: true, + type: BlockTypes.Nonstructural, isCollapsible: true)); if (compilationUnit.Usings.Count > 0 || compilationUnit.Externs.Count > 0 || compilationUnit.Members.Count > 0 || compilationUnit.AttributeLists.Count > 0) { - CSharpStructureHelpers.CollectCommentRegions(compilationUnit.EndOfFileToken.LeadingTrivia, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(compilationUnit.EndOfFileToken.LeadingTrivia, spans); } } diff --git a/src/Features/CSharp/Portable/Structure/Providers/ConstructorDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/ConstructorDeclarationStructureProvider.cs index 70c96e38db4..478dbce7bf4 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/ConstructorDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/ConstructorDeclarationStructureProvider.cs @@ -14,7 +14,7 @@ internal class ConstructorDeclarationStructureProvider : AbstractSyntaxNodeStruc ImmutableArray.Builder spans, CancellationToken cancellationToken) { - CSharpStructureHelpers.CollectCommentRegions(constructorDeclaration, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(constructorDeclaration, spans); // fault tolerance if (constructorDeclaration.Body == null || @@ -24,10 +24,12 @@ internal class ConstructorDeclarationStructureProvider : AbstractSyntaxNodeStruc return; } - spans.Add(CSharpStructureHelpers.CreateRegion( + spans.Add(CSharpStructureHelpers.CreateBlockSpan( constructorDeclaration, constructorDeclaration.ParameterList.GetLastToken(includeZeroWidth: true), - autoCollapse: true)); + autoCollapse: true, + type: BlockTypes.Constructor, + isCollapsible: true)); } } } diff --git a/src/Features/CSharp/Portable/Structure/Providers/ConversionOperatorDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/ConversionOperatorDeclarationStructureProvider.cs index 5ec0a87aa2c..39903a474a5 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/ConversionOperatorDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/ConversionOperatorDeclarationStructureProvider.cs @@ -14,7 +14,7 @@ internal class ConversionOperatorDeclarationStructureProvider : AbstractSyntaxNo ImmutableArray.Builder spans, CancellationToken cancellationToken) { - CSharpStructureHelpers.CollectCommentRegions(operatorDeclaration, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(operatorDeclaration, spans); // fault tolerance if (operatorDeclaration.Body == null || @@ -24,10 +24,12 @@ internal class ConversionOperatorDeclarationStructureProvider : AbstractSyntaxNo return; } - spans.Add(CSharpStructureHelpers.CreateRegion( + spans.Add(CSharpStructureHelpers.CreateBlockSpan( operatorDeclaration, operatorDeclaration.ParameterList.GetLastToken(includeZeroWidth: true), - autoCollapse: true)); + autoCollapse: true, + type: BlockTypes.Operator, + isCollapsible: true)); } } } diff --git a/src/Features/CSharp/Portable/Structure/Providers/DelegateDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/DelegateDeclarationStructureProvider.cs index 00de7129ac8..a5c2f873793 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/DelegateDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/DelegateDeclarationStructureProvider.cs @@ -14,7 +14,7 @@ internal class DelegateDeclarationStructureProvider : AbstractSyntaxNodeStructur ImmutableArray.Builder spans, CancellationToken cancellationToken) { - CSharpStructureHelpers.CollectCommentRegions(delegateDeclaration, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(delegateDeclaration, spans); } } } \ No newline at end of file diff --git a/src/Features/CSharp/Portable/Structure/Providers/DestructorDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/DestructorDeclarationStructureProvider.cs index 2da31800d3d..10aae6d1ee5 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/DestructorDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/DestructorDeclarationStructureProvider.cs @@ -14,7 +14,7 @@ internal class DestructorDeclarationStructureProvider : AbstractSyntaxNodeStruct ImmutableArray.Builder spans, CancellationToken cancellationToken) { - CSharpStructureHelpers.CollectCommentRegions(destructorDeclaration, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(destructorDeclaration, spans); // fault tolerance if (destructorDeclaration.Body == null || @@ -24,10 +24,12 @@ internal class DestructorDeclarationStructureProvider : AbstractSyntaxNodeStruct return; } - spans.Add(CSharpStructureHelpers.CreateRegion( + spans.Add(CSharpStructureHelpers.CreateBlockSpan( destructorDeclaration, destructorDeclaration.ParameterList.GetLastToken(includeZeroWidth: true), - autoCollapse: true)); + autoCollapse: true, + type: BlockTypes.Destructor, + isCollapsible: true)); } } } \ No newline at end of file diff --git a/src/Features/CSharp/Portable/Structure/Providers/EnumDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/EnumDeclarationStructureProvider.cs index e9f20762dfb..d882c33e0f0 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/EnumDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/EnumDeclarationStructureProvider.cs @@ -14,22 +14,24 @@ internal class EnumDeclarationStructureProvider : AbstractSyntaxNodeStructurePro ImmutableArray.Builder spans, CancellationToken cancellationToken) { - CSharpStructureHelpers.CollectCommentRegions(enumDeclaration, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(enumDeclaration, spans); if (!enumDeclaration.OpenBraceToken.IsMissing && !enumDeclaration.CloseBraceToken.IsMissing) { - spans.Add(CSharpStructureHelpers.CreateRegion( + spans.Add(CSharpStructureHelpers.CreateBlockSpan( enumDeclaration, enumDeclaration.Identifier, - autoCollapse: false)); + autoCollapse: false, + type: BlockTypes.Enum, + isCollapsible: true)); } // add any leading comments before the end of the type block if (!enumDeclaration.CloseBraceToken.IsMissing) { var leadingTrivia = enumDeclaration.CloseBraceToken.LeadingTrivia; - CSharpStructureHelpers.CollectCommentRegions(leadingTrivia, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(leadingTrivia, spans); } } } diff --git a/src/Features/CSharp/Portable/Structure/Providers/EventDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/EventDeclarationStructureProvider.cs index da3d5f83104..c192fef998c 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/EventDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/EventDeclarationStructureProvider.cs @@ -14,7 +14,7 @@ internal class EventDeclarationStructureProvider : AbstractSyntaxNodeStructurePr ImmutableArray.Builder spans, CancellationToken cancellationToken) { - CSharpStructureHelpers.CollectCommentRegions(eventDeclaration, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(eventDeclaration, spans); // fault tolerance if (eventDeclaration.AccessorList.IsMissing || @@ -24,10 +24,12 @@ internal class EventDeclarationStructureProvider : AbstractSyntaxNodeStructurePr return; } - spans.Add(CSharpStructureHelpers.CreateRegion( + spans.Add(CSharpStructureHelpers.CreateBlockSpan( eventDeclaration, eventDeclaration.Identifier, - autoCollapse: true)); + autoCollapse: true, + type: BlockTypes.Event, + isCollapsible: true)); } } } \ No newline at end of file diff --git a/src/Features/CSharp/Portable/Structure/Providers/EventFieldDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/EventFieldDeclarationStructureProvider.cs index f0b30526a18..cbe3c67d795 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/EventFieldDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/EventFieldDeclarationStructureProvider.cs @@ -14,7 +14,7 @@ internal class EventFieldDeclarationStructureProvider : AbstractSyntaxNodeStruct ImmutableArray.Builder spans, CancellationToken cancellationToken) { - CSharpStructureHelpers.CollectCommentRegions(eventFieldDeclaration, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(eventFieldDeclaration, spans); } } } \ No newline at end of file diff --git a/src/Features/CSharp/Portable/Structure/Providers/FieldDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/FieldDeclarationStructureProvider.cs index c2246be35f2..c50094e8c68 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/FieldDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/FieldDeclarationStructureProvider.cs @@ -14,7 +14,7 @@ internal class FieldDeclarationStructureProvider : AbstractSyntaxNodeStructurePr ImmutableArray.Builder spans, CancellationToken cancellationToken) { - CSharpStructureHelpers.CollectCommentRegions(fieldDeclaration, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(fieldDeclaration, spans); } } } \ No newline at end of file diff --git a/src/Features/CSharp/Portable/Structure/Providers/IndexerDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/IndexerDeclarationStructureProvider.cs index c5534456a7a..c1f523c8410 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/IndexerDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/IndexerDeclarationStructureProvider.cs @@ -14,7 +14,7 @@ internal class IndexerDeclarationStructureProvider : AbstractSyntaxNodeStructure ImmutableArray.Builder spans, CancellationToken cancellationToken) { - CSharpStructureHelpers.CollectCommentRegions(indexerDeclaration, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(indexerDeclaration, spans); // fault tolerance if (indexerDeclaration.AccessorList == null || @@ -25,10 +25,12 @@ internal class IndexerDeclarationStructureProvider : AbstractSyntaxNodeStructure return; } - spans.Add(CSharpStructureHelpers.CreateRegion( + spans.Add(CSharpStructureHelpers.CreateBlockSpan( indexerDeclaration, indexerDeclaration.ParameterList.GetLastToken(includeZeroWidth: true), - autoCollapse: true)); + autoCollapse: true, + type: BlockTypes.Indexer, + isCollapsible: true)); } } } \ No newline at end of file diff --git a/src/Features/CSharp/Portable/Structure/Providers/MethodDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/MethodDeclarationStructureProvider.cs index e44c099821e..ce35647efdb 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/MethodDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/MethodDeclarationStructureProvider.cs @@ -14,7 +14,7 @@ internal class MethodDeclarationStructureProvider : AbstractSyntaxNodeStructureP ImmutableArray.Builder spans, CancellationToken cancellationToken) { - CSharpStructureHelpers.CollectCommentRegions(methodDeclaration, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(methodDeclaration, spans); // fault tolerance if (methodDeclaration.Body == null || @@ -24,10 +24,12 @@ internal class MethodDeclarationStructureProvider : AbstractSyntaxNodeStructureP return; } - spans.Add(CSharpStructureHelpers.CreateRegion( + spans.Add(CSharpStructureHelpers.CreateBlockSpan( methodDeclaration, methodDeclaration.ParameterList.GetLastToken(includeZeroWidth: true), - autoCollapse: true)); + autoCollapse: true, + type: BlockTypes.Method, + isCollapsible: true)); } } } \ No newline at end of file diff --git a/src/Features/CSharp/Portable/Structure/Providers/NamespaceDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/NamespaceDeclarationStructureProvider.cs index b33af225a3b..680fda98e53 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/NamespaceDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/NamespaceDeclarationStructureProvider.cs @@ -16,15 +16,17 @@ internal class NamespaceDeclarationStructureProvider : AbstractSyntaxNodeStructu CancellationToken cancellationToken) { // add leading comments - CSharpStructureHelpers.CollectCommentRegions(namespaceDeclaration, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(namespaceDeclaration, spans); if (!namespaceDeclaration.OpenBraceToken.IsMissing && !namespaceDeclaration.CloseBraceToken.IsMissing) { - spans.Add(CSharpStructureHelpers.CreateRegion( + spans.Add(CSharpStructureHelpers.CreateBlockSpan( namespaceDeclaration, namespaceDeclaration.Name.GetLastToken(includeZeroWidth: true), - autoCollapse: false)); + autoCollapse: false, + type: BlockTypes.Namespace, + isCollapsible: true)); } // extern aliases and usings are outlined in a single region @@ -35,15 +37,17 @@ internal class NamespaceDeclarationStructureProvider : AbstractSyntaxNodeStructu // add any leading comments before the extern aliases and usings if (externsAndUsings.Count > 0) { - CSharpStructureHelpers.CollectCommentRegions(externsAndUsings.First(), spans); + CSharpStructureHelpers.CollectCommentBlockSpans(externsAndUsings.First(), spans); } - spans.Add(CSharpStructureHelpers.CreateRegion(externsAndUsings, autoCollapse: true)); + spans.Add(CSharpStructureHelpers.CreateBlockSpan( + externsAndUsings, autoCollapse: true, + type: BlockTypes.Nonstructural, isCollapsible: true)); // finally, add any leading comments before the end of the namespace block if (!namespaceDeclaration.CloseBraceToken.IsMissing) { - CSharpStructureHelpers.CollectCommentRegions(namespaceDeclaration.CloseBraceToken.LeadingTrivia, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(namespaceDeclaration.CloseBraceToken.LeadingTrivia, spans); } } diff --git a/src/Features/CSharp/Portable/Structure/Providers/OperatorDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/OperatorDeclarationStructureProvider.cs index 025bed4c630..399ecf3f7a7 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/OperatorDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/OperatorDeclarationStructureProvider.cs @@ -14,7 +14,7 @@ internal class OperatorDeclarationStructureProvider : AbstractSyntaxNodeStructur ImmutableArray.Builder spans, CancellationToken cancellationToken) { - CSharpStructureHelpers.CollectCommentRegions(operatorDeclaration, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(operatorDeclaration, spans); // fault tolerance if (operatorDeclaration.Body == null || @@ -24,10 +24,12 @@ internal class OperatorDeclarationStructureProvider : AbstractSyntaxNodeStructur return; } - spans.Add(CSharpStructureHelpers.CreateRegion( + spans.Add(CSharpStructureHelpers.CreateBlockSpan( operatorDeclaration, operatorDeclaration.ParameterList.GetLastToken(includeZeroWidth: true), - autoCollapse: true)); + autoCollapse: true, + type: BlockTypes.Operator, + isCollapsible: true)); } } } \ No newline at end of file diff --git a/src/Features/CSharp/Portable/Structure/Providers/ParenthesizedLambdaExpressionStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/ParenthesizedLambdaExpressionStructureProvider.cs index 5dc40bfee6e..bafacec7435 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/ParenthesizedLambdaExpressionStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/ParenthesizedLambdaExpressionStructureProvider.cs @@ -34,11 +34,13 @@ internal class ParenthesizedLambdaExpressionStructureProvider : AbstractSyntaxNo return; } - spans.Add(CSharpStructureHelpers.CreateRegion( + spans.Add(CSharpStructureHelpers.CreateBlockSpan( lambdaExpression, lambdaExpression.ArrowToken, lastToken, - autoCollapse: false)); + autoCollapse: false, + type: BlockTypes.AnonymousMethod, + isCollapsible: true)); } } } \ No newline at end of file diff --git a/src/Features/CSharp/Portable/Structure/Providers/PropertyDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/PropertyDeclarationStructureProvider.cs index 292262398b0..f946c9fdda6 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/PropertyDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/PropertyDeclarationStructureProvider.cs @@ -14,7 +14,7 @@ internal class PropertyDeclarationStructureProvider : AbstractSyntaxNodeStructur ImmutableArray.Builder spans, CancellationToken cancellationToken) { - CSharpStructureHelpers.CollectCommentRegions(propertyDeclaration, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(propertyDeclaration, spans); // fault tolerance if (propertyDeclaration.AccessorList == null || @@ -24,10 +24,12 @@ internal class PropertyDeclarationStructureProvider : AbstractSyntaxNodeStructur return; } - spans.Add(CSharpStructureHelpers.CreateRegion( + spans.Add(CSharpStructureHelpers.CreateBlockSpan( propertyDeclaration, propertyDeclaration.Identifier, - autoCollapse: true)); + autoCollapse: true, + type: BlockTypes.Property, + isCollapsible: true)); } } } diff --git a/src/Features/CSharp/Portable/Structure/Providers/SimpleLambdaExpressionStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/SimpleLambdaExpressionStructureProvider.cs index 6a0488a82a0..c7a137d3cf0 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/SimpleLambdaExpressionStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/SimpleLambdaExpressionStructureProvider.cs @@ -34,11 +34,13 @@ internal class SimpleLambdaExpressionStructureProvider : AbstractSyntaxNodeStruc return; } - spans.Add(CSharpStructureHelpers.CreateRegion( + spans.Add(CSharpStructureHelpers.CreateBlockSpan( lambdaExpression, lambdaExpression.ArrowToken, lastToken, - autoCollapse: false)); + autoCollapse: false, + type: BlockTypes.AnonymousMethod, + isCollapsible: true)); } } } \ No newline at end of file diff --git a/src/Features/CSharp/Portable/Structure/Providers/TypeDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/TypeDeclarationStructureProvider.cs index 1d21703ce84..627d4fe63eb 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/TypeDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/TypeDeclarationStructureProvider.cs @@ -14,7 +14,7 @@ internal class TypeDeclarationStructureProvider : AbstractSyntaxNodeStructurePro ImmutableArray.Builder spans, CancellationToken cancellationToken) { - CSharpStructureHelpers.CollectCommentRegions(typeDeclaration, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(typeDeclaration, spans); if (!typeDeclaration.OpenBraceToken.IsMissing && !typeDeclaration.CloseBraceToken.IsMissing) @@ -23,17 +23,24 @@ internal class TypeDeclarationStructureProvider : AbstractSyntaxNodeStructurePro ? typeDeclaration.Identifier : typeDeclaration.TypeParameterList.GetLastToken(includeZeroWidth: true); - spans.Add(CSharpStructureHelpers.CreateRegion( + var type = typeDeclaration.Kind() == SyntaxKind.InterfaceDeclaration + ? BlockTypes.Interface + : typeDeclaration.Kind() == SyntaxKind.StructDeclaration + ? BlockTypes.Structure + : BlockTypes.Class; + spans.Add(CSharpStructureHelpers.CreateBlockSpan( typeDeclaration, lastToken, - autoCollapse: false)); + autoCollapse: false, + type: type, + isCollapsible: true)); } // add any leading comments before the end of the type block if (!typeDeclaration.CloseBraceToken.IsMissing) { var leadingTrivia = typeDeclaration.CloseBraceToken.LeadingTrivia; - CSharpStructureHelpers.CollectCommentRegions(leadingTrivia, spans); + CSharpStructureHelpers.CollectCommentBlockSpans(leadingTrivia, spans); } } } diff --git a/src/Features/Core/Portable/Structure/BlockTypes.cs b/src/Features/Core/Portable/Structure/BlockTypes.cs index 024b440cd5d..b606a41df1e 100644 --- a/src/Features/Core/Portable/Structure/BlockTypes.cs +++ b/src/Features/Core/Portable/Structure/BlockTypes.cs @@ -4,25 +4,40 @@ namespace Microsoft.CodeAnalysis.Structure { internal static class BlockTypes { - public const string AccessorBlock = "AccessorBlock"; - public const string AnonymousMethodBlock = "AnonymousMethodBlock"; - public const string Case = "Case"; - public const string Class = "Class"; - public const string Conditional = "Conditional"; - public const string Constructor = "Constructor"; - public const string Destructor = "Destructor"; - public const string Interface = "Interface"; - public const string Lock = "Context"; - public const string Loop = "Loop"; - public const string Method = "Method"; - public const string Namespace = "Namespace"; - public const string Nonstructural = "Nonstructural"; - public const string Operator = "Operator"; - public const string PropertyBlock = "PropertyBlock"; - public const string Standalone = "Standalone"; - public const string Struct = "Struct"; - public const string Structural = "Structural"; - public const string TryCatchFinally = "TryCatchFinally"; - public const string Unknown = "Unknown"; + // Basic types. + public const string Structural = nameof(Structural); + public const string Nonstructural = nameof(Nonstructural); + + // Top level declarations. + public const string Namespace = nameof(Namespace); + public const string Class = nameof(Class); + public const string Enum = nameof(Enum); + public const string Interface = nameof(Interface); + public const string Module = nameof(Module); + public const string Structure = nameof(Structure); + + // Type level declarations. + public const string Accessor = nameof(Accessor); + public const string Constructor = nameof(Constructor); + public const string Destructor = nameof(Destructor); + public const string Event = nameof(Event); + public const string Indexer = nameof(Indexer); + public const string Method = nameof(Method); + public const string Operator = nameof(Operator); + public const string Property = nameof(Property); + + // Statements + public const string Case = nameof(Case); + public const string Conditional = nameof(Conditional); + public const string Lock = nameof(Lock); + public const string Loop = nameof(Loop); + public const string TryCatchFinally = nameof(TryCatchFinally); + public const string Standalone = nameof(Standalone); + + // Expressions + public const string AnonymousMethod = nameof(AnonymousMethod); + public const string Xml = nameof(Xml); + + public const string Other = nameof(Other); } } \ No newline at end of file diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/AccessorDeclarationStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/AccessorDeclarationStructureProvider.vb index f171dc936b9..c2976a246cd 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/AccessorDeclarationStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/AccessorDeclarationStructureProvider.vb @@ -16,8 +16,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure Dim block = TryCast(accessorDeclaration.Parent, AccessorBlockSyntax) If Not block?.EndBlockStatement.IsMissing Then - spans.Add( - CreateRegionFromBlock(block, bannerNode:=accessorDeclaration, autoCollapse:=True)) + spans.Add(CreateRegionFromBlock( + block, bannerNode:=accessorDeclaration, + autoCollapse:=True, type:=BlockTypes.Accessor, isCollapsible:=True)) End If End Sub End Class diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/CompilationUnitStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/CompilationUnitStructureProvider.vb index fa2e7b238d5..412fb67b7cf 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/CompilationUnitStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/CompilationUnitStructureProvider.vb @@ -15,7 +15,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure Dim regions As New List(Of BlockSpan) CollectCommentsRegions(compilationUnit, spans) - spans.Add(CreateRegion(compilationUnit.Imports, bannerText:="Imports" & SpaceEllipsis, autoCollapse:=True)) + spans.Add(CreateRegion( + compilationUnit.Imports, bannerText:="Imports" & SpaceEllipsis, + autoCollapse:=True, type:=BlockTypes.Nonstructural, isCollapsible:=True)) CollectCommentsRegions(compilationUnit.EndOfFileToken.LeadingTrivia, spans) End Sub diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/ConstructorDeclarationStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/ConstructorDeclarationStructureProvider.vb index 49196af9a8b..f8c6025fafc 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/ConstructorDeclarationStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/ConstructorDeclarationStructureProvider.vb @@ -18,8 +18,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure Dim block = TryCast(constructorDeclaration.Parent, ConstructorBlockSyntax) If Not block?.EndBlockStatement.IsMissing Then - spans.Add( - CreateRegionFromBlock(block, bannerNode:=constructorDeclaration, autoCollapse:=True)) + spans.Add(CreateRegionFromBlock( + block, bannerNode:=constructorDeclaration, autoCollapse:=True, + type:=BlockTypes.Constructor, isCollapsible:=True)) End If End Sub End Class diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/DisabledTextTriviaStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/DisabledTextTriviaStructureProvider.vb index 3d2a4af0345..e59a413d8fa 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/DisabledTextTriviaStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/DisabledTextTriviaStructureProvider.vb @@ -18,11 +18,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure Dim startPos = nodeSpan.Start Dim endPos = startPos + trivia.ToString().TrimEnd().Length - spans.Add( - CreateRegion( - span:=TextSpan.FromBounds(startPos, endPos), - bannerText:=Ellipsis, - autoCollapse:=True)) + spans.Add(CreateRegion( + span:=TextSpan.FromBounds(startPos, endPos), + bannerText:=Ellipsis, autoCollapse:=True, + type:=BlockTypes.Nonstructural, isCollapsible:=True)) End If End Sub End Class diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/DocumentationCommentStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/DocumentationCommentStructureProvider.vb index 934687c8554..32e7e8f2555 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/DocumentationCommentStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/DocumentationCommentStructureProvider.vb @@ -87,8 +87,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure Dim fullSpan = TextSpan.FromBounds(startPos, endPos) - spans.Add( - CreateRegion(fullSpan, GetBannerText(documentationComment, cancellationToken), autoCollapse:=True)) + spans.Add(CreateRegion( + fullSpan, GetBannerText(documentationComment, cancellationToken), + autoCollapse:=True, type:=BlockTypes.Nonstructural, isCollapsible:=True)) End Sub End Class End Namespace \ No newline at end of file diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/EnumDeclarationStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/EnumDeclarationStructureProvider.vb index bf3f7e55449..50d9c05b70d 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/EnumDeclarationStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/EnumDeclarationStructureProvider.vb @@ -16,8 +16,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure Dim block = TryCast(enumDeclaration.Parent, EnumBlockSyntax) If Not block?.EndEnumStatement.IsMissing Then - spans.Add( - CreateRegionFromBlock(block, bannerNode:=enumDeclaration, autoCollapse:=True)) + spans.Add(CreateRegionFromBlock( + block, bannerNode:=enumDeclaration, autoCollapse:=True, + type:=BlockTypes.Enum, isCollapsible:=True)) CollectCommentsRegions(block.EndEnumStatement, spans) End If diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/EventDeclarationStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/EventDeclarationStructureProvider.vb index b02914f1d54..4a0052d5a71 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/EventDeclarationStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/EventDeclarationStructureProvider.vb @@ -16,8 +16,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure Dim block = TryCast(eventDeclaration.Parent, EventBlockSyntax) If Not block?.EndEventStatement.IsMissing Then - spans.Add( - CreateRegionFromBlock(block, bannerNode:=eventDeclaration, autoCollapse:=True)) + spans.Add(CreateRegionFromBlock( + block, bannerNode:=eventDeclaration, autoCollapse:=True, + type:=BlockTypes.Event, isCollapsible:=True)) CollectCommentsRegions(block.EndEventStatement, spans) End If diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/MetadataAsSource/MetadataRegionDirectiveStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/MetadataAsSource/MetadataRegionDirectiveStructureProvider.vb index b382d9fbff8..10a446c6748 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/MetadataAsSource/MetadataRegionDirectiveStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/MetadataAsSource/MetadataRegionDirectiveStructureProvider.vb @@ -25,11 +25,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure.MetadataAsSource cancellationToken As CancellationToken) Dim match = regionDirective.GetMatchingStartOrEndDirective(cancellationToken) If match IsNot Nothing Then - spans.Add( - VisualBasicOutliningHelpers.CreateRegion( - TextSpan.FromBounds(regionDirective.SpanStart, match.Span.End), - GetBannerText(regionDirective), - autoCollapse:=True)) + spans.Add(CreateRegion( + TextSpan.FromBounds(regionDirective.SpanStart, match.Span.End), + GetBannerText(regionDirective), + autoCollapse:=True, + type:=BlockTypes.Nonstructural, isCollapsible:=True)) End If End Sub diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/MethodDeclarationStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/MethodDeclarationStructureProvider.vb index 97e735c00eb..48bac9962ad 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/MethodDeclarationStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/MethodDeclarationStructureProvider.vb @@ -16,8 +16,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure Dim block = TryCast(methodDeclaration.Parent, MethodBlockSyntax) If Not block?.EndBlockStatement.IsMissing Then - spans.Add( - CreateRegionFromBlock(block, bannerNode:=methodDeclaration, autoCollapse:=True)) + spans.Add(CreateRegionFromBlock( + block, bannerNode:=methodDeclaration, autoCollapse:=True, + type:=BlockTypes.Method, isCollapsible:=True)) End If End Sub End Class diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/MultilineLambdaStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/MultilineLambdaStructureProvider.vb index d744191162f..ee1c270c458 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/MultilineLambdaStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/MultilineLambdaStructureProvider.vb @@ -13,8 +13,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure spans As ImmutableArray(Of BlockSpan).Builder, cancellationToken As CancellationToken) If Not lambdaExpression.EndSubOrFunctionStatement.IsMissing Then - spans.Add( - CreateRegionFromBlock(lambdaExpression, bannerNode:=lambdaExpression.SubOrFunctionHeader, autoCollapse:=False)) + spans.Add(CreateRegionFromBlock( + lambdaExpression, bannerNode:=lambdaExpression.SubOrFunctionHeader, autoCollapse:=False, + type:=BlockTypes.AnonymousMethod, isCollapsible:=True)) End If End Sub End Class diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/NamespaceDeclarationStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/NamespaceDeclarationStructureProvider.vb index 5bd2e33077b..70944d7e414 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/NamespaceDeclarationStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/NamespaceDeclarationStructureProvider.vb @@ -16,8 +16,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure Dim block = TryCast(namespaceDeclaration.Parent, NamespaceBlockSyntax) If Not block?.EndNamespaceStatement.IsMissing Then - spans.Add( - CreateRegionFromBlock(block, bannerNode:=namespaceDeclaration, autoCollapse:=False)) + spans.Add(CreateRegionFromBlock( + block, bannerNode:=namespaceDeclaration, autoCollapse:=False, + type:=BlockTypes.Namespace, isCollapsible:=True)) CollectCommentsRegions(block.EndNamespaceStatement, spans) End If diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/OperatorDeclarationStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/OperatorDeclarationStructureProvider.vb index aae9049eb4f..ccd5d289175 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/OperatorDeclarationStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/OperatorDeclarationStructureProvider.vb @@ -16,8 +16,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure Dim block = TryCast(operatorDeclaration.Parent, OperatorBlockSyntax) If Not block?.EndBlockStatement.IsMissing Then - spans.Add( - CreateRegionFromBlock(block, bannerNode:=operatorDeclaration, autoCollapse:=True)) + spans.Add(CreateRegionFromBlock( + block, bannerNode:=operatorDeclaration, autoCollapse:=True, + type:=BlockTypes.Operator, isCollapsible:=True)) End If End Sub End Class diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/PropertyDeclarationStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/PropertyDeclarationStructureProvider.vb index 50d9e8c71d9..6a928fd0941 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/PropertyDeclarationStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/PropertyDeclarationStructureProvider.vb @@ -16,8 +16,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure Dim block = TryCast(propertyDeclaration.Parent, PropertyBlockSyntax) If Not block?.EndPropertyStatement.IsMissing Then - spans.Add( - CreateRegionFromBlock(block, bannerNode:=propertyDeclaration, autoCollapse:=True)) + spans.Add(CreateRegionFromBlock( + block, bannerNode:=propertyDeclaration, autoCollapse:=True, + type:=BlockTypes.Property, isCollapsible:=True)) CollectCommentsRegions(block.EndPropertyStatement, spans) End If diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/RegionDirectiveStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/RegionDirectiveStructureProvider.vb index 84abf6ee43d..054207c3f09 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/RegionDirectiveStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/RegionDirectiveStructureProvider.vb @@ -25,12 +25,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure cancellationToken As CancellationToken) Dim matchingDirective = regionDirective.GetMatchingStartOrEndDirective(cancellationToken) If matchingDirective IsNot Nothing Then - spans.Add( - CreateRegion( - TextSpan.FromBounds(regionDirective.SpanStart, matchingDirective.Span.End), - GetBannerText(regionDirective), - autoCollapse:=False, - isDefaultCollapsed:=True)) + spans.Add(CreateRegion( + TextSpan.FromBounds(regionDirective.SpanStart, matchingDirective.Span.End), + GetBannerText(regionDirective), + autoCollapse:=False, + isDefaultCollapsed:=True, + type:=BlockTypes.Nonstructural, + isCollapsible:=True)) End If End Sub diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/TypeDeclarationStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/TypeDeclarationStructureProvider.vb index 9b3988ea16b..bbf6cfc98a9 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/TypeDeclarationStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/TypeDeclarationStructureProvider.vb @@ -16,8 +16,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure Dim block = TryCast(typeDeclaration.Parent, TypeBlockSyntax) If Not block?.EndBlockStatement.IsMissing Then - spans.Add( - CreateRegionFromBlock(block, bannerNode:=typeDeclaration, autoCollapse:=False)) + Dim type = + If(typeDeclaration.Kind() = SyntaxKind.InterfaceStatement, BlockTypes.Interface, + If(typeDeclaration.Kind() = SyntaxKind.StructureStatement, BlockTypes.Structure, + If(typeDeclaration.Kind() = SyntaxKind.ModuleStatement, BlockTypes.Module, + BlockTypes.Class))) + spans.Add(CreateRegionFromBlock( + block, bannerNode:=typeDeclaration, autoCollapse:=False, + type:=type, isCollapsible:=True)) CollectCommentsRegions(block.EndBlockStatement, spans) End If diff --git a/src/Features/VisualBasic/Portable/Structure/Providers/XmlExpressionStructureProvider.vb b/src/Features/VisualBasic/Portable/Structure/Providers/XmlExpressionStructureProvider.vb index baddd374cbe..b938b5c0887 100644 --- a/src/Features/VisualBasic/Portable/Structure/Providers/XmlExpressionStructureProvider.vb +++ b/src/Features/VisualBasic/Portable/Structure/Providers/XmlExpressionStructureProvider.vb @@ -23,8 +23,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure Dim lineText = line.ToString().Substring(span.Start - line.Start) Dim bannerText = lineText & SpaceEllipsis - spans.Add( - CreateRegion(span, bannerText, autoCollapse:=False)) + spans.Add(CreateRegion( + span, bannerText, autoCollapse:=False, + type:=BlockTypes.Xml, isCollapsible:=True)) End Sub End Class End Namespace \ No newline at end of file diff --git a/src/Features/VisualBasic/Portable/Structure/VisualBasicStructureHelpers.vb b/src/Features/VisualBasic/Portable/Structure/VisualBasicStructureHelpers.vb index 2f27f19017b..9ff6a571fe2 100644 --- a/src/Features/VisualBasic/Portable/Structure/VisualBasicStructureHelpers.vb +++ b/src/Features/VisualBasic/Portable/Structure/VisualBasicStructureHelpers.vb @@ -22,7 +22,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure Return CreateRegion( TextSpan.FromBounds(startComment.SpanStart, endComment.Span.End), GetCommentBannerText(startComment), - autoCollapse:=True) + autoCollapse:=True, + type:=BlockTypes.Nonstructural, + isCollapsible:=True) End Function ' For testing purposes @@ -72,31 +74,56 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure CollectCommentsRegions(triviaList, spans) End Sub - Friend Function CreateRegion(span As TextSpan, bannerText As String, autoCollapse As Boolean, Optional isDefaultCollapsed As Boolean = False) As BlockSpan + Friend Function CreateRegion( + span As TextSpan, + bannerText As String, + autoCollapse As Boolean, + type As String, + isCollapsible As Boolean, + Optional isDefaultCollapsed As Boolean = False) As BlockSpan Return New BlockSpan( - isCollapsible:=True, textSpan:=span, bannerText:=bannerText, autoCollapse:=autoCollapse, - isDefaultCollapsed:=isDefaultCollapsed) + isDefaultCollapsed:=isDefaultCollapsed, + type:=type, + isCollapsible:=isCollapsible) End Function - Friend Function CreateRegionFromBlock(blockNode As SyntaxNode, bannerText As String, autoCollapse As Boolean) As BlockSpan - Return CreateRegion(blockNode.Span, bannerText, autoCollapse) + Friend Function CreateRegionFromBlock( + blockNode As SyntaxNode, + bannerText As String, + autoCollapse As Boolean, + type As String, + isCollapsible As Boolean) As BlockSpan + Return CreateRegion(blockNode.Span, bannerText, autoCollapse, type, isCollapsible) End Function - Friend Function CreateRegionFromBlock(blockNode As SyntaxNode, bannerNode As SyntaxNode, autoCollapse As Boolean) As BlockSpan - Return CreateRegion(blockNode.Span, GetNodeBannerText(bannerNode), autoCollapse) + Friend Function CreateRegionFromBlock( + blockNode As SyntaxNode, + bannerNode As SyntaxNode, + autoCollapse As Boolean, + type As String, + isCollapsible As Boolean) As BlockSpan + Return CreateRegion( + blockNode.Span, GetNodeBannerText(bannerNode), + autoCollapse, type, isCollapsible) End Function - Friend Function CreateRegion(syntaxList As IEnumerable(Of SyntaxNode), bannerText As String, autoCollapse As Boolean) As BlockSpan + Friend Function CreateRegion(syntaxList As IEnumerable(Of SyntaxNode), + bannerText As String, + autoCollapse As Boolean, + type As String, + isCollapsible As Boolean) As BlockSpan If syntaxList.IsEmpty() Then Return Nothing End If Dim startPos = syntaxList.First().SpanStart Dim endPos = syntaxList.Last().Span.End - Return CreateRegion(TextSpan.FromBounds(startPos, endPos), bannerText, autoCollapse) + Return CreateRegion( + TextSpan.FromBounds(startPos, endPos), bannerText, + autoCollapse, type, isCollapsible) End Function End Module End Namespace \ No newline at end of file diff --git a/src/Workspaces/Core/Portable/Workspaces.csproj b/src/Workspaces/Core/Portable/Workspaces.csproj index f98a31a92e2..c787688008f 100644 --- a/src/Workspaces/Core/Portable/Workspaces.csproj +++ b/src/Workspaces/Core/Portable/Workspaces.csproj @@ -242,6 +242,7 @@ + -- GitLab