diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/ImplementInterface/ImplementInterfaceTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/ImplementInterface/ImplementInterfaceTests.cs index 6452b6106cc0960eca1e3ffd160348c1f3a33783..bd2acd4d2fb5762c0e947803eb5c1469540b5cc2 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/ImplementInterface/ImplementInterfaceTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/ImplementInterface/ImplementInterfaceTests.cs @@ -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() { diff --git a/src/EditorFeatures/Test2/Diagnostics/ImplementInterface/ImplementInterfaceCrossLanguageTests.vb b/src/EditorFeatures/Test2/Diagnostics/ImplementInterface/ImplementInterfaceCrossLanguageTests.vb index f7be4a0e3829dc72e15383427f20d6858d043f90..add2cd8da0dcb9fcc6087a001779dc78f05c763e 100644 --- a/src/EditorFeatures/Test2/Diagnostics/ImplementInterface/ImplementInterfaceCrossLanguageTests.vb +++ b/src/EditorFeatures/Test2/Diagnostics/ImplementInterface/ImplementInterfaceCrossLanguageTests.vb @@ -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 diff --git a/src/EditorFeatures/VisualBasicTest/Diagnostics/ImplementInterface/ImplementInterfaceTests.vb b/src/EditorFeatures/VisualBasicTest/Diagnostics/ImplementInterface/ImplementInterfaceTests.vb index a6d0deb7a9eceeb720c4f2c806e68a8ba7f9c6d7..a068855d2d18a30c6c585e5d8aed3e021f7b2b96 100644 --- a/src/EditorFeatures/VisualBasicTest/Diagnostics/ImplementInterface/ImplementInterfaceTests.vb +++ b/src/EditorFeatures/VisualBasicTest/Diagnostics/ImplementInterface/ImplementInterfaceTests.vb @@ -134,6 +134,48 @@ NewLines("Interface I \n Sub M() \n End Interface \n Class C \n Implements I \n index:=1) End Sub + + + 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 + + + + 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 + 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]]>.Value.Replace(vbLf, vbCrLf), +compareTokens:=False) + End Sub + + + + Public Sub TestEnumParameters2() + Test( + +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]]>.Value.Replace(vbLf, vbCrLf), + +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 diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs index d45590f714a206c0a736ed23c176e1fa0537a1f2..6f1f312053b416c0dbbbf8e8d9e7308cafef0217 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs @@ -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) diff --git a/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicSyntaxGenerator.vb b/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicSyntaxGenerator.vb index c772f4fb46ee6c1c4cb7fc36178b0847b176daf5..2258684f4cb4f4141b04ff46bae952a1feaff0f4 100644 --- a/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicSyntaxGenerator.vb +++ b/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicSyntaxGenerator.vb @@ -1,15 +1,11 @@ ' 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 @@ -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")