diff --git a/src/EditorFeatures/CSharpTest/Structure/CommentStructureTests.cs b/src/EditorFeatures/CSharpTest/Structure/CommentStructureTests.cs index 6d051bcd755dfe5c551e8d08bc549ac06d813b62..7dffc08cf0e7190f681bff5c3ab818b21dd344fd 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 2a95222484351c371300f090001f2859dbb231fc..dca8ccd56ca05c34e3e603682888aa5c6e277225 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 ab4ae668f5c3199669793896a0090fcdfb02c521..0000000000000000000000000000000000000000 --- 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 46e071b61f3dd6fd8d301b2a81a18f03d5e098e6..4a8aae32a56a4bf91fecafe417e8144acc0e4908 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 0000000000000000000000000000000000000000..d141b6f57a70058afb24f5451ddbafcca7e5c3d2 --- /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 12a18ac45c009622e54deb90c573b88c0a643e30..3fc9cb4d60341c68affbde095fbcbd87f9996cc0 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 260d46a231c8e70577762213859436af2df69ba6..cceaf345eb59a7ee7050653f9c946b5a360f9d3b 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 0000000000000000000000000000000000000000..cc147dba261142d21c174ca45b5120b4a30ee99f --- /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 b38a85058ada78d54c00f83e88ddeb90247ba252..acc0b8ca3bb7fb791606063c3ad3212107215af9 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 75d765bb78a374534961a0ceb9492b64729eef67..888f5ab04ecba83ee679d0d01957494d1432e257 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 e0c4ccc89396fbebc971ba92d2fd409e06904ef1..066741cbe823a43a087f0106e02a4c493361b0b6 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 e2c1e1d4834f048a094bef8f43c673bfa58a471c..00a600268d0d5d67e552ff6ebf8d6dbfc439977f 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 3985a501b5fe9331eb38dd3b182827845c802baf..8ef02d8a72b1d2f0815c159f518490454bb0c149 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 70c96e38db4c55d7fb0d675ca063d6e3a65d29b0..478dbce7bf4aee4faa910e3aec417ee87e2e730e 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 5ec0a87aa2c734ea2e2c0e47ec2cdceb4f354b03..39903a474a5839b625e9fcc02942ed3798985435 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 00de7129ac88d0edd71e1646fd7d815f6c164299..a5c2f8737936b23a598bbbc0c694b4b3421481c3 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 2da31800d3ded4e8eae84a8f3e1945662eadead0..10aae6d1ee5f9c8cdd42586bfd7314bca6568b01 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 e9f20762dfbdb6fa5128efb97fa9cccd4052fd35..d882c33e0f09a66667d16cd374a23e286240b007 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 da3d5f831043678cb756c782ffd073d39f316a29..c192fef998c0b254c705e78a776d50f266fcf09b 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 f0b30526a18451b5f18acdd2e79a0363bae01800..cbe3c67d7956a846038b91580e29c6631cbcdb1c 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 c2246be35f22e9e11858139f34485add0e4b5248..c50094e8c681f9e6d3e971990c8c0b7a798c7669 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 c5534456a7ace11c63e9994dfc13c1af5fa5cbf6..c1f523c84109d31c7f6a11fd255e341fc22b8549 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 e44c099821e7365f3b268620cafbb878901c0e1a..ce35647efdb98e4998bffd7b058e65904f1f2564 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 b33af225a3bf9ec6968daef63ac0d80c3ae98757..680fda98e534cf9fd5350a3002b3efd90593232d 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 025bed4c63075b402ea2e756a3029851de1df47d..399ecf3f7a733483703ce28b6e234b9f026613bc 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 5dc40bfee6e3b64a868955b15580378294c594a1..bafacec7435391733d7726f7baae72faf9ae9ca3 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 292262398b06dbdf3ae26002bdf4db94bc73f773..f946c9fdda68a4bd15d8bee290b3f55b9efea75a 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 6a0488a82a01dbb5ad4c9802d808cb66d0feacfe..c7a137d3cf0b622f4748197c80743c048d971721 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 1d21703ce846b7a563e0d8ae0e6cc62a1804be56..627d4fe63eb0ab25e15fc64355b8bbee2179a66a 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 024b440cd5d173c815729be2930714c9ba4268e7..b606a41df1e34dc3c9d1354c4ff539af7872d25c 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 f171dc936b97e2c430761a383da6e9a293769fc2..c2976a246cdaca35bf4734364f49cf3aa1aba342 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 fa2e7b238d5dc22e4df8f4df11a6093165ac34bf..412fb67b7cfe341eb58049e700750ec672c10fbf 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 49196af9a8b15f80a1c0b920f0fd2f007d7eed0e..f8c6025fafc654846e5b20e7ce1275e25973c2de 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 3d2a4af03455802ba8e4b3f56b5283bf6f6d11e8..e59a413d8fab2692ec6ae279df281ca0b7952bfb 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 934687c855496131ac1f696e0c01aee237107e3a..32e7e8f25551e6b9583f9db65ea206cecaad5de4 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 bf3f7e5544972e719582c596ca9db8549a18c467..50d9c05b70d1aa571cb6fbe8b58b1de81eee49ad 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 b02914f1d5432b0dc28ee022546517e8449cbb14..4a0052d5a712d3b0f927e9954e563351694c785d 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 b382d9fbff89c807fbb78e632935e8ebcede7b3d..10a446c674830752cfcb671d00b3966bc2bf40d9 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 97e735c00eb3557cee2af2ffd8f88c286faeac31..48bac9962ad089b26c2e244170d781a02cb64719 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 d744191162ff465f5e4e899dc785643af86f88a4..ee1c270c4585966c860bb8badcdf63de55f01d89 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 5bd2e33077bbd0ff7dfe4ea7adfca84824400086..70944d7e41400da79cbf0536af50ba2b597a7faf 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 aae9049eb4fbd082a6309b6324fbc2d88d592ce9..ccd5d289175318aea1187e71d75460eb48e0361e 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 50d9e8c71d9984a3b0236004bc03fdebd64152e1..6a928fd0941f39d34dda789e37b37c1d3bac2cd6 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 84abf6ee43d6616faaa224944c1c2b464594d2dc..054207c3f09dc8a12056d69ddfb3ec44b5fa6897 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 9b3988ea16bd504654f5b8420dea38c818a55b28..bbf6cfc98a93cc931cb484ca180689e799c75dfd 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 baddd374cbea0ed48a8217a26bd58871a6650d64..b938b5c0887dac750d43107b2f6b906449e94b87 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 2f27f19017bcf0b036493ec2157c20eae805aaa1..9ff6a571fe24a8c04c142e48692555fee8f78c1b 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 f98a31a92e25f48f5eff563dd4513dd43fb23245..c787688008f1317342891e502fd72d5b3cbfb002 100644 --- a/src/Workspaces/Core/Portable/Workspaces.csproj +++ b/src/Workspaces/Core/Portable/Workspaces.csproj @@ -242,6 +242,7 @@ +