Skip to content

Commit

Permalink
Merge pull request #53052 from Youssef1313/records-xml-doc-ide
Browse files Browse the repository at this point in the history
Add records support to XmlDocCommentCompletion and ChangeSignature
  • Loading branch information
CyrusNajmabadi authored Jul 12, 2021
2 parents ce3a20e + 327b8e2 commit 0049504
Show file tree
Hide file tree
Showing 16 changed files with 306 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using Microsoft.CodeAnalysis.Editor.UnitTests.ChangeSignature;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities.ChangeSignature;
using Roslyn.Test.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature
Expand Down Expand Up @@ -412,5 +411,26 @@ public override int M(string x, int newIntegerParameter, int y)
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}

[Fact(Skip = "https://github.com/dotnet/roslyn/issues/53091"), Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task AddParameter_Cascade_Record()
{
var markup = @"
record $$BaseR(int A, int B);
record DerivedR() : BaseR(0, 1);";
var permutation = new AddedParameterOrExistingIndex[]
{
new(1),
new(new AddedParameter(null, "int", "C", CallSiteKind.Value, "3"), "int"),
new(0)
};
var updatedCode = @"
record BaseR(int B, int C, int A);
record DerivedR() : BaseR(1, 3, 0);";

await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
}
}
34 changes: 34 additions & 0 deletions src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1261,5 +1261,39 @@ public void M()
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}

[Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
[WorkItem(44558, "https://github.com/dotnet/roslyn/issues/44558")]
public async Task AddParameters_Record()
{
var markup = @"
/// <param name=""First""></param>
/// <param name=""Second""></param>
/// <param name=""Third""></param>
record $$R(int First, int Second, int Third)
{
static R M() => new R(1, 2, 3);
}
";
var updatedSignature = new AddedParameterOrExistingIndex[]
{
new(0),
new(2),
new(1),
new(new AddedParameter(null, "int", "Forth", CallSiteKind.Value, "12345"), "System.Int32")
};
var updatedCode = @"
/// <param name=""First""></param>
/// <param name=""Third""></param>
/// <param name=""Second""></param>
/// <param name=""Forth""></param>
record R(int First, int Third, int Second, int Forth)
{
static R M() => new R(1, 3, 2, 12345);
}
";

await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -951,5 +951,29 @@ class D : C, I

await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}

[Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task ReorderParamTagsInDocComments_Record()
{
var markup = @"
/// <param name=""A""></param>
/// <param name=""B""></param>
/// <param name=""C""></param>
record $$R(int A, int B, int C)
{
public static R Instance = new(0, 1, 2);
}";
var permutation = new[] { 2, 1, 0 };
var updatedCode = @"
/// <param name=""C""></param>
/// <param name=""B""></param>
/// <param name=""A""></param>
record R(int C, int B, int A)
{
public static R Instance = new(2, 1, 0);
}";

await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1012,5 +1012,27 @@ static void Goo()
await VerifyItemExistsAsync(text, "term");
await VerifyItemExistsAsync(text, "description");
}

[WorkItem(52738, "https://github.com/dotnet/roslyn/issues/52738")]
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task RecordParam()
{
await VerifyItemsExistAsync(@"
/// $$
public record Goo<T>(string MyParameter);
", "param name=\"MyParameter\"", "typeparam name=\"T\"");
}

[WorkItem(52738, "https://github.com/dotnet/roslyn/issues/52738")]
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task RecordParamRef()
{
await VerifyItemsExistAsync(@"
/// <summary>
/// $$
/// <summary>
public record Goo<T>(string MyParameter);
", "paramref name=\"MyParameter\"", "typeparamref name=\"T\"");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -785,5 +786,29 @@ public void Fizz(int i, int j, int k) {}

await TestAsync(initial, expected);
}

[WorkItem(52738, "https://github.com/dotnet/roslyn/issues/52738")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)]
public async Task AddsParamTag_Record()
{
var initial = @"
/// <summary>
///
/// </summary>
/// <param name=""Second""></param>
record R(int [|First|], int Second, int Third);
";

var expected = @"
/// <summary>
///
/// </summary>
/// <param name=""First""></param>
/// <param name=""Second""></param>
/// <param name=""Third""></param>
record R(int First, int Second, int Third);
";
await TestAsync(initial, expected);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,25 @@ class c<T>
End Using
End Function

<WpfTheory, CombinatorialData, Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function CommitParam_Record(showCompletionInArgumentLists As Boolean) As Task
Using state = TestStateFactory.CreateCSharpTestState(
<Document><![CDATA[
/// <param$$
record R(int I);
]]></Document>, showCompletionInArgumentLists:=showCompletionInArgumentLists)

state.SendInvokeCompletionList()
Await state.AssertCompletionSession()
Await state.AssertSelectedCompletionItem(displayText:="param name=""I""")
state.SendReturn()
Await state.AssertNoCompletionSession()

' /// <param name="I"$$
Await state.AssertLineTextAroundCaret("/// <param name=""I""", "")
End Using
End Function

<WpfTheory, CombinatorialData, Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function CommitParamNoOpenAngle(showCompletionInArgumentLists As Boolean) As Task

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -825,5 +825,36 @@ End Class]]></Text>.NormalizedValue()

Await TestChangeSignatureViaCommandAsync(LanguageNames.VisualBasic, markup, updatedSignature:=permutation, expectedUpdatedInvocationDocumentCode:=updatedCode)
End Function

<WorkItem(49941, "https://github.com/dotnet/roslyn/issues/49941")>
<Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)>
Public Async Function TestAddParameter_NoLastWhitespaceTrivia() As Task

Dim markup = <Text><![CDATA[
Class C
''' <summary>
''' </summary>
''' <param name="a"></param>
Sub $$M(a As Integer)
End Sub
End Class]]></Text>.NormalizedValue()
Dim permutation =
{
New AddedParameterOrExistingIndex(0),
New AddedParameterOrExistingIndex(New AddedParameter(Nothing, "Integer", "b", CallSiteKind.Value), "Integer")
}

Dim updatedCode = <Text><![CDATA[
Class C
''' <summary>
''' </summary>
''' <param name="a"></param>
''' <param name="b"></param>
Sub M(a As Integer, b As Integer)
End Sub
End Class]]></Text>.NormalizedValue()

Await TestChangeSignatureViaCommandAsync(LanguageNames.VisualBasic, markup, updatedSignature:=permutation, expectedUpdatedInvocationDocumentCode:=updatedCode)
End Function
End Class
End Namespace
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Collections.Immutable;
using System.Composition;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -42,7 +43,9 @@ internal sealed class CSharpChangeSignatureService : AbstractChangeSignatureServ
SyntaxKind.DelegateDeclaration,
SyntaxKind.SimpleLambdaExpression,
SyntaxKind.ParenthesizedLambdaExpression,
SyntaxKind.LocalFunctionStatement);
SyntaxKind.LocalFunctionStatement,
SyntaxKind.RecordStructDeclaration,
SyntaxKind.RecordDeclaration);

private static readonly ImmutableArray<SyntaxKind> _declarationAndInvocableKinds =
_declarationKinds.Concat(ImmutableArray.Create(
Expand Down Expand Up @@ -85,7 +88,9 @@ internal sealed class CSharpChangeSignatureService : AbstractChangeSignatureServ
SyntaxKind.NameMemberCref,
SyntaxKind.AnonymousMethodExpression,
SyntaxKind.ParenthesizedLambdaExpression,
SyntaxKind.SimpleLambdaExpression);
SyntaxKind.SimpleLambdaExpression,
SyntaxKind.RecordStructDeclaration,
SyntaxKind.RecordDeclaration);

[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
Expand Down Expand Up @@ -270,7 +275,9 @@ public override async Task<SyntaxNode> ChangeSignatureAsync(
if (updatedNode.IsKind(SyntaxKind.MethodDeclaration) ||
updatedNode.IsKind(SyntaxKind.ConstructorDeclaration) ||
updatedNode.IsKind(SyntaxKind.IndexerDeclaration) ||
updatedNode.IsKind(SyntaxKind.DelegateDeclaration))
updatedNode.IsKind(SyntaxKind.DelegateDeclaration) ||
updatedNode.IsKind(SyntaxKind.RecordStructDeclaration) ||
updatedNode.IsKind(SyntaxKind.RecordDeclaration))
{
var updatedLeadingTrivia = UpdateParamTagsInLeadingTrivia(document, updatedNode, declarationSymbol, signaturePermutation);
if (updatedLeadingTrivia != default && !updatedLeadingTrivia.IsEmpty)
Expand All @@ -286,6 +293,12 @@ public override async Task<SyntaxNode> ChangeSignatureAsync(
return method.WithParameterList(method.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
}

if (updatedNode is RecordDeclarationSyntax { ParameterList: not null } record)
{
var updatedParameters = UpdateDeclaration(record.ParameterList.Parameters, signaturePermutation, CreateNewParameterSyntax);
return record.WithParameterList(record.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
}

if (updatedNode.IsKind(SyntaxKind.LocalFunctionStatement, out LocalFunctionStatementSyntax? localFunction))
{
var updatedParameters = UpdateDeclaration(localFunction.ParameterList.Parameters, signaturePermutation, CreateNewParameterSyntax);
Expand Down Expand Up @@ -745,13 +758,14 @@ private ImmutableArray<SyntaxTrivia> UpdateParamTagsInLeadingTrivia(Document doc
return GetPermutedDocCommentTrivia(document, node, permutedParamNodes);
}

private static ImmutableArray<SyntaxNode> VerifyAndPermuteParamNodes(IEnumerable<XmlElementSyntax> paramNodes, ISymbol declarationSymbol, SignatureChange updatedSignature)
private ImmutableArray<SyntaxNode> VerifyAndPermuteParamNodes(IEnumerable<XmlElementSyntax> paramNodes, ISymbol declarationSymbol, SignatureChange updatedSignature)
{
// Only reorder if count and order match originally.
var originalParameters = updatedSignature.OriginalConfiguration.ToListOfParameters();
var reorderedParameters = updatedSignature.UpdatedConfiguration.ToListOfParameters();

var declaredParameters = declarationSymbol.GetParameters();
var declaredParameters = GetParameters(declarationSymbol);

if (paramNodes.Count() != declaredParameters.Length)
{
return ImmutableArray<SyntaxNode>.Empty;
Expand Down Expand Up @@ -875,5 +889,20 @@ protected override bool SupportsOptionalAndParamsArrayParametersSimultaneously()

protected override SyntaxToken CommaTokenWithElasticSpace()
=> Token(SyntaxKind.CommaToken).WithTrailingTrivia(ElasticSpace);

protected override bool TryGetRecordPrimaryConstructor(INamedTypeSymbol typeSymbol, [NotNullWhen(true)] out IMethodSymbol? primaryConstructor)
=> typeSymbol.TryGetRecordPrimaryConstructor(out primaryConstructor);

protected override ImmutableArray<IParameterSymbol> GetParameters(ISymbol declarationSymbol)
{
var declaredParameters = declarationSymbol.GetParameters();
if (declarationSymbol is INamedTypeSymbol namedTypeSymbol &&
namedTypeSymbol.TryGetRecordPrimaryConstructor(out var primaryConstructor))
{
declaredParameters = primaryConstructor.Parameters;
}

return declaredParameters;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -365,6 +366,18 @@ private string GetAttributeValue(XmlAttributeSyntax attribute)
}
}

protected override ImmutableArray<IParameterSymbol> GetParameters(ISymbol declarationSymbol)
{
var declaredParameters = declarationSymbol.GetParameters();
if (declarationSymbol is INamedTypeSymbol namedTypeSymbol &&
namedTypeSymbol.TryGetRecordPrimaryConstructor(out var primaryConstructor))
{
declaredParameters = primaryConstructor.Parameters;
}

return declaredParameters;
}

private static readonly CompletionItemRules s_defaultRules =
CompletionItemRules.Create(
filterCharacterRules: FilterRules,
Expand Down
Loading

0 comments on commit 0049504

Please sign in to comment.