From 3be3f265d8d52274ebac6f278f2264421ab91350 Mon Sep 17 00:00:00 2001 From: yoyobbi Date: Mon, 2 May 2016 21:42:36 -0700 Subject: [PATCH] Fix multi-dimensional array parameters. ILSpy navigation requires the "0:" lower bound specifier. --- ILSpy.AddIn/CodeElementXmlDocKeyProvider.cs | 40 +++++++++++++++++---- ILSpy.AddIn/Samples/ILSpyAddInSamples.cs | 14 +++----- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/ILSpy.AddIn/CodeElementXmlDocKeyProvider.cs b/ILSpy.AddIn/CodeElementXmlDocKeyProvider.cs index 81dafc36b..b7210e918 100644 --- a/ILSpy.AddIn/CodeElementXmlDocKeyProvider.cs +++ b/ILSpy.AddIn/CodeElementXmlDocKeyProvider.cs @@ -11,7 +11,7 @@ namespace ICSharpCode.ILSpy.AddIn /// Used to support the "/navigateTo" command line option when opening ILSpy. Must match /// the logic of ICSharpCode.ILSpy.XmlDoc.XmlDocKeyProvider, which does the same thing for /// a Mono.Cecil.MemberReference. See "ID string format" in Appendix A of the C# language - /// specification for formatting requirements. + /// specification for formatting requirements, and Samples/ILSpyAddInSamples.cs for examples. /// public static class CodeElementXmlDocKeyProvider { @@ -191,16 +191,44 @@ namespace ICSharpCode.ILSpy.AddIn substringStart = i + 1; b.Append('}'); break; + case '[': - case ']': + AppendParameterTypeSubstring(b, parameterTypeString, substringStart, i, genericTypeParameters, genericMethodParameters); + b.Append('['); + + // Skip ahead to the closing bracket, counting commas to determine array rank. + int rank = 1; + do { + ++i; + ch = parameterTypeString[i]; + if (ch == ',') { + ++rank; + } + } + while (ch != ']'); + substringStart = i + 1; + + // For multi-dimensional arrays, add "0:" default array bounds. Note that non-standard bounds are not possible via C# declaration. + if (rank > 1) { + for (int r = 0; r < rank; ++r) { + if (r != 0) { + b.Append(','); + } + b.Append("0:"); + } + } + + b.Append(']'); + break; + case ',': AppendParameterTypeSubstring(b, parameterTypeString, substringStart, i, genericTypeParameters, genericMethodParameters); substringStart = i + 1; - // Skip space after comma if present. - if ((substringStart < parameterTypeString.Length) && (parameterTypeString[substringStart] == ' ')) { + // Skip space after comma if present. (e.g. System.Collections.Generic.KeyValuePair`2{System.String,System.String}.) + if (parameterTypeString[substringStart] == ' ') { ++substringStart; } - b.Append(ch); + b.Append(','); break; } } @@ -214,7 +242,7 @@ namespace ICSharpCode.ILSpy.AddIn } // Note there is no need to append a '*' for pointers, as this is included in the full name of the type. - // Multi-dimensional and nested arrays are also captured in the full name of the type. + // Multi-dimensional and jagged arrays are handled above during string parsing. } private static void AppendParameterTypeSubstring(StringBuilder b, string parameterTypeString, int substringStart, int substringStop, string[] genericTypeParameters, string[] genericMethodParameters) diff --git a/ILSpy.AddIn/Samples/ILSpyAddInSamples.cs b/ILSpy.AddIn/Samples/ILSpyAddInSamples.cs index 803b3bfc4..559501bd2 100644 --- a/ILSpy.AddIn/Samples/ILSpyAddInSamples.cs +++ b/ILSpy.AddIn/Samples/ILSpyAddInSamples.cs @@ -331,12 +331,12 @@ namespace ILSpy.AddIn.Tests { } - // NOT? M:ILSpy.AddIn.Tests.SomeGenericClass`2.ArrayMethod(`0[,],System.Int32[,]) + // M:ILSpy.AddIn.Tests.SomeGenericClass`2.ArrayMethod(`0[0:,0:],System.Int32[0:,0:]) public void ArrayMethod(T1[,] x, int[,] y) { } - // NOT? M:ILSpy.AddIn.Tests.SomeGenericClass`2.ArrayMethod(System.Int32[,],System.Int32[,]) + // M:ILSpy.AddIn.Tests.SomeGenericClass`2.ArrayMethod(System.Int32[0:,0:],System.Int32[0:,0:]) public void ArrayMethod(int[,] x, int[,] y) { } @@ -349,27 +349,21 @@ namespace ILSpy.AddIn.Tests // M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``2(`0,``0,ILSpy.AddIn.Tests.SomeClass) public T3 GenericClassGenericMethod(T1 x, T3 y, SomeClass z) { - mField1 = x; - string foo = y.ToString() + z.ToString(); return y; } // M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``2(`0,``0,ILSpy.AddIn.Tests.SomeClass[]@) public T3 GenericClassGenericMethod(T1 x, T3 y, out SomeClass[] z) { - mField1 = x; z = null; - string foo = y.ToString() + z.ToString(); return y; } - // M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``2(System.Int32[],ILSpy.AddIn.Tests.SomeGenericClass{``0,``1}) - public void GenericClassGenericMethod(int[] x, SomeGenericClass y) + // M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``2(System.Int32[],ILSpy.AddIn.Tests.SomeGenericClass{``0[],``1[0:,0:,0:]}[0:,0:,0:]) + public void GenericClassGenericMethod(int[] x, SomeGenericClass[,,] y) { - string foo = x.ToString() + y.ToString(); } - // M:ILSpy.AddIn.Tests.SomeGenericClass`2.op_Addition(ILSpy.AddIn.Tests.SomeGenericClass{`0,`1},ILSpy.AddIn.Tests.SomeGenericClass{`0,`1}) public static SomeGenericClass operator +(SomeGenericClass a, SomeGenericClass b) {