public static async Task BeforeMethodInConditional() { var code = @" namespace N { public class C { #if true private int M() => 1; #endif } }"; var sln = CodeFactory.CreateSolution(code); var editor = await DocumentEditor.CreateAsync(sln.Projects.First().Documents.First()).ConfigureAwait(false); var containingType = editor.OriginalRoot.SyntaxTree.FindClassDeclaration("C"); var method = (MethodDeclarationSyntax)SyntaxFactory.ParseMemberDeclaration("public int NewMethod() => 1;"); var expected = @" namespace N { public class C { public int NewMethod() => 1; #if true private int M() => 1; #endif } }"; _ = editor.AddMethod(containingType, method); CodeAssert.AreEqual(expected, editor.GetChangedDocument()); }
public void CreateSolutionFromClassLibrary1() { Assert.AreEqual(true, ProjectFile.TryFind("ClassLibrary1.csproj", out var projectFile)); var solution = CodeFactory.CreateSolution( projectFile, new[] { new FieldNameMustNotBeginWithUnderscore(), }, CreateMetadataReferences(typeof(object))); Assert.AreEqual("ClassLibrary1", solution.Projects.Single().Name); var expected = new[] { "AllowCompilationErrors.cs", "AssemblyInfo.cs", "ClassLibrary1Class1.cs", }; var actual = solution.Projects .SelectMany(p => p.Documents) .Select(d => d.Name) .OrderBy(x => x) .ToArray(); //// ReSharper disable UnusedVariable for debug. var expectedString = string.Join(Environment.NewLine, expected); var actualString = string.Join(Environment.NewLine, actual); //// ReSharper restore UnusedVariable CollectionAssert.AreEqual(expected, actual); }
public void BinarySolution() { var binaryReferencedCode = @" namespace BinaryReferencedAssembly { public class Base { private int _fieldName; } }"; var code = @" namespace RoslynSandbox { using System.Reflection; public class C : BinaryReferencedAssembly.Base { private int f; } }"; var analyzer = new FieldNameMustNotBeginWithUnderscore(); var solution = CodeFactory.CreateSolution( code, CodeFactory.DefaultCompilationOptions(new[] { analyzer }), AnalyzerAssert.MetadataReferences.Append(Asserts.MetadataReferences.CreateBinary(binaryReferencedCode))); AnalyzerAssert.Valid(analyzer, solution); }
public static async Task AddEventWhenUsing() { var code = @" namespace N { using System; class C { } }"; var sln = CodeFactory.CreateSolution(code); var editor = await DocumentEditor.CreateAsync(sln.Projects.First().Documents.First()).ConfigureAwait(false); var eventDeclaration = (EventFieldDeclarationSyntax)editor.Generator.EventDeclaration("E", SyntaxFactory.ParseTypeName("System.EventHandler"), Accessibility.Public) .WithSimplifiedNames(); var containingType = editor.OriginalRoot.SyntaxTree.FindClassDeclaration("C"); _ = editor.AddEvent(containingType, eventDeclaration); var expected = @" namespace N { using System; class C { public event EventHandler E; } }"; CodeAssert.AreEqual(expected, editor.GetChangedDocument()); }
public void CreateSolutionFromProjectFile() { Assert.AreEqual(true, ProjectFile.TryFind(ExecutingAssemblyDll, out var projectFile)); var solution = CodeFactory.CreateSolution( projectFile, new[] { new FieldNameMustNotBeginWithUnderscore(), }, CreateMetadataReferences(typeof(object))); Assert.AreEqual(Path.GetFileNameWithoutExtension(ExecutingAssemblyDll.FullName), solution.Projects.Single().Name); var expected = projectFile.Directory .EnumerateFiles("*.cs", SearchOption.AllDirectories) .Where(f => !f.DirectoryName.Contains("bin")) .Where(f => !f.DirectoryName.Contains("obj")) .Select(f => f.Name) .OrderBy(x => x) .ToArray(); var actual = solution.Projects .SelectMany(p => p.Documents) .Select(d => d.Name) .OrderBy(x => x) .ToArray(); //// ReSharper disable UnusedVariable for debug. var expectedString = string.Join(Environment.NewLine, expected); var actualString = string.Join(Environment.NewLine, actual); //// ReSharper restore UnusedVariable CollectionAssert.AreEqual(expected, actual); }
public void CreateSolutionWithInheritQualified() { var code1 = @" namespace RoslynSandbox.Core { public class Foo1 { private readonly int _value; } }"; var code2 = @" namespace RoslynSandbox.Client { public class Foo2 : RoslynSandbox.Core.Foo1 { } }"; foreach (var sources in new[] { new[] { code1, code2 }, new[] { code2, code1 } }) { var sln = CodeFactory.CreateSolution(sources, new[] { new FieldNameMustNotBeginWithUnderscore() }); CollectionAssert.AreEquivalent(new[] { "RoslynSandbox.Core", "RoslynSandbox.Client" }, sln.Projects.Select(x => x.Name)); CollectionAssert.AreEquivalent(new[] { "Foo1.cs", "Foo2.cs" }, sln.Projects.Select(x => x.Documents.Single().Name)); var project1 = sln.Projects.Single(x => x.Name == "RoslynSandbox.Core"); CollectionAssert.IsEmpty(project1.AllProjectReferences); var project2 = sln.Projects.Single(x => x.Name == "RoslynSandbox.Client"); CollectionAssert.AreEqual(new[] { project1.Id }, project2.AllProjectReferences.Select(x => x.ProjectId)); } }
public void CreateSolutionFromSources() { var code1 = @" namespace Project1 { class Foo1 { private readonly int _value; } }"; var code2 = @" namespace Project2 { class Foo2 { private readonly int _value; } }"; var sln = CodeFactory.CreateSolution(new[] { code1, code2 }); CollectionAssert.AreEqual(new[] { "Project1", "Project2" }, sln.Projects.Select(x => x.Name)); Assert.AreEqual(new[] { "Foo1.cs", "Foo2.cs" }, sln.Projects.Select(x => x.Documents.Single().Name)); sln = CodeFactory.CreateSolution(new[] { code2, code1 }); CollectionAssert.AreEqual(new[] { "Project1", "Project2" }, sln.Projects.Select(x => x.Name)); Assert.AreEqual(new[] { "Foo1.cs", "Foo2.cs" }, sln.Projects.Select(x => x.Documents.Single().Name)); }
public static async Task ListOfStringBuilderType() { var code = @" namespace N { }"; var sln = CodeFactory.CreateSolution(code); var document = sln.Projects.First().Documents.First(); var editor = await DocumentEditor.CreateAsync(document).ConfigureAwait(false); var expected = @" namespace N { using System.Collections.Generic; using System.Text; }"; var type = editor.SemanticModel.GetSpeculativeTypeInfo( 0, SyntaxFactory.ParseTypeName("System.Collections.Generic.List<System.Text.StringBuilder>"), SpeculativeBindingOption.BindAsTypeOrNamespace).Type; _ = editor.AddUsing(type); CodeAssert.AreEqual(expected, editor.GetChangedDocument()); }
public static async Task TypeInNestedDeepNamespace() { var classCode = @" namespace A.B.C.Extensions { class C { } } "; var code = @" namespace A.B.C { }"; var sln = CodeFactory.CreateSolution(new[] { classCode, code }); var document = sln.Projects.First().Documents.First(); var editor = await DocumentEditor.CreateAsync(document).ConfigureAwait(false); var expected = @" namespace A.B.C { using A.B.C.Extensions; }"; var type = editor.SemanticModel.Compilation.GetTypeByMetadataName("A.B.C.Extensions.C"); _ = editor.AddUsing(type); CodeAssert.AreEqual(expected, editor.GetChangedDocument()); }
public static async Task AddPublicFieldWhenPublicAndPrivateExists() { var code = @" namespace N { class C { public int F; private int f; } }"; var sln = CodeFactory.CreateSolution(code); var editor = await DocumentEditor.CreateAsync(sln.Projects.First().Documents.First()).ConfigureAwait(false); var containingType = editor.OriginalRoot.SyntaxTree.FindClassDeclaration("C"); var expected = @" namespace N { class C { public int F; public int NewField; private int f; } }"; var newField = (FieldDeclarationSyntax)SyntaxFactory.ParseMemberDeclaration("public int NewField;"); _ = editor.AddField(containingType, newField); CodeAssert.AreEqual(expected, editor.GetChangedDocument()); }
public void SingleClassOneErrorCorrectFixAll() { var code = @" namespace RoslynSandbox { class Foo { private readonly int _value; } }"; var fixedCode = @" namespace RoslynSandbox { class Foo { private readonly int value; } }"; var analyzer = new FieldNameMustNotBeginWithUnderscore(); var cSharpCompilationOptions = CodeFactory.DefaultCompilationOptions(analyzer); var metadataReferences = new[] { MetadataReference.CreateFromFile(typeof(int).Assembly.Location) }; var sln = CodeFactory.CreateSolution(code, cSharpCompilationOptions, metadataReferences); var diagnostics = Analyze.GetDiagnostics(sln, analyzer); var fixedSln = Fix.Apply(sln, new DontUseUnderscoreCodeFixProvider(), diagnostics); CodeAssert.AreEqual(fixedCode, fixedSln.Projects.Single().Documents.Single()); }
public static void FiguresOutFromOtherDocument(string declaration, CodeStyleResult expected) { var sln = CodeFactory.CreateSolution(new[] { @" namespace N { class C1 { private int _f; } }".AssertReplace("private int _f", declaration), @" namespace N { class C2 { } }", }); foreach (var document in sln.Projects.Single().Documents) { var editor = Microsoft.CodeAnalysis.Editing.DocumentEditor.CreateAsync(document).Result; Assert.AreEqual(expected, CodeStyle.UnderscoreFields(editor)); } }
public static async Task FiguresOutFromOtherClass(string expression, CodeStyleResult expected) { var sln = CodeFactory.CreateSolution(new[] { @" namespace N { class C1 { C1() { this.P = 1; } public int P { get; } } }".AssertReplace("this.P = 1", expression), @" namespace N { class C2 { } }", }); foreach (var document in sln.Projects.Single().Documents) { var editor = await Microsoft.CodeAnalysis.Editing.DocumentEditor.CreateAsync(document).ConfigureAwait(false); Assert.AreEqual(expected, await editor.QualifyPropertyAccessAsync(CancellationToken.None).ConfigureAwait(false)); } }
public static async Task FiguresOutFromOtherDocument(string declaration, CodeStyleResult expected) { var sln = CodeFactory.CreateSolution( new[] { @" namespace N { class C1 { private int _f; } }".AssertReplace("private int _f", declaration), @" namespace N { class C2 { } }", }); foreach (var document in sln.Projects.Single().Documents) { Assert.AreEqual(expected, await CodeStyle.UnderscoreFieldsAsync(document, CancellationToken.None).ConfigureAwait(false)); } }
public static void ConstructorCycle(DiagnosticAnalyzer analyzer) { var code = @" namespace N { using System; public sealed class C : IDisposable { private IDisposable disposable; public C(int i, IDisposable disposable) : this(disposable, i) { this.disposable = disposable; } public C(IDisposable disposable, int i) : this(i, disposable) { this.disposable = disposable; } public void Dispose() { } } }"; var solution = CodeFactory.CreateSolution(code, CodeFactory.DefaultCompilationOptions(analyzer), MetadataReferences.FromAttributes()); RoslynAssert.NoDiagnostics(Analyze.GetDiagnostics(analyzer, solution)); }
public static async Task SystemWhenEmptyOutside() { var code = @" namespace N { }"; var otherCode = @" using System; namespace N { }"; var sln = CodeFactory.CreateSolution(new[] { code, otherCode }); var editor = await DocumentEditor.CreateAsync(sln.Projects.First().Documents.First()).ConfigureAwait(false); var expected = @"using System; namespace N { }"; var usingDirective = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System")); _ = editor.AddUsing(usingDirective); CodeAssert.AreEqual(expected, editor.GetChangedDocument()); }
public void AnalyzeWhenAllInformationIsProvidedByAttributeWhenDataClassIsInSeparateAssembly() { var testCode = TestUtility.WrapClassInNamespaceAndAddUsing(@" public class Tests { [Test] [TestCaseSource(typeof(TestData), nameof(TestData.TestCaseDataProvider))] public void Test1(int a, int b, int c) { Assert.That(a + b, Is.EqualTo(c)); } }"); var testDataCode = TestUtility.WrapClassInNamespaceAndAddUsing(@" public static class TestData { public static IEnumerable TestCaseDataProvider() { yield return new object[] { 1, 2, 3 }; yield return new object[] { 2, 3, 5 }; } }", "using System.Collections;"); var solution = CodeFactory.CreateSolution(new[] { testCode, testDataCode }); RoslynAssert.Valid(analyzer, solution); }
public static async Task TypeInSameNamespaceWhenEmptyNamespace() { var classCode = @" namespace N { class C1 { } } "; var code = @" namespace N { }"; var sln = CodeFactory.CreateSolution(new[] { classCode, code }); var document = sln.Projects.First().Documents.Last(); var editor = await DocumentEditor.CreateAsync(document).ConfigureAwait(false); var expected = @" namespace N { }"; var type = editor.SemanticModel.Compilation.GetTypeByMetadataName("N.C1"); _ = editor.AddUsing(type); CodeAssert.AreEqual(expected, editor.GetChangedDocument()); }
public void CreateSolutionWhenNestedNamespaces() { var resourcesCode = @" namespace RoslynSandbox.Properties { public class Resources { } }"; var testCode = @" namespace RoslynSandbox { using RoslynSandbox.Properties; public class Foo { } }"; foreach (var sources in new[] { new[] { resourcesCode, testCode }, new[] { resourcesCode, testCode } }) { var sln = CodeFactory.CreateSolution(sources); var project = sln.Projects.Single(); Assert.AreEqual("RoslynSandbox", project.AssemblyName); CollectionAssert.AreEquivalent(new[] { "Resources.cs", "Foo.cs" }, project.Documents.Select(x => x.Name)); } }
public static async Task WithProtectedMember(string before, string after) { var code = @" namespace N { class C { protected int f; } }".AssertReplace("protected int f;", before); var sln = CodeFactory.CreateSolution(code); var editor = await DocumentEditor.CreateAsync(sln.Projects.First().Documents.First()).ConfigureAwait(false); var expected = @" namespace N { sealed class C { private int f; } }".AssertReplace("private int f;", after); _ = editor.Seal(editor.OriginalRoot.Find <ClassDeclarationSyntax>("class C")); CodeAssert.AreEqual(expected, editor.GetChangedDocument()); }
public void CreateSolutionWithDependenciesFromQualified() { var code1 = @" namespace Project1 { public class Foo1 { private readonly int _value; } }"; var code2 = @" namespace Project2 { public class Foo2 { private readonly Project1.Foo1 _value; } }"; var sln = CodeFactory.CreateSolution(new[] { code1, code2 }, new[] { new FieldNameMustNotBeginWithUnderscore() }); CollectionAssert.AreEqual(new[] { "Project1", "Project2" }, sln.Projects.Select(x => x.Name)); CollectionAssert.AreEqual(new[] { "Foo1.cs", "Foo2.cs" }, sln.Projects.Select(x => x.Documents.Single().Name)); var project1 = sln.Projects.Single(x => x.Name == "Project1"); CollectionAssert.IsEmpty(project1.AllProjectReferences); var project2 = sln.Projects.Single(x => x.Name == "Project2"); CollectionAssert.AreEqual(new[] { project1.Id }, project2.AllProjectReferences.Select(x => x.ProjectId)); }
public static void ProjectFromDisk() { var after = @"// ReSharper disable All namespace ClassLibrary1 { public class ClassLibrary1Class1 { private int value; public ClassLibrary1Class1(int value) { this.value = value; } } } "; var csproj = ProjectFile.Find("ClassLibrary1.csproj"); var analyzer = new FieldNameMustNotBeginWithUnderscore(); var expectedDiagnostic = ExpectedDiagnostic.Create( FieldNameMustNotBeginWithUnderscore.DiagnosticId, "Field '_value' must not begin with an underscore", Path.Combine(csproj.DirectoryName, "ClassLibrary1Class1.cs"), 5, 20); var solution = CodeFactory.CreateSolution( csproj, analyzer, expectedDiagnostic, metadataReferences: new[] { MetadataReference.CreateFromFile(typeof(int).Assembly.Location) }); RoslynAssert.CodeFix(analyzer, new DoNotUseUnderscoreFix(), expectedDiagnostic, solution, after); }
public void CreateSolutionWithTwoAnalyzersReportingSameDiagnostic() { Assert.AreEqual(true, CodeFactory.TryFindProjectFile("ClassLibrary1.csproj", out var projectFile)); var solution = CodeFactory.CreateSolution( projectFile, new[] { new DummyAnalyzer(ID1234.Descriptor), new DummyAnalyzer(ID1234.Descriptor) }, CreateMetadataReferences(typeof(object))); Assert.AreEqual("ClassLibrary1", solution.Projects.Single().Name); var expected = new[] { "AllowCompilationErrors.cs", "AssemblyInfo.cs", "ClassLibrary1Class1.cs", }; var actual = solution.Projects .SelectMany(p => p.Documents) .Select(d => d.Name) .OrderBy(x => x) .ToArray(); //// ReSharper disable UnusedVariable for debug. var expectedString = string.Join(Environment.NewLine, expected); var actualString = string.Join(Environment.NewLine, actual); //// ReSharper restore UnusedVariable CollectionAssert.AreEqual(expected, actual); }
public static async Task FiguresOutFromOtherClass(string expression, CodeStyleResult expected) { var sln = CodeFactory.CreateSolution(new[] { @" namespace N { class C1 { private int f; C1() { this.f = 1; } } }".AssertReplace("this.f = 1", expression), @" namespace N { class C2 { } }", }); foreach (var document in sln.Projects.Single().Documents) { Assert.AreEqual(expected, await document.QualifyFieldAccessAsync(CancellationToken.None).ConfigureAwait(false)); } }
public void CreateSolutionFromWpfApp1() { Assert.AreEqual(true, ProjectFile.TryFind("WpfApp1.csproj", out var projectFile)); var solution = CodeFactory.CreateSolution( projectFile, new[] { new FieldNameMustNotBeginWithUnderscore(), }, CreateMetadataReferences(typeof(object))); Assert.AreEqual("WpfApp1", solution.Projects.Single().Name); var expected = new[] { "App.xaml.cs", "AssemblyInfo.cs", "Class1.cs", "MainWindow.xaml.cs", "Resources.Designer.cs", "Settings.Designer.cs", "UserControl1.xaml.cs", }; var actual = solution.Projects .SelectMany(p => p.Documents) .Select(d => d.Name) .OrderBy(x => x) .ToArray(); //// ReSharper disable UnusedVariable for debug. var expectedString = string.Join(Environment.NewLine, expected); var actualString = string.Join(Environment.NewLine, actual); //// ReSharper restore UnusedVariable CollectionAssert.AreEqual(expected, actual); }
public static async Task TypicalClass() { var code = @" namespace N { public abstract class C { public int F1 = 1; private int f2; public C() { } private C(int i) { } public int P1 { get; set; } public void M1() { } } }"; var sln = CodeFactory.CreateSolution(code); var editor = await DocumentEditor.CreateAsync(sln.Projects.First().Documents.First()).ConfigureAwait(false); var declaration = (PropertyDeclarationSyntax)SyntaxFactory.ParseMemberDeclaration("public int NewProperty { get; set; }"); var containingType = editor.OriginalRoot.SyntaxTree.FindClassDeclaration("C"); _ = editor.AddProperty(containingType, declaration); var expected = @" namespace N { public abstract class C { public int F1 = 1; private int f2; public C() { } private C(int i) { } public int P1 { get; set; } public int NewProperty { get; set; } public void M1() { } } }"; CodeAssert.AreEqual(expected, editor.GetChangedDocument()); }
public static async Task AddEventFieldDeclarationSyntax() { var code = @" namespace N { public abstract class C { public int Filed1 = 1; private int filed1; public C() { } private C(int i) { } public int P1 { get; set; } public void M1() { } } }"; var sln = CodeFactory.CreateSolution(code); var editor = await DocumentEditor.CreateAsync(sln.Projects.First().Documents.First()).ConfigureAwait(false); var eventDeclaration = (EventFieldDeclarationSyntax)editor.Generator.EventDeclaration("SomeEvent", SyntaxFactory.ParseTypeName("System.EventHandler"), Accessibility.Public); var containingType = editor.OriginalRoot.SyntaxTree.FindClassDeclaration("C"); _ = editor.AddEvent(containingType, eventDeclaration); var expected = @" namespace N { public abstract class C { public int Filed1 = 1; private int filed1; public C() { } private C(int i) { } public event System.EventHandler SomeEvent; public int P1 { get; set; } public void M1() { } } }"; CodeAssert.AreEqual(expected, editor.GetChangedDocument()); }
public static async Task AfterPropertyWhenLastMember() { var code = @" namespace N { public class C { public int P { get; } } }"; var sln = CodeFactory.CreateSolution(code); var editor = await DocumentEditor.CreateAsync(sln.Projects.First().Documents.First()).ConfigureAwait(false); var containingType = editor.OriginalRoot.SyntaxTree.FindClassDeclaration("C"); var property = (PropertyDeclarationSyntax)SyntaxFactory.ParseMemberDeclaration("public int NewProperty => 1;"); var expected = @" namespace N { public class C { public int P { get; } public int NewProperty => 1; } }"; _ = editor.AddProperty(containingType, property); CodeAssert.AreEqual(expected, editor.GetChangedDocument()); }
public async Task AddBackingFieldWhenNameCollision() { var testCode = @" namespace RoslynSandbox { public class Foo { private int value; public int Value { get; set; } } }"; var sln = CodeFactory.CreateSolution(testCode); var editor = await DocumentEditor.CreateAsync(sln.Projects.First().Documents.First()).ConfigureAwait(false); var property = editor.OriginalRoot.SyntaxTree.FindPropertyDeclaration("Value"); var field = editor.AddBackingField(property, usesUnderscoreNames: false, cancellationToken: CancellationToken.None); Assert.AreEqual("privateint value_;", field.ToFullString()); var expected = @" namespace RoslynSandbox { public class Foo { private int value; private int value_; public int Value { get; set; } } }"; CodeAssert.AreEqual(expected, editor.GetChangedDocument()); }
public static async Task AfterPropertyWithPragma() { var code = @" namespace N { public abstract class C { #pragma warning disable INPC002 // Mutable public property should notify. public int P { get; set; } #pragma warning restore INPC002 // Mutable public property should notify. } }"; var sln = CodeFactory.CreateSolution(code); var editor = await DocumentEditor.CreateAsync(sln.Projects.First().Documents.First()).ConfigureAwait(false); var containingType = editor.OriginalRoot.SyntaxTree.FindClassDeclaration("C"); var method = (MethodDeclarationSyntax)SyntaxFactory.ParseMemberDeclaration("public int NewMethod() => 1;"); var expected = @" namespace N { public abstract class C { #pragma warning disable INPC002 // Mutable public property should notify. public int P { get; set; } #pragma warning restore INPC002 // Mutable public property should notify. public int NewMethod() => 1; } }"; _ = editor.AddMethod(containingType, method); CodeAssert.AreEqual(expected, editor.GetChangedDocument()); }