|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.SimplifyThisOrMe;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics;
using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
using Xunit.Abstractions;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.SimplifyThisOrMe;
public partial class SimplifyThisOrMeTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor
{
public SimplifyThisOrMeTests(ITestOutputHelper logger)
: base(logger)
{
}
internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace)
=> (new CSharpSimplifyThisOrMeDiagnosticAnalyzer(), new CSharpSimplifyThisOrMeCodeFixProvider());
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyThisOrMe)]
public async Task TestSimplifyDiagnosticId()
{
await TestInRegularAndScriptAsync(
"""
using System;
class C
{
private int x = 0;
public void z()
{
var a = [|this.x|];
}
}
""",
"""
using System;
class C
{
private int x = 0;
public void z()
{
var a = x;
}
}
""");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyThisOrMe)]
[WorkItem("https://github.com/dotnet/roslyn/issues/6682")]
public async Task TestThisWithNoType()
{
await TestInRegularAndScriptAsync(
"""
class Program
{
dynamic x = 7;
static void Main(string[] args)
{
[|this|].x = default(dynamic);
}
}
""",
"""
class Program
{
dynamic x = 7;
static void Main(string[] args)
{
x = default(dynamic);
}
}
""");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyThisOrMe)]
public async Task TestAppropriateDiagnosticOnMissingQualifier()
{
await TestDiagnosticInfoAsync(
"""
class C
{
int SomeProperty { get; set; }
void M()
{
[|this|].SomeProperty = 1;
}
}
""",
options: Option(CodeStyleOptions2.QualifyPropertyAccess, false, NotificationOption2.Warning),
diagnosticId: IDEDiagnosticIds.RemoveThisOrMeQualificationDiagnosticId,
diagnosticSeverity: DiagnosticSeverity.Warning);
}
[Fact]
[Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyThisOrMe)]
[Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)]
public async Task TestFixAllInSolution_RemoveThis()
{
var input = """
<Workspace>
<Project Language="C#" AssemblyName="Assembly1" CommonReferences="true">
<Document>
using System;
class ProgramA
{
private int x = 0;
private int y = 0;
private int z = 0;
private System.Int32 F(System.Int32 p1, System.Int16 p2)
{
System.Int32 i1 = {|FixAllInSolution:this.x|};
System.Int16 s1 = this.y;
System.Int32 i2 = this.z;
System.Console.Write(i1 + s1 + i2);
System.Console.WriteLine(i1 + s1 + i2);
System.Exception ex = null;
return i1 + s1 + i2;
}
}
class ProgramB
{
private int x2 = 0;
private int y2 = 0;
private int z2 = 0;
private System.Int32 F(System.Int32 p1, System.Int16 p2)
{
System.Int32 i1 = this.x2;
System.Int16 s1 = this.y2;
System.Int32 i2 = this.z2;
System.Console.Write(i1 + s1 + i2);
System.Console.WriteLine(i1 + s1 + i2);
System.Exception ex = null;
return i1 + s1 + i2;
}
}
</Document>
<Document>
using System;
class ProgramA2
{
private int x = 0;
private int y = 0;
private int z = 0;
private System.Int32 F(System.Int32 p1, System.Int16 p2)
{
System.Int32 i1 = this.x;
System.Int16 s1 = this.y;
System.Int32 i2 = this.z;
System.Console.Write(i1 + s1 + i2);
System.Console.WriteLine(i1 + s1 + i2);
System.Exception ex = null;
return i1 + s1 + i2;
}
}
class ProgramB2
{
private int x2 = 0;
private int y2 = 0;
private int z2 = 0;
private System.Int32 F(System.Int32 p1, System.Int16 p2)
{
System.Int32 i1 = this.x2;
System.Int16 s1 = this.y2;
System.Int32 i2 = this.z2;
System.Console.Write(i1 + s1 + i2);
System.Console.WriteLine(i1 + s1 + i2);
System.Exception ex = null;
return i1 + s1 + i2;
}
}
</Document>
</Project>
<Project Language="C#" AssemblyName="Assembly2" CommonReferences="true">
<Document>
using System;
class ProgramA3
{
private int x = 0;
private int y = 0;
private int z = 0;
private System.Int32 F(System.Int32 p1, System.Int16 p2)
{
System.Int32 i1 = this.x;
System.Int16 s1 = this.y;
System.Int32 i2 = this.z;
System.Console.Write(i1 + s1 + i2);
System.Console.WriteLine(i1 + s1 + i2);
System.Exception ex = null;
return i1 + s1 + i2;
}
}
class ProgramB3
{
private int x2 = 0;
private int y2 = 0;
private int z2 = 0;
private System.Int32 F(System.Int32 p1, System.Int16 p2)
{
System.Int32 i1 = this.x2;
System.Int16 s1 = this.y2;
System.Int32 i2 = this.z2;
System.Console.Write(i1 + s1 + i2);
System.Console.WriteLine(i1 + s1 + i2);
System.Exception ex = null;
return i1 + s1 + i2;
}
}
</Document>
</Project>
</Workspace>
""";
var expected = """
<Workspace>
<Project Language="C#" AssemblyName="Assembly1" CommonReferences="true">
<Document>
using System;
class ProgramA
{
private int x = 0;
private int y = 0;
private int z = 0;
private System.Int32 F(System.Int32 p1, System.Int16 p2)
{
System.Int32 i1 = x;
System.Int16 s1 = y;
System.Int32 i2 = z;
System.Console.Write(i1 + s1 + i2);
System.Console.WriteLine(i1 + s1 + i2);
System.Exception ex = null;
return i1 + s1 + i2;
}
}
class ProgramB
{
private int x2 = 0;
private int y2 = 0;
private int z2 = 0;
private System.Int32 F(System.Int32 p1, System.Int16 p2)
{
System.Int32 i1 = x2;
System.Int16 s1 = y2;
System.Int32 i2 = z2;
System.Console.Write(i1 + s1 + i2);
System.Console.WriteLine(i1 + s1 + i2);
System.Exception ex = null;
return i1 + s1 + i2;
}
}
</Document>
<Document>
using System;
class ProgramA2
{
private int x = 0;
private int y = 0;
private int z = 0;
private System.Int32 F(System.Int32 p1, System.Int16 p2)
{
System.Int32 i1 = x;
System.Int16 s1 = y;
System.Int32 i2 = z;
System.Console.Write(i1 + s1 + i2);
System.Console.WriteLine(i1 + s1 + i2);
System.Exception ex = null;
return i1 + s1 + i2;
}
}
class ProgramB2
{
private int x2 = 0;
private int y2 = 0;
private int z2 = 0;
private System.Int32 F(System.Int32 p1, System.Int16 p2)
{
System.Int32 i1 = x2;
System.Int16 s1 = y2;
System.Int32 i2 = z2;
System.Console.Write(i1 + s1 + i2);
System.Console.WriteLine(i1 + s1 + i2);
System.Exception ex = null;
return i1 + s1 + i2;
}
}
</Document>
</Project>
<Project Language="C#" AssemblyName="Assembly2" CommonReferences="true">
<Document>
using System;
class ProgramA3
{
private int x = 0;
private int y = 0;
private int z = 0;
private System.Int32 F(System.Int32 p1, System.Int16 p2)
{
System.Int32 i1 = x;
System.Int16 s1 = y;
System.Int32 i2 = z;
System.Console.Write(i1 + s1 + i2);
System.Console.WriteLine(i1 + s1 + i2);
System.Exception ex = null;
return i1 + s1 + i2;
}
}
class ProgramB3
{
private int x2 = 0;
private int y2 = 0;
private int z2 = 0;
private System.Int32 F(System.Int32 p1, System.Int16 p2)
{
System.Int32 i1 = x2;
System.Int16 s1 = y2;
System.Int32 i2 = z2;
System.Console.Write(i1 + s1 + i2);
System.Console.WriteLine(i1 + s1 + i2);
System.Exception ex = null;
return i1 + s1 + i2;
}
}
</Document>
</Project>
</Workspace>
""";
await TestInRegularAndScriptAsync(input, expected);
}
[Fact]
[Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyThisOrMe)]
[Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)]
public async Task TestFixAllInSolution_RemoveMemberAccessQualification()
{
var input = """
<Workspace>
<Project Language="C#" AssemblyName="Assembly1" CommonReferences="true">
<Document>
using System;
class C
{
int Property { get; set; }
int OtherProperty { get; set; }
void M()
{
{|FixAllInSolution:this.Property|} = 1;
var x = this.OtherProperty;
}
}
</Document>
<Document>
using System;
class D
{
string StringProperty { get; set; }
int field;
void N()
{
this.StringProperty = string.Empty;
this.field = 0; // ensure qualification isn't removed
}
}
</Document>
</Project>
</Workspace>
""";
var expected = """
<Workspace>
<Project Language="C#" AssemblyName="Assembly1" CommonReferences="true">
<Document>
using System;
class C
{
int Property { get; set; }
int OtherProperty { get; set; }
void M()
{
Property = 1;
var x = OtherProperty;
}
}
</Document>
<Document>
using System;
class D
{
string StringProperty { get; set; }
int field;
void N()
{
StringProperty = string.Empty;
this.field = 0; // ensure qualification isn't removed
}
}
</Document>
</Project>
</Workspace>
""";
var options =
new OptionsCollection(GetLanguage())
{
{ CodeStyleOptions2.QualifyPropertyAccess, false, NotificationOption2.Suggestion },
{ CodeStyleOptions2.QualifyFieldAccess, true, NotificationOption2.Suggestion },
};
await TestInRegularAndScriptAsync(
initialMarkup: input,
expectedMarkup: expected,
options: options);
}
}
|