From 04d5c366777eee689fd95fa07c7cd1cb7c6bd1f1 Mon Sep 17 00:00:00 2001 From: bygu4 Date: Thu, 5 Dec 2024 18:44:01 +0300 Subject: [PATCH 1/8] add Reflector implementation --- Tasks/Test2/Reflector.cs | 152 ++++++++++++++++++ .../Test2.Tests/ExpectedOutput/Output1.txt | 17 ++ Tasks/Test2/Test2.Tests/GlobalUsings.cs | 1 + Tasks/Test2/Test2.Tests/ReflectorTest.cs | 14 ++ Tasks/Test2/Test2.Tests/Test2.Tests.csproj | 30 ++++ .../Test2.Tests/TestClasses/TestClass1.cs | 25 +++ .../Test2.Tests/TestClasses/TestClass2.cs | 0 Tasks/Test2/Test2.csproj | 9 ++ Tasks/Test2/Test2.sln | 31 ++++ Test2.sln | 27 ++++ 10 files changed, 306 insertions(+) create mode 100644 Tasks/Test2/Reflector.cs create mode 100644 Tasks/Test2/Test2.Tests/ExpectedOutput/Output1.txt create mode 100644 Tasks/Test2/Test2.Tests/GlobalUsings.cs create mode 100644 Tasks/Test2/Test2.Tests/ReflectorTest.cs create mode 100644 Tasks/Test2/Test2.Tests/Test2.Tests.csproj create mode 100644 Tasks/Test2/Test2.Tests/TestClasses/TestClass1.cs create mode 100644 Tasks/Test2/Test2.Tests/TestClasses/TestClass2.cs create mode 100644 Tasks/Test2/Test2.csproj create mode 100644 Tasks/Test2/Test2.sln create mode 100644 Test2.sln diff --git a/Tasks/Test2/Reflector.cs b/Tasks/Test2/Reflector.cs new file mode 100644 index 0000000..f5d0965 --- /dev/null +++ b/Tasks/Test2/Reflector.cs @@ -0,0 +1,152 @@ +namespace Test2; + +using System.Reflection; + +public static class Reflector +{ + private const string Tab = " "; + + public static async Task PrintStructure(Type someClass) + { + using var writer = new StreamWriter($"{someClass.Name}.cs"); + await PrintStructureInternal(someClass, 0, writer); + } + + private static async Task PrintStructureInternal( + Type someClass, int numberOfTabs, StreamWriter writer) + { + var indent = GetIndent(numberOfTabs); + await WriteClassInfo(someClass, numberOfTabs, writer); + await writer.WriteAsync(indent + '{'); + foreach (var field in someClass.GetFields()) + { + await PrintField(field, numberOfTabs + 1, writer); + } + + await writer.WriteAsync('\n'); + foreach (var method in someClass.GetMethods()) + { + await PrintMethod(method, numberOfTabs + 1, writer); + } + + await writer.WriteAsync('\n'); + foreach (var nestedClass in someClass.GetNestedTypes()) + { + await PrintStructureInternal(nestedClass, numberOfTabs + 1, writer); + } + + await writer.WriteAsync(indent + '}'); + } + + private static async Task WriteClassInfo( + Type classInfo, int numberOfTabs, StreamWriter writer) + { + var indent = GetIndent(numberOfTabs); + var signature = GetClassSignature(classInfo); + await writer.WriteLineAsync(indent + signature); + } + + private static async Task PrintField( + FieldInfo field, int numberOfTabs, StreamWriter writer) + { + var indent = GetIndent(numberOfTabs); + var signature = GetFieldSignature(field); + await writer.WriteLineAsync(indent + signature); + } + + private static async Task PrintMethod( + MethodInfo method, int numberOfTabs, StreamWriter writer) + { + var indent = GetIndent(numberOfTabs); + var signature = GetMethodSignature(method); + await writer.WriteLineAsync(indent + signature); + } + + private static string GetClassSignature(Type classInfo) + { + var signature = ""; + if (classInfo.IsPublic) + { + signature += "public "; + } + else if (classInfo.IsNestedPrivate) + { + signature += "private "; + } + else if (!classInfo.IsVisible) + { + signature += "internal "; + } + if (classInfo.IsAbstract) + { + signature += "abstract "; + } + if (classInfo.IsSealed) + { + signature += "sealed "; + } + if (classInfo.IsClass) + { + signature += "class "; + } + else if (classInfo.IsInterface) + { + signature += "interface "; + } + + signature += classInfo.Name; + return signature; + } + + private static string GetFieldSignature(FieldInfo field) + { + var signature = ""; + if (field.IsPublic) + { + signature += "public "; + } + else if (field.IsPrivate) + { + signature += "private "; + } + if (field.IsStatic) + { + signature += "static "; + } + + signature += $"{field.FieldType} {field.Name};"; + return signature; + } + + private static string GetMethodSignature(MethodInfo method) + { + var signature = ""; + if (method.IsPublic) + { + signature += "public "; + } + else if (method.IsPrivate) + { + signature += "private "; + } + if (method.IsStatic) + { + signature += "static "; + } + + signature += $"{method.ReturnType} {method.Name}"; + signature += '('; + var parameters = new List(); + foreach (var parameter in method.GetParameters()) + { + parameters.Add($"{parameter.ParameterType} {parameter.Name}"); + } + + signature += string.Join(", ", parameters); + signature += ')'; + return signature; + } + + private static string GetIndent(int numberOfTabs) + => string.Concat(Enumerable.Repeat(Tab, numberOfTabs)); +} diff --git a/Tasks/Test2/Test2.Tests/ExpectedOutput/Output1.txt b/Tasks/Test2/Test2.Tests/ExpectedOutput/Output1.txt new file mode 100644 index 0000000..40f9e6e --- /dev/null +++ b/Tasks/Test2/Test2.Tests/ExpectedOutput/Output1.txt @@ -0,0 +1,17 @@ +public class TestClass1 +{ + public int testField1 + private static string testField2 + + public int TestMethod1(float attribute1) + public static float TestMethod2() + private string TestMethod3(string attribute1, int attribute2) + + private class NestedClass + { + public float testField1; + private string testField2; + + public double TestMethod1() + } +} \ No newline at end of file diff --git a/Tasks/Test2/Test2.Tests/GlobalUsings.cs b/Tasks/Test2/Test2.Tests/GlobalUsings.cs new file mode 100644 index 0000000..cefced4 --- /dev/null +++ b/Tasks/Test2/Test2.Tests/GlobalUsings.cs @@ -0,0 +1 @@ +global using NUnit.Framework; \ No newline at end of file diff --git a/Tasks/Test2/Test2.Tests/ReflectorTest.cs b/Tasks/Test2/Test2.Tests/ReflectorTest.cs new file mode 100644 index 0000000..677d2d4 --- /dev/null +++ b/Tasks/Test2/Test2.Tests/ReflectorTest.cs @@ -0,0 +1,14 @@ +namespace Test2.Tests; + +public static class ReflectorTest +{ + private const string ExpectedOutputPath1 = "ExpectedOutput/Output1.txt" + + [Test] + public static async Task TestReflector_PrintStructure_CompareResults() + { + var expectedOutput = await File.ReadAllTextAsync(ExpectedOutputPath1) + await Reflector.PrintStructure(typeof(TestClass1)); + + } +} diff --git a/Tasks/Test2/Test2.Tests/Test2.Tests.csproj b/Tasks/Test2/Test2.Tests/Test2.Tests.csproj new file mode 100644 index 0000000..913b827 --- /dev/null +++ b/Tasks/Test2/Test2.Tests/Test2.Tests.csproj @@ -0,0 +1,30 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + Always + + + + diff --git a/Tasks/Test2/Test2.Tests/TestClasses/TestClass1.cs b/Tasks/Test2/Test2.Tests/TestClasses/TestClass1.cs new file mode 100644 index 0000000..802e122 --- /dev/null +++ b/Tasks/Test2/Test2.Tests/TestClasses/TestClass1.cs @@ -0,0 +1,25 @@ +namespace Test2.Tests; + +public class TestClass1 +{ + public int testField1 = 0; + private static string testField2 = "a"; + + public int TestMethod1(float attribute1) => 1; + public static float TestMethod2() => 9090; + private string TestMethod3(string attribute1, int attribute2) + { + return "Hello"; + } + + private class NestedClass + { + public float testField1 = 321; + private string testField2 = "abc"; + + public double TestMethod1() + { + throw new InvalidDataException(); + } + } +} \ No newline at end of file diff --git a/Tasks/Test2/Test2.Tests/TestClasses/TestClass2.cs b/Tasks/Test2/Test2.Tests/TestClasses/TestClass2.cs new file mode 100644 index 0000000..e69de29 diff --git a/Tasks/Test2/Test2.csproj b/Tasks/Test2/Test2.csproj new file mode 100644 index 0000000..fa71b7a --- /dev/null +++ b/Tasks/Test2/Test2.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/Tasks/Test2/Test2.sln b/Tasks/Test2/Test2.sln new file mode 100644 index 0000000..0ee2c9f --- /dev/null +++ b/Tasks/Test2/Test2.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.002.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test2", "Test2.csproj", "{3E6CE21D-2E31-4029-BDF6-DA6035A9DDF5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test2.Tests", "Test2.Tests\Test2.Tests.csproj", "{831E003E-1101-4084-9D34-01D93677C71F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3E6CE21D-2E31-4029-BDF6-DA6035A9DDF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E6CE21D-2E31-4029-BDF6-DA6035A9DDF5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E6CE21D-2E31-4029-BDF6-DA6035A9DDF5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E6CE21D-2E31-4029-BDF6-DA6035A9DDF5}.Release|Any CPU.Build.0 = Release|Any CPU + {831E003E-1101-4084-9D34-01D93677C71F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {831E003E-1101-4084-9D34-01D93677C71F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {831E003E-1101-4084-9D34-01D93677C71F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {831E003E-1101-4084-9D34-01D93677C71F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {963E18C0-5EA6-409C-A583-DB0620321B65} + EndGlobalSection +EndGlobal diff --git a/Test2.sln b/Test2.sln new file mode 100644 index 0000000..f03d9ed --- /dev/null +++ b/Test2.sln @@ -0,0 +1,27 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tasks", "Tasks", "{AE05F47D-4707-43A4-978D-37D7155FD65E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test2", "Tasks\Test2\Test2.csproj", "{56E15C84-FC37-4EB2-B28B-91DE7464DEB8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {56E15C84-FC37-4EB2-B28B-91DE7464DEB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {56E15C84-FC37-4EB2-B28B-91DE7464DEB8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {56E15C84-FC37-4EB2-B28B-91DE7464DEB8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {56E15C84-FC37-4EB2-B28B-91DE7464DEB8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {56E15C84-FC37-4EB2-B28B-91DE7464DEB8} = {AE05F47D-4707-43A4-978D-37D7155FD65E} + EndGlobalSection +EndGlobal From 0b468d6373e6cd463c4f7b259467abd78f37ab0a Mon Sep 17 00:00:00 2001 From: bygu4 Date: Thu, 5 Dec 2024 19:01:28 +0300 Subject: [PATCH 2/8] add tests --- Tasks/Test2/Test2.Tests/GlobalUsings.cs | 1 - Tasks/Test2/Test2.Tests/ReflectorTest.cs | 16 +++++++++++++--- Tasks/Test2/Test2.Tests/Test2.Tests.csproj | 10 ++++++---- .../Test2/Test2.Tests/TestClasses/TestClass2.cs | 0 Tasks/Test2/Test2.sln | 2 +- Tasks/Test2/{ => Test2}/Reflector.cs | 0 Tasks/Test2/{ => Test2}/Test2.csproj | 0 7 files changed, 20 insertions(+), 9 deletions(-) delete mode 100644 Tasks/Test2/Test2.Tests/GlobalUsings.cs delete mode 100644 Tasks/Test2/Test2.Tests/TestClasses/TestClass2.cs rename Tasks/Test2/{ => Test2}/Reflector.cs (100%) rename Tasks/Test2/{ => Test2}/Test2.csproj (100%) diff --git a/Tasks/Test2/Test2.Tests/GlobalUsings.cs b/Tasks/Test2/Test2.Tests/GlobalUsings.cs deleted file mode 100644 index cefced4..0000000 --- a/Tasks/Test2/Test2.Tests/GlobalUsings.cs +++ /dev/null @@ -1 +0,0 @@ -global using NUnit.Framework; \ No newline at end of file diff --git a/Tasks/Test2/Test2.Tests/ReflectorTest.cs b/Tasks/Test2/Test2.Tests/ReflectorTest.cs index 677d2d4..f6af738 100644 --- a/Tasks/Test2/Test2.Tests/ReflectorTest.cs +++ b/Tasks/Test2/Test2.Tests/ReflectorTest.cs @@ -1,14 +1,24 @@ namespace Test2.Tests; +using NUnit.Framework; + public static class ReflectorTest { - private const string ExpectedOutputPath1 = "ExpectedOutput/Output1.txt" + private const string ExpectedOutputPath1 = "ExpectedOutput/Output1.txt"; + private const string ResultPath = "TestClass.cs"; [Test] public static async Task TestReflector_PrintStructure_CompareResults() { - var expectedOutput = await File.ReadAllTextAsync(ExpectedOutputPath1) + var expectedOutput = await File.ReadAllTextAsync(ExpectedOutputPath1); await Reflector.PrintStructure(typeof(TestClass1)); - + var actualOutput = await File.ReadAllTextAsync(ResultPath); + Assert.That(actualOutput, Is.EqualTo(expectedOutput)); + } + + public static async Task TestReflector_PrintSomeTypes() + { + await Reflector.PrintStructure(typeof(Int32)); + await Reflector.PrintStructure(typeof(String)); } } diff --git a/Tasks/Test2/Test2.Tests/Test2.Tests.csproj b/Tasks/Test2/Test2.Tests/Test2.Tests.csproj index 913b827..5d9741e 100644 --- a/Tasks/Test2/Test2.Tests/Test2.Tests.csproj +++ b/Tasks/Test2/Test2.Tests/Test2.Tests.csproj @@ -7,6 +7,8 @@ false true + false + false @@ -17,14 +19,14 @@ - - - - Always + + + + diff --git a/Tasks/Test2/Test2.Tests/TestClasses/TestClass2.cs b/Tasks/Test2/Test2.Tests/TestClasses/TestClass2.cs deleted file mode 100644 index e69de29..0000000 diff --git a/Tasks/Test2/Test2.sln b/Tasks/Test2/Test2.sln index 0ee2c9f..c7474e3 100644 --- a/Tasks/Test2/Test2.sln +++ b/Tasks/Test2/Test2.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.5.002.0 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test2", "Test2.csproj", "{3E6CE21D-2E31-4029-BDF6-DA6035A9DDF5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test2", "Test2\Test2.csproj", "{3E6CE21D-2E31-4029-BDF6-DA6035A9DDF5}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test2.Tests", "Test2.Tests\Test2.Tests.csproj", "{831E003E-1101-4084-9D34-01D93677C71F}" EndProject diff --git a/Tasks/Test2/Reflector.cs b/Tasks/Test2/Test2/Reflector.cs similarity index 100% rename from Tasks/Test2/Reflector.cs rename to Tasks/Test2/Test2/Reflector.cs diff --git a/Tasks/Test2/Test2.csproj b/Tasks/Test2/Test2/Test2.csproj similarity index 100% rename from Tasks/Test2/Test2.csproj rename to Tasks/Test2/Test2/Test2.csproj From 97a235cf85ec54f7ebb6c3436bd33cf2b61f5874 Mon Sep 17 00:00:00 2001 From: bygu4 Date: Thu, 5 Dec 2024 19:10:05 +0300 Subject: [PATCH 3/8] update tests --- Tasks/Test2/Test2.Tests/ReflectorTest.cs | 5 +++-- Tasks/Test2/Test2.Tests/Test2.Tests.csproj | 2 +- Tasks/Test2/Test2/Reflector.cs | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Tasks/Test2/Test2.Tests/ReflectorTest.cs b/Tasks/Test2/Test2.Tests/ReflectorTest.cs index f6af738..bd9447c 100644 --- a/Tasks/Test2/Test2.Tests/ReflectorTest.cs +++ b/Tasks/Test2/Test2.Tests/ReflectorTest.cs @@ -5,7 +5,7 @@ namespace Test2.Tests; public static class ReflectorTest { private const string ExpectedOutputPath1 = "ExpectedOutput/Output1.txt"; - private const string ResultPath = "TestClass.cs"; + private const string ResultPath = "TestClass1.cs"; [Test] public static async Task TestReflector_PrintStructure_CompareResults() @@ -16,7 +16,8 @@ public static async Task TestReflector_PrintStructure_CompareResults() Assert.That(actualOutput, Is.EqualTo(expectedOutput)); } - public static async Task TestReflector_PrintSomeTypes() + [Test] + public static async Task TestReflector_PrintSomeTypes_NotThrowException() { await Reflector.PrintStructure(typeof(Int32)); await Reflector.PrintStructure(typeof(String)); diff --git a/Tasks/Test2/Test2.Tests/Test2.Tests.csproj b/Tasks/Test2/Test2.Tests/Test2.Tests.csproj index 5d9741e..714d7d0 100644 --- a/Tasks/Test2/Test2.Tests/Test2.Tests.csproj +++ b/Tasks/Test2/Test2.Tests/Test2.Tests.csproj @@ -20,7 +20,7 @@ - + Always diff --git a/Tasks/Test2/Test2/Reflector.cs b/Tasks/Test2/Test2/Reflector.cs index f5d0965..532b272 100644 --- a/Tasks/Test2/Test2/Reflector.cs +++ b/Tasks/Test2/Test2/Reflector.cs @@ -17,7 +17,7 @@ private static async Task PrintStructureInternal( { var indent = GetIndent(numberOfTabs); await WriteClassInfo(someClass, numberOfTabs, writer); - await writer.WriteAsync(indent + '{'); + await writer.WriteLineAsync(indent + '{'); foreach (var field in someClass.GetFields()) { await PrintField(field, numberOfTabs + 1, writer); @@ -35,7 +35,7 @@ private static async Task PrintStructureInternal( await PrintStructureInternal(nestedClass, numberOfTabs + 1, writer); } - await writer.WriteAsync(indent + '}'); + await writer.WriteLineAsync(indent + '}'); } private static async Task WriteClassInfo( From 6b7abbf163b5fb54660aa3f9aa38aaeb87a33306 Mon Sep 17 00:00:00 2001 From: bygu4 Date: Sat, 12 Apr 2025 21:25:09 +0300 Subject: [PATCH 4/8] set binding flags, update tests --- .../Test2.Tests/ExpectedOutput/Output1.txt | 27 ++++---- Tasks/Test2/Test2.Tests/ReflectorTest.cs | 6 ++ .../Test2.Tests/TestClasses/TestClass1.cs | 17 ++++- Tasks/Test2/Test2/Reflector.cs | 68 ++++++++++++------- 4 files changed, 76 insertions(+), 42 deletions(-) diff --git a/Tasks/Test2/Test2.Tests/ExpectedOutput/Output1.txt b/Tasks/Test2/Test2.Tests/ExpectedOutput/Output1.txt index 40f9e6e..445a3ab 100644 --- a/Tasks/Test2/Test2.Tests/ExpectedOutput/Output1.txt +++ b/Tasks/Test2/Test2.Tests/ExpectedOutput/Output1.txt @@ -1,17 +1,18 @@ public class TestClass1 { - public int testField1 - private static string testField2 - - public int TestMethod1(float attribute1) - public static float TestMethod2() - private string TestMethod3(string attribute1, int attribute2) - - private class NestedClass + public System.Int32 testField1; + private static System.String testField2; + public System.Int32 TestMethod1(System.Single attribute1) + public static System.Single TestMethod2() + private System.String TestMethod3(System.String attribute1, System.Int32 attribute2) + public abstract interface INestedInterface { - public float testField1; - private string testField2; - - public double TestMethod1() + public System.Void Foo() } -} \ No newline at end of file + private sealed class NestedClass + { + public System.Single testField1; + private static System.String testField2; + public System.Double TestMethod1() + } +} diff --git a/Tasks/Test2/Test2.Tests/ReflectorTest.cs b/Tasks/Test2/Test2.Tests/ReflectorTest.cs index bd9447c..1b3c858 100644 --- a/Tasks/Test2/Test2.Tests/ReflectorTest.cs +++ b/Tasks/Test2/Test2.Tests/ReflectorTest.cs @@ -1,3 +1,9 @@ +// Copyright (c) Alexander Bugaev 2024 +// +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file or at +// https://opensource.org/licenses/MIT. + namespace Test2.Tests; using NUnit.Framework; diff --git a/Tasks/Test2/Test2.Tests/TestClasses/TestClass1.cs b/Tasks/Test2/Test2.Tests/TestClasses/TestClass1.cs index 802e122..853c715 100644 --- a/Tasks/Test2/Test2.Tests/TestClasses/TestClass1.cs +++ b/Tasks/Test2/Test2.Tests/TestClasses/TestClass1.cs @@ -1,3 +1,9 @@ +// Copyright (c) Alexander Bugaev 2024 +// +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file or at +// https://opensource.org/licenses/MIT. + namespace Test2.Tests; public class TestClass1 @@ -12,14 +18,19 @@ private string TestMethod3(string attribute1, int attribute2) return "Hello"; } - private class NestedClass + public interface INestedInterface + { + void Foo(); + } + + private sealed class NestedClass { public float testField1 = 321; - private string testField2 = "abc"; + private static string testField2 = "abc"; public double TestMethod1() { throw new InvalidDataException(); } } -} \ No newline at end of file +} diff --git a/Tasks/Test2/Test2/Reflector.cs b/Tasks/Test2/Test2/Reflector.cs index 532b272..6e3d74b 100644 --- a/Tasks/Test2/Test2/Reflector.cs +++ b/Tasks/Test2/Test2/Reflector.cs @@ -1,63 +1,79 @@ -namespace Test2; +// Copyright (c) Alexander Bugaev 2024 +// +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file or at +// https://opensource.org/licenses/MIT. + +namespace Test2; using System.Reflection; public static class Reflector { - private const string Tab = " "; - - public static async Task PrintStructure(Type someClass) + private const string Indent = " "; + private const BindingFlags All = (BindingFlags)(-1); + + /// + /// Writes the signature of the given type with all fields, methods and nested classes. + /// Saves the resulting signature to the file with name of the type. + /// + /// The type to write signature of. + /// A task representing the writing process. + public static async Task PrintStructure(Type someType) { - using var writer = new StreamWriter($"{someClass.Name}.cs"); - await PrintStructureInternal(someClass, 0, writer); + using var writer = new StreamWriter($"{someType.Name}.cs"); + await PrintStructureInternal(someType, 0, writer); } private static async Task PrintStructureInternal( - Type someClass, int numberOfTabs, StreamWriter writer) + Type someType, int indentCount, StreamWriter writer) { - var indent = GetIndent(numberOfTabs); - await WriteClassInfo(someClass, numberOfTabs, writer); + var indent = GetIndent(indentCount); + await WriteClassInfo(someType, indentCount, writer); await writer.WriteLineAsync(indent + '{'); - foreach (var field in someClass.GetFields()) + + var fields = someType.GetFields(All); + var methods = someType.GetMethods(All); + var nestedTypes = someType.GetNestedTypes(All); + + foreach (var field in fields) { - await PrintField(field, numberOfTabs + 1, writer); + await PrintField(field, indentCount + 1, writer); } - await writer.WriteAsync('\n'); - foreach (var method in someClass.GetMethods()) + foreach (var method in methods) { - await PrintMethod(method, numberOfTabs + 1, writer); + await PrintMethod(method, indentCount + 1, writer); } - await writer.WriteAsync('\n'); - foreach (var nestedClass in someClass.GetNestedTypes()) + foreach (var nestedType in nestedTypes) { - await PrintStructureInternal(nestedClass, numberOfTabs + 1, writer); + await PrintStructureInternal(nestedType, indentCount + 1, writer); } await writer.WriteLineAsync(indent + '}'); } private static async Task WriteClassInfo( - Type classInfo, int numberOfTabs, StreamWriter writer) + Type classInfo, int indentCount, StreamWriter writer) { - var indent = GetIndent(numberOfTabs); + var indent = GetIndent(indentCount); var signature = GetClassSignature(classInfo); await writer.WriteLineAsync(indent + signature); } private static async Task PrintField( - FieldInfo field, int numberOfTabs, StreamWriter writer) + FieldInfo field, int indentCount, StreamWriter writer) { - var indent = GetIndent(numberOfTabs); + var indent = GetIndent(indentCount); var signature = GetFieldSignature(field); await writer.WriteLineAsync(indent + signature); } private static async Task PrintMethod( - MethodInfo method, int numberOfTabs, StreamWriter writer) + MethodInfo method, int indentCount, StreamWriter writer) { - var indent = GetIndent(numberOfTabs); + var indent = GetIndent(indentCount); var signature = GetMethodSignature(method); await writer.WriteLineAsync(indent + signature); } @@ -65,7 +81,7 @@ private static async Task PrintMethod( private static string GetClassSignature(Type classInfo) { var signature = ""; - if (classInfo.IsPublic) + if (classInfo.IsPublic || classInfo.IsNestedPublic) { signature += "public "; } @@ -147,6 +163,6 @@ private static string GetMethodSignature(MethodInfo method) return signature; } - private static string GetIndent(int numberOfTabs) - => string.Concat(Enumerable.Repeat(Tab, numberOfTabs)); + private static string GetIndent(int indentCount) + => string.Concat(Enumerable.Repeat(Indent, indentCount)); } From 6c5b2f41b375f64b530e74bd2ffb3216477697c3 Mon Sep 17 00:00:00 2001 From: bygu4 Date: Sat, 12 Apr 2025 21:31:05 +0300 Subject: [PATCH 5/8] update sln file --- Tasks/Test2/Test2.sln | 59 ++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/Tasks/Test2/Test2.sln b/Tasks/Test2/Test2.sln index c7474e3..84fc402 100644 --- a/Tasks/Test2/Test2.sln +++ b/Tasks/Test2/Test2.sln @@ -1,31 +1,28 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.5.002.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test2", "Test2\Test2.csproj", "{3E6CE21D-2E31-4029-BDF6-DA6035A9DDF5}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test2.Tests", "Test2.Tests\Test2.Tests.csproj", "{831E003E-1101-4084-9D34-01D93677C71F}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {3E6CE21D-2E31-4029-BDF6-DA6035A9DDF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3E6CE21D-2E31-4029-BDF6-DA6035A9DDF5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3E6CE21D-2E31-4029-BDF6-DA6035A9DDF5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3E6CE21D-2E31-4029-BDF6-DA6035A9DDF5}.Release|Any CPU.Build.0 = Release|Any CPU - {831E003E-1101-4084-9D34-01D93677C71F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {831E003E-1101-4084-9D34-01D93677C71F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {831E003E-1101-4084-9D34-01D93677C71F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {831E003E-1101-4084-9D34-01D93677C71F}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {963E18C0-5EA6-409C-A583-DB0620321B65} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test2", "Test2\Test2.csproj", "{23EF7123-539E-4886-9CDE-D10B48F31D66}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test2.Tests", "Test2.Tests\Test2.Tests.csproj", "{F46F0B0F-FF0D-470B-A0C0-2460BD3B9D3F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {23EF7123-539E-4886-9CDE-D10B48F31D66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {23EF7123-539E-4886-9CDE-D10B48F31D66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {23EF7123-539E-4886-9CDE-D10B48F31D66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {23EF7123-539E-4886-9CDE-D10B48F31D66}.Release|Any CPU.Build.0 = Release|Any CPU + {F46F0B0F-FF0D-470B-A0C0-2460BD3B9D3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F46F0B0F-FF0D-470B-A0C0-2460BD3B9D3F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F46F0B0F-FF0D-470B-A0C0-2460BD3B9D3F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F46F0B0F-FF0D-470B-A0C0-2460BD3B9D3F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal From aae927c9278091dc8489b2b49f28755bfdbcb7ba Mon Sep 17 00:00:00 2001 From: bygu4 Date: Sat, 12 Apr 2025 21:33:54 +0300 Subject: [PATCH 6/8] update comments and target framework --- Tasks/Test2/Test2.Tests/Test2.Tests.csproj | 2 +- Tasks/Test2/Test2/Reflector.cs | 3 +++ Tasks/Test2/Test2/Test2.csproj | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Tasks/Test2/Test2.Tests/Test2.Tests.csproj b/Tasks/Test2/Test2.Tests/Test2.Tests.csproj index 714d7d0..cfd3713 100644 --- a/Tasks/Test2/Test2.Tests/Test2.Tests.csproj +++ b/Tasks/Test2/Test2.Tests/Test2.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable enable diff --git a/Tasks/Test2/Test2/Reflector.cs b/Tasks/Test2/Test2/Reflector.cs index 6e3d74b..5abc254 100644 --- a/Tasks/Test2/Test2/Reflector.cs +++ b/Tasks/Test2/Test2/Reflector.cs @@ -8,6 +8,9 @@ namespace Test2; using System.Reflection; +/// +/// Class containing utility for printing type signatures using reflection. +/// public static class Reflector { private const string Indent = " "; diff --git a/Tasks/Test2/Test2/Test2.csproj b/Tasks/Test2/Test2/Test2.csproj index fa71b7a..125f4c9 100644 --- a/Tasks/Test2/Test2/Test2.csproj +++ b/Tasks/Test2/Test2/Test2.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 enable enable From 9de20d6efeb18a95d77d3776962d10292f6ef81f Mon Sep 17 00:00:00 2001 From: bygu4 Date: Sat, 12 Apr 2025 21:37:53 +0300 Subject: [PATCH 7/8] remove redundant sln file --- Test2.sln | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 Test2.sln diff --git a/Test2.sln b/Test2.sln deleted file mode 100644 index f03d9ed..0000000 --- a/Test2.sln +++ /dev/null @@ -1,27 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tasks", "Tasks", "{AE05F47D-4707-43A4-978D-37D7155FD65E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test2", "Tasks\Test2\Test2.csproj", "{56E15C84-FC37-4EB2-B28B-91DE7464DEB8}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {56E15C84-FC37-4EB2-B28B-91DE7464DEB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {56E15C84-FC37-4EB2-B28B-91DE7464DEB8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {56E15C84-FC37-4EB2-B28B-91DE7464DEB8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {56E15C84-FC37-4EB2-B28B-91DE7464DEB8}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {56E15C84-FC37-4EB2-B28B-91DE7464DEB8} = {AE05F47D-4707-43A4-978D-37D7155FD65E} - EndGlobalSection -EndGlobal From c60c77482a3f9f3b81d81821170dd40609f26d35 Mon Sep 17 00:00:00 2001 From: bygu4 Date: Sat, 12 Apr 2025 21:55:16 +0300 Subject: [PATCH 8/8] add semicolons after methods --- Tasks/Test2/Test2.Tests/ExpectedOutput/Output1.txt | 10 +++++----- Tasks/Test2/Test2/Reflector.cs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Tasks/Test2/Test2.Tests/ExpectedOutput/Output1.txt b/Tasks/Test2/Test2.Tests/ExpectedOutput/Output1.txt index 445a3ab..bda34a9 100644 --- a/Tasks/Test2/Test2.Tests/ExpectedOutput/Output1.txt +++ b/Tasks/Test2/Test2.Tests/ExpectedOutput/Output1.txt @@ -2,17 +2,17 @@ public class TestClass1 { public System.Int32 testField1; private static System.String testField2; - public System.Int32 TestMethod1(System.Single attribute1) - public static System.Single TestMethod2() - private System.String TestMethod3(System.String attribute1, System.Int32 attribute2) + public System.Int32 TestMethod1(System.Single attribute1); + public static System.Single TestMethod2(); + private System.String TestMethod3(System.String attribute1, System.Int32 attribute2); public abstract interface INestedInterface { - public System.Void Foo() + public System.Void Foo(); } private sealed class NestedClass { public System.Single testField1; private static System.String testField2; - public System.Double TestMethod1() + public System.Double TestMethod1(); } } diff --git a/Tasks/Test2/Test2/Reflector.cs b/Tasks/Test2/Test2/Reflector.cs index 5abc254..33c2b6b 100644 --- a/Tasks/Test2/Test2/Reflector.cs +++ b/Tasks/Test2/Test2/Reflector.cs @@ -162,7 +162,7 @@ private static string GetMethodSignature(MethodInfo method) } signature += string.Join(", ", parameters); - signature += ')'; + signature += ");"; return signature; }