未验证 提交 aa10efe4 编写于 作者: A Andrew Hall 提交者: GitHub

Merge pull request #33177 from ryzngard/issue/31377_movetype_extra_comment

Expand RemoveAllComments to have more in depth logic and handle more corner cases in csharp
......@@ -1172,5 +1172,216 @@ void Foo()
await TestMoveTypeToNewFileAsync(
code, codeAfterMove, expectedDocumentName, destinationDocumentText);
}
[WorkItem(31377, "https://github.com/dotnet/roslyn/issues/31377")]
[WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsMoveType)]
public async Task TestLeadingCommentInContainer()
{
var code =
@"// Banner Text
using System;
class Class1
// Leading comment
{
class [||]Class2
{
}
void Foo()
{
Console.WriteLine();
}
public int I() => 5;
}
";
var codeAfterMove = @"// Banner Text
using System;
partial class Class1
// Leading comment
{
void Foo()
{
Console.WriteLine();
}
public int I() => 5;
}
";
var expectedDocumentName = "Class2.cs";
var destinationDocumentText = @"// Banner Text
partial class Class1
{
class Class2
{
}
}
";
await TestMoveTypeToNewFileAsync(
code, codeAfterMove, expectedDocumentName, destinationDocumentText);
}
[WorkItem(31377, "https://github.com/dotnet/roslyn/issues/31377")]
[WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsMoveType)]
public async Task TestLeadingCommentInContainer2()
{
var code =
@"// Banner Text
using System;
class Class1
{ // Leading comment
class [||]Class2
{
}
void Foo()
{
Console.WriteLine();
}
public int I() => 5;
}
";
var codeAfterMove = @"// Banner Text
using System;
partial class Class1
{ // Leading comment
void Foo()
{
Console.WriteLine();
}
public int I() => 5;
}
";
var expectedDocumentName = "Class2.cs";
var destinationDocumentText = @"// Banner Text
partial class Class1
{
class Class2
{
}
}
";
await TestMoveTypeToNewFileAsync(
code, codeAfterMove, expectedDocumentName, destinationDocumentText);
}
[WorkItem(31377, "https://github.com/dotnet/roslyn/issues/31377")]
[WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsMoveType)]
public async Task TestTrailingCommentInContainer()
{
var code =
@"// Banner Text
using System;
class Class1
{
class [||]Class2
{
}
void Foo()
{
Console.WriteLine();
}
public int I() => 5;
// End of class document
}
";
var codeAfterMove = @"// Banner Text
using System;
partial class Class1
{
void Foo()
{
Console.WriteLine();
}
public int I() => 5;
// End of class document
}
";
var expectedDocumentName = "Class2.cs";
var destinationDocumentText = @"// Banner Text
partial class Class1
{
class Class2
{
}
}
";
await TestMoveTypeToNewFileAsync(
code, codeAfterMove, expectedDocumentName, destinationDocumentText);
}
[WorkItem(31377, "https://github.com/dotnet/roslyn/issues/31377")]
[WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsMoveType)]
public async Task TestTrailingCommentInContainer2()
{
var code =
@"// Banner Text
using System;
class Class1
{
class [||]Class2
{
}
void Foo()
{
Console.WriteLine();
}
public int I() => 5;
} // End of class document
";
var codeAfterMove = @"// Banner Text
using System;
partial class Class1
{
void Foo()
{
Console.WriteLine();
}
public int I() => 5;
} // End of class document
";
var expectedDocumentName = "Class2.cs";
var destinationDocumentText = @"// Banner Text
partial class Class1
{
class Class2
{
}
}";
await TestMoveTypeToNewFileAsync(
code, codeAfterMove, expectedDocumentName, destinationDocumentText);
}
}
}
......@@ -4266,6 +4266,45 @@ internal override SyntaxNode RefExpression(SyntaxNode expression)
public override SyntaxNode TupleExpression(IEnumerable<SyntaxNode> arguments)
=> SyntaxFactory.TupleExpression(SyntaxFactory.SeparatedList(arguments.Select(AsArgument)));
internal override SyntaxNode RemoveAllComments(SyntaxNode node)
{
var modifiedNode = RemoveLeadingAndTrailingComments(node);
if (modifiedNode is TypeDeclarationSyntax declarationSyntax)
{
return declarationSyntax.WithOpenBraceToken(RemoveLeadingAndTrailingComments(declarationSyntax.OpenBraceToken))
.WithCloseBraceToken(RemoveLeadingAndTrailingComments(declarationSyntax.CloseBraceToken));
}
return modifiedNode;
}
internal override SyntaxTriviaList RemoveCommentLines(SyntaxTriviaList syntaxTriviaList)
{
IEnumerable<IEnumerable<SyntaxTrivia>> splitIntoLines(SyntaxTriviaList triviaList)
{
int index = 0;
for (int i = 0; i < triviaList.Count; i++)
{
if (triviaList[i].IsEndOfLine())
{
yield return triviaList.TakeRange(index, i);
index = i + 1;
}
}
if (index < triviaList.Count)
{
yield return triviaList.TakeRange(index, triviaList.Count - 1);
}
}
var syntaxWithoutComments = splitIntoLines(syntaxTriviaList)
.Where(trivia => !trivia.Any(t => t.IsRegularOrDocComment()))
.SelectMany(t => t);
return new SyntaxTriviaList(syntaxWithoutComments);
}
#endregion
#region Patterns
......
......@@ -46,5 +46,16 @@ public static IEnumerable<SyntaxTrivia> SkipInitialWhitespace(this SyntaxTriviaL
{
return triviaList.SkipWhile(t => t.Kind() == SyntaxKind.WhitespaceTrivia);
}
/// <summary>
/// Takes an INCLUSIVE range of trivia from the trivia list.
/// </summary>
public static IEnumerable<SyntaxTrivia> TakeRange(this SyntaxTriviaList triviaList, int start, int end)
{
while (start <= end)
{
yield return triviaList[start++];
}
}
}
}
......@@ -864,12 +864,26 @@ public SyntaxNode AttributeArgument(SyntaxNode expression)
public SyntaxNode RemoveAllAttributes(SyntaxNode declaration)
=> this.RemoveNodes(declaration, this.GetAttributes(declaration).Concat(this.GetReturnAttributes(declaration)));
internal SyntaxNode RemoveAllComments(SyntaxNode declaration)
/// <summary>
/// Removes comments from leading and trailing trivia, as well
/// as potentially removing comments from opening and closing tokens.
/// </summary>
internal abstract SyntaxNode RemoveAllComments(SyntaxNode node);
internal SyntaxNode RemoveLeadingAndTrailingComments(SyntaxNode node)
{
return declaration.WithLeadingTrivia(declaration.GetLeadingTrivia().Where(t => !IsRegularOrDocComment(t)))
.WithTrailingTrivia(declaration.GetTrailingTrivia().Where(t => !IsRegularOrDocComment(t)));
return node.WithLeadingTrivia(RemoveCommentLines(node.GetLeadingTrivia()))
.WithTrailingTrivia(RemoveCommentLines(node.GetTrailingTrivia()));
}
internal SyntaxToken RemoveLeadingAndTrailingComments(SyntaxToken token)
{
return token.WithLeadingTrivia(RemoveCommentLines(token.LeadingTrivia))
.WithTrailingTrivia(RemoveCommentLines(token.TrailingTrivia));
}
internal abstract SyntaxTriviaList RemoveCommentLines(SyntaxTriviaList syntaxTriviaList);
internal abstract bool IsRegularOrDocComment(SyntaxTrivia trivia);
internal SyntaxNode RemoveAllTypeInheritance(SyntaxNode declaration)
......
......@@ -4170,6 +4170,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
Return trivia.IsRegularOrDocComment()
End Function
Friend Overrides Function RemoveAllComments(node As SyntaxNode) As SyntaxNode
Return RemoveLeadingAndTrailingComments(node)
End Function
Friend Overrides Function RemoveCommentLines(syntaxList As SyntaxTriviaList) As SyntaxTriviaList
Return syntaxList.Where(Function(s) Not IsRegularOrDocComment(s)).ToSyntaxTriviaList()
End Function
#End Region
#Region "Patterns"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册