提交 3945c7ee 编写于 作者: S Shyam N

Merge pull request #1914 from...

Merge pull request #1914 from shyamnamboodiripad/SimplifierAnnotationForImplementInterfaceThruMember

Add simplifier annotation to cast expressions generated using syntax generator.

This ensures that code fixes such as Implement Interface Through Member never generate casts that user has to simplify in a subsequent manual step.

Fixes #472
......@@ -3,12 +3,12 @@
using System;
using System.Linq;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.CodeFixes.ImplementInterface;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Roslyn.Test.Utilities;
using Xunit;
using Microsoft.CodeAnalysis.CSharp;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.ImplementInterface
{
......@@ -141,6 +141,26 @@ public void TestImplementThroughFieldMemberInterfaceWithIndexer()
index: 1);
}
[WorkItem(472, "https://github.com/dotnet/roslyn/issues/472")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)]
public void TestImplementThroughFieldMemberRemoveUnnecessaryCast()
{
Test(
@"using System.Collections; sealed class X : [|IComparer|] { X x; }",
@"using System.Collections; sealed class X : IComparer { X x; public int Compare(object x, object y) { return this.x.Compare(x, y); } }",
index: 1);
}
[WorkItem(472, "https://github.com/dotnet/roslyn/issues/472")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)]
public void TestImplementThroughFieldMemberRemoveUnnecessaryCastAndThis()
{
Test(
@"using System.Collections; sealed class X : [|IComparer|] { X a; }",
@"using System.Collections; sealed class X : IComparer { X a; public int Compare(object x, object y) { return a.Compare(x, y); } }",
index: 1);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)]
public void TestImplementAbstract()
{
......
......@@ -51,7 +51,7 @@ End Class
Class C
Implements I
Public Sub Foo(Optional x As E = CType(1, E)) Implements I.Foo
Public Sub Foo(Optional x As E = 1) Implements I.Foo
Throw New NotImplementedException()
End Sub
End Class
......@@ -93,7 +93,7 @@ End Class
Class C
Implements I
Public Sub Foo(Optional x As E = CType(1, E)) Implements I.Foo
Public Sub Foo(Optional x As E = 1) Implements I.Foo
Throw New NotImplementedException()
End Sub
End Class
......
......@@ -134,6 +134,48 @@ NewLines("Interface I \n Sub M() \n End Interface \n Class C \n Implements I \n
index:=1)
End Sub
<WorkItem(472, "https://github.com/dotnet/roslyn/issues/472")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)>
Public Sub TestImplementThroughFieldMemberRemoveUnnecessaryCast()
Test(
"Imports System.Collections
NotInheritable Class X : Implements [|IComparer|]
Private x As X
End Class",
"Imports System.Collections
NotInheritable Class X : Implements IComparer
Private x As X
Public Function Compare(x As Object, y As Object) As Integer Implements IComparer.Compare
Return Me.x.Compare(x, y)
End Function
End Class",
index:=1)
End Sub
<WorkItem(472, "https://github.com/dotnet/roslyn/issues/472")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)>
Public Sub TestImplementThroughFieldMemberRemoveUnnecessaryCastAndMe()
Test(
"Imports System.Collections
NotInheritable Class X : Implements [|IComparer|]
Private a As X
End Class",
"Imports System.Collections
NotInheritable Class X : Implements IComparer
Private a As X
Public Function Compare(x As Object, y As Object) As Integer Implements IComparer.Compare
Return a.Compare(x, y)
End Function
End Class",
index:=1)
End Sub
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)>
Public Sub TestImplementThroughFieldMemberInterfaceWithNonStandardProperties()
Dim source =
......@@ -868,6 +910,67 @@ Interface I
Sub M2(Optional e As FlagE = FlagE.A Or FlagE.B)
End Interface
Class C
Implements I
Public Sub M1(Optional e As E = 3) Implements I.M1
Throw New NotImplementedException()
End Sub
Public Sub M2(Optional e As FlagE = FlagE.A Or FlagE.B) Implements I.M2
Throw New NotImplementedException()
End Sub
End Class]]></Text>.Value.Replace(vbLf, vbCrLf),
compareTokens:=False)
End Sub
<WorkItem(715013)>
<Fact(), Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)>
Public Sub TestEnumParameters2()
Test(
<Text><![CDATA[
Option Strict On
Imports System
Enum E
A = 1
B = 2
End Enum
<FlagsAttribute>
Enum FlagE
A = 1
B = 2
End Enum
Interface I
Sub M1(Optional e As E = E.A Or E.B)
Sub M2(Optional e As FlagE = FlagE.A Or FlagE.B)
End Interface
Class C
Implements [|I|]
End Class]]></Text>.Value.Replace(vbLf, vbCrLf),
<Text><![CDATA[
Option Strict On
Imports System
Enum E
A = 1
B = 2
End Enum
<FlagsAttribute>
Enum FlagE
A = 1
B = 2
End Enum
Interface I
Sub M1(Optional e As E = E.A Or E.B)
Sub M2(Optional e As FlagE = FlagE.A Or FlagE.B)
End Interface
Class C
Implements I
......
......@@ -5,15 +5,11 @@
using System.Composition;
using System.Linq;
using System.Runtime.CompilerServices;
using Microsoft.CodeAnalysis.CodeGeneration;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Simplification;
using Roslyn.Utilities;
......@@ -3430,12 +3426,12 @@ public override SyntaxNode TryCastExpression(SyntaxNode expression, SyntaxNode t
public override SyntaxNode CastExpression(SyntaxNode type, SyntaxNode expression)
{
return SyntaxFactory.CastExpression((TypeSyntax)type, Parenthesize(expression));
return SyntaxFactory.CastExpression((TypeSyntax)type, Parenthesize(expression)).WithAdditionalAnnotations(Simplifier.Annotation);
}
public override SyntaxNode ConvertExpression(SyntaxNode type, SyntaxNode expression)
{
return SyntaxFactory.CastExpression((TypeSyntax)type, Parenthesize(expression));
return SyntaxFactory.CastExpression((TypeSyntax)type, Parenthesize(expression)).WithAdditionalAnnotations(Simplifier.Annotation);
}
public override SyntaxNode AssignmentStatement(SyntaxNode left, SyntaxNode right)
......
' 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.Linq
Imports System.Composition
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.CodeGeneration
Imports Microsoft.CodeAnalysis.Editing
Imports Microsoft.CodeAnalysis.Host.Mef
Imports Microsoft.CodeAnalysis.Simplification
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Microsoft.CodeAnalysis.Host
Imports Microsoft.CodeAnalysis.Host.Mef
Imports System.Composition
Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
<ExportLanguageService(GetType(SyntaxGenerator), LanguageNames.VisualBasic), [Shared]>
......@@ -57,11 +53,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
End Function
Public Overrides Function CastExpression(type As SyntaxNode, expression As SyntaxNode) As SyntaxNode
Return SyntaxFactory.DirectCastExpression(DirectCast(expression, ExpressionSyntax), DirectCast(type, TypeSyntax))
Return SyntaxFactory.DirectCastExpression(DirectCast(expression, ExpressionSyntax), DirectCast(type, TypeSyntax)).WithAdditionalAnnotations(Simplifier.Annotation)
End Function
Public Overrides Function ConvertExpression(type As SyntaxNode, expression As SyntaxNode) As SyntaxNode
Return SyntaxFactory.CTypeExpression(DirectCast(expression, ExpressionSyntax), DirectCast(type, TypeSyntax))
Return SyntaxFactory.CTypeExpression(DirectCast(expression, ExpressionSyntax), DirectCast(type, TypeSyntax)).WithAdditionalAnnotations(Simplifier.Annotation)
End Function
Public Overrides Function ConditionalExpression(condition As SyntaxNode, whenTrue As SyntaxNode, whenFalse As SyntaxNode) As SyntaxNode
......@@ -195,7 +191,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
' parenthesize the left-side of a dot or target of an invocation if not unnecessary
Private Function ParenthesizeLeft(expression As SyntaxNode) As ExpressionSyntax
Dim expressionSyntax = DirectCast(expression, expressionSyntax)
Dim expressionSyntax = DirectCast(expression, ExpressionSyntax)
If TypeOf expressionSyntax Is TypeSyntax _
OrElse expressionSyntax.IsMeMyBaseOrMyClass() _
OrElse expressionSyntax.IsKind(SyntaxKind.ParenthesizedExpression) _
......@@ -253,37 +249,37 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
Public Overrides Function TypeExpression(specialType As SpecialType) As SyntaxNode
Select Case specialType
Case specialType.System_Boolean
Case SpecialType.System_Boolean
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.BooleanKeyword))
Case specialType.System_Byte
Case SpecialType.System_Byte
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ByteKeyword))
Case specialType.System_Char
Case SpecialType.System_Char
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.CharKeyword))
Case specialType.System_Decimal
Case SpecialType.System_Decimal
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.DecimalKeyword))
Case specialType.System_Double
Case SpecialType.System_Double
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.DoubleKeyword))
Case specialType.System_Int16
Case SpecialType.System_Int16
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ShortKeyword))
Case specialType.System_Int32
Case SpecialType.System_Int32
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntegerKeyword))
Case specialType.System_Int64
Case SpecialType.System_Int64
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.LongKeyword))
Case specialType.System_Object
Case SpecialType.System_Object
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword))
Case specialType.System_SByte
Case SpecialType.System_SByte
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.SByteKeyword))
Case specialType.System_Single
Case SpecialType.System_Single
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.SingleKeyword))
Case specialType.System_String
Case SpecialType.System_String
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.StringKeyword))
Case specialType.System_UInt16
Case SpecialType.System_UInt16
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.UShortKeyword))
Case specialType.System_UInt32
Case SpecialType.System_UInt32
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.UIntegerKeyword))
Case specialType.System_UInt64
Case SpecialType.System_UInt64
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ULongKeyword))
Case specialType.System_DateTime
Case SpecialType.System_DateTime
Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.DateKeyword))
Case Else
Throw New NotSupportedException("Unsupported SpecialType")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册