diff --git a/TestPlatform.sln b/TestPlatform.sln index 321f401295..ce073a3a41 100644 --- a/TestPlatform.sln +++ b/TestPlatform.sln @@ -82,17 +82,17 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{EE49F5DC-5835-4AE3-B3BA-8BDE0AD56330}" ProjectSection(SolutionItems) = preProject scripts\build.ps1 = scripts\build.ps1 + scripts\build.sh = scripts\build.sh + scripts\PortableToFullPdb.ps1 = scripts\PortableToFullPdb.ps1 scripts\stylecop.json = scripts\stylecop.json scripts\stylecop.ruleset = scripts\stylecop.ruleset scripts\stylecop.test.ruleset = scripts\stylecop.test.ruleset scripts\test.ps1 = scripts\test.ps1 - scripts\verify-sign.ps1 = scripts\verify-sign.ps1 + scripts\test.sh = scripts\test.sh scripts\verify-nupkgs.ps1 = scripts\verify-nupkgs.ps1 - scripts\PortableToFullPdb.ps1 = scripts\PortableToFullPdb.ps1 + scripts\verify-sign.ps1 = scripts\verify-sign.ps1 scripts\vsts-prebuild.ps1 = scripts\vsts-prebuild.ps1 scripts\write-release-notes.ps1 = scripts\write-release-notes.ps1 - scripts\build.sh = scripts\build.sh - scripts\test.sh = scripts\test.sh EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E344E0A2-7715-4C7F-BAF7-D64EA94CB19B}" @@ -818,6 +818,8 @@ Global {9EFCEFB5-253E-4DE2-8A70-821D7B8189DF} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} {3A8080FB-9C93-45B9-8EB5-828DDC31FDF0} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} {BFF7714C-E5A3-4EEB-B04B-5FA47F29AD03} = {020E15EA-731F-4667-95AF-226671E0C3AE} + {0D4DF78D-7E5F-4516-B19F-E6AA71A1DBF4} = {EE49F5DC-5835-4AE3-B3BA-8BDE0AD56330} + {DED1590A-ED25-413B-8590-006A4DD5B2FD} = {EE49F5DC-5835-4AE3-B3BA-8BDE0AD56330} {E344E0A2-7715-4C7F-BAF7-D64EA94CB19B} = {EE49F5DC-5835-4AE3-B3BA-8BDE0AD56330} {DD9382B5-5EC4-4B3D-BEB7-95423731AE29} = {46250E12-4CF1-4051-B4A7-80C8C06E0068} {156F8811-28BB-4EC7-87D9-434F10FB7DBE} = {46250E12-4CF1-4051-B4A7-80C8C06E0068} @@ -829,7 +831,6 @@ Global {CAE652AF-6801-425E-AAF3-AB20DE7DF88E} = {7D4082EA-7AC9-4DFB-98E8-C5E08BDC0EC3} {FF80D706-8309-4E02-BAC0-D28B4CBCF600} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} {7D4082EA-7AC9-4DFB-98E8-C5E08BDC0EC3} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} - {DED1590A-ED25-413B-8590-006A4DD5B2FD} = {EE49F5DC-5835-4AE3-B3BA-8BDE0AD56330} {E141A226-CC0A-4F26-BD17-4AE427D81C3B} = {D27E1CB4-C641-4C6C-A140-EF5F6215AE29} {376C19DE-31E2-4FF6-88FC-0D0D6233C999} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} {3E698655-0701-482E-9AA7-F956F6337FC7} = {376C19DE-31E2-4FF6-88FC-0D0D6233C999} @@ -842,7 +843,6 @@ Global {65A25D6E-C9CC-4F45-8925-04087AC82634} = {B705537C-B82C-4A30-AFA5-6244D9A7DAEB} {D9A30E32-D466-4EC5-B4F2-62E17562279B} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} {21DB138B-85B7-479E-91FE-01E0F972EC56} = {D9A30E32-D466-4EC5-B4F2-62E17562279B} - {0D4DF78D-7E5F-4516-B19F-E6AA71A1DBF4} = {EE49F5DC-5835-4AE3-B3BA-8BDE0AD56330} {8C068694-23A2-47A2-A0DD-DB82D0AF0142} = {376C19DE-31E2-4FF6-88FC-0D0D6233C999} {24C7683D-2607-4901-B8EB-83A57E49E93D} = {376C19DE-31E2-4FF6-88FC-0D0D6233C999} {69F5FF81-5615-4F06-B83C-FCF979BB84CA} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959} @@ -850,7 +850,7 @@ Global {236A71E3-01DA-4679-9DFF-16A8E079ACFF} = {5E7F18A8-F843-4C8A-AB02-4C7D9205C6CF} {41248B96-6E15-4E5E-A78F-859897676814} = {020E15EA-731F-4667-95AF-226671E0C3AE} {074F5BD6-DC05-460B-B78F-044D125FD787} = {D9A30E32-D466-4EC5-B4F2-62E17562279B} - {DCD0C39E-C78C-4A44-B0BD-7325254A2E97} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6} + {DCD0C39E-C78C-4A44-B0BD-7325254A2E97} = {376C19DE-31E2-4FF6-88FC-0D0D6233C999} {2DE99835-A3A3-4922-82AD-6D10D284816D} = {7D4082EA-7AC9-4DFB-98E8-C5E08BDC0EC3} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/scripts/build.ps1 b/scripts/build.ps1 index d7af546be0..de6ebdf051 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -122,6 +122,7 @@ $env:MSBUILD_VERSION = "15.0" Write-Verbose "Setup build configuration." $TPB_Solution = "TestPlatform.sln" $TPB_TestAssets_Solution = Join-Path $env:TP_ROOT_DIR "test\TestAssets\TestAssets.sln" +$TPB_TestAssets_CILAssets = Join-Path $env:TP_ROOT_DIR "test\TestAssets\CILProject\CILProject.proj" $TPB_TargetFramework45 = "net45" $TPB_TargetFramework451 = "net451" $TPB_TargetFramework472 = "net472" @@ -277,6 +278,11 @@ function Invoke-Build & $dotnetExe build $TPB_Solution --configuration $TPB_Configuration -v:minimal -p:Version=$TPB_Version -p:CIBuild=$TPB_CIBuild -p:LocalizedBuild=$TPB_LocalizedBuild -bl:TestPlatform.binlog Write-Log ".. .. Build: Complete." + Write-Log ".. .. Build: Source: $TPB_TestAssets_CILAssets" + Write-Verbose "$dotnetExe build $TPB_TestAssets_CILAssets --configuration $TPB_Configuration -v:minimal -p:Version=$TPB_Version -p:CIBuild=$TPB_CIBuild" + & $dotnetExe build $TPB_TestAssets_CILAssets --configuration $TPB_Configuration -v:minimal -p:CIBuild=$TPB_CIBuild -p:LocalizedBuild=$TPB_LocalizedBuild -bl:"$($env:TP_ROOT_DIR)\CILAssets.binlog" + Write-Log ".. .. Build: Complete." + Set-ScriptFailedOnError Write-Log "Invoke-Build: Complete. {$(Get-ElapsedTime($timer))}" diff --git a/scripts/build/TestPlatform.Dependencies.props b/scripts/build/TestPlatform.Dependencies.props index 6c49704de9..9d1b7bb08d 100644 --- a/scripts/build/TestPlatform.Dependencies.props +++ b/scripts/build/TestPlatform.Dependencies.props @@ -29,6 +29,7 @@ 1.1.1 5.0.0 + 5.0.0 9.0.1 4.7.63 16.9.0-preview-4267359 diff --git a/scripts/test.ps1 b/scripts/test.ps1 index 576849ddf3..62dd097e33 100644 --- a/scripts/test.ps1 +++ b/scripts/test.ps1 @@ -207,6 +207,7 @@ function Invoke-Test } else { + Write-Log ".. . $testContainerName test container found. ($testOutputPath)" $testContainers += ,"$testContainerPath" } } diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.cs b/src/Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.cs index 2b30b8c129..41631c5ef5 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.cs +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Helpers/ReflectionHelpers.cs @@ -3,9 +3,12 @@ namespace Microsoft.TestPlatform.AdapterUtilities.Helpers { + using Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities; using Microsoft.TestPlatform.AdapterUtilities.Resources; using System; + using System.Globalization; + using System.Text; internal static partial class ReflectionHelpers { @@ -17,5 +20,79 @@ private static void AssertSupport(T obj, string methodName, string className) throw new NotImplementedException(string.Format(Resources.MethodNotImplementedOnPlatform, className, methodName)); } } + + internal static string ParseEscapedString(string escapedString) + { + var stringBuilder = new StringBuilder(); + var end = 0; + for (int i = 0; i < escapedString.Length; i++) + { + if (escapedString[i] == '\'') + { + stringBuilder.Append(escapedString, end, i - end); + end = i = ParseEscapedStringSegment(escapedString, i + 1, stringBuilder); + } + } + + if (stringBuilder.Length == 0) + { + return escapedString; + } + + if (end != 0 && end < escapedString.Length) + { + stringBuilder.Append(escapedString, end, escapedString.Length - end); + } + + return stringBuilder.ToString(); + } + + // Unescapes a C# style escaped string. + private static int ParseEscapedStringSegment(string escapedStringSegment, int pos, StringBuilder stringBuilder) + { + for (int i = pos; i < escapedStringSegment.Length; i++) + { + switch (escapedStringSegment[i]) + { + case '\\': + if (escapedStringSegment[i + 1] == 'u') + { + char c; + + try + { + var code = escapedStringSegment.Substring(i + 2, 4); + c = (char)Convert.ToInt32(code, 16); + } + catch + { + throw new InvalidManagedNameException( + string.Format(CultureInfo.CurrentCulture, Resources.ErrorInvalidSequenceAt, escapedStringSegment, i) + ); + } + + stringBuilder.Append(c); + i += 5; + } + else + { + stringBuilder.Append(escapedStringSegment[i + 1]); + i += 1; + } + + break; + + case '\'': + return i + 1; + + default: + stringBuilder.Append(escapedStringSegment[i]); + break; + } + } + + string message = string.Format(CultureInfo.CurrentCulture, Resources.ErrorNoClosingQuote, escapedStringSegment); + throw new InvalidManagedNameException(message); + } } } diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameHelper.Reflection.cs b/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameHelper.Reflection.cs index 93a0defca5..92421b6dff 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameHelper.Reflection.cs +++ b/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameHelper.Reflection.cs @@ -80,15 +80,15 @@ public static void GetManagedName(MethodBase method, out string managedTypeName, method = ((MethodInfo)method).GetGenericMethodDefinition(); } - var methodBuilder = new StringBuilder(); var typeBuilder = new StringBuilder(); + var methodBuilder = new StringBuilder(); // Namespace and Type Name (with arity designation) AppendTypeString(typeBuilder, semanticType, closedType: false); // Method Name with method arity - methodBuilder.Append(method.Name); var arity = method.GetGenericArguments().Length; + AppendMethodString(methodBuilder, method.Name, arity); if (arity > 0) { methodBuilder.Append('`'); @@ -143,12 +143,14 @@ public static MethodBase GetMethod(Assembly assembly, string managedTypeName, st { Type type; + var parsedManagedTypeName = ReflectionHelpers.ParseEscapedString(managedTypeName); + #if !NETSTANDARD1_0 && !NETSTANDARD1_3 && !WINDOWS_UWP - type = assembly.GetType(managedTypeName, throwOnError: false, ignoreCase: false); + type = assembly.GetType(parsedManagedTypeName, throwOnError: false, ignoreCase: false); #else try { - type = assembly.GetType(managedTypeName); + type = assembly.GetType(parsedManagedTypeName); } catch { @@ -158,14 +160,14 @@ public static MethodBase GetMethod(Assembly assembly, string managedTypeName, st if (type == null) { - string message = string.Format(CultureInfo.CurrentCulture, Resources.ErrorTypeNotFound, managedTypeName); + string message = string.Format(CultureInfo.CurrentCulture, Resources.ErrorTypeNotFound, parsedManagedTypeName); throw new InvalidManagedNameException(message); } MethodInfo method = null; ManagedNameParser.ParseManagedMethodName(managedMethodName, out var methodName, out var methodArity, out var parameterTypes); -#if NET20 || NET35 +#if NET20 || NET35 if (!IsNullOrWhiteSpace(methodName)) #else if (!string.IsNullOrWhiteSpace(methodName)) @@ -205,7 +207,7 @@ bool filter(MemberInfo mbr, object param) for (int i = 0; i < paramList.Length; i++) { - if (TypeString(paramList[i].ParameterType, closedType: true) != parameterTypes[i]) + if (GetTypeString(paramList[i].ParameterType, closedType: true) != parameterTypes[i]) { return false; } @@ -254,7 +256,7 @@ private static void AppendTypeString(StringBuilder b, Type type, bool closedType } else { - b.Append(type.Namespace); + AppendNamespace(b, type.Namespace); b.Append('.'); AppendNestedTypeName(b, type); @@ -266,14 +268,131 @@ private static void AppendTypeString(StringBuilder b, Type type, bool closedType } } - private static void AppendNestedTypeName(StringBuilder b, Type type) + private static void AppendNamespace(StringBuilder b, string namespaceString) + { + int start = 0; + bool shouldEscape = false; + + for (int i = 0; i <= namespaceString.Length; i++) + { + if (i == namespaceString.Length || namespaceString[i] == '.') + { + if (start != 0) + { + b.Append('.'); + } + + var part = namespaceString.Substring(start, i - start); + if (shouldEscape) + { + NormalizeAndAppendString(b, part); + shouldEscape = false; + } + else + { + b.Append(part); + } + + start = i + 1; + continue; + } + + shouldEscape = shouldEscape || NeedsEscaping(namespaceString[i], i - start); + } + } + + private static void AppendMethodString(StringBuilder methodBuilder, string name, int methodArity) { + var arityStart = name.LastIndexOf('`'); + var arity = 0; + if (arityStart > 0) + { + arityStart++; + var arityString = name.Substring(arityStart, name.Length - arityStart); + if (int.TryParse(arityString, out arity)) + { + if (arity == methodArity) + { + name = name.Substring(0, arityStart - 1); + } + } + } + + if (IsNormalized(name)) + { + methodBuilder.Append(name); + } + else + { + NormalizeAndAppendString(methodBuilder, name); + } + + if (arity > 0 && methodArity == arity) + { + methodBuilder.Append($"`{arity}"); + } + } + + private static void NormalizeAndAppendString(StringBuilder b, string name) + { + b.Append("'"); + for (int i = 0; i < name.Length; i++) + { + char c = name[i]; + if (NeedsEscaping(c, i)) + { + if (c == '\\' || c == '\'') + { + // var encoded = Convert.ToString(((uint)c), 16); + // b.Append("\\u"); + // b.Append('0', 4 - encoded.Length); + // b.Append(encoded); + + b.Append("\\"); + b.Append(c); + continue; + } + } + + b.Append(c); + } + b.Append("'"); + } + + private static int AppendNestedTypeName(StringBuilder b, Type type) + { + var outerArity = 0; if (type.IsNested) { - AppendNestedTypeName(b, type.DeclaringType); + outerArity = AppendNestedTypeName(b, type.DeclaringType); b.Append('+'); } - b.Append(type.Name); + + var typeName = type.Name; + var stars = 0; + if (type.IsPointer) + { + for (int i = typeName.Length - 1; i > 0; i--) + { + if (typeName[i] != '*') + { + stars = typeName.Length - i - 1; + typeName = typeName.Substring(0, i + 1); + break; + } + } + } + + var info = type.GetTypeInfo(); + var arity = !info.IsGenericType + ? 0 + : info.GenericTypeParameters.Length > 0 + ? info.GenericTypeParameters.Length + : info.GenericTypeArguments.Length; + + AppendMethodString(b, typeName, arity - outerArity); + b.Append('*', stars); + return arity; } private static void AppendGenericTypeParameters(StringBuilder b, Type type) @@ -299,7 +418,46 @@ private static void AppendGenericTypeParameters(StringBuilder b, Type type) } } - private static string TypeString(Type type, bool closedType) + private static bool IsNormalized(string s) + { + for (int i = 0; i < s.Length; i++) + { + if (NeedsEscaping(s[i], i) && s[i] != '.') + { + return false; + } + } + + return true; + } + + private static bool NeedsEscaping(char c, int pos) + { + if (pos == 0 && char.IsDigit(c)) + { + return true; + } + + if (c == '_' + || char.IsLetterOrDigit(c) // Lu, Ll, Lt, Lm, Lo, or Nl + ) + { + return false; + } + + var category = CharUnicodeInfo.GetUnicodeCategory(c); + if (category == UnicodeCategory.NonSpacingMark // Mn + || category == UnicodeCategory.SpacingCombiningMark // Mc + || category == UnicodeCategory.ConnectorPunctuation // Pc + || category == UnicodeCategory.Format) // Cf + { + return false; + } + + return true; + } + + private static string GetTypeString(Type type, bool closedType) { var builder = new StringBuilder(); AppendTypeString(builder, type, closedType); diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameParser.cs b/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameParser.cs index bf707f74c8..e61537ab75 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameParser.cs +++ b/src/Microsoft.TestPlatform.AdapterUtilities/ManagedNameUtilities/ManagedNameParser.cs @@ -3,6 +3,7 @@ namespace Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities { + using Microsoft.TestPlatform.AdapterUtilities.Helpers; using Microsoft.TestPlatform.AdapterUtilities.Resources; using System.Collections.Generic; @@ -66,7 +67,8 @@ public static void ParseManagedTypeName(string managedTypeName, out string names /// public static void ParseManagedMethodName(string managedMethodName, out string methodName, out int arity, out string[] parameterTypes) { - int pos = ParseMethodName(managedMethodName, 0, out methodName, out arity); + int pos = ParseMethodName(managedMethodName, 0, out var escapedMethodName, out arity); + methodName = ReflectionHelpers.ParseEscapedString(escapedMethodName); pos = ParseParameterTypeList(managedMethodName, pos, out parameterTypes); if (pos != managedMethodName.Length) { @@ -80,17 +82,27 @@ private static string Capture(string managedMethodName, int start, int end) private static int ParseMethodName(string managedMethodName, int start, out string methodName, out int arity) { - int i = start; + var i = start; + var quoted = false; for (; i < managedMethodName.Length; i++) { - switch (managedMethodName[i]) + var c = managedMethodName[i]; + if (c == '\'' || quoted) + { + quoted = c == '\'' ? !quoted : quoted; + continue; + } + + switch (c) { case var w when char.IsWhiteSpace(w): string message = string.Format(CultureInfo.CurrentCulture, Resources.ErrorWhitespaceNotValid, i); throw new InvalidManagedNameException(message); + case '`': methodName = Capture(managedMethodName, start, i); return ParseArity(managedMethodName, i, out arity); + case '(': methodName = Capture(managedMethodName, start, i); arity = 0; @@ -143,8 +155,10 @@ private static int ParseParameterTypeList(string managedMethodName, int start, o parameterTypes = types.ToArray(); } return i + 1; // consume right parens + case ',': break; + default: i = ParseParameterType(managedMethodName, i, out var parameterType); types.Add(parameterType); @@ -159,22 +173,32 @@ private static int ParseParameterTypeList(string managedMethodName, int start, o private static int ParseParameterType(string managedMethodName, int start, out string parameterType) { parameterType = string.Empty; + var quoted = false; int i = start; - for (; i < managedMethodName.Length; i++) + for (i = start; i < managedMethodName.Length; i++) { + if (managedMethodName[i] == '\'' || quoted) + { + quoted = managedMethodName[i] == '\'' ? !quoted : quoted; + continue; + } + switch (managedMethodName[i]) { case '<': i = ParseGenericBrackets(managedMethodName, i + 1); break; + case '[': i = ParseArrayBrackets(managedMethodName, i + 1); break; + case ',': case ')': parameterType = Capture(managedMethodName, start, i); return i - 1; + case var w when char.IsWhiteSpace(w): string message = string.Format(CultureInfo.CurrentCulture, Resources.ErrorWhitespaceNotValid, i); throw new InvalidManagedNameException(message); @@ -185,8 +209,16 @@ private static int ParseParameterType(string managedMethodName, int start, out s private static int ParseArrayBrackets(string managedMethodName, int start) { + var quoted = false; + for (int i = start; i < managedMethodName.Length; i++) { + if (managedMethodName[i] == '\'' || quoted) + { + quoted = managedMethodName[i] == '\'' ? !quoted : quoted; + continue; + } + switch (managedMethodName[i]) { case ']': @@ -203,15 +235,25 @@ private static int ParseArrayBrackets(string managedMethodName, int start) private static int ParseGenericBrackets(string managedMethodName, int start) { + var quoted = false; + for (int i = start; i < managedMethodName.Length; i++) { + if (managedMethodName[i] == '\'' || quoted) + { + quoted = managedMethodName[i] == '\'' ? !quoted : quoted; + continue; + } + switch (managedMethodName[i]) { case '<': i = ParseGenericBrackets(managedMethodName, i + 1); break; + case '>': return i; + case var w when char.IsWhiteSpace(w): string msg = string.Format(CultureInfo.CurrentCulture, Resources.ErrorWhitespaceNotValid, i); throw new InvalidManagedNameException(msg); diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.Designer.cs b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.Designer.cs index 039f006b5e..0239a66dd2 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.Designer.cs +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.Designer.cs @@ -131,5 +131,27 @@ internal static string MethodNotImplementedOnPlatform return ResourceManager.GetString("MethodNotImplementedOnPlatform", resourceCulture); } } + + /// + /// Looks up a localized string similar to A closing single quote was expected at the end of the segment! (segment: {0}). + /// + internal static string ErrorNoClosingQuote + { + get + { + return ResourceManager.GetString("ErrorNoClosingQuote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid escape sequence! (segment: {0}, pos: {1}) + /// + internal static string ErrorInvalidSequenceAt + { + get + { + return ResourceManager.GetString("ErrorInvalidSequenceAt", resourceCulture); + } + } } } diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.resx b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.resx index da81725acf..52fe4e0b37 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.resx +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/Resources.resx @@ -120,6 +120,10 @@ ManagedName is incomplete + + Invalid escape sequence! (segment: {0}, pos: {1}) + An escape sequence started with '\', but it wasn't legal. {0}: Invalid string, {1}: starting postion of invalid sequence. + Method arity must be numeric @@ -127,6 +131,10 @@ Method '{0}' not found on type '{1}' {0} is the method name, {1} is the full type name. + + A closing single quote was expected at the end of the segment! (segment: {0}) + An error thrown when the type name ended but opened single qoute was not matched. + Type '{0}' not found {0} is the full type name. diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.cs.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.cs.xlf index 77e0cf29b0..9c66651779 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.cs.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.cs.xlf @@ -39,6 +39,16 @@ Example: 'System.Reflection.MethodBase' is not implemented on this platform! + + Invalid escape sequence! (segment: {0}, pos: {1}) + Invalid escape sequence! (segment: {0}, pos: {1}) + An escape sequence started with '\', but it wasn't legal. {0}: Invalid string, {1}: starting postion of invalid sequence. + + + A closing single quote was expected at the end of the segment! (segment: {0}) + A closing single quote was expected at the end of the segment! (segment: {0}) + An error thrown when the type name ended but opened single qoute was not matched. + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.de.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.de.xlf index cc3be8f402..5511eba1e6 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.de.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.de.xlf @@ -39,6 +39,16 @@ Example: 'System.Reflection.MethodBase' is not implemented on this platform! + + Invalid escape sequence! (segment: {0}, pos: {1}) + Invalid escape sequence! (segment: {0}, pos: {1}) + An escape sequence started with '\', but it wasn't legal. {0}: Invalid string, {1}: starting postion of invalid sequence. + + + A closing single quote was expected at the end of the segment! (segment: {0}) + A closing single quote was expected at the end of the segment! (segment: {0}) + An error thrown when the type name ended but opened single qoute was not matched. + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.es.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.es.xlf index 111e6b9dd4..bae3fc5372 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.es.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.es.xlf @@ -39,6 +39,16 @@ Example: 'System.Reflection.MethodBase' is not implemented on this platform! + + Invalid escape sequence! (segment: {0}, pos: {1}) + Invalid escape sequence! (segment: {0}, pos: {1}) + An escape sequence started with '\', but it wasn't legal. {0}: Invalid string, {1}: starting postion of invalid sequence. + + + A closing single quote was expected at the end of the segment! (segment: {0}) + A closing single quote was expected at the end of the segment! (segment: {0}) + An error thrown when the type name ended but opened single qoute was not matched. + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.fr.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.fr.xlf index 13be1b762b..57b0689ad5 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.fr.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.fr.xlf @@ -39,6 +39,16 @@ Example: 'System.Reflection.MethodBase' is not implemented on this platform! + + Invalid escape sequence! (segment: {0}, pos: {1}) + Invalid escape sequence! (segment: {0}, pos: {1}) + An escape sequence started with '\', but it wasn't legal. {0}: Invalid string, {1}: starting postion of invalid sequence. + + + A closing single quote was expected at the end of the segment! (segment: {0}) + A closing single quote was expected at the end of the segment! (segment: {0}) + An error thrown when the type name ended but opened single qoute was not matched. + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.it.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.it.xlf index 1602378445..7e1f6c0ee9 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.it.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.it.xlf @@ -39,6 +39,16 @@ Example: 'System.Reflection.MethodBase' is not implemented on this platform! + + Invalid escape sequence! (segment: {0}, pos: {1}) + Invalid escape sequence! (segment: {0}, pos: {1}) + An escape sequence started with '\', but it wasn't legal. {0}: Invalid string, {1}: starting postion of invalid sequence. + + + A closing single quote was expected at the end of the segment! (segment: {0}) + A closing single quote was expected at the end of the segment! (segment: {0}) + An error thrown when the type name ended but opened single qoute was not matched. + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ja.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ja.xlf index 2bc25ce3ae..475a14a8be 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ja.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ja.xlf @@ -39,6 +39,16 @@ Example: 'System.Reflection.MethodBase' is not implemented on this platform! + + Invalid escape sequence! (segment: {0}, pos: {1}) + Invalid escape sequence! (segment: {0}, pos: {1}) + An escape sequence started with '\', but it wasn't legal. {0}: Invalid string, {1}: starting postion of invalid sequence. + + + A closing single quote was expected at the end of the segment! (segment: {0}) + A closing single quote was expected at the end of the segment! (segment: {0}) + An error thrown when the type name ended but opened single qoute was not matched. + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ko.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ko.xlf index 2ef4e1cdc3..9689268c15 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ko.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ko.xlf @@ -39,6 +39,16 @@ Example: 'System.Reflection.MethodBase' is not implemented on this platform! + + Invalid escape sequence! (segment: {0}, pos: {1}) + Invalid escape sequence! (segment: {0}, pos: {1}) + An escape sequence started with '\', but it wasn't legal. {0}: Invalid string, {1}: starting postion of invalid sequence. + + + A closing single quote was expected at the end of the segment! (segment: {0}) + A closing single quote was expected at the end of the segment! (segment: {0}) + An error thrown when the type name ended but opened single qoute was not matched. + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pl.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pl.xlf index 9f40119244..20b2d8ad32 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pl.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pl.xlf @@ -39,6 +39,16 @@ Example: 'System.Reflection.MethodBase' is not implemented on this platform! + + Invalid escape sequence! (segment: {0}, pos: {1}) + Invalid escape sequence! (segment: {0}, pos: {1}) + An escape sequence started with '\', but it wasn't legal. {0}: Invalid string, {1}: starting postion of invalid sequence. + + + A closing single quote was expected at the end of the segment! (segment: {0}) + A closing single quote was expected at the end of the segment! (segment: {0}) + An error thrown when the type name ended but opened single qoute was not matched. + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pt-BR.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pt-BR.xlf index 6e08e8348c..1df561a023 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pt-BR.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.pt-BR.xlf @@ -39,6 +39,16 @@ Example: 'System.Reflection.MethodBase' is not implemented on this platform! + + Invalid escape sequence! (segment: {0}, pos: {1}) + Invalid escape sequence! (segment: {0}, pos: {1}) + An escape sequence started with '\', but it wasn't legal. {0}: Invalid string, {1}: starting postion of invalid sequence. + + + A closing single quote was expected at the end of the segment! (segment: {0}) + A closing single quote was expected at the end of the segment! (segment: {0}) + An error thrown when the type name ended but opened single qoute was not matched. + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ru.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ru.xlf index 98ab3c94da..4b42002335 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ru.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.ru.xlf @@ -39,6 +39,16 @@ Example: 'System.Reflection.MethodBase' is not implemented on this platform! + + Invalid escape sequence! (segment: {0}, pos: {1}) + Invalid escape sequence! (segment: {0}, pos: {1}) + An escape sequence started with '\', but it wasn't legal. {0}: Invalid string, {1}: starting postion of invalid sequence. + + + A closing single quote was expected at the end of the segment! (segment: {0}) + A closing single quote was expected at the end of the segment! (segment: {0}) + An error thrown when the type name ended but opened single qoute was not matched. + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.tr.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.tr.xlf index fb6cc464b2..beac02557b 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.tr.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.tr.xlf @@ -39,6 +39,16 @@ Example: 'System.Reflection.MethodBase' is not implemented on this platform! + + Invalid escape sequence! (segment: {0}, pos: {1}) + Invalid escape sequence! (segment: {0}, pos: {1}) + An escape sequence started with '\', but it wasn't legal. {0}: Invalid string, {1}: starting postion of invalid sequence. + + + A closing single quote was expected at the end of the segment! (segment: {0}) + A closing single quote was expected at the end of the segment! (segment: {0}) + An error thrown when the type name ended but opened single qoute was not matched. + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.xlf index 232d95bf2d..cb8d1c6ab6 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.xlf @@ -33,6 +33,16 @@ Example: 'System.Reflection.MethodBase' is not implemented on this platform! + + Invalid escape sequence! (segment: {0}, pos: {1}) + Invalid escape sequence! (segment: {0}, pos: {1}) + An escape sequence started with '\', but it wasn't legal. {0}: Invalid string, {1}: starting postion of invalid sequence. + + + A closing single quote was expected at the end of the segment! (segment: {0}) + A closing single quote was expected at the end of the segment! (segment: {0}) + An error thrown when the type name ended but opened single qoute was not matched. + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hans.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hans.xlf index 2a3e79c29d..5995212d21 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hans.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hans.xlf @@ -39,6 +39,16 @@ Example: 'System.Reflection.MethodBase' is not implemented on this platform! + + Invalid escape sequence! (segment: {0}, pos: {1}) + Invalid escape sequence! (segment: {0}, pos: {1}) + An escape sequence started with '\', but it wasn't legal. {0}: Invalid string, {1}: starting postion of invalid sequence. + + + A closing single quote was expected at the end of the segment! (segment: {0}) + A closing single quote was expected at the end of the segment! (segment: {0}) + An error thrown when the type name ended but opened single qoute was not matched. + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hant.xlf b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hant.xlf index b722fc446f..bc445fc74d 100644 --- a/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hant.xlf +++ b/src/Microsoft.TestPlatform.AdapterUtilities/Resources/xlf/Resources.zh-Hant.xlf @@ -39,6 +39,16 @@ Example: 'System.Reflection.MethodBase' is not implemented on this platform! + + Invalid escape sequence! (segment: {0}, pos: {1}) + Invalid escape sequence! (segment: {0}, pos: {1}) + An escape sequence started with '\', but it wasn't legal. {0}: Invalid string, {1}: starting postion of invalid sequence. + + + A closing single quote was expected at the end of the segment! (segment: {0}) + A closing single quote was expected at the end of the segment! (segment: {0}) + An error thrown when the type name ended but opened single qoute was not matched. + \ No newline at end of file diff --git a/src/package/external/external.csproj b/src/package/external/external.csproj index 4627131052..8fd05e8e83 100644 --- a/src/package/external/external.csproj +++ b/src/package/external/external.csproj @@ -108,6 +108,9 @@ 1.0.0 All + + + diff --git a/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/ManagedNameParserTests.cs b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/ManagedNameParserTests.cs index 5747d460da..416a182b35 100644 --- a/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/ManagedNameParserTests.cs +++ b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/ManagedNameParserTests.cs @@ -70,6 +70,5 @@ public void ParseInvalidMethodName() Assert.ThrowsException(() => Parse("Method("), "ManagedName is incomplete"); Assert.ThrowsException(() => Parse("Method`4a"), "Method arity must be numeric"); } - } } diff --git a/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/ManagedNameRoundTripTests.cs b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/ManagedNameRoundTripTests.cs index 5ff18ae6ad..12bb5cd280 100644 --- a/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/ManagedNameRoundTripTests.cs +++ b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/ManagedNameRoundTripTests.cs @@ -451,7 +451,7 @@ public void GenericExplicitInterfaceImplementation1() containingTypeSymbol: implT, methodSymbol: implT.FindMethod("TestClasses.IImplementation.ImplMethod0"), managedTypeName: "TestClasses.Impl`1", - managedMethodName: "TestClasses.IImplementation.ImplMethod0"); + managedMethodName: "'TestClasses.IImplementation.ImplMethod0'"); } [TestMethod] @@ -464,7 +464,7 @@ public void GenericExplicitInterfaceImplementation2() containingTypeSymbol: implT, methodSymbol: implT.FindMethod("TestClasses.IImplementation.ImplMethod1"), managedTypeName: "TestClasses.Impl`1", - managedMethodName: "TestClasses.IImplementation.ImplMethod1(!0)"); + managedMethodName: "'TestClasses.IImplementation.ImplMethod1'(!0)"); } [TestMethod] @@ -477,7 +477,7 @@ public void GenericExplicitInterfaceImplementation3() containingTypeSymbol: implT, methodSymbol: implT.FindMethod("TestClasses.IImplementation.ImplMethod2"), managedTypeName: "TestClasses.Impl`1", - managedMethodName: "TestClasses.IImplementation.ImplMethod2`1(!0,!!0,System.String)"); + managedMethodName: "'TestClasses.IImplementation.ImplMethod2'`1(!0,!!0,System.String)"); } [TestMethod] diff --git a/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/SpecialNameTests.cs b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/SpecialNameTests.cs new file mode 100644 index 0000000000..01e97719e4 --- /dev/null +++ b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/ManagedNameUtilities/SpecialNameTests.cs @@ -0,0 +1,43 @@ +๏ปฟ// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities.UnitTests +{ + using Microsoft.TestPlatform.TestUtilities; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + using System.Reflection; + + [TestClass] + [TestCategory("Windows")] + [TestCategory("AcceptanceTests")] + public class SpecialNameTests + { + [TestMethod] + public void VerifyThatInvalidIdentifierNamesAreParsed() + { + var environment = new IntegrationTestEnvironment(); + var asset = environment.GetTestAsset("CILProject.dll", "net451"); + var assembly = Assembly.LoadFrom(asset); + var types = assembly.GetTypes(); + + foreach (var type in types) + { + var methods = type.GetMethods(); + + foreach (var method in methods) + { + if (method.DeclaringType != type) continue; + + ManagedNameHelper.GetManagedName(method, out var typeName, out var methodName); + var methodInfo = ManagedNameHelper.GetMethod(assembly, typeName, methodName); + ManagedNameHelper.GetManagedName(methodInfo, out var typeName2, out var methodName2); + + Assert.IsTrue(method == methodInfo); + Assert.AreEqual(typeName, typeName2, $"Type parse roundtrip test failed: {method} ({typeName} != {typeName2})"); + Assert.AreEqual(methodName, methodName2, $"Method parse roundtrip test failed: {method} ({methodName} != {methodName2})"); + } + } + } + } +} diff --git a/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Microsoft.TestPlatform.AdapterUtilities.UnitTests.csproj b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Microsoft.TestPlatform.AdapterUtilities.UnitTests.csproj index dabed0d2f0..7c0d0612d7 100644 --- a/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Microsoft.TestPlatform.AdapterUtilities.UnitTests.csproj +++ b/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Microsoft.TestPlatform.AdapterUtilities.UnitTests.csproj @@ -22,6 +22,7 @@ + diff --git a/test/TestAssets/CILProject/CILProject.proj b/test/TestAssets/CILProject/CILProject.proj new file mode 100644 index 0000000000..cefbd5f276 --- /dev/null +++ b/test/TestAssets/CILProject/CILProject.proj @@ -0,0 +1,68 @@ + + + ..\..\..\ + $(TP_PACKAGES_DIR)\ + $(TestPlatformRoot)\packages\ + + + + + + + + net451 + bin\$(Configuration) + true + false + false + + + + + $(PackagesPath)microsoft.netcore.ilasm\$(ILAsmPackageVersion)\runtimes\native + $(IlasmPath)ilasm.exe + $(IlasmPath)ilasm + + + + + + + + + $(IlasmPath)\ + $(IlasmPath)ilasm + + + + + + + + + + + + + <_OutputTypeArgument Condition="'$(OutputType)' == 'Library'">-DLL + <_OutputTypeArgument Condition="'$(OutputType)' == 'Exe'">-EXE + + <_KeyFileArgument Condition="'$(KeyOriginatorFile)' != ''">-KEY=$(KeyOriginatorFile) + + <_IlasmSwitches Condition="'$(FoldIdenticalMethods)' == 'True'">$(_IlasmSwitches) -FOLD + <_IlasmSwitches Condition="'$(SizeOfStackReserve)' != ''">$(_IlasmSwitches) -STACK=$(SizeOfStackReserve) + <_IlasmSwitches Condition="'$(DebugType)' == 'Full'">$(_IlasmSwitches) -DEBUG + <_IlasmSwitches Condition="'$(DebugType)' == 'Impl'">$(_IlasmSwitches) -DEBUG=IMPL + <_IlasmSwitches Condition="'$(DebugType)' == 'PdbOnly'">$(_IlasmSwitches) -DEBUG=OPT + <_IlasmSwitches Condition="'$(Optimize)' == 'True'">$(_IlasmSwitches) -OPTIMIZE + <_IlasmSwitches Condition="'$(IlasmResourceFile)' != ''">$(_IlasmSwitches) -RESOURCES=$(IlasmResourceFile) + + + + + + + + + + \ No newline at end of file diff --git a/test/TestAssets/CILProject/OrphanMethod.il b/test/TestAssets/CILProject/OrphanMethod.il new file mode 100644 index 0000000000..d13d1457d1 --- /dev/null +++ b/test/TestAssets/CILProject/OrphanMethod.il @@ -0,0 +1,279 @@ +๏ปฟ.assembly OrphanMethod {} +.assembly extern mscorlib {} + +.method static public int32 Add(int32 x, int32 y) cil managed +{ + .maxstack 2 + + ldarg.0 + ldarg.1 + add + ret +} + +.method static public int32 'An awesome method to add ๐“งโž•๐“จ'(int32 '๐“ง', int32 '๐“จ') cil managed +{ + .maxstack 2 + + ldarg.0 + ldarg.1 + add + ret +} + +.class public CleanNamespaceName.SecondLevel.'๐Œ๐ฒ ๐—ฎ๐˜„๐—ฒ๐˜€๐—ผ๐—บ๐—ฒ ๐˜ค๐˜ญ๐˜ข๐˜ด๐˜ด ๐˜ข๐˜ฏ ๐’Š๐’๐’‚๐’„๐’„๐’†๐’”๐’”๐’Š๐’ƒ๐’๐’† ๐™ฃ๐™–๐™ข๐™š ๐Ÿ˜ญ' +{ + .method static public int32 '๐‘“'(int32 '๐“ง', int32 '๐“จ') cil managed + { + .maxstack 2 + + ldarg.0 + ldarg.1 + add + ret + } + + .method static public int32 Sum(int32 '๐“ง', int32 '๐“จ') cil managed + { + .maxstack 2 + + ldarg.0 + ldarg.1 + add + ret + } + + .method static public int32 'Method with . in it'(int32 '๐“ง', int32 '๐“จ') cil managed + { + .maxstack 2 + + ldarg.0 + ldarg.1 + add + ret + } +} + +.class public CleanNamespaceName.SecondLevel.'Deeply wrong .namespace name'.'My generic class'<'Generic Type'> +{ + .field private !0 'Generic Item' + + .method public instance void .ctor() + { + .maxstack 1 + ldarg.0 + call instance void System.Object::.ctor() + + ret + } + + .method static public int32 'Method with . in it'<'Generic Type'>(!'Generic Type' '๐“ง', int32 '๐“จ') cil managed + { + .maxstack 2 + + ldarg.0 + ldarg.1 + add + ret + } +} + +.class public CleanNamespaceName.SecondLevel.'Deeply wrong .namespace name'.'NamespaceA.NamespaceB.ClassName`1+InnerClass`2' +{ + .method public instance int32 'MethodName`1(System.Int32,System.Int32,System.Int32)'() + { + .maxstack 1 + + ldc.i4.s 0 + ret + } + + .method public instance int32 'MethodName`2(System.Int32,System.Int32,System.Int32)'(int32 '1st parameter', int32 '2nd parameter') + { + .maxstack 1 + + ldc.i4.s 0 + ret + } + + .method public instance int32 'MethodName`3'(int32 '1st parameter', int32 '2nd parameter') + { + .maxstack 1 + + ldc.i4.s 1 + ret + } + + .class nested public 'Inner Class' + { + .method public instance int32 'MethodName`3'(int32 '1st parameter', int32 '2nd parameter') + { + .maxstack 1 + + ldc.i4.s 1 + ret + } + } +} + +.class public 'My generic class'<'Generic Type'> +{ + .field private !0 'Generic Item' + + .method public instance void .ctor() + { + .maxstack 1 + ldarg.0 + call instance void System.Object::.ctor() + + ret + } +} + +.class public 'NamespaceA.NamespaceB.ClassName`1+InnerClass`2' +{ + .method public instance int32 'MethodName`2(System.Int32,System.Int32,System.Int32)'() + { + .maxstack 1 + + ldc.i4.s 0 + ret + } + + .method public instance int32 'MethodName`3'(int32 '1st parameter', int32 '2nd parameter') + { + .maxstack 1 + + ldc.i4.s 1 + ret + } + + .method public hidebysig instance void Overload0() cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0(int32 i) cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0(int32 i, class 'NamespaceA.NamespaceB.ClassName`1+InnerClass`2' c) cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0(int32* p) cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0(object d) cil managed + { + .param [1] + .custom instance void [System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0(!!U u) cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0() cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0() cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0(!!U[] u) cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0(!!U[][] u) cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0(!!U[0...,0...] u) cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0(!!U[0...,0...,0...] u) cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0(class [mscorlib]System.Collections.Generic.List`1 l) cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0(class [mscorlib]System.Collections.Generic.List`1 l) cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0(class [mscorlib]System.Tuple`2 t0, + class [mscorlib]System.Tuple`2 t1) cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0(class [mscorlib]System.Tuple`1> t0) cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0(class [mscorlib]System.Tuple`2,class [mscorlib]System.Tuple`1> t) cil managed + { + .maxstack 1 + nop + ret + } + + .method public hidebysig instance void Overload0(class [mscorlib]System.Tuple`1> t) cil managed + { + .maxstack 1 + nop + ret + } +} \ No newline at end of file