Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Structure;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Structure;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Structure;

[Trait(Traits.Feature, Traits.Features.Outlining)]
public sealed class ParameterListSyntaxStructureTests : AbstractCSharpSyntaxNodeStructureTests<ParameterListSyntax>
{
internal override AbstractSyntaxStructureProvider CreateProvider() => new ParameterListStructureProvider();

[Fact]
public Task TestMethodDeclarationSingleLine()
=> VerifyBlockSpansAsync("""
void M$$()
{
}
""");

[Fact]
public Task TestMethodDeclarationTwoParametersInTwoLines()
=> VerifyBlockSpansAsync("""
void M$$(string a,
string b)
{
}
""");

[Fact]
public Task TestMethodDeclarationThreeLines()
=> VerifyBlockSpansAsync("""
void M$${|span:(
string a,
string b)|}
{
}
""",
Region("span", CSharpStructureHelpers.Ellipsis, autoCollapse: false));

[Fact]
public Task TestConstructorDeclarationSingleLine()
=> VerifyBlockSpansAsync("""
class C
{
C$$() { }
}
""");

[Fact]
public Task TestConstructorDeclarationThreeLines()
=> VerifyBlockSpansAsync("""
class C
{
C$${|span:(
string a,
string b)|} { }
}
""",
Region("span", CSharpStructureHelpers.Ellipsis, autoCollapse: false));

[Fact]
public Task TestDelegateDeclarationSingleLine()
=> VerifyBlockSpansAsync("""
delegate void D$$();
""");

[Fact]
public Task TestDelegateDeclarationThreeLines()
=> VerifyBlockSpansAsync("""
delegate void D$${|span:(
string a,
string b)|};
""",
Region("span", CSharpStructureHelpers.Ellipsis, autoCollapse: false));

[Fact]
public Task TestLambdaExpressionSingleLine()
=> VerifyBlockSpansAsync("""
var x = $$() => { };
""");

[Fact]
public Task TestLambdaExpressionThreeLines()
=> VerifyBlockSpansAsync("""
var x = $${|span:(
string a,
string b)|} => { };
""",
Region("span", CSharpStructureHelpers.Ellipsis, autoCollapse: false));

[Fact]
public Task TestAnonymousMethodSingleLine()
=> VerifyBlockSpansAsync("""
var x = delegate$$() { };
""");

[Fact]
public Task TestAnonymousMethodThreeLines()
=> VerifyBlockSpansAsync("""
var x = delegate$${|span:(
string a,
string b)|} { };
""",
Region("span", CSharpStructureHelpers.Ellipsis, autoCollapse: false));

[Fact]
public Task TestLocalFunctionSingleLine()
=> VerifyBlockSpansAsync("""
void M()
{
void LocalFunction$$() { }
}
""");

[Fact]
public Task TestLocalFunctionThreeLines()
=> VerifyBlockSpansAsync("""
void M()
{
void LocalFunction$${|span:(
string a,
string b)|} { }
}
""",
Region("span", CSharpStructureHelpers.Ellipsis, autoCollapse: false));
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ private static ImmutableDictionary<Type, ImmutableArray<AbstractSyntaxStructureP
builder.Add<IfDirectiveTriviaSyntax, IfDirectiveTriviaStructureProvider>();
builder.Add<CollectionExpressionSyntax, CollectionExpressionStructureProvider>();
builder.Add<ArgumentListSyntax, ArgumentListStructureProvider>();
builder.Add<ParameterListSyntax, ParameterListStructureProvider>();

return builder.ToImmutable();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Structure;

namespace Microsoft.CodeAnalysis.CSharp.Structure;

internal sealed class ParameterListStructureProvider : AbstractSyntaxNodeStructureProvider<ParameterListSyntax>
{
protected override void CollectBlockSpans(SyntaxToken previousToken, ParameterListSyntax node, ArrayBuilder<BlockSpan> spans, BlockStructureOptions options, CancellationToken cancellationToken)
{
if (!IsCandidate(node, cancellationToken))
{
return;
}

spans.Add(new BlockSpan(
type: BlockTypes.Expression,
isCollapsible: true,
node.Span));
}

private static bool IsCandidate(ParameterListSyntax node, CancellationToken cancellationToken)
{
var openToken = node.OpenParenToken;
var closeToken = node.CloseParenToken;
if (openToken.IsMissing || closeToken.IsMissing)
{
return false;
}

var text = node.SyntaxTree.GetText(cancellationToken);
var start = text.Lines.GetLinePosition(openToken.SpanStart).Line;
var end = text.Lines.GetLinePosition(closeToken.SpanStart).Line;
return end - start >= 2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chatted offline about the >= 2 and it matches the behavior of the argument list provider.

}
}
Loading