mirror of
https://github.com/icsharpcode/ILSpy.git
synced 2026-10-12 02:15:58 +00:00
Merge pull request #697 from yoyobbi/dev.yggy.navigate-to-item
Fix "Open code in ILSpy" issues with certain member types and overloaded methods and constructors.
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ICSharpCode.ILSpy.AddIn
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides XML documentation tags for Visual Studio CodeElements.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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.
|
||||
/// </remarks>
|
||||
public static class CodeElementXmlDocKeyProvider
|
||||
{
|
||||
#region GetKey
|
||||
public static string GetKey(EnvDTE.CodeElement member)
|
||||
{
|
||||
StringBuilder b = new StringBuilder();
|
||||
if ((member.Kind == EnvDTE.vsCMElement.vsCMElementDelegate) ||
|
||||
(member.Kind == EnvDTE.vsCMElement.vsCMElementEnum) ||
|
||||
(member.Kind == EnvDTE.vsCMElement.vsCMElementInterface) ||
|
||||
(member.Kind == EnvDTE.vsCMElement.vsCMElementStruct) ||
|
||||
(member.Kind == EnvDTE.vsCMElement.vsCMElementClass)) {
|
||||
b.Append("T:");
|
||||
AppendTypeName(b, member.FullName, true, false);
|
||||
}
|
||||
else if (member.Kind == EnvDTE.vsCMElement.vsCMElementNamespace){
|
||||
b.Append("N:");
|
||||
b.Append(member.FullName);
|
||||
}
|
||||
else {
|
||||
if (member.Kind == EnvDTE.vsCMElement.vsCMElementVariable)
|
||||
b.Append("F:");
|
||||
else if (member.Kind == EnvDTE.vsCMElement.vsCMElementProperty)
|
||||
b.Append("P:");
|
||||
else if (member.Kind == EnvDTE.vsCMElement.vsCMElementEvent)
|
||||
b.Append("E:");
|
||||
else if (member.Kind == EnvDTE.vsCMElement.vsCMElementFunction)
|
||||
b.Append("M:");
|
||||
|
||||
int nameIndex = member.FullName.LastIndexOf(member.Name);
|
||||
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);
|
||||
b.Append('.');
|
||||
string[] genericMethodParameters = AppendTypeName(b, memberName.Replace('.', '#'), true, true);
|
||||
EnvDTE.CodeElements parameters;
|
||||
EnvDTE.CodeTypeRef explicitReturnType = null;
|
||||
if (member.Kind == EnvDTE.vsCMElement.vsCMElementProperty) {
|
||||
parameters = ((EnvDTE.CodeProperty)member).Getter.Parameters;
|
||||
}
|
||||
else if (member.Kind == EnvDTE.vsCMElement.vsCMElementFunction) {
|
||||
EnvDTE80.CodeFunction2 mr = (EnvDTE80.CodeFunction2)member;
|
||||
parameters = mr.Parameters;
|
||||
if (memberName == "op_Implicit" || memberName == "op_Explicit") {
|
||||
explicitReturnType = mr.Type;
|
||||
}
|
||||
}
|
||||
else {
|
||||
parameters = null;
|
||||
}
|
||||
if (parameters != null && parameters.Count > 0) {
|
||||
b.Append('(');
|
||||
int i = 0;
|
||||
foreach (EnvDTE80.CodeParameter2 parameter in parameters) {
|
||||
if (i > 0) b.Append(',');
|
||||
AppendParameterTypeName(b, parameter, genericTypeParameters, genericMethodParameters);
|
||||
++i;
|
||||
}
|
||||
b.Append(')');
|
||||
}
|
||||
if (explicitReturnType != null) {
|
||||
b.Append('~');
|
||||
AppendTypeName(b, explicitReturnType.AsFullName, true, false);
|
||||
}
|
||||
}
|
||||
return b.ToString();
|
||||
}
|
||||
|
||||
static string[] AppendTypeName(StringBuilder b, string typeName, bool appendGenericParameterCount, bool isMethod)
|
||||
{
|
||||
List<string> allGenericParameters = new List<string>();
|
||||
StringBuilder genericParameterName = new StringBuilder();
|
||||
|
||||
bool inGenericParameters = false;
|
||||
int genericParameterCount = 0;
|
||||
foreach (char ch in typeName) {
|
||||
if (inGenericParameters) {
|
||||
switch (ch) {
|
||||
case ',':
|
||||
++genericParameterCount;
|
||||
allGenericParameters.Add(genericParameterName.ToString());
|
||||
genericParameterName.Clear();
|
||||
break;
|
||||
case '>':
|
||||
++genericParameterCount;
|
||||
allGenericParameters.Add(genericParameterName.ToString());
|
||||
genericParameterName.Clear();
|
||||
if (appendGenericParameterCount) {
|
||||
b.Append(genericParameterCount);
|
||||
}
|
||||
inGenericParameters = false;
|
||||
break;
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
genericParameterName.Append(ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (ch) {
|
||||
case '<':
|
||||
if (appendGenericParameterCount) {
|
||||
b.Append('`');
|
||||
if (isMethod) {
|
||||
b.Append('`');
|
||||
}
|
||||
}
|
||||
inGenericParameters = true;
|
||||
genericParameterCount = 0;
|
||||
break;
|
||||
case '[':
|
||||
case ']':
|
||||
break;
|
||||
default:
|
||||
b.Append(ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allGenericParameters.ToArray();
|
||||
}
|
||||
|
||||
private static void AppendParameterTypeName(StringBuilder b, EnvDTE80.CodeParameter2 parameter, string[] genericTypeParameters, string[] genericMethodParameters)
|
||||
{
|
||||
EnvDTE80.CodeTypeRef2 parameterTypeRef = (EnvDTE80.CodeTypeRef2)parameter.Type;
|
||||
string parameterTypeString = parameterTypeRef.AsFullName;
|
||||
|
||||
int substringStart = 0;
|
||||
for (int i = 0; i < parameterTypeString.Length; ++i) {
|
||||
char ch = parameterTypeString[i];
|
||||
switch (ch) {
|
||||
case '<':
|
||||
AppendParameterTypeSubstring(b, parameterTypeString, substringStart, i, genericTypeParameters, genericMethodParameters);
|
||||
substringStart = i + 1;
|
||||
b.Append('{');
|
||||
break;
|
||||
case '>':
|
||||
AppendParameterTypeSubstring(b, parameterTypeString, substringStart, i, genericTypeParameters, genericMethodParameters);
|
||||
substringStart = i + 1;
|
||||
b.Append('}');
|
||||
break;
|
||||
case '[':
|
||||
case ']':
|
||||
case ',':
|
||||
AppendParameterTypeSubstring(b, parameterTypeString, substringStart, i, genericTypeParameters, genericMethodParameters);
|
||||
substringStart = i + 1;
|
||||
// Skip space after comma if present.
|
||||
if ((substringStart < parameterTypeString.Length) && (parameterTypeString[substringStart] == ' ')) {
|
||||
++substringStart;
|
||||
}
|
||||
b.Append(ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AppendParameterTypeSubstring(b, parameterTypeString, substringStart, parameterTypeString.Length, genericTypeParameters, genericMethodParameters);
|
||||
|
||||
// Append ref / out indicator if needed.
|
||||
if ((parameter.ParameterKind == EnvDTE80.vsCMParameterKind.vsCMParameterKindRef) ||
|
||||
(parameter.ParameterKind == EnvDTE80.vsCMParameterKind.vsCMParameterKindOut)) {
|
||||
b.Append('@');
|
||||
}
|
||||
|
||||
// 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.
|
||||
}
|
||||
|
||||
private static void AppendParameterTypeSubstring(StringBuilder b, string parameterTypeString, int substringStart, int substringStop, string[] genericTypeParameters, string[] genericMethodParameters)
|
||||
{
|
||||
if (substringStart < substringStop) {
|
||||
string substring = parameterTypeString.Substring(substringStart, substringStop - substringStart);
|
||||
int indexOfGenericTypeParameter = Array.IndexOf(genericTypeParameters, substring);
|
||||
int indexOfGenericMethodParameter = Array.IndexOf(genericMethodParameters, substring);
|
||||
if (indexOfGenericTypeParameter >= 0) {
|
||||
b.Append("`");
|
||||
b.Append(indexOfGenericTypeParameter);
|
||||
}
|
||||
else if (indexOfGenericMethodParameter >= 0) {
|
||||
b.Append("``");
|
||||
b.Append(indexOfGenericMethodParameter);
|
||||
}
|
||||
else {
|
||||
b.Append(substring);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -138,6 +138,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Guids.cs" />
|
||||
<Compile Include="CodeElementXmlDocKeyProvider.cs" />
|
||||
<Compile Include="Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
@@ -147,6 +148,7 @@
|
||||
<Compile Include="ILSpyAddInPackage.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="PkgCmdID.cs" />
|
||||
<None Include="Samples\ILSpyAddInSamples.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -66,22 +66,23 @@ namespace ICSharpCode.ILSpy.AddIn
|
||||
// Add our command handlers for menu (commands must exist in the .vsct file)
|
||||
OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
|
||||
if (null != mcs) {
|
||||
// Create the command for the menu item.
|
||||
// Create the command for the References context menu.
|
||||
CommandID menuCommandID = new CommandID(GuidList.guidILSpyAddInCmdSet, (int)PkgCmdIDList.cmdidOpenReferenceInILSpy);
|
||||
MenuCommand menuItem = new MenuCommand(OpenReferenceInILSpyCallback, menuCommandID);
|
||||
mcs.AddCommand(menuItem);
|
||||
|
||||
// Create the command for the menu item.
|
||||
// Create the command for the Project context menu, to open the output assembly.
|
||||
CommandID menuCommandID2 = new CommandID(GuidList.guidILSpyAddInCmdSet, (int)PkgCmdIDList.cmdidOpenProjectOutputInILSpy);
|
||||
MenuCommand menuItem2 = new MenuCommand(OpenProjectOutputInILSpyCallback, menuCommandID2);
|
||||
mcs.AddCommand(menuItem2);
|
||||
|
||||
// Create the command for the menu item.
|
||||
// Create the command for the code window context menu.
|
||||
CommandID menuCommandID3 = new CommandID(GuidList.guidILSpyAddInCmdSet, (int)PkgCmdIDList.cmdidOpenCodeItemInILSpy);
|
||||
MenuCommand menuItem3 = new MenuCommand(OpenCodeItemInILSpyCallback, menuCommandID3);
|
||||
OleMenuCommand menuItem3 = new OleMenuCommand(OpenCodeItemInILSpyCallback, menuCommandID3);
|
||||
menuItem3.BeforeQueryStatus += OpenCodeItemInILSpyCallback_BeforeQueryStatus;
|
||||
mcs.AddCommand(menuItem3);
|
||||
|
||||
// Create the command for the menu item.
|
||||
// Create the command for the Tools menu item.
|
||||
CommandID menuCommandID4 = new CommandID(GuidList.guidILSpyAddInCmdSet, (int)PkgCmdIDList.cmdidOpenILSpy);
|
||||
MenuCommand menuItem4 = new MenuCommand(OpenILSpyCallback, menuCommandID4);
|
||||
mcs.AddCommand(menuItem4);
|
||||
@@ -119,11 +120,22 @@ namespace ICSharpCode.ILSpy.AddIn
|
||||
|
||||
foreach (EnvDTE.UIHierarchyItem item in items) {
|
||||
EnvDTE.Project project = (EnvDTE.Project)item.Object;
|
||||
EnvDTE.Configuration config = project.ConfigurationManager.ActiveConfiguration;
|
||||
string projectPath = Path.GetDirectoryName(project.FileName);
|
||||
string outputPath = config.Properties.Item("OutputPath").Value.ToString();
|
||||
string assemblyFileName = project.Properties.Item("OutputFileName").Value.ToString();
|
||||
OpenAssemblyInILSpy(Path.Combine(projectPath, outputPath, assemblyFileName));
|
||||
OpenProjectInILSpy(project);
|
||||
}
|
||||
}
|
||||
|
||||
// Called when the menu is popped, determines whether "Open code in ILSpy" option is available.
|
||||
private void OpenCodeItemInILSpyCallback_BeforeQueryStatus(object sender, EventArgs e)
|
||||
{
|
||||
OleMenuCommand menuItem = sender as OleMenuCommand;
|
||||
if (menuItem != null) {
|
||||
var document = (EnvDTE.Document)(((EnvDTE80.DTE2)GetGlobalService(typeof(EnvDTE.DTE))).ActiveDocument);
|
||||
menuItem.Enabled =
|
||||
(document != null) &&
|
||||
(document.ProjectItem != null) &&
|
||||
(document.ProjectItem.ContainingProject != null) &&
|
||||
(document.ProjectItem.ContainingProject.ConfigurationManager != null) &&
|
||||
!string.IsNullOrEmpty(document.ProjectItem.ContainingProject.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,70 +143,47 @@ namespace ICSharpCode.ILSpy.AddIn
|
||||
{
|
||||
var document = (EnvDTE.Document)(((EnvDTE80.DTE2)GetGlobalService(typeof(EnvDTE.DTE))).ActiveDocument);
|
||||
var selection = (EnvDTE.TextPoint)((EnvDTE.TextSelection)document.Selection).ActivePoint;
|
||||
var projectItem = document.ProjectItem;
|
||||
|
||||
string navigateTo = null;
|
||||
// Search code elements in desired order, working from innermost to outermost.
|
||||
// Should eventually find something, and if not we'll just open the assembly itself.
|
||||
var codeElement = GetSelectedCodeElement(selection,
|
||||
EnvDTE.vsCMElement.vsCMElementFunction,
|
||||
EnvDTE.vsCMElement.vsCMElementEvent,
|
||||
EnvDTE.vsCMElement.vsCMElementVariable, // There is no vsCMElementField, fields are just variables outside of function scope.
|
||||
EnvDTE.vsCMElement.vsCMElementProperty,
|
||||
EnvDTE.vsCMElement.vsCMElementDelegate,
|
||||
EnvDTE.vsCMElement.vsCMElementEnum,
|
||||
EnvDTE.vsCMElement.vsCMElementInterface,
|
||||
EnvDTE.vsCMElement.vsCMElementStruct,
|
||||
EnvDTE.vsCMElement.vsCMElementClass,
|
||||
EnvDTE.vsCMElement.vsCMElementNamespace);
|
||||
|
||||
// Find the full name of the method or class enclosing the current selection.
|
||||
// Note that order of testing is important, need to get the narrowest, most
|
||||
// internal element first.
|
||||
//
|
||||
// Add a prefix to match the ILSpy command line (see doc\Command Line.txt).
|
||||
// The prefix characters are documented in Appendix A of the C# specification:
|
||||
// E Event
|
||||
// F Field
|
||||
// M Method (including constructors, destructors, and operators)
|
||||
// N Namespace
|
||||
// P Property (including indexers)
|
||||
// T Type (such as class, delegate, enum, interface, and struct)
|
||||
navigateTo = GetCodeElementFullName("/navigateTo:M:", projectItem, selection, EnvDTE.vsCMElement.vsCMElementFunction);
|
||||
if (navigateTo == null) {
|
||||
navigateTo = GetCodeElementFullName("/navigateTo:E:", projectItem, selection, EnvDTE.vsCMElement.vsCMElementEvent);
|
||||
if (codeElement != null) {
|
||||
OpenCodeItemInILSpy(codeElement);
|
||||
}
|
||||
if (navigateTo == null) {
|
||||
navigateTo = GetCodeElementFullName("/navigateTo:P:", projectItem, selection, EnvDTE.vsCMElement.vsCMElementProperty);
|
||||
else {
|
||||
OpenProjectInILSpy(document.ProjectItem.ContainingProject);
|
||||
}
|
||||
if (navigateTo == null) {
|
||||
navigateTo = GetCodeElementFullName("/navigateTo:T:", projectItem, selection,
|
||||
EnvDTE.vsCMElement.vsCMElementDelegate,
|
||||
EnvDTE.vsCMElement.vsCMElementEnum,
|
||||
EnvDTE.vsCMElement.vsCMElementInterface,
|
||||
EnvDTE.vsCMElement.vsCMElementStruct,
|
||||
EnvDTE.vsCMElement.vsCMElementClass);
|
||||
}
|
||||
|
||||
EnvDTE.Project project = projectItem.ContainingProject;
|
||||
EnvDTE.Configuration config = project.ConfigurationManager.ActiveConfiguration;
|
||||
string projectPath = Path.GetDirectoryName(project.FileName);
|
||||
string outputPath = config.Properties.Item("OutputPath").Value.ToString();
|
||||
string assemblyFileName = project.Properties.Item("OutputFileName").Value.ToString();
|
||||
|
||||
// Note that if navigateTo is still null this will just open ILSpy on the assembly.
|
||||
OpenAssemblyInILSpy(Path.Combine(projectPath, outputPath, assemblyFileName), navigateTo);
|
||||
}
|
||||
|
||||
private string GetCodeElementFullName(string prefix, EnvDTE.ProjectItem file, EnvDTE.TextPoint selection, params EnvDTE.vsCMElement[] elementTypes)
|
||||
private EnvDTE.CodeElement GetSelectedCodeElement(EnvDTE.TextPoint selection, params EnvDTE.vsCMElement[] elementTypes)
|
||||
{
|
||||
foreach (var elementType in elementTypes)
|
||||
{
|
||||
try
|
||||
{
|
||||
var codeElement = file.FileCodeModel.CodeElementFromPoint(selection, elementType);
|
||||
if (elementType == EnvDTE.vsCMElement.vsCMElementFunction)
|
||||
{
|
||||
// TODO: use codeElement.Parameters to disambiguate overloaded methods
|
||||
}
|
||||
return prefix + codeElement.FullName;
|
||||
}
|
||||
catch (COMException)
|
||||
{
|
||||
//Don’t do anything – this is expected if there is no such code element at specified point.
|
||||
foreach (var elementType in elementTypes) {
|
||||
var codeElement = selection.CodeElement[elementType];
|
||||
if (codeElement != null) {
|
||||
return codeElement;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void OpenCodeItemInILSpy(EnvDTE.CodeElement codeElement)
|
||||
{
|
||||
string codeElementKey = CodeElementXmlDocKeyProvider.GetKey(codeElement);
|
||||
OpenProjectInILSpy(codeElement.ProjectItem.ContainingProject, "/navigateTo:" + codeElementKey);
|
||||
}
|
||||
|
||||
private void OpenILSpyCallback(object sender, EventArgs e)
|
||||
{
|
||||
Process.Start(GetILSpyPath());
|
||||
@@ -206,6 +195,15 @@ namespace ICSharpCode.ILSpy.AddIn
|
||||
return Path.Combine(basePath, "ILSpy.exe");
|
||||
}
|
||||
|
||||
private void OpenProjectInILSpy(EnvDTE.Project project, params string[] arguments)
|
||||
{
|
||||
EnvDTE.Configuration config = project.ConfigurationManager.ActiveConfiguration;
|
||||
string projectPath = Path.GetDirectoryName(project.FileName);
|
||||
string outputPath = config.Properties.Item("OutputPath").Value.ToString();
|
||||
string assemblyFileName = project.Properties.Item("OutputFileName").Value.ToString();
|
||||
OpenAssemblyInILSpy(Path.Combine(projectPath, outputPath, assemblyFileName), arguments);
|
||||
}
|
||||
|
||||
private void OpenAssemblyInILSpy(string assemblyFileName, params string[] arguments)
|
||||
{
|
||||
if (!File.Exists(assemblyFileName)) {
|
||||
|
||||
@@ -0,0 +1,420 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// Sample source file indicating a wide variety of code elements that should work
|
||||
/// with the "Open code in ILSpy" Visual Studio add-in feature. Each code element is
|
||||
/// commented with the string generated by CodeElementXmlDocKeyProvider.GetKey and
|
||||
/// used with the ILSpy /navigateTo command line option.
|
||||
///
|
||||
/// 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;
|
||||
|
||||
// P:ILSpy.AddIn.Tests.SomeClass.Property
|
||||
private int Property
|
||||
{
|
||||
get
|
||||
{
|
||||
return mField;
|
||||
}
|
||||
set
|
||||
{
|
||||
mField = value;
|
||||
}
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
mField = 0;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.#ctor(System.Int32)
|
||||
public SomeClass(int x)
|
||||
{
|
||||
mField = x;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.#ctor(System.Int32,System.Int32)
|
||||
public SomeClass(int x, int y)
|
||||
{
|
||||
mField = x + y;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.Method
|
||||
public int Method()
|
||||
{
|
||||
return mField;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.MethodWithGenericParameter(System.IEquatable{System.String})
|
||||
public void MethodWithGenericParameter(IEquatable<string> x)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.MethodWithGenericParameter(System.IEquatable{System.String},System.Int32)
|
||||
public void MethodWithGenericParameter(IEquatable<string> x, int y)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.GenericMethod``1(``0)
|
||||
public int GenericMethod<T>(T x)
|
||||
{
|
||||
return mField + x.GetHashCode();
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.GenericOverloadedMethod``1(System.Int32,``0)
|
||||
public int GenericOverloadedMethod<T1>(int x, T1 y)
|
||||
{
|
||||
return mField + x + y.GetHashCode();
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.GenericOverloadedMethod``2(System.Int32,``0,``1)
|
||||
public int GenericOverloadedMethod<T1, T2>(int x, T1 y, T2 z)
|
||||
{
|
||||
return mField + x + y.GetHashCode() + z.GetHashCode();
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedMethod
|
||||
public int OverloadedMethod()
|
||||
{
|
||||
return mField * mField;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedMethod(System.Int32)
|
||||
public int OverloadedMethod(int m)
|
||||
{
|
||||
return mField * m;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedMethod(System.Int32,System.Int32)
|
||||
public int OverloadedMethod(int m1, int m2)
|
||||
{
|
||||
return mField * m1 * m2;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1
|
||||
public int OverloadedGenericMethod<T>()
|
||||
{
|
||||
return mField * mField;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1(System.Int32)
|
||||
public int OverloadedGenericMethod<T>(int m)
|
||||
{
|
||||
return mField * m;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1(System.Int32,System.Int32)
|
||||
public int OverloadedGenericMethod<T>(int m1, int m2)
|
||||
{
|
||||
return mField * m1 * m2;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1(System.Int32,System.Int32,System.Collections.IEnumerable)
|
||||
public int OverloadedGenericMethod<T>(int m1, int m2, IEnumerable m3)
|
||||
{
|
||||
return mField * m1 * m2;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1(System.Int32,System.Int32,System.Collections.Generic.IEnumerable{``0})
|
||||
public int OverloadedGenericMethod<T>(int m1, int m2, IEnumerable<T> m3)
|
||||
{
|
||||
return mField * m1 * m2;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1(System.Int32,System.Int32,System.Collections.Generic.IEnumerable{System.String})
|
||||
public int OverloadedGenericMethod<T>(int m1, int m2, IEnumerable<string> m3)
|
||||
{
|
||||
return mField * m1 * m2;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1(System.Collections.Generic.IEnumerable{System.Collections.Generic.IEnumerable{ILSpy.AddIn.Tests.SomeGenericClass{System.String,``0}}})
|
||||
public int OverloadedGenericMethod<T>(IEnumerable<IEnumerable<SomeGenericClass<string, T>>> m3)
|
||||
{
|
||||
return mField;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1(ILSpy.AddIn.Tests.SomeGenericClass{``0,ILSpy.AddIn.Tests.SomeGenericClass{``0,``0}}.NestedGeneric{System.String,``0})
|
||||
public void OverloadedGenericMethod<T>(SomeGenericClass<T, SomeGenericClass<T, T>>.NestedGeneric<string, T> wow)
|
||||
{
|
||||
}
|
||||
|
||||
// T:ILSpy.AddIn.Tests.SomeClass.NestedEnum
|
||||
public enum NestedEnum
|
||||
{
|
||||
// F:ILSpy.AddIn.Tests.SomeClass.NestedEnum.First
|
||||
First = 1,
|
||||
Second = 2,
|
||||
Third = 3
|
||||
}
|
||||
|
||||
// T:ILSpy.AddIn.Tests.SomeClass.NestedInterface
|
||||
public interface NestedInterface
|
||||
{
|
||||
// P:ILSpy.AddIn.Tests.SomeClass.NestedInterface.SomeProperty
|
||||
int SomeProperty { get; }
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.NestedInterface.SomeMethod
|
||||
int SomeMethod();
|
||||
}
|
||||
|
||||
// T:ILSpy.AddIn.Tests.SomeClass.NestedClass
|
||||
public class NestedClass : NestedInterface
|
||||
{
|
||||
// F:ILSpy.AddIn.Tests.SomeClass.NestedClass.mX
|
||||
private int mX;
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.NestedClass.#ctor(System.Int32)
|
||||
public NestedClass(int x)
|
||||
{
|
||||
mX = x;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.NestedClass.#ctor(ILSpy.AddIn.Tests.SomeClass.NestedEnum)
|
||||
public NestedClass(NestedEnum x)
|
||||
{
|
||||
mX = (int)x;
|
||||
}
|
||||
|
||||
// P:ILSpy.AddIn.Tests.SomeClass.NestedClass.SomeProperty
|
||||
public int SomeProperty
|
||||
{
|
||||
get { return mX; }
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.NestedClass.SomeMethod
|
||||
public int SomeMethod()
|
||||
{
|
||||
return mX * mX;
|
||||
}
|
||||
}
|
||||
|
||||
// T:ILSpy.AddIn.Tests.SomeClass.NestedStruct
|
||||
public struct NestedStruct : NestedInterface
|
||||
{
|
||||
// F:ILSpy.AddIn.Tests.SomeClass.NestedStruct.X
|
||||
public int X;
|
||||
// F:ILSpy.AddIn.Tests.SomeClass.NestedStruct.Y
|
||||
public int Y;
|
||||
|
||||
// P:ILSpy.AddIn.Tests.SomeClass.NestedStruct.SomeProperty
|
||||
public int SomeProperty
|
||||
{
|
||||
get { return X + Y; }
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeClass.NestedStruct.SomeMethod
|
||||
public int SomeMethod()
|
||||
{
|
||||
return X * Y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// T:ILSpy.AddIn.Tests.SomeGenericClass`2
|
||||
public class SomeGenericClass<T1, T2>
|
||||
{
|
||||
// F:ILSpy.AddIn.Tests.SomeGenericClass`2.mField1
|
||||
T1 mField1;
|
||||
// F:ILSpy.AddIn.Tests.SomeGenericClass`2.mField2
|
||||
T2 mField2;
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.#ctor(`0,`1)
|
||||
public SomeGenericClass(T1 a, T2 b)
|
||||
{
|
||||
mField1 = a;
|
||||
mField2 = b;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.#ctor(`0)
|
||||
public SomeGenericClass(T1 a)
|
||||
{
|
||||
mField1 = a;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.#ctor
|
||||
public SomeGenericClass()
|
||||
{
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.Finalize
|
||||
~SomeGenericClass()
|
||||
{
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassMethod(`0,`1)
|
||||
public void GenericClassMethod(T1 a, T2 b)
|
||||
{
|
||||
mField1 = a;
|
||||
mField2 = b;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassMethod(System.Int32*)
|
||||
unsafe public void GenericClassMethod(int* x)
|
||||
{
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassMethod(System.Int32*[])
|
||||
unsafe public void GenericClassMethod(int*[] x)
|
||||
{
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassMethod(`0[]@)
|
||||
unsafe public void GenericClassMethod(out T1[] x)
|
||||
{
|
||||
x = null;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassMethod(System.Int32@)
|
||||
public void GenericClassMethod(ref int a)
|
||||
{
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``1(``0@)
|
||||
public T3 GenericClassGenericMethod<T3>(ref T3 x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``1
|
||||
public T3 GenericClassGenericMethod<T3>()
|
||||
{
|
||||
return default(T3);
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``1(System.Int32)
|
||||
public void GenericClassGenericMethod<T3>(int x)
|
||||
{
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``2(`0,``1,System.Int32,`1@)
|
||||
public T4 GenericClassGenericMethod<T3, T4>(T1 x, T4 y, int z, out T2 result)
|
||||
{
|
||||
mField1 = x;
|
||||
string foo = y.ToString() + z.ToString();
|
||||
result = mField2;
|
||||
return y;
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``2(`0,``0,System.Int32[])
|
||||
public T3 GenericClassGenericMethod<T3, T4>(T1 x, T3 y, int[] z)
|
||||
{
|
||||
mField1 = x;
|
||||
string foo = y.ToString() + z.ToString();
|
||||
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(System.Int32[,],System.Int32[,])
|
||||
public void ArrayMethod(int[,] x, int[,] y)
|
||||
{
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.ArrayMethod(`0[][],System.Int32[][])
|
||||
public void ArrayMethod(T1[][] x, int[][] y)
|
||||
{
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``2(`0,``0,ILSpy.AddIn.Tests.SomeClass)
|
||||
public T3 GenericClassGenericMethod<T3, T4>(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<T3, T4>(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<T3, T4>(int[] x, SomeGenericClass<T3, T4> 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<T1, T2> operator +(SomeGenericClass<T1, T2> a, SomeGenericClass<T1, T2> b)
|
||||
{
|
||||
return new SomeGenericClass<T1, T2>();
|
||||
}
|
||||
|
||||
// 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<T1, T2>(SomeGenericClass<T1, T2> sgc)
|
||||
{
|
||||
return new NestedGeneric<T1, T2>();
|
||||
}
|
||||
|
||||
// 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<T2, T1>(SomeGenericClass<T1, T2> sgc)
|
||||
{
|
||||
return new NestedGeneric<T2, T1>();
|
||||
}
|
||||
|
||||
// T:ILSpy.AddIn.Tests.SomeGenericClass`2.NestedGeneric`2
|
||||
public class NestedGeneric<T3, T4>
|
||||
{
|
||||
// T:ILSpy.AddIn.Tests.SomeGenericClass`2.NestedGeneric`2.NestedDelegate
|
||||
public delegate int NestedDelegate(T3 x, IEnumerable<T4> y);
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.NestedGeneric`2.NestedGenericMethod``1(`0,``0)
|
||||
public void NestedGenericMethod<T5>(T1 x, T5 y)
|
||||
{
|
||||
}
|
||||
|
||||
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.NestedGeneric`2.NestedGenericMethod``3(`0,`3,``0[],System.Collections.Generic.IEnumerable{``2})
|
||||
public void NestedGenericMethod<T5, T6, T7>(T1 x, T4 y, T5[] z, IEnumerable<T7> w)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// T:SpaceFreeClass
|
||||
class SpaceFreeClass
|
||||
{
|
||||
// F:SpaceFreeClass.mField
|
||||
int mField;
|
||||
|
||||
// M:SpaceFreeClass.Method
|
||||
private void Method()
|
||||
{
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user