From 807143052b83fd680e07bd274cc17dc25ab14cb9 Mon Sep 17 00:00:00 2001 From: yggy Date: Mon, 25 Apr 2016 16:42:55 -0700 Subject: [PATCH] fix: destructors / finalizers fix: implicit and explicit conversion operators fix: other operators (numeric, logical, etc.) fix: indexers ("Item", not "this") TODO: multi-dimensional arrays not working correctly --- ILSpy.AddIn/CodeElementXmlDocKeyProvider.cs | 31 ++++++++++++++-- ILSpy.AddIn/Samples/ILSpyAddInSamples.cs | 39 ++++++++++++++++++--- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/ILSpy.AddIn/CodeElementXmlDocKeyProvider.cs b/ILSpy.AddIn/CodeElementXmlDocKeyProvider.cs index d80b19114..54dca7ef4 100644 --- a/ILSpy.AddIn/CodeElementXmlDocKeyProvider.cs +++ b/ILSpy.AddIn/CodeElementXmlDocKeyProvider.cs @@ -45,11 +45,39 @@ namespace ICSharpCode.ILSpy.AddIn string typeName = member.FullName.Substring(0, nameIndex - 1); string memberName = member.FullName.Substring(nameIndex); + // Name substitutions for special cases. if (member.Kind == EnvDTE.vsCMElement.vsCMElementFunction) { EnvDTE80.CodeFunction2 mr = (EnvDTE80.CodeFunction2)member; if (mr.FunctionKind == EnvDTE.vsCMFunction.vsCMFunctionConstructor) { memberName = memberName.Replace(member.Name, "#ctor"); } + else if (mr.FunctionKind == EnvDTE.vsCMFunction.vsCMFunctionDestructor) { + memberName = memberName.Replace(member.Name, "Finalize"); + } + else if (mr.FunctionKind == EnvDTE.vsCMFunction.vsCMFunctionOperator) { + if (memberName.StartsWith("implicit operator")) { + memberName = "op_Implicit"; + } + else if (memberName.StartsWith("explicit operator")) { + memberName = "op_Explicit"; + } + else { + // NRefactory has a handy mapping we can make use of, just need to extract the operator sybol first. + string[] memberNameWords = member.Name.Split(' '); + if (memberNameWords.Length >= 2) { + string operatorSymbol = memberNameWords[1]; + string operatorName = ICSharpCode.NRefactory.MonoCSharp.Operator.GetMetadataName(operatorSymbol); + if (operatorName != null) { + memberName = memberName.Replace(member.Name, operatorName); + } + } + } + } + } + else if (member.Kind == EnvDTE.vsCMElement.vsCMElementProperty) { + if (member.Name == "this") { + memberName = memberName.Replace(member.Name, "Item"); + } } string[] genericTypeParameters = AppendTypeName(b, typeName, true, false); @@ -63,8 +91,7 @@ namespace ICSharpCode.ILSpy.AddIn else if (member.Kind == EnvDTE.vsCMElement.vsCMElementFunction) { EnvDTE80.CodeFunction2 mr = (EnvDTE80.CodeFunction2)member; parameters = mr.Parameters; - if (mr.Name == "op_Implicit" || mr.Name == "op_Explicit") { - // TODO: check operator overloads to see if these work + if (memberName == "op_Implicit" || memberName == "op_Explicit") { explicitReturnType = mr.Type; } } diff --git a/ILSpy.AddIn/Samples/ILSpyAddInSamples.cs b/ILSpy.AddIn/Samples/ILSpyAddInSamples.cs index b09025c7f..fc85a3462 100644 --- a/ILSpy.AddIn/Samples/ILSpyAddInSamples.cs +++ b/ILSpy.AddIn/Samples/ILSpyAddInSamples.cs @@ -10,12 +10,16 @@ using System.Collections.Generic; /// Note that this code is not compiled or used in the project in any way, it is /// only provided for reference. + // N:ILSpy.AddIn.Tests namespace ILSpy.AddIn.Tests { // T:ILSpy.AddIn.Tests.SomeClass public class SomeClass { + // E:ILSpy.AddIn.Tests.SomeClass.OnEvent + public event Action OnEvent; + // F:ILSpy.AddIn.Tests.SomeClass.mField private int mField; @@ -32,6 +36,12 @@ namespace ILSpy.AddIn.Tests } } + // P:ILSpy.AddIn.Tests.SomeClass.Item(System.Int32,System.Int32) + public int this[int x, int y] + { + get { return x + y + mField; } + } + // M:ILSpy.AddIn.Tests.SomeClass.#ctor public SomeClass() { @@ -249,6 +259,11 @@ namespace ILSpy.AddIn.Tests { } + // M:ILSpy.AddIn.Tests.SomeGenericClass`2.Finalize + ~SomeGenericClass() + { + } + // M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassMethod(`0,`1) public void GenericClassMethod(T1 a, T2 b) { @@ -311,6 +326,21 @@ namespace ILSpy.AddIn.Tests return y; } + // M:ILSpy.AddIn.Tests.SomeGenericClass`2.ArrayMethod(`0[],System.Int32[]) + public void ArrayMethod(T1[] x, int[] y) + { + } + + // NOT? M:ILSpy.AddIn.Tests.SomeGenericClass`2.ArrayMethod(`0[,],System.Int32[,]) + public void ArrayMethod(T1[,] x, int[,] y) + { + } + + // NOT! M:ILSpy.AddIn.Tests.SomeGenericClass`2.ArrayMethod([],[]) + public void ArrayMethod(T1[][] x, int[][] y) + { + } + // M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``2(`0,``0,ILSpy.AddIn.Tests.SomeClass) public T3 GenericClassGenericMethod(T1 x, T3 y, SomeClass z) { @@ -333,20 +363,21 @@ namespace ILSpy.AddIn.Tests { string foo = x.ToString() + y.ToString(); } - - // NOT M:ILSpy.AddIn.Tests.SomeGenericClass`2.operator +(ILSpy.AddIn.Tests.SomeGenericClass{`0,`1},ILSpy.AddIn.Tests.SomeGenericClass{`0,`1}) + + + // 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) { return new SomeGenericClass(); } - // NOT M:ILSpy.AddIn.Tests.SomeGenericClass`2.explicit operator NestedGeneric``2(ILSpy.AddIn.Tests.SomeGenericClass{`0,`1}) + // M:ILSpy.AddIn.Tests.SomeGenericClass`2.op_Explicit(ILSpy.AddIn.Tests.SomeGenericClass{`0,`1})~ILSpy.AddIn.Tests.SomeGenericClass`2.NestedGeneric`2 public static explicit operator NestedGeneric(SomeGenericClass sgc) { return new NestedGeneric(); } - // NOT M:ILSpy.AddIn.Tests.SomeGenericClass`2.implicit operator NestedGeneric``2(ILSpy.AddIn.Tests.SomeGenericClass{`0,`1}) + // M:ILSpy.AddIn.Tests.SomeGenericClass`2.op_Implicit(ILSpy.AddIn.Tests.SomeGenericClass{`0,`1})~ILSpy.AddIn.Tests.SomeGenericClass`2.NestedGeneric`2 public static implicit operator NestedGeneric(SomeGenericClass sgc) { return new NestedGeneric();