提交 66dfc111 编写于 作者: C CyrusNajmabadi 提交者: GitHub

Merge pull request #14942 from CyrusNajmabadi/outliningExpressions

Support outlining for collection initializers.
......@@ -93,8 +93,10 @@
<AssemblyName>Roslyn.Services.Editor.CSharp.UnitTests</AssemblyName>
<RoslynProjectType>UnitTest</RoslynProjectType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "></PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="PresentationCore" />
......@@ -279,6 +281,7 @@
<Compile Include="Formatting\Indentation\SmartTokenFormatterFormatTokenTests.cs" />
<Compile Include="InlineDeclaration\CSharpInlineDeclarationTests_FixAllTests.cs" />
<Compile Include="InlineDeclaration\CSharpInlineDeclarationTests.cs" />
<Compile Include="Structure\InitializerExpressionStructureTests.cs" />
<Compile Include="UseCollectionInitializer\UseCollectionInitializerTests.cs" />
<Compile Include="UseCoalesceExpression\UseCoalesceExpressionForNullableTests.cs" />
<Compile Include="UseCoalesceExpression\UseCoalesceExpressionTests.cs" />
......
// 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.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Structure;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Structure;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Structure
{
public class InitializerExpressionStructureTests : AbstractCSharpSyntaxNodeStructureTests<InitializerExpressionSyntax>
{
internal override AbstractSyntaxStructureProvider CreateProvider()
=> new InitializerExpressionStructureProvider();
[Fact, Trait(Traits.Feature, Traits.Features.Outlining)]
public async Task TestOuterInitializer()
{
await VerifyBlockSpansAsync(
@"
class C
{
void M()
{
var v = {|hint:new Dictionary<int, int>{|textspan: $${
{ 1, 2 },
{ 1, 2 },
}|}|};
}
}
",
Region("textspan", "hint", CSharpStructureHelpers.Ellipsis, autoCollapse: false));
}
[Fact, Trait(Traits.Feature, Traits.Features.Outlining)]
public async Task TestInnerInitializer()
{
await VerifyBlockSpansAsync(
@"
class C
{
void M()
{
var v = new Dictionary<int, int>{
{|hint:{|textspan:$${
1, 2
},|}|}
{ 1, 2 },
};
}
}
",
Region("textspan", "hint", CSharpStructureHelpers.Ellipsis, autoCollapse: false));
}
}
}
......@@ -120,6 +120,7 @@
<Compile Include="Classification\SemanticClassifierTests.vb" />
<Compile Include="Classification\SyntacticClassifierTests.vb" />
<Compile Include="CodeActions\AbstractVisualBasicCodeActionTest.vb" />
<Compile Include="Structure\CollectionInitializerStructureProviderTests.vb" />
<Compile Include="ConvertToInterpolatedString\ConvertPlaceholderToInterpolatedStringTests.vb" />
<Compile Include="CodeActions\EncapsulateField\EncapsulateFieldTests.vb" />
<Compile Include="CodeActions\ExtractMethod\ExtractMethodTests.vb" />
......@@ -190,6 +191,7 @@
<Compile Include="Diagnostics\OverloadBase\OverloadBaseTests.vb" />
<Compile Include="Diagnostics\PreferFrameworkType\PreferFrameworkTypeTests.vb" />
<Compile Include="Diagnostics\PreferFrameworkType\PreferFrameworkTypeTests_FixAllTests.vb" />
<Compile Include="Structure\ObjectCreationInitializerStructureProviderTests.vb" />
<Compile Include="QualifyMemberAccess\QualifyMemberAccessTests.vb" />
<Compile Include="QualifyMemberAccess\QualifyMemberAccessTests_FixAllTests.vb" />
<Compile Include="Diagnostics\RemoveUnnecessaryCast\RemoveUnnecessaryCastTests.vb" />
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.Structure
Imports Microsoft.CodeAnalysis.VisualBasic.Structure
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Outlining
Public Class CollectionInitializerStructureProviderTests
Inherits AbstractVisualBasicSyntaxNodeStructureProviderTests(Of CollectionInitializerSyntax)
Friend Overrides Function CreateProvider() As AbstractSyntaxStructureProvider
Return New CollectionInitializerStructureProvider()
End Function
<Fact, Trait(Traits.Feature, Traits.Features.Outlining)>
Public Async Function TestInnerInitializer() As Task
Const code = "
Class C
Sub M()
dim d = new Dictionary(of integer, string) From {
{|hintspan:{|textspan:$${
1, ""foo""
},|}|}
{
1, ""foo""
}
}
End Sub
End Class
"
Await VerifyBlockSpansAsync(code,
Region("textspan", "hintspan", bannerText:="...", autoCollapse:=False))
End Function
End Class
End Namespace
\ No newline at end of file
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.Structure
Imports Microsoft.CodeAnalysis.VisualBasic.Structure
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Outlining
Public Class ObjectCreationInitializerStructureProviderTests
Inherits AbstractVisualBasicSyntaxNodeStructureProviderTests(Of ObjectCreationInitializerSyntax)
Friend Overrides Function CreateProvider() As AbstractSyntaxStructureProvider
Return New ObjectCreationInitializerStructureProvider()
End Function
<Fact, Trait(Traits.Feature, Traits.Features.Outlining)>
Public Async Function TestCollectionInitializer() As Task
Const code = "
Class C
Sub M()
dim d = {|hintspan:new Dictionary(of integer, string){|textspan: $$From {
{ 1, ""foo"" }
}|}|}
End Sub
End Class
"
Await VerifyBlockSpansAsync(code,
Region("textspan", "hintspan", bannerText:="...", autoCollapse:=False))
End Function
<Fact, Trait(Traits.Feature, Traits.Features.Outlining)>
Public Async Function TestMemberInitializer() As Task
Const code = "
Class C
private i as integer
Sub M()
dim d = {|hintspan:new C{|textspan: $$With {
.i = 1
}|}|}
End Sub
End Class
"
Await VerifyBlockSpansAsync(code,
Region("textspan", "hintspan", bannerText:="...", autoCollapse:=False))
End Function
End Class
End Namespace
\ No newline at end of file
......@@ -56,6 +56,7 @@
<Link>InternalUtilities\LambdaUtilities.cs</Link>
</Compile>
<Compile Include="ConvertToInterpolatedString\CSharpConvertConcatenationToInterpolatedStringRefactoringProvider.cs" />
<Compile Include="Structure\Providers\InitializerExpressionStructureProvider.cs" />
<Compile Include="UseCoalesceExpression\CSharpUseCoalesceExpressionForNullableDiagnosticAnalyzer.cs" />
<Compile Include="UseCoalesceExpression\CSharpUseCoalesceExpressionDiagnosticAnalyzer.cs" />
<Compile Include="UseExpressionBody\Accessors\UseExpressionBodyForAccessorsCodeFixProvider.cs" />
......
......@@ -7,6 +7,7 @@
namespace Microsoft.CodeAnalysis.CSharp.Structure
{
internal class CSharpBlockStructureProvider : AbstractBlockStructureProvider
{
private static ImmutableDictionary<Type, ImmutableArray<AbstractSyntaxStructureProvider>> CreateDefaultNodeProviderMap()
......@@ -29,6 +30,7 @@ internal class CSharpBlockStructureProvider : AbstractBlockStructureProvider
builder.Add<EventFieldDeclarationSyntax, EventFieldDeclarationStructureProvider, MetadataAsSource.MetadataEventFieldDeclarationStructureProvider>();
builder.Add<FieldDeclarationSyntax, FieldDeclarationStructureProvider, MetadataAsSource.MetadataFieldDeclarationStructureProvider>();
builder.Add<IndexerDeclarationSyntax, IndexerDeclarationStructureProvider, MetadataAsSource.MetadataIndexerDeclarationStructureProvider>();
builder.Add<InitializerExpressionSyntax, InitializerExpressionStructureProvider>();
builder.Add<InterfaceDeclarationSyntax, TypeDeclarationStructureProvider, MetadataAsSource.MetadataTypeDeclarationStructureProvider>();
builder.Add<MethodDeclarationSyntax, MethodDeclarationStructureProvider, MetadataAsSource.MetadataMethodDeclarationStructureProvider>();
builder.Add<NamespaceDeclarationSyntax, NamespaceDeclarationStructureProvider>();
......
// 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.Threading;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Structure;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.Structure
{
internal class InitializerExpressionStructureProvider : AbstractSyntaxNodeStructureProvider<InitializerExpressionSyntax>
{
protected override void CollectBlockSpans(
InitializerExpressionSyntax node,
ArrayBuilder<BlockSpan> spans,
CancellationToken cancellationToken)
{
if (node.Parent is InitializerExpressionSyntax)
{
// We have something like:
//
// new Dictionary<int, string>
// {
// ...
// {
// ...
// },
// ...
// }
//
// In this case, we want to collapse the "{ ... }," (including the comma).
var nextToken = node.CloseBraceToken.GetNextToken();
var end = nextToken.Kind() == SyntaxKind.CommaToken
? nextToken.Span.End
: node.Span.End;
spans.Add(new BlockSpan(
isCollapsible: true,
textSpan: TextSpan.FromBounds(node.SpanStart, end),
hintSpan: TextSpan.FromBounds(node.SpanStart, end),
type: BlockTypes.Expression));
}
else
{
// Parent is something like:
//
// new Dictionary<int, string> {
// ...
// }
//
// The collapsed textspan should be from the > to the }
//
// However, the hint span should be the entire object creation.
var previousToken = node.OpenBraceToken.GetPreviousToken();
spans.Add(new BlockSpan(
isCollapsible: true,
textSpan: TextSpan.FromBounds(previousToken.Span.End, node.Span.End),
hintSpan: node.Parent.Span,
type: BlockTypes.Expression));
}
}
}
}
\ No newline at end of file
......@@ -5,7 +5,8 @@
<Platform Condition="'$(Platform)' == ''">AnyCPU</Platform>
<ProjectGuid>{A1BCD0CE-6C2F-4F8C-9A48-D9D93928E26D}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace></RootNamespace>
<RootNamespace>
</RootNamespace>
<AssemblyName>Microsoft.CodeAnalysis.VisualBasic.Features</AssemblyName>
<TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
......@@ -112,6 +113,8 @@
<Compile Include="CodeFixes\NamingStyles\VisualBasicNamingStyleCodeFixProvider.vb" />
<Compile Include="CodeFixes\OverloadBase\OverloadBaseCodeFixProvider.AddOverloads.vb" />
<Compile Include="CodeFixes\OverloadBase\OverloadBaseCodeFixProvider.vb" />
<Compile Include="Structure\Providers\CollectionInitializerStructureProvider.vb" />
<Compile Include="Structure\Providers\ObjectCreationInitializerStructureProvider.vb" />
<Compile Include="QualifyMemberAccess\VisualBasicQualifyMemberAccessCodeFixProvider.vb" />
<Compile Include="CodeFixes\RemoveUnnecessaryCast\RemoveUnnecessaryCastCodeFixProvider.RemoveUnnecessaryCastFixAllProvider.vb" />
<Compile Include="CodeFixes\RemoveUnnecessaryCast\RemoveUnnecessaryCastCodeFixProvider.Rewriter.vb" />
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Threading
Imports Microsoft.CodeAnalysis.Structure
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic.Structure
Friend Class CollectionInitializerStructureProvider
Inherits AbstractSyntaxNodeStructureProvider(Of CollectionInitializerSyntax)
Protected Overrides Sub CollectBlockSpans(node As CollectionInitializerSyntax,
spans As ArrayBuilder(Of BlockSpan),
cancellationToken As CancellationToken)
' We don't want to make a span for the "{ ... }" in "From { ... }". The latter
' is already handled by ObjectCreationInitializerStructureProvider
If TypeOf node.Parent IsNot ObjectCollectionInitializerSyntax Then
' We have something Like:
'
' New Dictionary(Of int, string) From {
' ...
' {
' ...
' },
' ...
' }
'
' In this case, we want to collapse the "{ ... }," (including the comma).
Dim nextToken = node.CloseBraceToken.GetNextToken()
Dim endPos = If(nextToken.Kind() = SyntaxKind.CommaToken,
nextToken.Span.End,
node.Span.End)
spans.Add(New BlockSpan(
isCollapsible:=True,
textSpan:=TextSpan.FromBounds(node.SpanStart, endPos),
hintSpan:=TextSpan.FromBounds(node.SpanStart, endPos),
type:=BlockTypes.Expression))
End If
End Sub
End Class
End Namespace
\ No newline at end of file
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Threading
Imports Microsoft.CodeAnalysis.Structure
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic.Structure
Friend Class ObjectCreationInitializerStructureProvider
Inherits AbstractSyntaxNodeStructureProvider(Of ObjectCreationInitializerSyntax)
Protected Overrides Sub CollectBlockSpans(node As ObjectCreationInitializerSyntax,
spans As ArrayBuilder(Of BlockSpan),
cancellationToken As CancellationToken)
' ObjectCreationInitializerSyntax is either "With { ... }" or "From { ... }"
' Parent Is something Like
'
' New Dictionary(Of int, string) From {
' ...
' }
'
' The collapsed textspan should be from the ) to the }
'
' However, the hint span should be the entire object creation.
Dim previousToken = node.GetFirstToken().GetPreviousToken()
spans.Add(New BlockSpan(
isCollapsible:=True,
textSpan:=TextSpan.FromBounds(previousToken.Span.End, node.Span.End),
hintSpan:=node.Parent.Span,
type:=BlockTypes.Expression))
End Sub
End Class
End Namespace
\ No newline at end of file
......@@ -43,6 +43,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure
builder.Add(Of AccessorStatementSyntax, AccessorDeclarationStructureProvider)()
builder.Add(Of ClassStatementSyntax, TypeDeclarationStructureProvider, MetadataAsSource.MetadataTypeDeclarationStructureProvider)()
builder.Add(Of CollectionInitializerSyntax, CollectionInitializerStructureProvider)
builder.Add(Of CompilationUnitSyntax, CompilationUnitStructureProvider)()
builder.Add(Of SubNewStatementSyntax, ConstructorDeclarationStructureProvider, MetadataAsSource.MetadataConstructorDeclarationStructureProvider)()
builder.Add(Of DelegateStatementSyntax, DelegateDeclarationStructureProvider, MetadataAsSource.MetadataDelegateDeclarationStructureProvider)()
......@@ -61,6 +62,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure
builder.Add(Of MultiLineIfBlockSyntax, MultiLineIfBlockStructureProvider)()
builder.Add(Of MultiLineLambdaExpressionSyntax, MultilineLambdaStructureProvider)()
builder.Add(Of NamespaceStatementSyntax, NamespaceDeclarationStructureProvider)()
builder.Add(Of ObjectCollectionInitializerSyntax, ObjectCreationInitializerStructureProvider)
builder.Add(Of ObjectMemberInitializerSyntax, ObjectCreationInitializerStructureProvider)
builder.Add(Of OperatorStatementSyntax, OperatorDeclarationStructureProvider, MetadataAsSource.MetadataOperatorDeclarationStructureProvider)()
builder.Add(Of PropertyStatementSyntax, PropertyDeclarationStructureProvider, MetadataAsSource.MetadataPropertyDeclarationStructureProvider)()
builder.Add(Of RegionDirectiveTriviaSyntax, RegionDirectiveStructureProvider, MetadataAsSource.MetadataRegionDirectiveStructureProvider)()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册