diff --git a/src/Features/CSharp/Portable/Structure/Providers/AccessorDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/AccessorDeclarationStructureProvider.cs index c883f9097ecbeed5eca42c93f2d84a7dba33874d..e1116af85717b874a4aa779d3a5bf5659e8a8461 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/AccessorDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/AccessorDeclarationStructureProvider.cs @@ -32,10 +32,15 @@ internal class AccessorDeclarationStructureProvider : AbstractSyntaxNodeStructur SyntaxNodeOrToken current = accessorDeclaration; var nextSibling = current.GetNextSibling(); + // Check IsNode to compress blank lines after this node if it is the last child of the parent. + // + // All accessor kinds are grouped together. + var compressEmptyLines = !nextSibling.IsNode || nextSibling.AsNode() is AccessorDeclarationSyntax; + spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( accessorDeclaration, accessorDeclaration.Keyword, - compressEmptyLines: !nextSibling.IsNode || nextSibling.AsNode() is AccessorDeclarationSyntax, + compressEmptyLines: compressEmptyLines, autoCollapse: true, type: BlockTypes.Member, isCollapsible: true)); diff --git a/src/Features/CSharp/Portable/Structure/Providers/ConstructorDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/ConstructorDeclarationStructureProvider.cs index 27c2388990d3dd968a11e9fa28ba14ee795319b2..cd12f1e76b69897f5f18b425e98fa5e60ad89f78 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/ConstructorDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/ConstructorDeclarationStructureProvider.cs @@ -32,10 +32,13 @@ internal class ConstructorDeclarationStructureProvider : AbstractSyntaxNodeStruc SyntaxNodeOrToken current = constructorDeclaration; var nextSibling = current.GetNextSibling(); + // Check IsNode to compress blank lines after this node if it is the last child of the parent. + var compressEmptyLines = !nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.ConstructorDeclaration); + spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( constructorDeclaration, constructorDeclaration.ParameterList.GetLastToken(includeZeroWidth: true), - compressEmptyLines: !nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.ConstructorDeclaration), + compressEmptyLines: compressEmptyLines, autoCollapse: true, type: BlockTypes.Member, isCollapsible: true)); diff --git a/src/Features/CSharp/Portable/Structure/Providers/ConversionOperatorDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/ConversionOperatorDeclarationStructureProvider.cs index 335abb421df46f6550f356d55fb7e060151971e6..d8f89e4195af333ad2641a4065752f0afc2f0294 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/ConversionOperatorDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/ConversionOperatorDeclarationStructureProvider.cs @@ -32,10 +32,13 @@ internal class ConversionOperatorDeclarationStructureProvider : AbstractSyntaxNo SyntaxNodeOrToken current = operatorDeclaration; var nextSibling = current.GetNextSibling(); + // Check IsNode to compress blank lines after this node if it is the last child of the parent. + var compressEmptyLines = !nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.ConversionOperatorDeclaration); + spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( operatorDeclaration, operatorDeclaration.ParameterList.GetLastToken(includeZeroWidth: true), - compressEmptyLines: !nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.ConversionOperatorDeclaration), + compressEmptyLines: compressEmptyLines, autoCollapse: true, type: BlockTypes.Member, isCollapsible: true)); diff --git a/src/Features/CSharp/Portable/Structure/Providers/EnumDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/EnumDeclarationStructureProvider.cs index a40c302f68bd97df496e21926b34b167a4d377b2..2918adb46a10d79e2208bb0fc475dabcc1fd93c2 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/EnumDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/EnumDeclarationStructureProvider.cs @@ -27,10 +27,13 @@ internal class EnumDeclarationStructureProvider : AbstractSyntaxNodeStructurePro SyntaxNodeOrToken current = enumDeclaration; var nextSibling = current.GetNextSibling(); + // Check IsNode to compress blank lines after this node if it is the last child of the parent. + var compressEmptyLines = !nextSibling.IsNode || nextSibling.AsNode() is BaseTypeDeclarationSyntax; + spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( enumDeclaration, enumDeclaration.Identifier, - compressEmptyLines: !nextSibling.IsNode || nextSibling.AsNode() is BaseTypeDeclarationSyntax, + compressEmptyLines: compressEmptyLines, autoCollapse: false, type: BlockTypes.Member, isCollapsible: true)); diff --git a/src/Features/CSharp/Portable/Structure/Providers/EventDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/EventDeclarationStructureProvider.cs index f2b3cf236acdc1e1f9c8463ce167c08dfca2cb62..a72b6c3cc9da8b2234f6a848b608cb07dc7dfa3d 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/EventDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/EventDeclarationStructureProvider.cs @@ -33,10 +33,15 @@ internal class EventDeclarationStructureProvider : AbstractSyntaxNodeStructurePr SyntaxNodeOrToken current = eventDeclaration; var nextSibling = current.GetNextSibling(); + // Check IsNode to compress blank lines after this node if it is the last child of the parent. + // + // Full events are grouped together with event field definitions. + var compressEmptyLines = !nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.EventDeclaration) || nextSibling.IsKind(SyntaxKind.EventFieldDeclaration); + spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( eventDeclaration, eventDeclaration.Identifier, - compressEmptyLines: !nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.EventDeclaration) || nextSibling.IsKind(SyntaxKind.EventFieldDeclaration), + compressEmptyLines: compressEmptyLines, autoCollapse: true, type: BlockTypes.Member, isCollapsible: true)); diff --git a/src/Features/CSharp/Portable/Structure/Providers/IndexerDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/IndexerDeclarationStructureProvider.cs index 0877d2e75434e3a75a008b07957c186e69b2901d..1142a51726b907248e969e652a0952651eac4ff6 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/IndexerDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/IndexerDeclarationStructureProvider.cs @@ -33,10 +33,15 @@ internal class IndexerDeclarationStructureProvider : AbstractSyntaxNodeStructure SyntaxNodeOrToken current = indexerDeclaration; var nextSibling = current.GetNextSibling(); + // Check IsNode to compress blank lines after this node if it is the last child of the parent. + // + // Indexers are grouped together with properties. + var compressEmptyLines = !nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.IndexerDeclaration) || nextSibling.IsKind(SyntaxKind.PropertyDeclaration); + spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( indexerDeclaration, indexerDeclaration.ParameterList.GetLastToken(includeZeroWidth: true), - compressEmptyLines: !nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.IndexerDeclaration) || nextSibling.IsKind(SyntaxKind.PropertyDeclaration), + compressEmptyLines: compressEmptyLines, autoCollapse: true, type: BlockTypes.Member, isCollapsible: true)); diff --git a/src/Features/CSharp/Portable/Structure/Providers/MethodDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/MethodDeclarationStructureProvider.cs index 6af8b03dd92380e5da9efaf13c881907950f0023..49001a9fb3d9c6de40c494d71b76ee59cb627784 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/MethodDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/MethodDeclarationStructureProvider.cs @@ -32,10 +32,13 @@ internal class MethodDeclarationStructureProvider : AbstractSyntaxNodeStructureP SyntaxNodeOrToken current = methodDeclaration; var nextSibling = current.GetNextSibling(); + // Check IsNode to compress blank lines after this node if it is the last child of the parent. + var compressEmptyLines = !nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.MethodDeclaration); + spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( methodDeclaration, methodDeclaration.ParameterList.GetLastToken(includeZeroWidth: true), - compressEmptyLines: !nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.MethodDeclaration), + compressEmptyLines: compressEmptyLines, autoCollapse: true, type: BlockTypes.Member, isCollapsible: true)); diff --git a/src/Features/CSharp/Portable/Structure/Providers/OperatorDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/OperatorDeclarationStructureProvider.cs index dbfe3ec592dedda93806970aa6e55fb4c51c2fd1..4ba85795d0c594a5047d12fc251a303a08723628 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/OperatorDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/OperatorDeclarationStructureProvider.cs @@ -32,10 +32,13 @@ internal class OperatorDeclarationStructureProvider : AbstractSyntaxNodeStructur SyntaxNodeOrToken current = operatorDeclaration; var nextSibling = current.GetNextSibling(); + // Check IsNode to compress blank lines after this node if it is the last child of the parent. + var compressEmptyLines = !nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.OperatorDeclaration); + spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( operatorDeclaration, operatorDeclaration.ParameterList.GetLastToken(includeZeroWidth: true), - compressEmptyLines: !nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.OperatorDeclaration), + compressEmptyLines: compressEmptyLines, autoCollapse: true, type: BlockTypes.Member, isCollapsible: true)); diff --git a/src/Features/CSharp/Portable/Structure/Providers/PropertyDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/PropertyDeclarationStructureProvider.cs index b218d0c24939b4da51e41a2f1ef64f3eb38ea894..8d01a848ee863e9c9310a0d28b4afb82dc536b66 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/PropertyDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/PropertyDeclarationStructureProvider.cs @@ -32,10 +32,15 @@ internal class PropertyDeclarationStructureProvider : AbstractSyntaxNodeStructur SyntaxNodeOrToken current = propertyDeclaration; var nextSibling = current.GetNextSibling(); + // Check IsNode to compress blank lines after this node if it is the last child of the parent. + // + // Properties are grouped together with indexers. + var compressEmptyLines = !nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.PropertyDeclaration) || nextSibling.IsKind(SyntaxKind.IndexerDeclaration); + spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( propertyDeclaration, propertyDeclaration.Identifier, - compressEmptyLines: !nextSibling.IsNode || nextSibling.IsKind(SyntaxKind.PropertyDeclaration) || nextSibling.IsKind(SyntaxKind.IndexerDeclaration), + compressEmptyLines: compressEmptyLines, autoCollapse: true, type: BlockTypes.Member, isCollapsible: true)); diff --git a/src/Features/CSharp/Portable/Structure/Providers/TypeDeclarationStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/TypeDeclarationStructureProvider.cs index c483d64904d8eea5f9b14a95950cc10ee5153091..c001090228f24316f152656fa18467cac3550390 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/TypeDeclarationStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/TypeDeclarationStructureProvider.cs @@ -31,10 +31,16 @@ internal class TypeDeclarationStructureProvider : AbstractSyntaxNodeStructurePro SyntaxNodeOrToken current = typeDeclaration; var nextSibling = current.GetNextSibling(); + // Check IsNode to compress blank lines after this node if it is the last child of the parent. + // + // Collapse to Definitions doesn't collapse type nodes, but a Toggle All Outlining would collapse groups + // of types to the compressed form of not showing blank lines. All kinds of types are grouped together. + var compressEmptyLines = !nextSibling.IsNode || nextSibling.AsNode() is BaseTypeDeclarationSyntax; + spans.AddIfNotNull(CSharpStructureHelpers.CreateBlockSpan( typeDeclaration, lastToken, - compressEmptyLines: !nextSibling.IsNode || nextSibling.AsNode() is BaseTypeDeclarationSyntax, + compressEmptyLines: compressEmptyLines, autoCollapse: false, type: BlockTypes.Type, isCollapsible: true));