提交 fe82d0db 编写于 作者: C CyrusNajmabadi 提交者: GitHub

Merge pull request #14562 from CyrusNajmabadi/triviaMoveType

Remove comments when moving a type.
Fixes #14484
...@@ -373,6 +373,50 @@ class Class2 ...@@ -373,6 +373,50 @@ class Class2
await TestMoveTypeToNewFileAsync(code, codeAfterMove, expectedDocumentName, destinationDocumentText); await TestMoveTypeToNewFileAsync(code, codeAfterMove, expectedDocumentName, destinationDocumentText);
} }
[WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsMoveType)]
[WorkItem(14484, "https://github.com/dotnet/roslyn/issues/14484")]
public async Task MoveNestedTypeToNewFile_Comments1()
{
var code =
@"namespace N1
{
/// Outer doc comment.
class Class1
{
/// Inner doc comment
[||]class Class2
{
}
}
}";
var codeAfterMove =
@"namespace N1
{
/// Outer doc comment.
partial class Class1
{
}
}";
var expectedDocumentName = "Class2.cs";
var destinationDocumentText =
@"namespace N1
{
partial class Class1
{
/// Inner doc comment
class Class2
{
}
}
}";
await TestMoveTypeToNewFileAsync(
code, codeAfterMove, expectedDocumentName, destinationDocumentText,
compareTokens: false);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsMoveType)] [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsMoveType)]
public async Task MoveNestedTypeToNewFile_Simple_DottedName() public async Task MoveNestedTypeToNewFile_Simple_DottedName()
{ {
......
...@@ -106,5 +106,38 @@ End Class ...@@ -106,5 +106,38 @@ End Class
</File> </File>
Await TestMoveTypeToNewFileAsync(code, codeAfterMove, expectedDocumentName, destinationDocumentText, index:=1) Await TestMoveTypeToNewFileAsync(code, codeAfterMove, expectedDocumentName, destinationDocumentText, index:=1)
End Function End Function
<WorkItem(14484, "https://github.com/dotnet/roslyn/issues/14484")>
<WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsMoveType)>
Public Async Function MoveNestedTypeToNewFile_RemoveComments() As Task
Dim code =
<File>
''' Outer comment
Public Class Class1
''' Inner comment
Class Class2[||]
End Class
End Class
</File>
Dim codeAfterMove =
<File>
''' Outer comment
Public Partial Class Class1
End Class
</File>
Dim expectedDocumentName = "Class1.Class2.vb"
Dim destinationDocumentText =
<File>
Public Partial Class Class1
''' Inner comment
Class Class2
End Class
End Class
</File>
Await TestMoveTypeToNewFileAsync(
code, codeAfterMove, expectedDocumentName, destinationDocumentText,
index:=1, compareTokens:=False)
End Function
End Class End Class
End Namespace End Namespace
...@@ -83,7 +83,7 @@ internal override async Task<ImmutableArray<CodeActionOperation>> GetOperationsA ...@@ -83,7 +83,7 @@ internal override async Task<ImmutableArray<CodeActionOperation>> GetOperationsA
// Make the type chain above this new type partial. Also, remove any // Make the type chain above this new type partial. Also, remove any
// attributes from the containing partial types. We don't want to create // attributes from the containing partial types. We don't want to create
// duplicate attributes on things. // duplicate attributes on things.
AddPartialModifiersToTypeChain(documentEditor, removeAttributes: true); AddPartialModifiersToTypeChain(documentEditor, removeAttributesAndComments: true);
// remove things that are not being moved, from the forked document. // remove things that are not being moved, from the forked document.
var membersToRemove = GetMembersToRemove(root); var membersToRemove = GetMembersToRemove(root);
...@@ -121,7 +121,7 @@ private async Task<Solution> RemoveTypeFromSourceDocumentAsync(Document sourceDo ...@@ -121,7 +121,7 @@ private async Task<Solution> RemoveTypeFromSourceDocumentAsync(Document sourceDo
// Make the type chain above the type we're moving 'partial'. // Make the type chain above the type we're moving 'partial'.
// However, keep all the attributes on these types as theses are the // However, keep all the attributes on these types as theses are the
// original attributes and we don't want to mess with them. // original attributes and we don't want to mess with them.
AddPartialModifiersToTypeChain(documentEditor, removeAttributes: false); AddPartialModifiersToTypeChain(documentEditor, removeAttributesAndComments: false);
documentEditor.RemoveNode(State.TypeNode, SyntaxRemoveOptions.KeepNoTrivia); documentEditor.RemoveNode(State.TypeNode, SyntaxRemoveOptions.KeepNoTrivia);
var updatedDocument = documentEditor.GetChangedDocument(); var updatedDocument = documentEditor.GetChangedDocument();
...@@ -186,7 +186,7 @@ private static bool FilterToTopLevelMembers(SyntaxNode node, SyntaxNode typeNode ...@@ -186,7 +186,7 @@ private static bool FilterToTopLevelMembers(SyntaxNode node, SyntaxNode typeNode
/// if a nested type is being moved, this ensures its containing type is partial. /// if a nested type is being moved, this ensures its containing type is partial.
/// </summary> /// </summary>
private void AddPartialModifiersToTypeChain( private void AddPartialModifiersToTypeChain(
DocumentEditor documentEditor, bool removeAttributes) DocumentEditor documentEditor, bool removeAttributesAndComments)
{ {
var semanticFacts = State.SemanticDocument.Document.GetLanguageService<ISemanticFactsService>(); var semanticFacts = State.SemanticDocument.Document.GetLanguageService<ISemanticFactsService>();
var typeChain = State.TypeNode.Ancestors().OfType<TTypeDeclarationSyntax>(); var typeChain = State.TypeNode.Ancestors().OfType<TTypeDeclarationSyntax>();
...@@ -199,9 +199,10 @@ private static bool FilterToTopLevelMembers(SyntaxNode node, SyntaxNode typeNode ...@@ -199,9 +199,10 @@ private static bool FilterToTopLevelMembers(SyntaxNode node, SyntaxNode typeNode
documentEditor.SetModifiers(node, DeclarationModifiers.Partial); documentEditor.SetModifiers(node, DeclarationModifiers.Partial);
} }
if (removeAttributes) if (removeAttributesAndComments)
{ {
documentEditor.RemoveAllAttributes(node); documentEditor.RemoveAllAttributes(node);
documentEditor.RemoveAllComments(node);
} }
} }
} }
......
...@@ -3452,6 +3452,10 @@ private SyntaxNode ShiftTrivia(SyntaxNode root, SyntaxNode node) ...@@ -3452,6 +3452,10 @@ private SyntaxNode ShiftTrivia(SyntaxNode root, SyntaxNode node)
return root; return root;
} }
internal override bool IsRegularOrDocComment(SyntaxTrivia trivia)
=> trivia.IsRegularOrDocComment();
#endregion #endregion
#region Statements and Expressions #region Statements and Expressions
......
...@@ -21,6 +21,11 @@ internal static void RemoveAllAttributes(this SyntaxEditor editor, SyntaxNode de ...@@ -21,6 +21,11 @@ internal static void RemoveAllAttributes(this SyntaxEditor editor, SyntaxNode de
editor.ReplaceNode(declaration, (d, g) => g.RemoveAllAttributes(d)); editor.ReplaceNode(declaration, (d, g) => g.RemoveAllAttributes(d));
} }
internal static void RemoveAllComments(this SyntaxEditor editor, SyntaxNode declaration)
{
editor.ReplaceNode(declaration, (d, g) => g.RemoveAllComments(d));
}
public static void SetName(this SyntaxEditor editor, SyntaxNode declaration, string name) public static void SetName(this SyntaxEditor editor, SyntaxNode declaration, string name)
{ {
editor.ReplaceNode(declaration, (d, g) => g.WithName(d, name)); editor.ReplaceNode(declaration, (d, g) => g.WithName(d, name));
......
...@@ -802,6 +802,14 @@ public SyntaxNode RemoveAllAttributes(SyntaxNode declaration) ...@@ -802,6 +802,14 @@ public SyntaxNode RemoveAllAttributes(SyntaxNode declaration)
return this.RemoveNodes(declaration, this.GetAttributes(declaration).Concat(this.GetReturnAttributes(declaration))); return this.RemoveNodes(declaration, this.GetAttributes(declaration).Concat(this.GetReturnAttributes(declaration)));
} }
internal SyntaxNode RemoveAllComments(SyntaxNode declaration)
{
return declaration.WithLeadingTrivia(declaration.GetLeadingTrivia().Where(t => !IsRegularOrDocComment(t)))
.WithTrailingTrivia(declaration.GetTrailingTrivia().Where(t => !IsRegularOrDocComment(t)));
}
internal abstract bool IsRegularOrDocComment(SyntaxTrivia trivia);
/// <summary> /// <summary>
/// Gets the attributes of a declaration, not including the return attributes. /// Gets the attributes of a declaration, not including the return attributes.
/// </summary> /// </summary>
......
...@@ -3878,6 +3878,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration ...@@ -3878,6 +3878,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
DirectCast(expression, ExpressionSyntax)) DirectCast(expression, ExpressionSyntax))
End Function End Function
Friend Overrides Function IsRegularOrDocComment(trivia As SyntaxTrivia) As Boolean
Return trivia.IsRegularOrDocComment()
End Function
#End Region #End Region
End Class End Class
......
...@@ -22,5 +22,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions ...@@ -22,5 +22,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
Return trivia.Kind = SyntaxKind.WhitespaceTrivia OrElse Return trivia.Kind = SyntaxKind.WhitespaceTrivia OrElse
trivia.Kind = SyntaxKind.EndOfLineTrivia trivia.Kind = SyntaxKind.EndOfLineTrivia
End Function End Function
<Extension>
Public Function IsRegularOrDocComment(trivia As SyntaxTrivia) As Boolean
Return trivia.Kind = SyntaxKind.CommentTrivia OrElse trivia.Kind = SyntaxKind.DocumentationCommentTrivia
End Function
End Module End Module
End Namespace End Namespace
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册